diff --git a/configure.ac b/configure.ac index fff155a7f..6a7574b7a 100644 --- a/configure.ac +++ b/configure.ac @@ -1595,6 +1595,18 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_TRUNCATED_HMAC" fi +# Certificate Status Request : a.k.a. OCSP stapling +AC_ARG_ENABLE([statusrequest], + [ --enable-statusrequest Enable Certificate Status Request (default: disabled)], + [ ENABLED_CERTIFICATE_STATUS_REQUEST=$enableval ], + [ ENABLED_CERTIFICATE_STATUS_REQUEST=no ] + ) + +if test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_CERTIFICATE_STATUS_REQUEST" +fi + # Renegotiation Indication - (FAKE Secure Renegotiation) AC_ARG_ENABLE([renegotiation-indication], [AS_HELP_STRING([--enable-renegotiation-indication],[Enable Renegotiation Indication (default: disabled)])], @@ -2492,6 +2504,7 @@ echo " * Server Name Indication: $ENABLED_SNI" echo " * ALPN: $ENABLED_ALPN" echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" +echo " * Status Request: $ENABLED_CERTIFICATE_STATUS_REQUEST" echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" echo " * Session Ticket: $ENABLED_SESSION_TICKET" echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION" diff --git a/examples/client/client.c b/examples/client/client.c index 533621d19..b3a11e407 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -425,7 +425,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) byte maxFragment = 0; #endif #ifdef HAVE_TRUNCATED_HMAC - byte truncatedHMAC = 0; + byte truncatedHMAC = 0; +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + byte statusRequest = 0; #endif @@ -465,8 +468,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) StackTrap(); while ((ch = mygetopt(argc, argv, - "?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:aB:")) - != -1) { + "?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:aB:W")) != -1) { switch (ch) { case '?' : Usage(); @@ -653,6 +655,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case 'W' : + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST + statusRequest = 1; + #endif + break; + case 'o' : #ifdef HAVE_OCSP useOcsp = 1; @@ -938,6 +946,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS) err_sys("UseTruncatedHMAC failed"); #endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (statusRequest) + if (wolfSSL_CTX_UseCertificateStatusRequest(ctx, WOLFSSL_CSR_OCSP) + != SSL_SUCCESS) + err_sys("UseCertificateStatusRequest failed"); +#endif #ifdef HAVE_SESSION_TICKET if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS) err_sys("UseSessionTicket failed"); @@ -1320,4 +1334,3 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - diff --git a/src/internal.c b/src/internal.c index a54a76f52..f0b998e14 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4357,7 +4357,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(HAVE_OCSP) || defined(HAVE_CRL) if (ret == 0) { int doCrlLookup = 1; - (void)doCrlLookup; #ifdef HAVE_OCSP if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) { WOLFSSL_MSG("Doing Non Leaf OCSP check"); @@ -4380,6 +4379,8 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("\tCRL check not ok"); } } +#else + (void)doCrlLookup; #endif /* HAVE_CRL */ } #endif /* HAVE_OCSP || HAVE_CRL */ @@ -4447,7 +4448,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(HAVE_OCSP) || defined(HAVE_CRL) if (fatal == 0) { int doCrlLookup = 1; - (void)doCrlLookup; #ifdef HAVE_OCSP if (ssl->ctx->cm->ocspEnabled) { WOLFSSL_MSG("Doing Leaf OCSP check"); @@ -4469,6 +4469,8 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, fatal = 0; } } +#else + (void)doCrlLookup; #endif /* HAVE_CRL */ } #endif /* HAVE_OCSP || HAVE_CRL */ @@ -4776,6 +4778,101 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, return ret; } + +static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, + word32 size) +{ + int ret = 0; + byte status_type; + word32 status_length; + + if (size < ENUM_LEN + OPAQUE24_LEN) + return BUFFER_ERROR; + + status_type = input[(*inOutIdx)++]; + + c24to32(input + *inOutIdx, &status_length); + *inOutIdx += OPAQUE24_LEN; + + if (size != ENUM_LEN + OPAQUE24_LEN + status_length) + return BUFFER_ERROR; + + switch (status_type) { + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + + case WOLFSSL_CSR_OCSP: { + + #ifdef WOLFSSL_SMALL_STACK + CertStatus* status; + OcspResponse* response; + #else + CertStatus status[1]; + OcspResponse response[1]; + #endif + + do { + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (ssl->status_request) { + ssl->status_request = 0; + break; + } + #endif + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + if (ssl->status_request_v2) { + ssl->status_request_v2 = 0; + break; + } + #endif + return BUFFER_ERROR; + } while(0); + + #ifdef WOLFSSL_SMALL_STACK + status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (status == NULL || response == NULL) { + if (status) XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (response) XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return MEMORY_ERROR; + } + #endif + + InitOcspResponse(response, status, input +*inOutIdx, status_length); + + if ((ret = OcspResponseDecode(response)) == 0) { + if (response->responseStatus != OCSP_SUCCESSFUL) + ret = FATAL_ERROR; + /* TODO CSR */ + /*else if (CompareOcspReqResp(request, response) != 0) + ret = FATAL_ERROR; */ + else if (response->status->status != CERT_GOOD) + ret = FATAL_ERROR; + } + + *inOutIdx += status_length; + + #ifdef WOLFSSL_SMALL_STACK + XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + } + break; + #endif + + default: + ret = BUFFER_ERROR; + } + + if (ret != 0) + SendAlert(ssl, alert_fatal, bad_certificate_status_response); + + return ret; +} + #endif /* !NO_CERTS */ @@ -4971,6 +5068,26 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) #endif break; +#ifndef NO_WOLFSSL_CLIENT + case certificate_status: + if (ssl->msgsReceived.got_certificate_status) { + WOLFSSL_MSG("Duplicate CertificateSatatus received"); + return DUPLICATE_MSG_E; + } + ssl->msgsReceived.got_certificate_status = 1; + + if (ssl->msgsReceived.got_certificate == 0) { + WOLFSSL_MSG("No Certificate before CertificateStatus"); + return OUT_OF_ORDER_E; + } + if (ssl->msgsReceived.got_server_key_exchange != 0) { + WOLFSSL_MSG("CertificateStatus after ServerKeyExchange"); + return OUT_OF_ORDER_E; + } + + break; +#endif + #ifndef NO_WOLFSSL_CLIENT case server_key_exchange: if (ssl->msgsReceived.got_server_key_exchange) { @@ -4979,10 +5096,18 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) } ssl->msgsReceived.got_server_key_exchange = 1; - if ( ssl->msgsReceived.got_server_hello == 0) { - WOLFSSL_MSG("No ServerHello before Cert"); + if (ssl->msgsReceived.got_server_hello == 0) { + WOLFSSL_MSG("No ServerHello before ServerKeyExchange"); return OUT_OF_ORDER_E; } + if (ssl->msgsReceived.got_certificate_status == 0) { +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (ssl->status_request) { + WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); + return OUT_OF_ORDER_E; + } +#endif + } break; #endif @@ -5224,7 +5349,12 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifndef NO_CERTS case certificate: WOLFSSL_MSG("processing certificate"); - ret = DoCertificate(ssl, input, inOutIdx, size); + ret = DoCertificate(ssl, input, inOutIdx, size); + break; + + case certificate_status: + WOLFSSL_MSG("processing certificate status"); + ret = DoCertificateStatus(ssl, input, inOutIdx, size); break; #endif diff --git a/src/ssl.c b/src/ssl.c index c20c2e3aa..8b5a2efb8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -794,6 +794,27 @@ int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx) #endif /* NO_WOLFSSL_CLIENT */ #endif /* HAVE_TRUNCATED_HMAC */ +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + +int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type) +{ + if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END) + return BAD_FUNC_ARG; + + return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type); +} + + +int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type) +{ + if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END) + return BAD_FUNC_ARG; + + return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type); +} + +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ + /* Elliptic Curves */ #ifdef HAVE_SUPPORTED_CURVES #ifndef NO_WOLFSSL_CLIENT diff --git a/src/tls.c b/src/tls.c index ec756a9df..668951b3a 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1885,6 +1885,139 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions) #endif /* HAVE_TRUNCATED_HMAC */ +/******************************************************************************/ +/* Certificate Status Request */ +/******************************************************************************/ + +#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) { + case WOLFSSL_CSR_OCSP: + /* nothing to release for now... */ + break; + } + + XFREE(csr, NULL, DYNAMIC_TYPE_TLSX); +} + +static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) +{ + /* shut up compiler warnings */ + (void) csr; (void) isRequest; + +#ifndef NO_WOLFSSL_CLIENT + if (isRequest) { + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + return ENUM_LEN + 2 * OPAQUE16_LEN; + } + } +#endif + + return 0; +} + +static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, + byte isRequest) +{ + /* shut up compiler warnings */ + (void) csr; (void) output; (void) isRequest; + +#ifndef NO_WOLFSSL_CLIENT + if (isRequest) { + word16 offset = 0; + + /* type */ + output[offset++] = csr->status_type; + + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + /* responder id list */ + c16toa(0, output + offset); + offset += OPAQUE16_LEN; + + /* request extensions */ + c16toa(0, output + offset); + offset += OPAQUE16_LEN; + break; + } + + return offset; + } +#endif + + return 0; +} + +static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, + byte isRequest) +{ + /* shut up compiler warnings */ + (void) ssl; (void) input; + + if (!isRequest) { + ssl->status_request = 1; + + return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ + } + + return 0; +} + +int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type) +{ + CertificateStatusRequest* csr = NULL; + int ret = 0; + + if (!extensions) + return BAD_FUNC_ARG; + + csr = (CertificateStatusRequest*)XMALLOC(sizeof(CertificateStatusRequest), + NULL, DYNAMIC_TYPE_TLSX); + if (!csr) + return MEMORY_E; + + csr->status_type = status_type; + + switch (status_type) { + case WOLFSSL_CSR_OCSP: + /* nothing to handle for now... */ + break; + + default: + XFREE(csr, NULL, DYNAMIC_TYPE_TLSX); + return BAD_FUNC_ARG; + } + + if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr)) != 0) { + XFREE(csr, NULL, DYNAMIC_TYPE_TLSX); + return ret; + } + + return SSL_SUCCESS; +} + +#define CSR_FREE_ALL TLSX_CSR_Free +#define CSR_GET_SIZE TLSX_CSR_GetSize +#define CSR_WRITE TLSX_CSR_Write +#define CSR_PARSE TLSX_CSR_Parse + +#else + +#define CSR_FREE_ALL(data) +#define CSR_GET_SIZE(a, b) 0 +#define CSR_WRITE(a, b, c) 0 +#define CSR_PARSE(a, b, c, d) 0 + +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ + /******************************************************************************/ /* Supported Elliptic Curves */ /******************************************************************************/ @@ -3094,6 +3227,10 @@ void TLSX_FreeAll(TLSX* list) EC_FREE_ALL(extension->data); break; + case TLSX_STATUS_REQUEST: + CSR_FREE_ALL(extension->data); + break; + case TLSX_RENEGOTIATION_INFO: SCR_FREE_ALL(extension->data); break; @@ -3161,6 +3298,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) length += EC_GET_SIZE(extension->data); break; + case TLSX_STATUS_REQUEST: + length += CSR_GET_SIZE(extension->data, isRequest); + break; + case TLSX_RENEGOTIATION_INFO: length += SCR_GET_SIZE(extension->data, isRequest); break; @@ -3230,6 +3371,11 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, offset += EC_WRITE(extension->data, output + offset); break; + case TLSX_STATUS_REQUEST: + offset += CSR_WRITE(extension->data, output + offset, + isRequest); + break; + case TLSX_RENEGOTIATION_INFO: offset += SCR_WRITE(extension->data, output + offset, isRequest); @@ -3723,6 +3869,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, ret = EC_PARSE(ssl, input + offset, size, isRequest); break; + case TLSX_STATUS_REQUEST: + WOLFSSL_MSG("Certificate Status Request extension received"); + + ret = CSR_PARSE(ssl, input + offset, size, isRequest); + break; + case TLSX_RENEGOTIATION_INFO: WOLFSSL_MSG("Secure Renegotiation extension received"); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3cc87a979..0ac8a3b67 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -43,7 +43,11 @@ #include #include - +#ifdef NO_INLINE + #include +#else + #include +#endif #ifndef NO_RC4 #include @@ -8856,18 +8860,11 @@ int EncodeOcspRequest(OcspRequest* req) algoSz = SetAlgoID(SHAh, algoArray, hashType, 0); #endif - req->issuerHash = req->cert->issuerHash; - issuerSz = SetDigest(req->cert->issuerHash, KEYID_SIZE, issuerArray); + issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray); + issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray); + snSz = SetSerialNumber(req->serial, req->serialSz, snArray); + extSz = 0; - req->issuerKeyHash = req->cert->issuerKeyHash; - issuerKeySz = SetDigest(req->cert->issuerKeyHash, - KEYID_SIZE, issuerKeyArray); - - req->serial = req->cert->serial; - req->serialSz = req->cert->serialSz; - snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); - - extSz = 0; if (req->useNonce) { WC_RNG rng; if (wc_InitRng(&rng) != 0) { @@ -8885,25 +8882,30 @@ int EncodeOcspRequest(OcspRequest* req) } totalSz = algoSz + issuerSz + issuerKeySz + snSz; - for (i = 4; i >= 0; i--) { seqSz[i] = SetSequence(totalSz, seqArray[i]); totalSz += seqSz[i]; if (i == 2) totalSz += extSz; } + totalSz = 0; for (i = 0; i < 5; i++) { XMEMCPY(output + totalSz, seqArray[i], seqSz[i]); totalSz += seqSz[i]; } + XMEMCPY(output + totalSz, algoArray, algoSz); totalSz += algoSz; + XMEMCPY(output + totalSz, issuerArray, issuerSz); totalSz += issuerSz; + XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz); totalSz += issuerKeySz; + XMEMCPY(output + totalSz, snArray, snSz); totalSz += snSz; + if (extSz != 0) { XMEMCPY(output + totalSz, extArray, extSz); totalSz += extSz; @@ -8918,14 +8920,16 @@ void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, { WOLFSSL_ENTER("InitOcspRequest"); - req->cert = cert; - req->useNonce = useNonce; - req->nonceSz = 0; - req->issuerHash = NULL; - req->issuerKeyHash = NULL; - req->serial = NULL; - req->dest = dest; - req->destSz = destSz; + ForceZero(req, sizeof(OcspRequest)); + + req->cert = cert; + req->useNonce = useNonce; + req->issuerHash = cert->issuerHash; + req->issuerKeyHash = cert->issuerKeyHash; + req->serial = cert->serial; + req->serialSz = cert->serialSz; + req->dest = dest; + req->destSz = destSz; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0540b7df2..63d4d177b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1463,7 +1463,8 @@ typedef enum { TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */ TLSX_MAX_FRAGMENT_LENGTH = 0x0001, TLSX_TRUNCATED_HMAC = 0x0004, - TLSX_SUPPORTED_GROUPS = 0x000a, + TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stappling */ + TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */ TLSX_SESSION_TICKET = 0x0023, @@ -1498,6 +1499,7 @@ WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, #elif defined(HAVE_SNI) \ || defined(HAVE_MAX_FRAGMENT) \ || defined(HAVE_TRUNCATED_HMAC) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_SUPPORTED_CURVES) \ || defined(HAVE_ALPN) \ || defined(HAVE_QSH) \ @@ -1569,6 +1571,18 @@ WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions); #endif /* HAVE_TRUNCATED_HMAC */ +/** Certificate Status Request - RFC 6066 (session 8) */ +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + +typedef struct { + byte status_type; +} CertificateStatusRequest; + +WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions, + byte status_type); + +#endif + /** Supported Elliptic Curves - RFC 4492 (session 4) */ #ifdef HAVE_SUPPORTED_CURVES @@ -2301,6 +2315,7 @@ typedef struct MsgsReceived { word16 got_hello_verify_request:1; word16 got_session_ticket:1; word16 got_certificate:1; + word16 got_certificate_status:1; word16 got_server_key_exchange:1; word16 got_certificate_request:1; word16 got_server_hello_done:1; @@ -2452,6 +2467,9 @@ struct WOLFSSL { #ifdef HAVE_TRUNCATED_HMAC byte truncated_hmac; #endif + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST + byte status_request; + #endif #ifdef HAVE_SECURE_RENEGOTIATION SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */ #endif /* user turned on */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c11d3d5fd..b507df897 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -188,6 +188,7 @@ enum AlertDescription { #endif no_renegotiation = 100, unrecognized_name = 112, /**< RFC 6066, section 3 */ + bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ no_application_protocol = 120 }; @@ -1406,6 +1407,24 @@ WOLFSSL_API int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx); #endif #endif +/* Certificate Status Request */ +/* Certificate Status Type */ +enum { + WOLFSSL_CSR_OCSP = 1 +}; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, + unsigned char status_type); + +WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, + unsigned char status_type); + +#endif +#endif + /* Elliptic Curves */ enum { WOLFSSL_ECC_SECP160R1 = 0x10,