wolfssl
wolfssl copied to clipboard
OCSP stapling with HAProxy as a server
Version
v5.7.0-stable
Description
Hello guys !
We have some user requests to make work OCSP stapling extension with haproxy process as a server, i.e. haproxy loads, parses by itself OCSP response for the given server certificate and provides the status to clients.
haproxy is linked with libwolfssl.so.42, compiled from v5.7.0-stable.
We have some problems to make OCSP extension work, in spite of the support, which was added in our source code via this patch 3cbf09ed6411 "MEDIUM: ssl: add minimal WolfSSL support with OpenSSL compatibility mode" in haproxy ".
We have the following workflow for processing OCSP response files in DER format:
- haproxy starts and loads from the filesystem some server certificate and its corresponding OCSP response;
- it calculates CertID and it sets OCSP stapling callback here;
- it finally parses and checks OCSP response file by itself here.
Problems have started already, when we try to check CertID length via wolfSSL_i2d_OCSP_CERTID helper here. From the wolfSSL_i2d_OCSP_CERTID code we can see, that it uses rawCertId
and rawCertIdSize
fields from OcspEntry structure, which are not filled by wolfSSL_OCSP_cert_to_id. Could you, please, provide some explanations on this ?
When we did some workaround and started to simply check in our code the total length of
OcspEntry->issuerHash + OcspEntry->issuerKeyHash + OcspEntry->status->serial < OCSP_MAX_CERTID_ASN1_LENGTH (128 bytes)
,
we could advance further and could finally call wolfSSL_CTX_set_tlsext_status_cb
, which triggers the path:
wolfSSL_CTX_EnableOCSPStapling --> wolfSSL_CertManagerEnableOCSPStapling --> cm->ocspStaplingEnabled = 1
and sets our ssl_sock_ocsp_stapling_cbk
callback function.
Then we could also successfully parse DER OCSP response, wolfSSL_d2i_OCSP_RESPONSE works as expected. So, finally we've successfully loaded and checked OCSP response data, but still no OCSP extension provided in SERVER HELLO, when a client sends CLIENT HELLO with Certificate Status Request (TLSv1.2).
From WolfSSL debug logs we see that SendCertificateStatus returns 0 in the case:
wolfSSL Entering wolfSSL_new
wolfSSL Entering ReinitSSL
RNG_HEALTH_TEST_CHECK_SIZE = 128
sizeof(seedB_data) = 128
opened /dev/urandom.
rnd read...
wolfSSL Entering SetSSL_CTX
wolfSSL Entering wolfSSL_set_options
SSL_OP_ALL
WOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2
SSL_OP_NO_TLSv1_1
SSL_OP_NO_TLSv1
SSL_OP_NO_SSLv3
WOLFSSL_OP_CIPHER_SERVER_PREFERENCE
SSL_OP_NO_COMPRESSION: compression not compiled in
wolfSSL Entering wolfSSL_NewSession
InitSSL done. return 0 (success)
wolfSSL_new InitSSL success
wolfSSL Leaving wolfSSL_new InitSSL =, return 0
wolfSSL Entering wolfSSL_BIO_new
wolfSSL Stub wolfSSL_BIO_set_init not implemented
...
wolfSSL Entering wolfSSL_accept
wolfSSL Entering ReinitSSL
wolfSSL Entering RetrySendAlert
wolfSSL Entering RetrySendAlert
wolfSSL Entering BioReceive
wolfSSL Entering wolfSSL_BIO_read
wolfSSL Entering wolfSSL_BIO_get_data
wolfSSL Entering wolfSSL_BIO_clear_retry_flags
Client attempting to connect with different version
growing input buffer
wolfSSL Entering BioReceive
wolfSSL Entering wolfSSL_BIO_read
wolfSSL Entering wolfSSL_BIO_get_data
wolfSSL Entering wolfSSL_BIO_clear_retry_flags
received record layer msg
got HANDSHAKE
wolfSSL Entering wolfSSL_get_options
wolfSSL Entering DoTls13HandShakeMsg
wolfSSL Entering EarlySanityCheckMsgReceived
wolfSSL Leaving EarlySanityCheckMsgReceived, return 0
wolfSSL Entering DoTls13HandShakeMsgType
processing client hello
wolfSSL Entering DoTls13ClientHello
wolfSSL Entering DoClientHello
downgrading to TLSv1.2
Matched No Compression
Adding signature algorithms extension
Point Formats extension received
Supported Groups extension received
Session Ticket extension received
Certificate Status Request extension received
Encrypt-Then-Mac extension received
Extended Master Secret extension received
Signature Algorithms extension received
TLSX SigAlgo list exceeds max, truncating
wolfSSL Entering ALPN_Select
Calling user cert setup callback
wolfSSL Entering wolfSSL_get_client_suites_sigalgs
wolfSSL Entering wolfSSL_version
Unsupported cipher suite, CipherRequires
....
wolfSSL Entering wolfSSL_CTX_get_verify_mode
....
accept state ACCEPT_CLIENT_HELLO_DONE
accept state ACCEPT_FIRST_REPLY_DONE
wolfSSL Entering SendServerHello
growing output buffer
wolfSSL Entering wolfSSL_get_options
Session Ticket extension to write
Point Formats extension to write
Secure Renegotiation extension to write
EMS extension to write
wolfSSL Leaving SendServerHello, return 0
accept state SERVER_HELLO_SENT
wolfSSL Entering SendCertificate
growing output buffer
wolfSSL Leaving SendCertificate, return 0
accept state CERT_SENT
wolfSSL Entering SendCertificateStatus
wolfSSL Leaving SendCertificateStatus, return 0
According to the code from SendCertificateStatus, it seems, that we should enter in case WOLFSSL_CSR2_OCSP:
. Unfortunately, CreateOcspResponse
does not contain any traces to simply check where it fails.
From CreateOcspResponse
code we can see that probably it does not suppose to exit on:
/* unable to fetch status. skip. */
if (SSL_CM(ssl) == NULL || SSL_CM(ssl)->ocspStaplingEnabled == 0)
return 0;
check, as SSL_CM(ssl)->ocspStaplingEnabled was set to one.
We have an intention to make work OCSP and we could probably investigate further, but there are some worries about the fact that wolfSSL_CertManagerEnableOCSPStapling
along with ocspStaplingEnabled = 1
also sets the built-in OCSP lookup here (EmbedOcspLookup). In this lookup you build and send OCSP request to the detected OCSP URI. This is quite same logic, that we do on our side in ssl_ocsp_update_responses.
So could you please, confirm, that, if we reset cm->ocspIOCb
and cm->ocspRespFreeCb
to NULL, as we update OCSP responses by ourselves, we do not have any other drawbacks and we are on the right way to make things work. And could you also provide to us some hints, where potentially SendCertificateStatus
or CreateOcspResponse
may fail.
Many thanks in advance, Kind regards.