diff --git a/examples/server/server.c b/examples/server/server.c index 1808240a8..9e7dd230a 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -725,6 +725,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE); } #endif +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + wolfSSL_CTX_EnableOCSPStapling(ctx); +#endif #ifdef HAVE_PK_CALLBACKS if (pkCallbacks) SetupPkCallbacks(ctx, ssl); diff --git a/src/internal.c b/src/internal.c index 1c6a4c6e4..057e4c9f4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4368,7 +4368,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_OCSP if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) { WOLFSSL_MSG("Doing Non Leaf OCSP check"); - ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert); + ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL); doCrlLookup = (ret == OCSP_CERT_UNKNOWN); if (ret != 0) { doCrlLookup = 0; @@ -4469,7 +4469,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_OCSP if (doLookup && ssl->ctx->cm->ocspEnabled) { WOLFSSL_MSG("Doing Leaf OCSP check"); - ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert); + ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL); doLookup = (ret == OCSP_CERT_UNKNOWN); if (ret != 0) { WOLFSSL_MSG("\tOCSP Lookup not ok"); @@ -8141,6 +8141,86 @@ int SendCertificateRequest(WOLFSSL* ssl) else return SendBuffered(ssl); } + + +int SendCertificateStatus(WOLFSSL* ssl) +{ + int ret = 0; + byte status_type = 0; + + WOLFSSL_ENTER("SendCertificateStatus"); + + (void) ssl; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + status_type = ssl->status_request; +#endif + + switch (status_type) { +#if defined HAVE_CERTIFICATE_STATUS_REQUEST + case WOLFSSL_CSR_OCSP: { + buffer response = {NULL, 0}; + buffer der = ssl->buffers.certificate; +#ifdef WOLFSSL_SMALL_STACK + DecodedCert* cert = NULL; +#else + DecodedCert cert[1]; +#endif + + /* unable to fetch status. skip. */ + if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0) + return 0; + if (der.buffer == NULL || der.length == 0) + return 0; + +#ifdef WOLFSSL_SMALL_STACK + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (cert == NULL) + return MEMORY_E; +#endif + + InitDecodedCert(cert, der.buffer, der.length, NULL); + + if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, + ssl->ctx->cm)) != 0) { + WOLFSSL_MSG("ParseCert failed"); + } + else { + ret = CheckCertOCSP(ssl->ctx->cm->ocsp_stapling, cert, + &response); + + if (response.buffer) { + if (ret == OCSP_CERT_REVOKED || ret == OCSP_CERT_UNKNOWN) { + ret = 0; /* Forward status to client */ + } + + if (ret == 0) { + + } + + XFREE(response.buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + if (ret == OCSP_LOOKUP_FAIL) + ret = 0; /* Suppressing, not critical */ + } + + FreeDecodedCert(cert); +#ifdef WOLFSSL_SMALL_STACK + XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + } + break; +#endif + + default: + break; + } + + return ret; +} + #endif /* !NO_CERTS */ diff --git a/src/ocsp.c b/src/ocsp.c index 567a67de8..f503d5b9c 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -77,6 +77,10 @@ static void FreeOcspEntry(OcspEntry* entry) for (status = entry->status; status; status = next) { next = status->next; + + if (status->rawOcspResponse) + XFREE(status->rawOcspResponse, NULL, DYNAMIC_TYPE_OCSP_STATUS); + XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS); } } @@ -114,7 +118,7 @@ static int xstat2err(int stat) } -int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) +int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, void* encodedResponse) { int ret = OCSP_LOOKUP_FAIL; @@ -137,7 +141,7 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) #endif if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) { - ret = CheckOcspRequest(ocsp, ocspRequest); + ret = CheckOcspRequest(ocsp, ocspRequest, encodedResponse); FreeOcspRequest(ocspRequest); } @@ -186,7 +190,7 @@ static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request, static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, - OcspEntry* entry, CertStatus** status) + OcspEntry* entry, CertStatus** status, buffer* responseBuffer) { int ret = OCSP_INVALID_STATUS; @@ -204,11 +208,27 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz)) break; - if (*status) { + if (responseBuffer && *status && !(*status)->rawOcspResponse) { + /* force fetching again */ + ret = OCSP_INVALID_STATUS; + } + else if (*status) { if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE) && ((*status)->nextDate[0] != 0) && ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER)) ret = xstat2err((*status)->status); + + if (responseBuffer) { + responseBuffer->buffer = (byte*)XMALLOC( + (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (responseBuffer->buffer) { + responseBuffer->length = (*status)->rawOcspResponseSz; + XMEMCPY(responseBuffer->buffer, + (*status)->rawOcspResponse, + (*status)->rawOcspResponseSz); + } + } } UnLockMutex(&ocsp->ocspLock); @@ -216,16 +236,18 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, return ret; } -int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest) +int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, + void* encodedResponse) { - OcspEntry* entry = NULL; - CertStatus* status = NULL; - byte* request = NULL; - int requestSz = 2048; - byte* response = NULL; - const char* url; - int urlSz; - int ret = -1; + OcspEntry* entry = NULL; + CertStatus* status = NULL; + byte* request = NULL; + int requestSz = 2048; + byte* response = NULL; + buffer* responseBuffer = (buffer*) encodedResponse; + const char* url = NULL; + int urlSz = 0; + int ret = -1; #ifdef WOLFSSL_SMALL_STACK CertStatus* newStatus; @@ -237,11 +259,16 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest) WOLFSSL_ENTER("CheckOcspRequest"); + if (responseBuffer) { + responseBuffer->buffer = NULL; + responseBuffer->length = 0; + } + ret = GetOcspEntry(ocsp, ocspRequest, &entry); if (ret != 0) return ret; - ret = GetOcspStatus(ocsp, ocspRequest, entry, &status); + ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer); if (ret != OCSP_INVALID_STATUS) return ret; @@ -300,14 +327,29 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest) ret = OCSP_LOOKUP_FAIL; else { if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) { + if (responseBuffer) { + responseBuffer->buffer = (byte*)XMALLOC(ret, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (responseBuffer->buffer) { + responseBuffer->length = ret; + XMEMCPY(responseBuffer->buffer, response, ret); + } + } + ret = xstat2err(ocspResponse->status->status); if (LockMutex(&ocsp->ocspLock) != 0) ret = BAD_MUTEX_E; else { - if (status != NULL) + if (status != NULL) { + if (status->rawOcspResponse) + XFREE(status->rawOcspResponse, NULL, + DYNAMIC_TYPE_OCSP_STATUS); + /* Replace existing certificate entry with updated */ XMEMCPY(status, newStatus, sizeof(CertStatus)); + } else { /* Save new certificate entry */ status = (CertStatus*)XMALLOC(sizeof(CertStatus), @@ -320,6 +362,19 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest) } } + if (responseBuffer && responseBuffer->buffer) { + status->rawOcspResponse = (byte*)XMALLOC( + responseBuffer->length, NULL, + DYNAMIC_TYPE_OCSP_STATUS); + + if (status->rawOcspResponse) { + status->rawOcspResponseSz = responseBuffer->length; + XMEMCPY(status->rawOcspResponse, + responseBuffer->buffer, + responseBuffer->length); + } + } + UnLockMutex(&ocsp->ocspLock); } } diff --git a/src/ssl.c b/src/ssl.c index 1473748b0..38c7d7ea7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1643,6 +1643,10 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) #ifdef HAVE_OCSP if (cm->ocsp) FreeOCSP(cm->ocsp, 1); + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + if (cm->ocsp_stapling) + FreeOCSP(cm->ocsp_stapling, 1); + #endif #endif FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL); FreeMutex(&cm->caLock); @@ -3460,6 +3464,42 @@ int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm) return SSL_SUCCESS; } +/* turn on OCSP Stapling if off and compiled in, set options */ +int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = SSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling"); + if (cm == NULL) + return BAD_FUNC_ARG; + + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + if (cm->ocsp_stapling == NULL) { + cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), + cm->heap, DYNAMIC_TYPE_OCSP); + if (cm->ocsp_stapling == NULL) + return MEMORY_E; + + if (InitOCSP(cm->ocsp_stapling, cm) != 0) { + WOLFSSL_MSG("Init OCSP failed"); + FreeOCSP(cm->ocsp_stapling, 1); + cm->ocsp_stapling = NULL; + return SSL_FAILURE; + } + } + cm->ocspStaplingEnabled = 1; + + #ifndef WOLFSSL_USER_IO + cm->ocspIOCb = EmbedOcspLookup; + cm->ocspRespFreeCb = EmbedOcspRespFree; + #endif /* WOLFSSL_USER_IO */ + #else + ret = NOT_COMPILED_IN; + #endif + + return ret; +} + #ifdef HAVE_OCSP @@ -3494,7 +3534,7 @@ int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz) if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) { WOLFSSL_MSG("ParseCert failed"); } - else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) { + else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) { WOLFSSL_MSG("CheckCertOCSP failed"); } @@ -3629,6 +3669,16 @@ int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb, return BAD_FUNC_ARG; } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) +int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx) +{ + WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling"); + if (ctx) + return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm); + else + return BAD_FUNC_ARG; +} +#endif #endif /* HAVE_OCSP */ @@ -6132,6 +6182,15 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, WOLFSSL_MSG("accept state CERT_SENT"); case CERT_SENT : + if (!ssl->options.resuming) + if ( (ssl->error = SendCertificateStatus(ssl)) != 0) { + WOLFSSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } + ssl->options.acceptState = CERT_STATUS_SENT; + WOLFSSL_MSG("accept state CERT_STATUS_SENT"); + + case CERT_STATUS_SENT : if (!ssl->options.resuming) if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) { WOLFSSL_ERROR(ssl->error); diff --git a/src/tls.c b/src/tls.c index 619f96856..652c6dabf 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1891,11 +1891,6 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions) #ifdef HAVE_CERTIFICATE_STATUS_REQUEST -#ifndef HAVE_OCSP -#error Status Request Extension requires OCSP. \ - Use --enable-ocsp in the configure script or define HAVE_OCSP. -#endif - static void TLSX_CSR_Free(CertificateStatusRequest* csr) { switch (csr->status_type) { @@ -1972,7 +1967,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest) { - int ret = 0; + int ret; /* shut up compiler warnings */ (void) ssl; (void) input; @@ -2019,8 +2014,56 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ #endif } + else { +#ifndef NO_WOLFSSL_SERVER + byte status_type; + word16 offset = 0; + word16 size = 0; - return ret; + if (length < ENUM_LEN) + return BUFFER_ERROR; + + status_type = input[offset++]; + + switch (status_type) { + case WOLFSSL_CSR_OCSP: { + + /* skip responder_id_list */ + if (length - offset < OPAQUE16_LEN) + return BUFFER_ERROR; + + ato16(input + offset, &size); + offset += OPAQUE16_LEN + size; + + /* skip request_extensions */ + if (length - offset < OPAQUE16_LEN) + return BUFFER_ERROR; + + ato16(input + offset, &size); + offset += OPAQUE16_LEN + size; + + if (offset > length) + return BUFFER_ERROR; + + /* is able to send OCSP response? */ + if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled) + return 0; + } + break; + } + + ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type, + 0); + if (ret != SSL_SUCCESS) + return ret; /* throw error */ + + TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); + ssl->status_request = status_type; + +#endif + } + + return 0; } int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert) @@ -2078,7 +2121,7 @@ int TLSX_CSR_ForceRequest(WOLFSSL* ssl) case WOLFSSL_CSR_OCSP: if (ssl->ctx->cm->ocspEnabled) return CheckOcspRequest(ssl->ctx->cm->ocsp, - &csr->request.ocsp); + &csr->request.ocsp, NULL); else return OCSP_LOOKUP_FAIL; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 88073abd2..935574ac7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8776,20 +8776,13 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status, { WOLFSSL_ENTER("InitOcspResponse"); + XMEMSET(status, 0, sizeof(CertStatus)); + XMEMSET(resp, 0, sizeof(OcspResponse)); + resp->responseStatus = -1; - resp->response = NULL; - resp->responseSz = 0; - resp->producedDateFormat = 0; - resp->issuerHash = NULL; - resp->issuerKeyHash = NULL; - resp->sig = NULL; - resp->sigSz = 0; - resp->sigOID = 0; - resp->status = status; - resp->nonce = NULL; - resp->nonceSz = 0; - resp->source = source; - resp->maxIdx = inSz; + resp->status = status; + resp->source = source; + resp->maxIdx = inSz; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 76f7f108a..ead5aae36 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1361,22 +1361,26 @@ struct WOLFSSL_CRL { /* wolfSSL Certificate Manager */ struct WOLFSSL_CERT_MANAGER { Signer* caTable[CA_TABLE_SIZE]; /* the CA signer table */ - void* heap; /* heap helper */ - WOLFSSL_CRL* crl; /* CRL checker */ - WOLFSSL_OCSP* ocsp; /* OCSP checker */ - char* ocspOverrideURL; /* use this responder */ - void* ocspIOCtx; /* I/O callback CTX */ - CallbackCACache caCacheCallback; /* CA cache addition callback */ - CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */ - CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */ - CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */ - wolfSSL_Mutex caLock; /* CA list lock */ - byte crlEnabled; /* is CRL on ? */ - byte crlCheckAll; /* always leaf, but all ? */ - byte ocspEnabled; /* is OCSP on ? */ - byte ocspCheckAll; /* always leaf, but all ? */ - byte ocspSendNonce; /* send the OCSP nonce ? */ - byte ocspUseOverrideURL; /* ignore cert's responder, override */ + void* heap; /* heap helper */ + WOLFSSL_CRL* crl; /* CRL checker */ + WOLFSSL_OCSP* ocsp; /* OCSP checker */ +#if !defined(NO_WOLFSSL_SEVER) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) + WOLFSSL_OCSP* ocsp_stapling; /* OCSP checker for OCSP stapling */ +#endif + char* ocspOverrideURL; /* use this responder */ + void* ocspIOCtx; /* I/O callback CTX */ + CallbackCACache caCacheCallback; /* CA cache addition callback */ + CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */ + CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */ + CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */ + wolfSSL_Mutex caLock; /* CA list lock */ + byte crlEnabled; /* is CRL on ? */ + byte crlCheckAll; /* always leaf, but all ? */ + byte ocspEnabled; /* is OCSP on ? */ + byte ocspCheckAll; /* always leaf, but all ? */ + byte ocspSendNonce; /* send the OCSP nonce ? */ + byte ocspUseOverrideURL; /* ignore cert's responder, override */ + byte ocspStaplingEnabled; /* is OCSP Stapling on ? */ }; WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*); @@ -2033,6 +2037,7 @@ enum AcceptState { ACCEPT_FIRST_REPLY_DONE, SERVER_HELLO_SENT, CERT_SENT, + CERT_STATUS_SENT, KEY_EXCHANGE_SENT, CERT_REQ_SENT, SERVER_HELLO_DONE, @@ -2640,6 +2645,7 @@ WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32); WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int); WOLFSSL_LOCAL int SendCertificate(WOLFSSL*); WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*); +WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*); WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*); WOLFSSL_LOCAL int SendBuffered(WOLFSSL*); WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int); diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index dc76ca16e..8d05c26d0 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -39,9 +39,9 @@ typedef struct WOLFSSL_OCSP WOLFSSL_OCSP; WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*); WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic); -WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*); +WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*, void*); WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp, - OcspRequest* ocspRequest); + OcspRequest* ocspRequest, void*); #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5a30c8c81..415b4bd60 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1269,6 +1269,9 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER*, CbOCSPIO, CbOCSPRespFree, void*); + WOLFSSL_API int wolfSSL_CertManagerEnableOCSPStapling( + WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options); WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int); @@ -1287,6 +1290,8 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX*, const char*); WOLFSSL_API int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX*, CbOCSPIO, CbOCSPRespFree, void*); + + WOLFSSL_API int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX*); #endif /* !NO_CERTS */ /* end of handshake frees temporary arrays, if user needs for get_keys or diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 339680ca2..e3fd7a569 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -675,6 +675,9 @@ struct CertStatus { byte nextDate[MAX_DATE_SIZE]; byte thisDateFormat; byte nextDateFormat; + + byte* rawOcspResponse; + word32 rawOcspResponseSz; };