From 21d70636dc977622e7c402f5089e7f6e6d4f799f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Mon, 2 Nov 2015 15:51:01 -0300 Subject: [PATCH] Merge branch csr into 'master' --- .gitignore | 10 +- configure.ac | 213 +++++++++-------- examples/client/client.c | 29 ++- examples/server/server.c | 2 +- pull_to_vagrant.sh | 1 + src/internal.c | 193 +++++++++++++-- src/ocsp.c | 282 +++++++++++++--------- src/ssl.c | 56 ++++- src/tls.c | 492 +++++++++++++++++++++++++++++++------- wolfcrypt/src/asn.c | 214 +++++++++++------ wolfssl/error-ssl.h | 218 ++++++++--------- wolfssl/internal.h | 154 +++++++----- wolfssl/ocsp.h | 2 + wolfssl/ssl.h | 66 +++-- wolfssl/wolfcrypt/asn.h | 33 ++- wolfssl/wolfcrypt/types.h | 3 +- 16 files changed, 1337 insertions(+), 631 deletions(-) diff --git a/.gitignore b/.gitignore index d84c77d378..dd3e2058e9 100644 --- a/.gitignore +++ b/.gitignore @@ -112,11 +112,11 @@ cov-int cyassl.tgz *.log *.trs -IDE\MDK-ARM\Projects/ -IDE\MDK-ARM\STM32F2xx_StdPeriph_Lib/inc -IDE\MDK-ARM\STM32F2xx_StdPeriph_Lib/src -IDE\MDK-ARM\LPC43xx\Drivers/ -IDE\MDK-ARM\LPC43xx\LPC43xx/ +IDE/MDK-ARM/Projects/ +IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/inc +IDE/MDK-ARM/STM32F2xx_StdPeriph_Lib/src +IDE/MDK-ARM/LPC43xx/Drivers/ +IDE/MDK-ARM/LPC43xx/LPC43xx/ *.gcno *.gcda *.gcov diff --git a/configure.ac b/configure.ac index d7fdca0e8b..51178b1146 100644 --- a/configure.ac +++ b/configure.ac @@ -1655,6 +1655,26 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_TRUNCATED_HMAC" fi +# Certificate Status Request : a.k.a. OCSP Stapling +AC_ARG_ENABLE([ocspstapling], + [AS_HELP_STRING([--enable-ocspstapling],[Enable Certificate Status Request - a.k.a. OCSP Stapling (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" + + # Requires OCSP make sure on + if test "x$ENABLED_OCSP" = "xno" + then + ENABLED_OCSP="yes" + AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP" + AM_CONDITIONAL([BUILD_OCSP], [test "x$ENABLED_OCSP" = "xyes"]) + fi +fi + # Renegotiation Indication - (FAKE Secure Renegotiation) AC_ARG_ENABLE([renegotiation-indication], [AS_HELP_STRING([--enable-renegotiation-indication],[Enable Renegotiation Indication (default: disabled)])], @@ -2613,103 +2633,104 @@ done < $OPTION_FILE echo "---" echo "Configuration summary for $PACKAGE_NAME version $VERSION" echo "" -echo " * Installation prefix: $prefix" -echo " * System type: $host_vendor-$host_os" -echo " * Host CPU: $host_cpu" -echo " * C Compiler: $CC" -echo " * C Flags: $CFLAGS" -echo " * C++ Compiler: $CXX" -echo " * C++ Flags: $CXXFLAGS" -echo " * CPP Flags: $CPPFLAGS" -echo " * CCAS Flags: $CCASFLAGS" -echo " * LIB Flags: $LIB" -echo " * Debug enabled: $ax_enable_debug" -echo " * Warnings as failure: $ac_cv_warnings_as_errors" -echo " * make -j: $enable_jobserver" -echo " * VCS checkout: $ac_cv_vcs_checkout" +echo " * Installation prefix: $prefix" +echo " * System type: $host_vendor-$host_os" +echo " * Host CPU: $host_cpu" +echo " * C Compiler: $CC" +echo " * C Flags: $CFLAGS" +echo " * C++ Compiler: $CXX" +echo " * C++ Flags: $CXXFLAGS" +echo " * CPP Flags: $CPPFLAGS" +echo " * CCAS Flags: $CCASFLAGS" +echo " * LIB Flags: $LIB" +echo " * Debug enabled: $ax_enable_debug" +echo " * Warnings as failure: $ac_cv_warnings_as_errors" +echo " * make -j: $enable_jobserver" +echo " * VCS checkout: $ac_cv_vcs_checkout" echo echo " Features " -echo " * Single threaded: $ENABLED_SINGLETHREADED" -echo " * Filesystem: $ENABLED_FILESYSTEM" -echo " * OpenSSH Build: $ENABLED_OPENSSH" -echo " * OpenSSL Extra API: $ENABLED_OPENSSLEXTRA" -echo " * Max Strength Build: $ENABLED_MAXSTRENGTH" -echo " * fastmath: $ENABLED_FASTMATH" -echo " * sniffer: $ENABLED_SNIFFER" -echo " * snifftest: $ENABLED_SNIFFTEST" -echo " * ARC4: $ENABLED_ARC4" -echo " * AES: $ENABLED_AES" -echo " * AES-NI: $ENABLED_AESNI" -echo " * AES-GCM: $ENABLED_AESGCM" -echo " * AES-CCM: $ENABLED_AESCCM" -echo " * DES3: $ENABLED_DES3" -echo " * IDEA: $ENABLED_IDEA" -echo " * Camellia: $ENABLED_CAMELLIA" -echo " * NULL Cipher: $ENABLED_NULL_CIPHER" -echo " * MD5: $ENABLED_MD5" -echo " * RIPEMD: $ENABLED_RIPEMD" -echo " * SHA: $ENABLED_SHA" -echo " * SHA-512: $ENABLED_SHA512" -echo " * BLAKE2: $ENABLED_BLAKE2" -echo " * keygen: $ENABLED_KEYGEN" -echo " * certgen: $ENABLED_CERTGEN" -echo " * certreq: $ENABLED_CERTREQ" -echo " * certext: $ENABLED_CERTEXT" -echo " * HC-128: $ENABLED_HC128" -echo " * RABBIT: $ENABLED_RABBIT" -echo " * CHACHA: $ENABLED_CHACHA" -echo " * Hash DRBG: $ENABLED_HASHDRBG" -echo " * PWDBASED: $ENABLED_PWDBASED" -echo " * wolfCrypt Only: $ENABLED_CRYPTONLY" -echo " * HKDF: $ENABLED_HKDF" -echo " * MD4: $ENABLED_MD4" -echo " * PSK: $ENABLED_PSK" -echo " * Poly1305: $ENABLED_POLY1305" -echo " * LEANPSK: $ENABLED_LEANPSK" -echo " * RSA: $ENABLED_RSA" -echo " * DSA: $ENABLED_DSA" -echo " * DH: $ENABLED_DH" -echo " * ECC: $ENABLED_ECC" -echo " * CURVE25519: $ENABLED_CURVE25519" -echo " * ED25519: $ENABLED_ED25519" -echo " * FPECC: $ENABLED_FPECC" -echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" -echo " * ASN: $ENABLED_ASN" -echo " * Anonymous cipher: $ENABLED_ANON" -echo " * CODING: $ENABLED_CODING" -echo " * MEMORY: $ENABLED_MEMORY" -echo " * I/O POOL: $ENABLED_IOPOOL" -echo " * LIGHTY: $ENABLED_LIGHTY" -echo " * STUNNEL: $ENABLED_STUNNEL" -echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS" -echo " * DTLS: $ENABLED_DTLS" -echo " * Old TLS Versions: $ENABLED_OLD_TLS" -echo " * SSL version 3.0: $ENABLED_SSLV3" -echo " * OCSP: $ENABLED_OCSP" -echo " * CRL: $ENABLED_CRL" -echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR" -echo " * Persistent session cache: $ENABLED_SAVESESSION" -echo " * Persistent cert cache: $ENABLED_SAVECERT" -echo " * Atomic User Record Layer: $ENABLED_ATOMICUSER" -echo " * Public Key Callbacks: $ENABLED_PKCALLBACKS" -echo " * NTRU: $ENABLED_NTRU" -echo " * SNI: $ENABLED_SNI" -echo " * ALPN: $ENABLED_ALPN" -echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" -echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" -echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION" -echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION" -echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" -echo " * Session Ticket: $ENABLED_SESSION_TICKET" -echo " * All TLS Extensions: $ENABLED_TLSX" -echo " * PKCS#7 $ENABLED_PKCS7" -echo " * wolfSCEP $ENABLED_WOLFSCEP" -echo " * Secure Remote Password $ENABLED_SRP" -echo " * Small Stack: $ENABLED_SMALL_STACK" -echo " * valgrind unit tests: $ENABLED_VALGRIND" -echo " * LIBZ: $ENABLED_LIBZ" -echo " * Examples: $ENABLED_EXAMPLES" -echo " * User Crypto: $ENABLED_USER_CRYPTO" -echo " * Fast RSA: $ENABLED_FAST_RSA" +echo " * Single threaded: $ENABLED_SINGLETHREADED" +echo " * Filesystem: $ENABLED_FILESYSTEM" +echo " * OpenSSH Build: $ENABLED_OPENSSH" +echo " * OpenSSL Extra API: $ENABLED_OPENSSLEXTRA" +echo " * Max Strength Build: $ENABLED_MAXSTRENGTH" +echo " * fastmath: $ENABLED_FASTMATH" +echo " * sniffer: $ENABLED_SNIFFER" +echo " * snifftest: $ENABLED_SNIFFTEST" +echo " * ARC4: $ENABLED_ARC4" +echo " * AES: $ENABLED_AES" +echo " * AES-NI: $ENABLED_AESNI" +echo " * AES-GCM: $ENABLED_AESGCM" +echo " * AES-CCM: $ENABLED_AESCCM" +echo " * DES3: $ENABLED_DES3" +echo " * IDEA: $ENABLED_IDEA" +echo " * Camellia: $ENABLED_CAMELLIA" +echo " * NULL Cipher: $ENABLED_NULL_CIPHER" +echo " * MD5: $ENABLED_MD5" +echo " * RIPEMD: $ENABLED_RIPEMD" +echo " * SHA: $ENABLED_SHA" +echo " * SHA-512: $ENABLED_SHA512" +echo " * BLAKE2: $ENABLED_BLAKE2" +echo " * keygen: $ENABLED_KEYGEN" +echo " * certgen: $ENABLED_CERTGEN" +echo " * certreq: $ENABLED_CERTREQ" +echo " * certext: $ENABLED_CERTEXT" +echo " * HC-128: $ENABLED_HC128" +echo " * RABBIT: $ENABLED_RABBIT" +echo " * CHACHA: $ENABLED_CHACHA" +echo " * Hash DRBG: $ENABLED_HASHDRBG" +echo " * PWDBASED: $ENABLED_PWDBASED" +echo " * wolfCrypt Only: $ENABLED_CRYPTONLY" +echo " * HKDF: $ENABLED_HKDF" +echo " * MD4: $ENABLED_MD4" +echo " * PSK: $ENABLED_PSK" +echo " * Poly1305: $ENABLED_POLY1305" +echo " * LEANPSK: $ENABLED_LEANPSK" +echo " * RSA: $ENABLED_RSA" +echo " * DSA: $ENABLED_DSA" +echo " * DH: $ENABLED_DH" +echo " * ECC: $ENABLED_ECC" +echo " * CURVE25519: $ENABLED_CURVE25519" +echo " * ED25519: $ENABLED_ED25519" +echo " * FPECC: $ENABLED_FPECC" +echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" +echo " * ASN: $ENABLED_ASN" +echo " * Anonymous cipher: $ENABLED_ANON" +echo " * CODING: $ENABLED_CODING" +echo " * MEMORY: $ENABLED_MEMORY" +echo " * I/O POOL: $ENABLED_IOPOOL" +echo " * LIGHTY: $ENABLED_LIGHTY" +echo " * STUNNEL: $ENABLED_STUNNEL" +echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS" +echo " * DTLS: $ENABLED_DTLS" +echo " * Old TLS Versions: $ENABLED_OLD_TLS" +echo " * SSL version 3.0: $ENABLED_SSLV3" +echo " * OCSP: $ENABLED_OCSP" +echo " * CRL: $ENABLED_CRL" +echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR" +echo " * Persistent session cache: $ENABLED_SAVESESSION" +echo " * Persistent cert cache: $ENABLED_SAVECERT" +echo " * Atomic User Record Layer: $ENABLED_ATOMICUSER" +echo " * Public Key Callbacks: $ENABLED_PKCALLBACKS" +echo " * NTRU: $ENABLED_NTRU" +echo " * Server Name Indication: $ENABLED_SNI" +echo " * ALPN: $ENABLED_ALPN" +echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" +echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" +echo " * Certificate 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" +echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION" +echo " * All TLS Extensions: $ENABLED_TLSX" +echo " * PKCS#7 $ENABLED_PKCS7" +echo " * wolfSCEP $ENABLED_WOLFSCEP" +echo " * Secure Remote Password $ENABLED_SRP" +echo " * Small Stack: $ENABLED_SMALL_STACK" +echo " * valgrind unit tests: $ENABLED_VALGRIND" +echo " * LIBZ: $ENABLED_LIBZ" +echo " * Examples: $ENABLED_EXAMPLES" +echo " * User Crypto: $ENABLED_USER_CRYPTO" +echo " * Fast RSA: $ENABLED_FAST_RSA" echo "" echo "---" diff --git a/examples/client/client.c b/examples/client/client.c index c27619c4c1..479b4d2d31 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -310,7 +310,7 @@ static void Usage(void) #endif printf("-b Benchmark connections and print stats\n"); #ifdef HAVE_ALPN - printf("-L Application-Layer Protocole Name ({C,F}:)\n"); + printf("-L Application-Layer Protocol Negotiation ({C,F}:)\n"); #endif printf("-B Benchmark throughput using bytes and print stats\n"); printf("-s Use pre Shared keys\n"); @@ -348,6 +348,9 @@ static void Usage(void) printf("-o Perform OCSP lookup on peer certificate\n"); printf("-O Perform OCSP lookup using as responder\n"); #endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + printf("-W Use OCSP Stapling\n"); +#endif #ifdef ATOMIC_USER printf("-U Atomic User Record Layer Callbacks\n"); #endif @@ -425,7 +428,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 @@ -466,8 +472,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef WOLFSSL_VXWORKS 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(); @@ -654,6 +659,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; @@ -976,6 +987,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt); } #endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (statusRequest) { + if (wolfSSL_UseCertificateStatusRequest(ssl, WOLFSSL_CSR_OCSP, + WOLFSSL_CSR_OCSP_USE_NONCE) != SSL_SUCCESS) + err_sys("UseCertificateStatusRequest failed"); + + wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE); + } +#endif tcp_connect(&sockfd, host, port, doDTLS, ssl); @@ -1317,4 +1337,3 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - diff --git a/examples/server/server.c b/examples/server/server.c index d432f2d352..d2e97e17b9 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -200,7 +200,7 @@ static void Usage(void) DEFAULT_MIN_DHKEY_BITS); #endif #ifdef HAVE_ALPN - printf("-L Application-Layer Protocole Name ({C,F}:)\n"); + printf("-L Application-Layer Protocol Negotiation ({C,F}:)\n"); #endif printf("-d Disable client cert check\n"); printf("-b Bind to any interface instead of localhost only\n"); diff --git a/pull_to_vagrant.sh b/pull_to_vagrant.sh index e2d245632e..15d88d97d8 100755 --- a/pull_to_vagrant.sh +++ b/pull_to_vagrant.sh @@ -10,4 +10,5 @@ rsync -rvt /$SRC/.git ~/$DST/ rsync -rvt /$SRC/IDE ~/$DST/ rsync -rvt /$SRC/mcapi ~/$DST/ rsync -rvt /$SRC/mplabx ~/$DST/ +rsync -rvt /$SRC/certs ~/$DST/ rsync -rvt /$SRC/configure.ac ~/$DST/ diff --git a/src/internal.c b/src/internal.c index c20a92f33a..1c6a4c6e42 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4365,7 +4365,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"); @@ -4388,6 +4387,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 */ @@ -4454,12 +4455,22 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(HAVE_OCSP) || defined(HAVE_CRL) if (fatal == 0) { - int doCrlLookup = 1; - (void)doCrlLookup; + int doLookup = 1; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (ssl->status_request) { + fatal = TLSX_CSR_InitRequest(ssl->extensions, dCert); + doLookup = 0; + } + } +#endif + #ifdef HAVE_OCSP - if (ssl->ctx->cm->ocspEnabled) { + if (doLookup && ssl->ctx->cm->ocspEnabled) { + WOLFSSL_MSG("Doing Leaf OCSP check"); ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert); - doCrlLookup = (ret == OCSP_CERT_UNKNOWN); + doLookup = (ret == OCSP_CERT_UNKNOWN); if (ret != 0) { WOLFSSL_MSG("\tOCSP Lookup not ok"); fatal = 0; @@ -4468,7 +4479,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* HAVE_OCSP */ #ifdef HAVE_CRL - if (doCrlLookup && ssl->ctx->cm->crlEnabled) { + if (doLookup && ssl->ctx->cm->crlEnabled) { WOLFSSL_MSG("Doing Leaf CRL check"); ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); if (ret != 0) { @@ -4477,11 +4488,12 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, } } #endif /* HAVE_CRL */ + (void)doLookup; } #endif /* HAVE_OCSP || HAVE_CRL */ #ifdef KEEP_PEER_CERT - { + if (fatal == 0) { /* set X509 format for peer cert even if fatal */ int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert); if (copyRet == MEMORY_E) @@ -4783,6 +4795,95 @@ 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: { + OcspRequest* request = TLSX_CSR_GetRequest(ssl->extensions); + + #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 + 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, ssl->ctx->cm)) == 0) { + if (response->responseStatus != OCSP_SUCCESSFUL) + ret = BAD_CERTIFICATE_STATUS_ERROR; + else if (CompareOcspReqResp(request, response) != 0) + ret = BAD_CERTIFICATE_STATUS_ERROR; + else if (response->status->status != CERT_GOOD) + ret = BAD_CERTIFICATE_STATUS_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 */ @@ -4978,6 +5079,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) { @@ -4986,10 +5107,21 @@ 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) { + int ret; + + WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); + if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0) + return ret; + } +#endif + } break; #endif @@ -5231,7 +5363,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 @@ -8604,11 +8741,17 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case RSA_SIGN_FAULT: return "RSA Signature Fault Error"; + case HANDSHAKE_SIZE_ERROR: + return "Handshake message too large Error"; + case UNKNOWN_ALPN_PROTOCOL_NAME_E: return "Unrecognized protocol name Error"; - case HANDSHAKE_SIZE_ERROR: - return "Handshake message too large Error"; + case BAD_CERTIFICATE_STATUS_ERROR: + return "Bad Certificate Status Message Error"; + + case OCSP_INVALID_STATUS: + return "Invalid OCSP Status Error"; default : return "unknown error number"; @@ -10371,7 +10514,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, @@ -11076,7 +11219,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, size, 0)) < 0) @@ -11912,7 +12055,7 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) return MEMORY_E; /* extension type */ - c16toa(WOLFSSL_QSH, output + idx); + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); idx += OPAQUE16_LEN; /* write to output and check amount written */ @@ -12672,7 +12815,7 @@ int DoSessionTicket(WOLFSSL* ssl, return MEMORY_E; /* extension type */ - c16toa(WOLFSSL_QSH, output + idx); + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); idx += OPAQUE16_LEN; /* write to output and check amount written */ @@ -12821,7 +12964,7 @@ int DoSessionTicket(WOLFSSL* ssl, QSH_KeyExchangeWrite(ssl, 1); /* extension type */ - c16toa(WOLFSSL_QSH, output + idx); + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); idx += OPAQUE16_LEN; /* write to output and check amount written */ @@ -13462,7 +13605,7 @@ int DoSessionTicket(WOLFSSL* ssl, QSH_KeyExchangeWrite(ssl, 1); /* extension type */ - c16toa(WOLFSSL_QSH, output + idx); + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); idx += OPAQUE16_LEN; /* write to output and check amount written */ @@ -14004,7 +14147,7 @@ int DoSessionTicket(WOLFSSL* ssl, QSH_KeyExchangeWrite(ssl, 1); /* extension type */ - c16toa(WOLFSSL_QSH, output + idx); + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); idx += OPAQUE16_LEN; /* write to output and check amount written */ @@ -15382,7 +15525,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input @@ -15460,7 +15603,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, @@ -15522,7 +15665,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, @@ -15610,7 +15753,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, @@ -15665,7 +15808,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, @@ -15760,7 +15903,7 @@ int DoSessionTicket(WOLFSSL* ssl, ato16(input + *inOutIdx, &name); *inOutIdx += OPAQUE16_LEN; - if (name == WOLFSSL_QSH) { + if (name == TLSX_QUANTUM_SAFE_HYBRID) { /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, diff --git a/src/ocsp.c b/src/ocsp.c index 2b355d988d..567a67de86 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -34,59 +34,68 @@ #include #include +#ifdef NO_INLINE + #include +#else + #include +#endif + int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm) { WOLFSSL_ENTER("InitOCSP"); - XMEMSET(ocsp, 0, sizeof(*ocsp)); - ocsp->cm = cm; + + ForceZero(ocsp, sizeof(WOLFSSL_OCSP)); + if (InitMutex(&ocsp->ocspLock) != 0) return BAD_MUTEX_E; + ocsp->cm = cm; + return 0; } -static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert) +static int InitOcspEntry(OcspEntry* entry, OcspRequest* request) { - WOLFSSL_ENTER("InitOCSP_Entry"); + WOLFSSL_ENTER("InitOcspEntry"); - XMEMSET(ocspe, 0, sizeof(*ocspe)); - XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE); - XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE); + ForceZero(entry, sizeof(OcspEntry)); + + XMEMCPY(entry->issuerHash, request->issuerHash, OCSP_DIGEST_SIZE); + XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE); return 0; } -static void FreeOCSP_Entry(OCSP_Entry* ocspe) +static void FreeOcspEntry(OcspEntry* entry) { - CertStatus* tmp = ocspe->status; + CertStatus *status, *next; - WOLFSSL_ENTER("FreeOCSP_Entry"); + WOLFSSL_ENTER("FreeOcspEntry"); - while (tmp) { - CertStatus* next = tmp->next; - XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS); - tmp = next; + for (status = entry->status; status; status = next) { + next = status->next; + XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS); } } void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic) { - OCSP_Entry* tmp = ocsp->ocspList; + OcspEntry *entry, *next; WOLFSSL_ENTER("FreeOCSP"); - while (tmp) { - OCSP_Entry* next = tmp->next; - FreeOCSP_Entry(tmp); - XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY); - tmp = next; + for (entry = ocsp->ocspList; entry; entry = next) { + next = entry->next; + FreeOcspEntry(entry); + XFREE(entry, NULL, DYNAMIC_TYPE_OCSP_ENTRY); } FreeMutex(&ocsp->ocspLock); + if (dynamic) XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP); } @@ -107,84 +116,135 @@ static int xstat2err(int stat) int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) { - byte* ocspReqBuf = NULL; - int ocspReqSz = 2048; - byte* ocspRespBuf = NULL; - int result = -1; - OCSP_Entry* ocspe; - CertStatus* certStatus = NULL; - const char *url; - int urlSz; + int ret = OCSP_LOOKUP_FAIL; + #ifdef WOLFSSL_SMALL_STACK - CertStatus* newStatus; OcspRequest* ocspRequest; - OcspResponse* ocspResponse; #else - CertStatus newStatus[1]; OcspRequest ocspRequest[1]; - OcspResponse ocspResponse[1]; #endif WOLFSSL_ENTER("CheckCertOCSP"); + +#ifdef WOLFSSL_SMALL_STACK + ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (ocspRequest == NULL) { + WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); + return MEMORY_E; + } +#endif + + if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) { + ret = CheckOcspRequest(ocsp, ocspRequest); + + FreeOcspRequest(ocspRequest); + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + WOLFSSL_LEAVE("CheckCertOCSP", ret); + return ret; +} + +static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request, + OcspEntry** entry) +{ + WOLFSSL_ENTER("GetOcspEntry"); + + *entry = NULL; + if (LockMutex(&ocsp->ocspLock) != 0) { WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); return BAD_MUTEX_E; } - ocspe = ocsp->ocspList; - while (ocspe) { - if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0 - && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash, - SHA_DIGEST_SIZE) == 0) + for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next) + if (XMEMCMP((*entry)->issuerHash, request->issuerHash, + OCSP_DIGEST_SIZE) == 0 + && XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash, + OCSP_DIGEST_SIZE) == 0) break; - else - ocspe = ocspe->next; - } - if (ocspe == NULL) { - ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry), - NULL, DYNAMIC_TYPE_OCSP_ENTRY); - if (ocspe != NULL) { - InitOCSP_Entry(ocspe, cert); - ocspe->next = ocsp->ocspList; - ocsp->ocspList = ocspe; - } - else { - UnLockMutex(&ocsp->ocspLock); - WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); - return MEMORY_ERROR; + if (*entry == NULL) { + *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), + NULL, DYNAMIC_TYPE_OCSP_ENTRY); + if (*entry) { + InitOcspEntry(*entry, request); + (*entry)->next = ocsp->ocspList; + ocsp->ocspList = *entry; } } - else { - certStatus = ocspe->status; - while (certStatus) { - if (certStatus->serialSz == cert->serialSz && - XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0) - break; - else - certStatus = certStatus->next; - } + + UnLockMutex(&ocsp->ocspLock); + + return *entry ? 0 : MEMORY_ERROR; +} + + +static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, + OcspEntry* entry, CertStatus** status) +{ + int ret = OCSP_INVALID_STATUS; + + WOLFSSL_ENTER("GetOcspStatus"); + + *status = NULL; + + if (LockMutex(&ocsp->ocspLock) != 0) { + WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); + return BAD_MUTEX_E; } - if (certStatus != NULL) { - if (!ValidateDate(certStatus->thisDate, - certStatus->thisDateFormat, BEFORE) || - (certStatus->nextDate[0] == 0) || - !ValidateDate(certStatus->nextDate, - certStatus->nextDateFormat, AFTER)) { - WOLFSSL_MSG("\tinvalid status date, looking up cert"); - } - else { - result = xstat2err(certStatus->status); - UnLockMutex(&ocsp->ocspLock); - WOLFSSL_LEAVE("CheckCertOCSP", result); - return result; - } + for (*status = entry->status; *status; *status = (*status)->next) + if ((*status)->serialSz == request->serialSz + && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz)) + break; + + if (*status) { + if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE) + && ((*status)->nextDate[0] != 0) + && ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER)) + ret = xstat2err((*status)->status); } UnLockMutex(&ocsp->ocspLock); + return ret; +} + +int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest) +{ + OcspEntry* entry = NULL; + CertStatus* status = NULL; + byte* request = NULL; + int requestSz = 2048; + byte* response = NULL; + const char* url; + int urlSz; + int ret = -1; + +#ifdef WOLFSSL_SMALL_STACK + CertStatus* newStatus; + OcspResponse* ocspResponse; +#else + CertStatus newStatus[1]; + OcspResponse ocspResponse[1]; +#endif + + WOLFSSL_ENTER("CheckOcspRequest"); + + ret = GetOcspEntry(ocsp, ocspRequest, &entry); + if (ret != 0) + return ret; + + ret = GetOcspStatus(ocsp, ocspRequest, entry, &status); + if (ret != OCSP_INVALID_STATUS) + return ret; + if (ocsp->cm->ocspUseOverrideURL) { url = ocsp->cm->ocspOverrideURL; if (url != NULL && url[0] != '\0') @@ -192,17 +252,17 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) else return OCSP_NEED_URL; } - else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) { - url = (const char *)cert->extAuthInfo; - urlSz = cert->extAuthInfoSz; + else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) { + url = (const char *)ocspRequest->url; + urlSz = ocspRequest->urlSz; } else { /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ return 0; } - ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); - if (ocspReqBuf == NULL) { + request = (byte*)XMALLOC(requestSz, NULL, DYNAMIC_TYPE_IN_BUFFER); + if (request == NULL) { WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_ERROR; } @@ -210,58 +270,53 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) #ifdef WOLFSSL_SMALL_STACK newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, DYNAMIC_TYPE_TMP_BUFFER); - ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, - DYNAMIC_TYPE_TMP_BUFFER); ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) { + if (newStatus == NULL || ocspResponse == NULL) { if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (ocspRequest) XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(request, NULL, DYNAMIC_TYPE_TMP_BUFFER); WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_E; } #endif - InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce, - ocspReqBuf, ocspReqSz); - ocspReqSz = EncodeOcspRequest(ocspRequest); - + requestSz = EncodeOcspRequest(ocspRequest, request, requestSz); + if (ocsp->cm->ocspIOCb) - result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, - ocspReqBuf, ocspReqSz, &ocspRespBuf); + ret = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, + request, requestSz, &response); - if (result >= 0 && ocspRespBuf) { + if (ret >= 0 && response) { XMEMSET(newStatus, 0, sizeof(CertStatus)); - InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result); - OcspResponseDecode(ocspResponse); - + InitOcspResponse(ocspResponse, newStatus, response, ret); + OcspResponseDecode(ocspResponse, ocsp->cm); + if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) - result = OCSP_LOOKUP_FAIL; + ret = OCSP_LOOKUP_FAIL; else { if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) { - result = xstat2err(ocspResponse->status->status); + ret = xstat2err(ocspResponse->status->status); if (LockMutex(&ocsp->ocspLock) != 0) - result = BAD_MUTEX_E; + ret = BAD_MUTEX_E; else { - if (certStatus != NULL) + if (status != NULL) /* Replace existing certificate entry with updated */ - XMEMCPY(certStatus, newStatus, sizeof(CertStatus)); + XMEMCPY(status, newStatus, sizeof(CertStatus)); else { /* Save new certificate entry */ - certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), + status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, DYNAMIC_TYPE_OCSP_STATUS); - if (certStatus != NULL) { - XMEMCPY(certStatus, newStatus, sizeof(CertStatus)); - certStatus->next = ocspe->status; - ocspe->status = certStatus; - ocspe->totalStatus++; + if (status != NULL) { + XMEMCPY(status, newStatus, sizeof(CertStatus)); + status->next = entry->status; + entry->status = status; + entry->totalStatus++; } } @@ -269,25 +324,22 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert) } } else - result = OCSP_LOOKUP_FAIL; + ret = OCSP_LOOKUP_FAIL; } } else - result = OCSP_LOOKUP_FAIL; - - XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); + ret = OCSP_LOOKUP_FAIL; #ifdef WOLFSSL_SMALL_STACK XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb) - ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf); + if (response != NULL && ocsp->cm->ocspRespFreeCb) + ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response); - WOLFSSL_LEAVE("CheckCertOCSP", result); - return result; + WOLFSSL_LEAVE("CheckOcspRequest", ret); + return ret; } diff --git a/src/ssl.c b/src/ssl.c index 575e9a8a72..e8431550b2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -690,8 +690,9 @@ int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size) return TLSX_UseSNI(&ssl->extensions, type, data, size); } -int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, - const void* data, word16 size) + +int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data, + word16 size) { if (ctx == NULL) return BAD_FUNC_ARG; @@ -707,17 +708,20 @@ void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options) TLSX_SNI_SetOptions(ssl->extensions, type, options); } + void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options) { if (ctx && ctx->extensions) TLSX_SNI_SetOptions(ctx->extensions, type, options); } + byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type) { return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type); } + word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data) { if (data) @@ -729,6 +733,7 @@ word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data) return 0; } + int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, byte type, byte* sni, word32* inOutSz) { @@ -745,6 +750,7 @@ int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, #ifdef HAVE_MAX_FRAGMENT #ifndef NO_WOLFSSL_CLIENT + int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl) { if (ssl == NULL) @@ -753,6 +759,7 @@ int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl) return TLSX_UseMaxFragment(&ssl->extensions, mfl); } + int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl) { if (ctx == NULL) @@ -760,11 +767,13 @@ int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl) return TLSX_UseMaxFragment(&ctx->extensions, mfl); } + #endif /* NO_WOLFSSL_CLIENT */ #endif /* HAVE_MAX_FRAGMENT */ #ifdef HAVE_TRUNCATED_HMAC #ifndef NO_WOLFSSL_CLIENT + int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl) { if (ssl == NULL) @@ -773,6 +782,7 @@ int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl) return TLSX_UseTruncatedHMAC(&ssl->extensions); } + int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx) { if (ctx == NULL) @@ -780,9 +790,35 @@ int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx) return TLSX_UseTruncatedHMAC(&ctx->extensions); } + #endif /* NO_WOLFSSL_CLIENT */ #endif /* HAVE_TRUNCATED_HMAC */ +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + +int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type, + byte options) +{ + if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END) + return BAD_FUNC_ARG; + + return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type, + options); +} + + +int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type, + byte options) +{ + if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END) + return BAD_FUNC_ARG; + + return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type, + options); +} + +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ + /* Elliptic Curves */ #ifdef HAVE_SUPPORTED_CURVES #ifndef NO_WOLFSSL_CLIENT @@ -808,6 +844,7 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) return TLSX_UseSupportedCurve(&ssl->extensions, name); } + int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) { if (ctx == NULL) @@ -885,7 +922,7 @@ int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name) #endif /* HAVE_QSH */ -/* Application-Layer Procotol Name */ +/* Application-Layer Procotol Negotiation */ #ifdef HAVE_ALPN int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list, @@ -988,7 +1025,7 @@ int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl) ret = TLSX_UseSecureRenegotiation(&ssl->extensions); if (ret == SSL_SUCCESS) { - TLSX* extension = TLSX_Find(ssl->extensions, SECURE_RENEGOTIATION); + TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO); if (extension) ssl->secure_renegotiation = (SecureRenegotiation*)extension->data; @@ -2479,7 +2516,7 @@ static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password, #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - + if (ret == MP_OKAY) return SSL_SUCCESS; else if (ret == SSL_BAD_FILE) @@ -11853,7 +11890,7 @@ char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn) XFREE(buf, NULL, DYNAMIC_TYPE_ECC); return NULL; } - + return buf; } #else @@ -14878,7 +14915,7 @@ int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, int ret; (void)ctx; - + WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp"); if (group == NULL || a == NULL || a->internal == NULL || b == NULL || @@ -15348,7 +15385,7 @@ int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc, WOLFSSL_MSG("ECC private key file write failed"); return SSL_FAILURE; } - + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); return SSL_SUCCESS; } @@ -15523,7 +15560,7 @@ int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, WOLFSSL_MSG("DSA private key file write failed"); return SSL_FAILURE; } - + XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER); return SSL_SUCCESS; } @@ -17097,4 +17134,3 @@ void* wolfSSL_get_jobject(WOLFSSL* ssl) #endif /* WOLFSSL_JNI */ #endif /* WOLFCRYPT_ONLY */ - diff --git a/src/tls.c b/src/tls.c index 97dc09ef5f..77e3694d33 100644 --- a/src/tls.c +++ b/src/tls.c @@ -755,7 +755,7 @@ static INLINE word16 TLSX_ToSemaphore(word16 type) { switch (type) { - case SECURE_RENEGOTIATION: /* 0xFF01 */ + case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */ return 63; default: @@ -784,7 +784,7 @@ static INLINE word16 TLSX_ToSemaphore(word16 type) /** Creates a new extension. */ static TLSX* TLSX_New(TLSX_Type type, void* data) { - TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX); + TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), NULL, DYNAMIC_TYPE_TLSX); if (extension) { extension->type = type; @@ -845,6 +845,9 @@ void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) #endif +/******************************************************************************/ +/* Application-Layer Protocol Negotiation */ +/******************************************************************************/ #ifdef HAVE_ALPN /** Creates a new ALPN object, providing protocol name to use. */ @@ -981,7 +984,7 @@ static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size) alpn->negociated = 1; - ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn); + ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn); if (ret != 0) { TLSX_ALPN_Free(alpn); return ret; @@ -1001,9 +1004,10 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length, TLSX *extension; ALPN *alpn = NULL, *list; - extension = TLSX_Find(ssl->extensions, WOLFSSL_ALPN); + extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL); if (extension == NULL) - extension = TLSX_Find(ssl->ctx->extensions, WOLFSSL_ALPN); + extension = TLSX_Find(ssl->ctx->extensions, + TLSX_APPLICATION_LAYER_PROTOCOL); if (extension == NULL || extension->data == NULL) { WOLFSSL_MSG("No ALPN extensions not used or bad"); @@ -1088,7 +1092,7 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length, /* reply to ALPN extension sent from client */ if (isRequest) { #ifndef NO_WOLFSSL_SERVER - TLSX_SetResponse(ssl, WOLFSSL_ALPN); + TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL); #endif } @@ -1114,9 +1118,10 @@ int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options) /* Set Options of ALPN */ alpn->options = options; - extension = TLSX_Find(*extensions, WOLFSSL_ALPN); + extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL); if (extension == NULL) { - ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn); + ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, + (void*)alpn); if (ret != 0) { TLSX_ALPN_Free(alpn); return ret; @@ -1140,7 +1145,7 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz) if (extensions == NULL || data == NULL || dataSz == NULL) return BAD_FUNC_ARG; - extension = TLSX_Find(extensions, WOLFSSL_ALPN); + extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL); if (extension == NULL) { WOLFSSL_MSG("TLS extension not found"); return SSL_ALPN_NOT_FOUND; @@ -1192,13 +1197,16 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz) #endif /* HAVE_ALPN */ -/* Server Name Indication */ +/******************************************************************************/ +/* Server Name Indication */ +/******************************************************************************/ + #ifdef HAVE_SNI /** Creates a new SNI object. */ static SNI* TLSX_SNI_New(byte type, const void* data, word16 size) { - SNI* sni = (SNI*)XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX); + SNI* sni = (SNI*)XMALLOC(sizeof(SNI), NULL, DYNAMIC_TYPE_TLSX); if (sni) { sni->type = type; @@ -1211,7 +1219,7 @@ static SNI* TLSX_SNI_New(byte type, const void* data, word16 size) switch (sni->type) { case WOLFSSL_SNI_HOST_NAME: - sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX); + sni->data.host_name = XMALLOC(size+1, NULL, DYNAMIC_TYPE_TLSX); if (sni->data.host_name) { XSTRNCPY(sni->data.host_name, (const char*)data, size); @@ -1325,7 +1333,7 @@ static SNI* TLSX_SNI_Find(SNI *list, byte type) /** Sets the status of a SNI object. */ static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) { - TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); + TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); if (sni) @@ -1335,7 +1343,7 @@ static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status) /** Gets the status of a SNI object. */ byte TLSX_SNI_Status(TLSX* extensions, byte type) { - TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); + TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); if (sni) @@ -1356,10 +1364,10 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length, int cacheOnly = 0; #endif - TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION); + TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); if (!extension) - extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION); + extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); (void)isRequest; (void)input; @@ -1438,7 +1446,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length, TLSX_SNI_SetStatus(ssl->extensions, type, matchStat); if(!cacheOnly) - TLSX_SetResponse(ssl, SERVER_NAME_INDICATION); + TLSX_SetResponse(ssl, TLSX_SERVER_NAME); } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) { SendAlert(ssl, alert_fatal, unrecognized_name); @@ -1461,8 +1469,8 @@ static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest) if (isRequest) { #ifndef NO_WOLFSSL_SERVER - TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION); - TLSX* ssl_ext = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION); + TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME); + TLSX* ssl_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); SNI* ctx_sni = ctx_ext ? ctx_ext->data : NULL; SNI* ssl_sni = ssl_ext ? ssl_ext->data : NULL; SNI* sni = NULL; @@ -1502,7 +1510,7 @@ static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest) int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) { - TLSX* extension = TLSX_Find(*extensions, SERVER_NAME_INDICATION); + TLSX* extension = TLSX_Find(*extensions, TLSX_SERVER_NAME); SNI* sni = NULL; if (extensions == NULL || data == NULL) @@ -1512,7 +1520,7 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) return MEMORY_E; if (!extension) { - int ret = TLSX_Push(extensions, SERVER_NAME_INDICATION, (void*)sni); + int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni); if (ret != 0) { TLSX_SNI_Free(sni); return ret; @@ -1546,7 +1554,7 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) /** Tells the SNI requested by the client. */ word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) { - TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); + TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) { @@ -1563,7 +1571,7 @@ word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) /** Sets the options for a SNI object. */ void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) { - TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); + TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); if (sni) @@ -1681,7 +1689,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, if (helloSz < offset + extLen) return BUFFER_ERROR; - if (extType != SERVER_NAME_INDICATION) { + if (extType != TLSX_SERVER_NAME) { offset += extLen; /* skip extension */ } else { word16 listLen; @@ -1739,6 +1747,10 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, #endif /* HAVE_SNI */ +/******************************************************************************/ +/* Max Fragment Length Negotiation */ +/******************************************************************************/ + #ifdef HAVE_MAX_FRAGMENT static word16 TLSX_MFL_Write(byte* data, byte* output) @@ -1775,7 +1787,7 @@ static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length, if (r != SSL_SUCCESS) return r; /* throw error */ - TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH); + TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH); } #endif @@ -1793,13 +1805,13 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl) if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl) return BAD_FUNC_ARG; - if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL) + if ((data = XMALLOC(ENUM_LEN, NULL, DYNAMIC_TYPE_TLSX)) == NULL) return MEMORY_E; data[0] = mfl; /* push new MFL extension. */ - if ((ret = TLSX_Push(extensions, MAX_FRAGMENT_LENGTH, data)) != 0) { + if ((ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data)) != 0) { XFREE(data, 0, DYNAMIC_TYPE_TLSX); return ret; } @@ -1822,6 +1834,10 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl) #endif /* HAVE_MAX_FRAGMENT */ +/******************************************************************************/ +/* Truncated HMAC */ +/******************************************************************************/ + #ifdef HAVE_TRUNCATED_HMAC static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length, @@ -1836,9 +1852,10 @@ static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length, if (isRequest) { int r = TLSX_UseTruncatedHMAC(&ssl->extensions); - if (r != SSL_SUCCESS) return r; /* throw error */ + if (r != SSL_SUCCESS) + return r; /* throw error */ - TLSX_SetResponse(ssl, TRUNCATED_HMAC); + TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC); } #endif @@ -1854,7 +1871,7 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions) if (extensions == NULL) return BAD_FUNC_ARG; - if ((ret = TLSX_Push(extensions, TRUNCATED_HMAC, NULL)) != 0) + if ((ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL)) != 0) return ret; return SSL_SUCCESS; @@ -1868,6 +1885,269 @@ 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: + FreeOcspRequest(&csr->request.ocsp); + break; + } + + XFREE(csr, NULL, DYNAMIC_TYPE_TLSX); +} + +static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) +{ + word16 size = 0; + + /* shut up compiler warnings */ + (void) csr; (void) isRequest; + +#ifndef NO_WOLFSSL_CLIENT + if (isRequest) { + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + size += ENUM_LEN + 2 * OPAQUE16_LEN; + + if (csr->request.ocsp.nonceSz) + size += MAX_OCSP_EXT_SZ; + } + } +#endif + + return size; +} + +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; + word16 length = 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 */ + if (csr->request.ocsp.nonceSz) + length = EncodeOcspRequestExtensions( + &csr->request.ocsp, + output + offset + OPAQUE16_LEN, + MAX_OCSP_EXT_SZ); + + c16toa(length, output + offset); + offset += OPAQUE16_LEN + length; + + break; + } + + return offset; + } +#endif + + return 0; +} + +static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length, + byte isRequest) +{ + int ret = 0; + + /* shut up compiler warnings */ + (void) ssl; (void) input; + + if (!isRequest) { +#ifndef NO_WOLFSSL_CLIENT + TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); + CertificateStatusRequest* csr = extension ? extension->data : NULL; + + if (!csr) { + /* look at context level */ + + extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST); + csr = extension ? extension->data : NULL; + + if (!csr) + return BUFFER_ERROR; /* unexpected extension */ + + /* enable extension at ssl level */ + ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, + csr->status_type, csr->options); + if (ret != SSL_SUCCESS) + return ret; + + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + /* propagate nonce */ + if (csr->request.ocsp.nonceSz) { + OcspRequest* request = + TLSX_CSR_GetRequest(ssl->extensions); + + if (request) { + XMEMCPY(request->nonce, csr->request.ocsp.nonce, + csr->request.ocsp.nonceSz); + request->nonceSz = csr->request.ocsp.nonceSz; + } + } + break; + } + } + + ssl->status_request = 1; + + return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ +#endif + } + + return ret; +} + +int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert) +{ + TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); + CertificateStatusRequest* csr = extension ? extension->data : NULL; + int ret = 0; + + if (csr) { + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: { + byte nonce[MAX_OCSP_NONCE_SZ]; + int nonceSz = csr->request.ocsp.nonceSz; + + /* preserve nonce */ + XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz); + + if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0)) != 0) + return ret; + + /* restore nonce */ + XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz); + csr->request.ocsp.nonceSz = nonceSz; + } + break; + } + } + + return ret; +} + +void* TLSX_CSR_GetRequest(TLSX* extensions) +{ + TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST); + CertificateStatusRequest* csr = extension ? extension->data : NULL; + + if (csr) { + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + return &csr->request.ocsp; + break; + } + } + + return NULL; +} + +int TLSX_CSR_ForceRequest(WOLFSSL* ssl) +{ + TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); + CertificateStatusRequest* csr = extension ? extension->data : NULL; + + if (csr) { + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + if (ssl->ctx->cm->ocspEnabled) + return CheckOcspRequest(ssl->ctx->cm->ocsp, + &csr->request.ocsp); + else + return OCSP_LOOKUP_FAIL; + } + } + + return 0; +} + +int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type, + byte options) +{ + CertificateStatusRequest* csr = NULL; + int ret = 0; + + if (!extensions || status_type != WOLFSSL_CSR_OCSP) + return BAD_FUNC_ARG; + + csr = (CertificateStatusRequest*) + XMALLOC(sizeof(CertificateStatusRequest), NULL, DYNAMIC_TYPE_TLSX); + if (!csr) + return MEMORY_E; + + ForceZero(csr, sizeof(CertificateStatusRequest)); + + csr->status_type = status_type; + csr->options = options; + + switch (csr->status_type) { + case WOLFSSL_CSR_OCSP: + if (options & WOLFSSL_CSR_OCSP_USE_NONCE) { + WC_RNG rng; + + if (wc_InitRng(&rng) == 0) { + if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce, + MAX_OCSP_NONCE_SZ) == 0) + csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ; + + wc_FreeRng(&rng); + } + } + break; + } + + 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 */ +/******************************************************************************/ + #ifdef HAVE_SUPPORTED_CURVES #ifndef HAVE_ECC @@ -1887,12 +2167,14 @@ static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list) static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name) { - EllipticCurve* curve; + EllipticCurve* curve = NULL; if (list == NULL) return BAD_FUNC_ARG; - if ((curve = XMALLOC(sizeof(EllipticCurve), 0, DYNAMIC_TYPE_TLSX)) == NULL) + curve = (EllipticCurve*)XMALLOC(sizeof(EllipticCurve), NULL, + DYNAMIC_TYPE_TLSX); + if (curve == NULL) return MEMORY_E; curve->name = name; @@ -1914,7 +2196,7 @@ static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) return; /* turns semaphore on to avoid sending this extension. */ - TURN_ON(semaphore, TLSX_ToSemaphore(ELLIPTIC_CURVES)); + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS)); } static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list) @@ -1988,7 +2270,7 @@ static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { TLSX* extension = (first == ECC_BYTE) - ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES) + ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) : NULL; EllipticCurve* curve = NULL; word32 oid = 0; @@ -2097,7 +2379,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { int TLSX_UseSupportedCurve(TLSX** extensions, word16 name) { - TLSX* extension = TLSX_Find(*extensions, ELLIPTIC_CURVES); + TLSX* extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS); EllipticCurve* curve = NULL; int ret = 0; @@ -2108,7 +2390,7 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name) return ret; if (!extension) { - if ((ret = TLSX_Push(extensions, ELLIPTIC_CURVES, curve)) != 0) { + if ((ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve)) != 0) { XFREE(curve, 0, DYNAMIC_TYPE_TLSX); return ret; } @@ -2161,6 +2443,10 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name) #endif /* HAVE_SUPPORTED_CURVES */ +/******************************************************************************/ +/* Renegotiation Indication */ +/******************************************************************************/ + #ifdef HAVE_SECURE_RENEGOTIATION static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data, @@ -2259,7 +2545,7 @@ int TLSX_UseSecureRenegotiation(TLSX** extensions) XMEMSET(data, 0, sizeof(SecureRenegotiation)); - ret = TLSX_Push(extensions, SECURE_RENEGOTIATION, data); + ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data); if (ret != 0) { XFREE(data, 0, DYNAMIC_TYPE_TLSX); return ret; @@ -2283,11 +2569,15 @@ int TLSX_UseSecureRenegotiation(TLSX** extensions) #endif /* HAVE_SECURE_RENEGOTIATION */ +/******************************************************************************/ +/* Session Tickets */ +/******************************************************************************/ + #ifdef HAVE_SESSION_TICKET static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl) { - TLSX* extension = TLSX_Find(ssl->extensions, SESSION_TICKET); + TLSX* extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET); SessionTicket* ticket = extension ? extension->data : NULL; if (ticket) { @@ -2345,7 +2635,7 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length, ret = TLSX_UseSessionTicket(&ssl->extensions, NULL); if (ret == SSL_SUCCESS) { ret = 0; - TLSX_SetResponse(ssl, SESSION_TICKET); /* send blank ticket */ + TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); /* send blank ticket */ ssl->options.createTicket = 1; /* will send ticket msg */ ssl->options.useTicket = 1; } @@ -2361,7 +2651,7 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length, ret = TLSX_UseSessionTicket(&ssl->extensions, NULL); if (ret == SSL_SUCCESS) { ret = 0; - TLSX_SetResponse(ssl, SESSION_TICKET); + TLSX_SetResponse(ssl, TLSX_SESSION_TICKET); /* send blank ticket */ ssl->options.createTicket = 1; /* will send ticket msg */ ssl->options.useTicket = 1; @@ -2416,7 +2706,7 @@ int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket) /* If the ticket is NULL, the client will request a new ticket from the server. Otherwise, the client will use it in the next client hello. */ - if ((ret = TLSX_Push(extensions, SESSION_TICKET, (void*)ticket)) != 0) + if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket)) != 0) return ret; return SSL_SUCCESS; @@ -2436,6 +2726,9 @@ int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket) #endif /* HAVE_SESSION_TICKET */ +/******************************************************************************/ +/* Quantum-Safe-Hybrid */ +/******************************************************************************/ #ifdef HAVE_QSH static WC_RNG* rng; @@ -2459,7 +2752,7 @@ static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub, if (list == NULL) return BAD_FUNC_ARG; - if ((temp = XMALLOC(sizeof(QSHScheme), 0, DYNAMIC_TYPE_TLSX)) == NULL) + if ((temp = XMALLOC(sizeof(QSHScheme), NULL, DYNAMIC_TYPE_TLSX)) == NULL) return MEMORY_E; temp->name = name; @@ -2499,7 +2792,7 @@ static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore) return; /* No QSH suite found */ - TURN_ON(semaphore, TLSX_ToSemaphore(WOLFSSL_QSH)); + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID)); } @@ -2610,7 +2903,7 @@ word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output) static void TLSX_QSHAgreement(TLSX** extensions) { - TLSX* extension = TLSX_Find(*extensions, WOLFSSL_QSH); + TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); QSHScheme* format = NULL; QSHScheme* delete = NULL; QSHScheme* prev = NULL; @@ -2735,7 +3028,7 @@ static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, while ((offset_len < offset_pk) && numKeys) { QSHKey * temp; - if ((temp = XMALLOC(sizeof(QSHKey), 0, DYNAMIC_TYPE_TLSX)) == NULL) + if ((temp = XMALLOC(sizeof(QSHKey), NULL, DYNAMIC_TYPE_TLSX)) == NULL) return MEMORY_E; /* initialize */ @@ -2768,7 +3061,7 @@ static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, /* read in public key */ if (PKLen > 0) { temp->pub.buffer = (byte*)XMALLOC(temp->pub.length, - 0, DYNAMIC_TYPE_PUBLIC_KEY); + NULL, DYNAMIC_TYPE_PUBLIC_KEY); XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length); offset_len += PKLen; } @@ -2797,7 +3090,7 @@ static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length, /* reply to a QSH extension sent from client */ if (isRequest) { - TLSX_SetResponse(ssl, WOLFSSL_QSH); + TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID); /* only use schemes we have key generated for -- free the rest */ TLSX_QSHAgreement(&ssl->extensions); } @@ -2903,7 +3196,7 @@ int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length, /* return 1 on success */ int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) { - TLSX* extension = TLSX_Find(*extensions, WOLFSSL_QSH); + TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); QSHScheme* format = NULL; /* if no extension is sent then do not use QSH */ @@ -2947,7 +3240,7 @@ static int TLSX_HaveQSHScheme(word16 name) /* Add a QSHScheme struct to list of usable ones */ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz) { - TLSX* extension = TLSX_Find(*extensions, WOLFSSL_QSH); + TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); QSHScheme* format = NULL; int ret = 0; @@ -2961,7 +3254,8 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz) return ret; if (!extension) { - if ((ret = TLSX_Push(extensions, WOLFSSL_QSH, format)) != 0) { + if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format)) + != 0) { XFREE(format, 0, DYNAMIC_TYPE_TLSX); return ret; } @@ -3018,6 +3312,9 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz) #endif /* HAVE_QSH */ +/******************************************************************************/ +/* TLS Extensions Framework */ +/******************************************************************************/ /** Finds an extension in the provided list. */ TLSX* TLSX_Find(TLSX* list, TLSX_Type type) @@ -3040,35 +3337,39 @@ void TLSX_FreeAll(TLSX* list) switch (extension->type) { - case SERVER_NAME_INDICATION: + case TLSX_SERVER_NAME: SNI_FREE_ALL((SNI*)extension->data); break; - case MAX_FRAGMENT_LENGTH: + case TLSX_MAX_FRAGMENT_LENGTH: MFL_FREE_ALL(extension->data); break; - case TRUNCATED_HMAC: + case TLSX_TRUNCATED_HMAC: /* Nothing to do. */ break; - case ELLIPTIC_CURVES: + case TLSX_SUPPORTED_GROUPS: EC_FREE_ALL(extension->data); break; - case SECURE_RENEGOTIATION: + case TLSX_STATUS_REQUEST: + CSR_FREE_ALL(extension->data); + break; + + case TLSX_RENEGOTIATION_INFO: SCR_FREE_ALL(extension->data); break; - case SESSION_TICKET: + case TLSX_SESSION_TICKET: /* Nothing to do. */ break; - case WOLFSSL_QSH: + case TLSX_QUANTUM_SAFE_HYBRID: QSH_FREE_ALL(extension->data); break; - case WOLFSSL_ALPN: + case TLSX_APPLICATION_LAYER_PROTOCOL: ALPN_FREE_ALL((ALPN*)extension->data); break; } @@ -3105,37 +3406,41 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) switch (extension->type) { - case SERVER_NAME_INDICATION: + case TLSX_SERVER_NAME: /* SNI only sends the name on the request. */ if (isRequest) length += SNI_GET_SIZE(extension->data); break; - case MAX_FRAGMENT_LENGTH: + case TLSX_MAX_FRAGMENT_LENGTH: length += MFL_GET_SIZE(extension->data); break; - case TRUNCATED_HMAC: + case TLSX_TRUNCATED_HMAC: /* always empty. */ break; - case ELLIPTIC_CURVES: + case TLSX_SUPPORTED_GROUPS: length += EC_GET_SIZE(extension->data); break; - case SECURE_RENEGOTIATION: + case TLSX_STATUS_REQUEST: + length += CSR_GET_SIZE(extension->data, isRequest); + break; + + case TLSX_RENEGOTIATION_INFO: length += SCR_GET_SIZE(extension->data, isRequest); break; - case SESSION_TICKET: + case TLSX_SESSION_TICKET: length += STK_GET_SIZE(extension->data, isRequest); break; - case WOLFSSL_QSH: + case TLSX_QUANTUM_SAFE_HYBRID: length += QSH_GET_SIZE(extension->data, isRequest); break; - case WOLFSSL_ALPN: + case TLSX_APPLICATION_LAYER_PROTOCOL: length += ALPN_GET_SIZE(extension->data); break; @@ -3175,34 +3480,39 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, /* extension data should be written internally. */ switch (extension->type) { - case SERVER_NAME_INDICATION: + case TLSX_SERVER_NAME: if (isRequest) offset += SNI_WRITE(extension->data, output + offset); break; - case MAX_FRAGMENT_LENGTH: + case TLSX_MAX_FRAGMENT_LENGTH: offset += MFL_WRITE(extension->data, output + offset); break; - case TRUNCATED_HMAC: + case TLSX_TRUNCATED_HMAC: /* always empty. */ break; - case ELLIPTIC_CURVES: + case TLSX_SUPPORTED_GROUPS: offset += EC_WRITE(extension->data, output + offset); break; - case SECURE_RENEGOTIATION: + 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); break; - case SESSION_TICKET: + case TLSX_SESSION_TICKET: offset += STK_WRITE(extension->data, output + offset, isRequest); break; - case WOLFSSL_QSH: + case TLSX_QUANTUM_SAFE_HYBRID: if (isRequest) { offset += QSH_WRITE(extension->data, output + offset); } @@ -3210,7 +3520,7 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, offset += QSH_SERREQ(output + offset, isRequest); break; - case WOLFSSL_ALPN: + case TLSX_APPLICATION_LAYER_PROTOCOL: offset += ALPN_WRITE(extension->data, output + offset); break; } @@ -3234,14 +3544,14 @@ static word32 GetEntropy(unsigned char* out, word32 num_bytes) int ret = 0; if (rng == NULL) { - if ((rng = XMALLOC(sizeof(WC_RNG), 0, DYNAMIC_TYPE_TLSX)) == NULL) + if ((rng = XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TLSX)) == NULL) return DRBG_OUT_OF_MEMORY; wc_InitRng(rng); } if (rngMutex == NULL) { - if ((rngMutex = XMALLOC(sizeof(wolfSSL_Mutex), 0, - DYNAMIC_TYPE_TLSX)) == NULL) + if ((rngMutex = XMALLOC(sizeof(wolfSSL_Mutex), NULL, + DYNAMIC_TYPE_TLSX)) == NULL) return DRBG_OUT_OF_MEMORY; InitMutex(rngMutex); } @@ -3360,7 +3670,7 @@ int TLSX_CreateNtruKey(WOLFSSL* ssl, int type) return ret; } - if ((temp = XMALLOC(sizeof(QSHKey), 0, DYNAMIC_TYPE_TLSX)) == NULL) + if ((temp = XMALLOC(sizeof(QSHKey), NULL, DYNAMIC_TYPE_TLSX)) == NULL) return MEMORY_E; temp->name = type; temp->pub.length = public_key_len; @@ -3471,7 +3781,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) } else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { /* for each scheme make a client key */ - extension = TLSX_Find(ssl->extensions, WOLFSSL_QSH); + extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); if (extension) { qsh = (QSHScheme*)extension->data; @@ -3596,7 +3906,7 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl) #ifdef HAVE_QSH /* change response if not using TLS_QSH */ if (!ssl->options.haveQSH) { - TLSX* ext = TLSX_Find(ssl->extensions, WOLFSSL_QSH); + TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); if (ext) ext->resp = 0; } @@ -3661,49 +3971,55 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, return BUFFER_ERROR; switch (type) { - case SERVER_NAME_INDICATION: + case TLSX_SERVER_NAME: WOLFSSL_MSG("SNI extension received"); ret = SNI_PARSE(ssl, input + offset, size, isRequest); break; - case MAX_FRAGMENT_LENGTH: + case TLSX_MAX_FRAGMENT_LENGTH: WOLFSSL_MSG("Max Fragment Length extension received"); ret = MFL_PARSE(ssl, input + offset, size, isRequest); break; - case TRUNCATED_HMAC: + case TLSX_TRUNCATED_HMAC: WOLFSSL_MSG("Truncated HMAC extension received"); ret = THM_PARSE(ssl, input + offset, size, isRequest); break; - case ELLIPTIC_CURVES: + case TLSX_SUPPORTED_GROUPS: WOLFSSL_MSG("Elliptic Curves extension received"); ret = EC_PARSE(ssl, input + offset, size, isRequest); break; - case SECURE_RENEGOTIATION: + 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"); ret = SCR_PARSE(ssl, input + offset, size, isRequest); break; - case SESSION_TICKET: + case TLSX_SESSION_TICKET: WOLFSSL_MSG("Session Ticket extension received"); ret = STK_PARSE(ssl, input + offset, size, isRequest); break; - case WOLFSSL_QSH: + case TLSX_QUANTUM_SAFE_HYBRID: WOLFSSL_MSG("Quantum-Safe-Hybrid extension received"); ret = QSH_PARSE(ssl, input + offset, size, isRequest); break; - case WOLFSSL_ALPN: + case TLSX_APPLICATION_LAYER_PROTOCOL: WOLFSSL_MSG("ALPN extension received"); ret = ALPN_PARSE(ssl, input + offset, size, isRequest); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 03353d45a7..eecb57ba7c 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 @@ -8624,8 +8628,13 @@ static int DecodeResponseData(byte* source, if (DecodeSingleResponse(source, &idx, resp, size) < 0) return ASN_PARSE_E; - if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0) - return ASN_PARSE_E; + /* + * Check the length of the ResponseData against the current index to + * see if there are extensions, they are optional. + */ + if (idx - prev_idx < resp->responseSz) + if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0) + return ASN_PARSE_E; *ioIndex = idx; return 0; @@ -8658,12 +8667,13 @@ static int DecodeCerts(byte* source, return 0; } -static int DecodeBasicOcspResponse(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) +static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, + OcspResponse* resp, word32 size, void* cm) { int length; word32 idx = *ioIndex; word32 end_index; + int ret; WOLFSSL_ENTER("DecodeBasicOcspResponse"); @@ -8699,13 +8709,12 @@ static int DecodeBasicOcspResponse(byte* source, if (idx < end_index) { DecodedCert cert; - int ret; if (DecodeCerts(source, &idx, resp, size) < 0) return ASN_PARSE_E; InitDecodedCert(&cert, resp->cert, resp->certSz, 0); - ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0); + ret = ParseCertRelative(&cert, CERT_TYPE, VERIFY, cm); if (ret < 0) return ret; @@ -8720,6 +8729,20 @@ static int DecodeBasicOcspResponse(byte* source, return ASN_OCSP_CONFIRM_E; } } + else { + Signer* ca = GetCA(cm, resp->issuerHash); + + if (ca) + ret = ConfirmSignature(resp->response, resp->responseSz, + ca->publicKey, ca->pubKeySize, ca->keyOID, + resp->sig, resp->sigSz, resp->sigOID, NULL); + + if (!ca || ret == 0) + { + WOLFSSL_MSG("\tOCSP Confirm signature failed"); + return ASN_OCSP_CONFIRM_E; + } + } *ioIndex = idx; return 0; @@ -8748,7 +8771,7 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status, } -int OcspResponseDecode(OcspResponse* resp) +int OcspResponseDecode(OcspResponse* resp, void* cm) { int length = 0; word32 idx = 0; @@ -8792,67 +8815,68 @@ int OcspResponseDecode(OcspResponse* resp) if (GetLength(source, &idx, &length, size) < 0) return ASN_PARSE_E; - if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0) + if (DecodeBasicOcspResponse(source, &idx, resp, size, cm) < 0) return ASN_PARSE_E; return 0; } -static word32 SetOcspReqExtensions(word32 extSz, byte* output, - const byte* nonce, word32 nonceSz) +word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size) { static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02 }; - byte seqArray[5][MAX_SEQ_SZ]; - word32 seqSz[5], totalSz; + byte seqArray[6][MAX_SEQ_SZ]; + word32 seqSz[6], totalSz = (word32)sizeof(NonceObjId); WOLFSSL_ENTER("SetOcspReqExtensions"); - if (nonce == NULL || nonceSz == 0) return 0; - - seqArray[0][0] = ASN_OCTET_STRING; - seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]); - - seqArray[1][0] = ASN_OBJECT_ID; - seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]); - - totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId); - - seqSz[2] = SetSequence(totalSz, seqArray[2]); - totalSz += seqSz[2]; - - seqSz[3] = SetSequence(totalSz, seqArray[3]); - totalSz += seqSz[3]; + if (!req || !output || !req->nonceSz) + return 0; - seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2); - seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]); - totalSz += seqSz[4]; + totalSz += req->nonceSz; + totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]); + totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]); + seqArray[2][0] = ASN_OBJECT_ID; + totalSz += seqSz[2] = 1 + SetLength(sizeof(NonceObjId), &seqArray[2][1]); + totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]); + totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]); + totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]); - if (totalSz < extSz) + if (totalSz < size) { totalSz = 0; + + XMEMCPY(output + totalSz, seqArray[5], seqSz[5]); + totalSz += seqSz[5]; + XMEMCPY(output + totalSz, seqArray[4], seqSz[4]); totalSz += seqSz[4]; + XMEMCPY(output + totalSz, seqArray[3], seqSz[3]); totalSz += seqSz[3]; + XMEMCPY(output + totalSz, seqArray[2], seqSz[2]); totalSz += seqSz[2]; - XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); - totalSz += seqSz[1]; + XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId)); totalSz += (word32)sizeof(NonceObjId); + + XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); + totalSz += seqSz[1]; + XMEMCPY(output + totalSz, seqArray[0], seqSz[0]); totalSz += seqSz[0]; - XMEMCPY(output + totalSz, nonce, nonceSz); - totalSz += nonceSz; + + XMEMCPY(output + totalSz, req->nonce, req->nonceSz); + totalSz += req->nonceSz; } return totalSz; } -int EncodeOcspRequest(OcspRequest* req) +int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) { byte seqArray[5][MAX_SEQ_SZ]; /* The ASN.1 of the OCSP Request is an onion of sequences */ @@ -8861,7 +8885,6 @@ int EncodeOcspRequest(OcspRequest* req) byte issuerKeyArray[MAX_ENCODED_DIG_SZ]; byte snArray[MAX_SN_SZ]; byte extArray[MAX_OCSP_EXT_SZ]; - byte* output = req->dest; word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; int i; @@ -8873,54 +8896,42 @@ int EncodeOcspRequest(OcspRequest* req) algoSz = SetAlgoID(SHAh, algoArray, hashType, 0); #endif - req->issuerHash = req->cert->issuerHash; - issuerSz = SetDigest(req->cert->issuerHash, KEYID_SIZE, issuerArray); - - 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); + issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray); + issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray); + snSz = SetSerialNumber(req->serial, req->serialSz, snArray); + extSz = 0; - extSz = 0; - if (req->useNonce) { - WC_RNG rng; - if (wc_InitRng(&rng) != 0) { - WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); - } else { - if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0) - WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce."); - else { - req->nonceSz = MAX_OCSP_NONCE_SZ; - extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, - req->nonce, req->nonceSz); - } - wc_FreeRng(&rng); - } - } + if (req->nonceSz) + extSz = EncodeOcspRequestExtensions(req, extArray, MAX_OCSP_EXT_SZ); 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; } + + if (totalSz > size) + return BUFFER_E; + 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; @@ -8930,19 +8941,70 @@ int EncodeOcspRequest(OcspRequest* req) } -void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, - byte* dest, word32 destSz) +int 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; + if (req == NULL) + return BAD_FUNC_ARG; + + ForceZero(req, sizeof(OcspRequest)); + + if (cert) { + XMEMCPY(req->issuerHash, cert->issuerHash, KEYID_SIZE); + XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE); + + req->serial = (byte*)XMALLOC(cert->serialSz, NULL, + DYNAMIC_TYPE_OCSP_REQUEST); + if (req->serial == NULL) + return MEMORY_E; + + XMEMCPY(req->serial, cert->serial, cert->serialSz); + req->serialSz = cert->serialSz; + + if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) { + req->url = (byte*)XMALLOC(cert->extAuthInfoSz, NULL, + DYNAMIC_TYPE_OCSP_REQUEST); + if (req->url == NULL) { + XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP); + return MEMORY_E; + } + + XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz); + req->urlSz = cert->extAuthInfoSz; + } + + } + + if (useNonce) { + WC_RNG rng; + + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); + } else { + if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0) + WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce."); + else + req->nonceSz = MAX_OCSP_NONCE_SZ; + + wc_FreeRng(&rng); + } + } + + return 0; +} + +void FreeOcspRequest(OcspRequest* req) +{ + WOLFSSL_ENTER("FreeOcspRequest"); + + if (req) { + if (req->serial) + XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP_REQUEST); + + if (req->url) + XFREE(req->url, NULL, DYNAMIC_TYPE_OCSP_REQUEST); + } } @@ -8966,7 +9028,7 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) /* Nonces are not critical. The responder may not necessarily add * the nonce to the response. */ - if (req->useNonce && resp->nonceSz != 0) { + if (req->nonceSz && resp->nonceSz != 0) { cmp = req->nonceSz - resp->nonceSz; if (cmp != 0) { diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index f077960792..bfccee9cdf 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -30,121 +30,123 @@ #endif enum wolfSSL_ErrorCodes { - INPUT_CASE_ERROR = -301, /* process input state error */ - PREFIX_ERROR = -302, /* bad index to key rounds */ - MEMORY_ERROR = -303, /* out of memory */ - VERIFY_FINISHED_ERROR = -304, /* verify problem on finished */ - VERIFY_MAC_ERROR = -305, /* verify mac problem */ - PARSE_ERROR = -306, /* parse error on header */ - UNKNOWN_HANDSHAKE_TYPE = -307, /* weird handshake type */ - SOCKET_ERROR_E = -308, /* error state on socket */ - SOCKET_NODATA = -309, /* expected data, not there */ - INCOMPLETE_DATA = -310, /* don't have enough data to + INPUT_CASE_ERROR = -301, /* process input state error */ + PREFIX_ERROR = -302, /* bad index to key rounds */ + MEMORY_ERROR = -303, /* out of memory */ + VERIFY_FINISHED_ERROR = -304, /* verify problem on finished */ + VERIFY_MAC_ERROR = -305, /* verify mac problem */ + PARSE_ERROR = -306, /* parse error on header */ + UNKNOWN_HANDSHAKE_TYPE = -307, /* weird handshake type */ + SOCKET_ERROR_E = -308, /* error state on socket */ + SOCKET_NODATA = -309, /* expected data, not there */ + INCOMPLETE_DATA = -310, /* don't have enough data to complete task */ - UNKNOWN_RECORD_TYPE = -311, /* unknown type in record hdr */ - DECRYPT_ERROR = -312, /* error during decryption */ - FATAL_ERROR = -313, /* recvd alert fatal error */ - ENCRYPT_ERROR = -314, /* error during encryption */ - FREAD_ERROR = -315, /* fread problem */ - NO_PEER_KEY = -316, /* need peer's key */ - NO_PRIVATE_KEY = -317, /* need the private key */ - RSA_PRIVATE_ERROR = -318, /* error during rsa priv op */ - NO_DH_PARAMS = -319, /* server missing DH params */ - BUILD_MSG_ERROR = -320, /* build message failure */ - - BAD_HELLO = -321, /* client hello malformed */ - DOMAIN_NAME_MISMATCH = -322, /* peer subject name mismatch */ - WANT_READ = -323, /* want read, call again */ - NOT_READY_ERROR = -324, /* handshake layer not ready */ - PMS_VERSION_ERROR = -325, /* pre m secret version error */ - VERSION_ERROR = -326, /* record layer version error */ - WANT_WRITE = -327, /* want write, call again */ - BUFFER_ERROR = -328, /* malformed buffer input */ - VERIFY_CERT_ERROR = -329, /* verify cert error */ - VERIFY_SIGN_ERROR = -330, /* verify sign error */ - CLIENT_ID_ERROR = -331, /* psk client identity error */ - SERVER_HINT_ERROR = -332, /* psk server hint error */ - PSK_KEY_ERROR = -333, /* psk key error */ - ZLIB_INIT_ERROR = -334, /* zlib init error */ - ZLIB_COMPRESS_ERROR = -335, /* zlib compression error */ - ZLIB_DECOMPRESS_ERROR = -336, /* zlib decompression error */ - - GETTIME_ERROR = -337, /* gettimeofday failed ??? */ - GETITIMER_ERROR = -338, /* getitimer failed ??? */ - SIGACT_ERROR = -339, /* sigaction failed ??? */ - SETITIMER_ERROR = -340, /* setitimer failed ??? */ - LENGTH_ERROR = -341, /* record layer length error */ - PEER_KEY_ERROR = -342, /* can't decode peer key */ - ZERO_RETURN = -343, /* peer sent close notify */ - SIDE_ERROR = -344, /* wrong client/server type */ - NO_PEER_CERT = -345, /* peer didn't send key */ - NTRU_KEY_ERROR = -346, /* NTRU key error */ - NTRU_DRBG_ERROR = -347, /* NTRU drbg error */ - NTRU_ENCRYPT_ERROR = -348, /* NTRU encrypt error */ - NTRU_DECRYPT_ERROR = -349, /* NTRU decrypt error */ - ECC_CURVETYPE_ERROR = -350, /* Bad ECC Curve Type */ - ECC_CURVE_ERROR = -351, /* Bad ECC Curve */ - ECC_PEERKEY_ERROR = -352, /* Bad Peer ECC Key */ - ECC_MAKEKEY_ERROR = -353, /* Bad Make ECC Key */ - ECC_EXPORT_ERROR = -354, /* Bad ECC Export Key */ - ECC_SHARED_ERROR = -355, /* Bad ECC Shared Secret */ - NOT_CA_ERROR = -357, /* Not a CA cert error */ - BAD_PATH_ERROR = -358, /* Bad path for opendir */ - BAD_CERT_MANAGER_ERROR = -359, /* Bad Cert Manager */ - OCSP_CERT_REVOKED = -360, /* OCSP Certificate revoked */ - CRL_CERT_REVOKED = -361, /* CRL Certificate revoked */ - CRL_MISSING = -362, /* CRL Not loaded */ - MONITOR_RUNNING_E = -363, /* CRL Monitor already running */ - THREAD_CREATE_E = -364, /* Thread Create Error */ - OCSP_NEED_URL = -365, /* OCSP need an URL for lookup */ - OCSP_CERT_UNKNOWN = -366, /* OCSP responder doesn't know */ - OCSP_LOOKUP_FAIL = -367, /* OCSP lookup not successful */ - MAX_CHAIN_ERROR = -368, /* max chain depth exceeded */ - COOKIE_ERROR = -369, /* dtls cookie error */ - SEQUENCE_ERROR = -370, /* dtls sequence error */ - SUITES_ERROR = -371, /* suites pointer error */ - SSL_NO_PEM_HEADER = -372, /* no PEM header found */ - OUT_OF_ORDER_E = -373, /* out of order message */ - BAD_KEA_TYPE_E = -374, /* bad KEA type found */ - SANITY_CIPHER_E = -375, /* sanity check on cipher error */ - RECV_OVERFLOW_E = -376, /* RXCB returned more than rqed */ - GEN_COOKIE_E = -377, /* Generate Cookie Error */ - NO_PEER_VERIFY = -378, /* Need peer cert verify Error */ - FWRITE_ERROR = -379, /* fwrite problem */ - CACHE_MATCH_ERROR = -380, /* chache hdr match error */ - UNKNOWN_SNI_HOST_NAME_E = -381, /* Unrecognized host name Error */ - UNKNOWN_MAX_FRAG_LEN_E = -382, /* Unrecognized max frag len Error */ - KEYUSE_SIGNATURE_E = -383, /* KeyUse digSignature error */ - KEYUSE_ENCIPHER_E = -385, /* KeyUse keyEncipher error */ - EXTKEYUSE_AUTH_E = -386, /* ExtKeyUse server|client_auth */ - SEND_OOB_READ_E = -387, /* Send Cb out of bounds read */ - SECURE_RENEGOTIATION_E = -388, /* Invalid Renegotiation Info */ - SESSION_TICKET_LEN_E = -389, /* Session Ticket too large */ - SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */ - SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */ - SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */ - NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */ - SANITY_MSG_E = -394, /* Sanity check on msg order error */ - DUPLICATE_MSG_E = -395, /* Duplicate message error */ - SNI_UNSUPPORTED = -396, /* SSL 3.0 does not support SNI */ - SOCKET_PEER_CLOSED_E = -397, /* Underlying transport closed */ - - BAD_TICKET_KEY_CB_SZ = -398, /* Bad session ticket key cb size */ - BAD_TICKET_MSG_SZ = -399, /* Bad session ticket msg size */ - BAD_TICKET_ENCRYPT = -400, /* Bad user ticket encrypt */ - - DH_KEY_SIZE_E = -401, /* DH Key too small */ - SNI_ABSENT_ERROR = -402, /* No SNI request. */ - RSA_SIGN_FAULT = -403, /* RSA Sign fault */ - HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */ + UNKNOWN_RECORD_TYPE = -311, /* unknown type in record hdr */ + DECRYPT_ERROR = -312, /* error during decryption */ + FATAL_ERROR = -313, /* recvd alert fatal error */ + ENCRYPT_ERROR = -314, /* error during encryption */ + FREAD_ERROR = -315, /* fread problem */ + NO_PEER_KEY = -316, /* need peer's key */ + NO_PRIVATE_KEY = -317, /* need the private key */ + RSA_PRIVATE_ERROR = -318, /* error during rsa priv op */ + NO_DH_PARAMS = -319, /* server missing DH params */ + BUILD_MSG_ERROR = -320, /* build message failure */ + + BAD_HELLO = -321, /* client hello malformed */ + DOMAIN_NAME_MISMATCH = -322, /* peer subject name mismatch */ + WANT_READ = -323, /* want read, call again */ + NOT_READY_ERROR = -324, /* handshake layer not ready */ + PMS_VERSION_ERROR = -325, /* pre m secret version error */ + VERSION_ERROR = -326, /* record layer version error */ + WANT_WRITE = -327, /* want write, call again */ + BUFFER_ERROR = -328, /* malformed buffer input */ + VERIFY_CERT_ERROR = -329, /* verify cert error */ + VERIFY_SIGN_ERROR = -330, /* verify sign error */ + CLIENT_ID_ERROR = -331, /* psk client identity error */ + SERVER_HINT_ERROR = -332, /* psk server hint error */ + PSK_KEY_ERROR = -333, /* psk key error */ + ZLIB_INIT_ERROR = -334, /* zlib init error */ + ZLIB_COMPRESS_ERROR = -335, /* zlib compression error */ + ZLIB_DECOMPRESS_ERROR = -336, /* zlib decompression error */ + + GETTIME_ERROR = -337, /* gettimeofday failed ??? */ + GETITIMER_ERROR = -338, /* getitimer failed ??? */ + SIGACT_ERROR = -339, /* sigaction failed ??? */ + SETITIMER_ERROR = -340, /* setitimer failed ??? */ + LENGTH_ERROR = -341, /* record layer length error */ + PEER_KEY_ERROR = -342, /* can't decode peer key */ + ZERO_RETURN = -343, /* peer sent close notify */ + SIDE_ERROR = -344, /* wrong client/server type */ + NO_PEER_CERT = -345, /* peer didn't send key */ + NTRU_KEY_ERROR = -346, /* NTRU key error */ + NTRU_DRBG_ERROR = -347, /* NTRU drbg error */ + NTRU_ENCRYPT_ERROR = -348, /* NTRU encrypt error */ + NTRU_DECRYPT_ERROR = -349, /* NTRU decrypt error */ + ECC_CURVETYPE_ERROR = -350, /* Bad ECC Curve Type */ + ECC_CURVE_ERROR = -351, /* Bad ECC Curve */ + ECC_PEERKEY_ERROR = -352, /* Bad Peer ECC Key */ + ECC_MAKEKEY_ERROR = -353, /* Bad Make ECC Key */ + ECC_EXPORT_ERROR = -354, /* Bad ECC Export Key */ + ECC_SHARED_ERROR = -355, /* Bad ECC Shared Secret */ + NOT_CA_ERROR = -357, /* Not a CA cert error */ + BAD_PATH_ERROR = -358, /* Bad path for opendir */ + BAD_CERT_MANAGER_ERROR = -359, /* Bad Cert Manager */ + OCSP_CERT_REVOKED = -360, /* OCSP Certificate revoked */ + CRL_CERT_REVOKED = -361, /* CRL Certificate revoked */ + CRL_MISSING = -362, /* CRL Not loaded */ + MONITOR_RUNNING_E = -363, /* CRL Monitor already running */ + THREAD_CREATE_E = -364, /* Thread Create Error */ + OCSP_NEED_URL = -365, /* OCSP need an URL for lookup */ + OCSP_CERT_UNKNOWN = -366, /* OCSP responder doesn't know */ + OCSP_LOOKUP_FAIL = -367, /* OCSP lookup not successful */ + MAX_CHAIN_ERROR = -368, /* max chain depth exceeded */ + COOKIE_ERROR = -369, /* dtls cookie error */ + SEQUENCE_ERROR = -370, /* dtls sequence error */ + SUITES_ERROR = -371, /* suites pointer error */ + SSL_NO_PEM_HEADER = -372, /* no PEM header found */ + OUT_OF_ORDER_E = -373, /* out of order message */ + BAD_KEA_TYPE_E = -374, /* bad KEA type found */ + SANITY_CIPHER_E = -375, /* sanity check on cipher error */ + RECV_OVERFLOW_E = -376, /* RXCB returned more than rqed */ + GEN_COOKIE_E = -377, /* Generate Cookie Error */ + NO_PEER_VERIFY = -378, /* Need peer cert verify Error */ + FWRITE_ERROR = -379, /* fwrite problem */ + CACHE_MATCH_ERROR = -380, /* chache hdr match error */ + UNKNOWN_SNI_HOST_NAME_E = -381, /* Unrecognized host name Error */ + UNKNOWN_MAX_FRAG_LEN_E = -382, /* Unrecognized max frag len Error */ + KEYUSE_SIGNATURE_E = -383, /* KeyUse digSignature error */ + KEYUSE_ENCIPHER_E = -385, /* KeyUse keyEncipher error */ + EXTKEYUSE_AUTH_E = -386, /* ExtKeyUse server|client_auth */ + SEND_OOB_READ_E = -387, /* Send Cb out of bounds read */ + SECURE_RENEGOTIATION_E = -388, /* Invalid Renegotiation Info */ + SESSION_TICKET_LEN_E = -389, /* Session Ticket too large */ + SESSION_TICKET_EXPECT_E = -390, /* Session Ticket missing */ + SCR_DIFFERENT_CERT_E = -391, /* SCR Different cert error */ + SESSION_SECRET_CB_E = -392, /* Session secret Cb fcn failure */ + NO_CHANGE_CIPHER_E = -393, /* Finished before change cipher */ + SANITY_MSG_E = -394, /* Sanity check on msg order error */ + DUPLICATE_MSG_E = -395, /* Duplicate message error */ + SNI_UNSUPPORTED = -396, /* SSL 3.0 does not support SNI */ + SOCKET_PEER_CLOSED_E = -397, /* Underlying transport closed */ + + BAD_TICKET_KEY_CB_SZ = -398, /* Bad session ticket key cb size */ + BAD_TICKET_MSG_SZ = -399, /* Bad session ticket msg size */ + BAD_TICKET_ENCRYPT = -400, /* Bad user ticket encrypt */ + + DH_KEY_SIZE_E = -401, /* DH Key too small */ + SNI_ABSENT_ERROR = -402, /* No SNI request. */ + RSA_SIGN_FAULT = -403, /* RSA Sign fault */ + HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */ UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/ + BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */ + OCSP_INVALID_STATUS = -407, /* Invalid OCSP Status */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ - UNSUPPORTED_SUITE = -500, /* unsupported cipher suite */ - MATCH_SUITE_ERROR = -501 /* can't match cipher suite */ + UNSUPPORTED_SUITE = -500, /* unsupported cipher suite */ + MATCH_SUITE_ERROR = -501 /* can't match cipher suite */ /* end negotiation parameter errors only 10 for now */ /* add strings to SetErrorString !!!!! */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d65665ec04..76f7f108ac 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -868,7 +868,7 @@ enum Misc { COMP_LEN = 1, /* compression length */ CURVE_LEN = 2, /* ecc named curve length */ SERVER_ID_LEN = 20, /* server session id length */ - + HANDSHAKE_HEADER_SZ = 4, /* type + length(3) */ RECORD_HEADER_SZ = 5, /* type + version + len(2) */ CERT_HEADER_SZ = 3, /* always 3 bytes */ @@ -897,7 +897,7 @@ enum Misc { MAX_PRF_LABSEED = 128, /* Maximum label + seed len */ MAX_PRF_DIG = 224, /* Maximum digest len */ MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ - SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ + SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ RC4_KEY_SIZE = 16, /* always 128bit */ DES_KEY_SIZE = 8, /* des */ @@ -1156,7 +1156,7 @@ enum { /* only the sniffer needs space in the buffer for extra MTU record(s) */ #ifdef WOLFSSL_SNIFFER - #define MTU_EXTRA MAX_MTU * 3 + #define MTU_EXTRA MAX_MTU * 3 #else #define MTU_EXTRA 0 #endif @@ -1174,9 +1174,9 @@ enum { #define RECORD_SIZE MAX_RECORD_SIZE #else #ifdef WOLFSSL_DTLS - #define RECORD_SIZE MAX_MTU + #define RECORD_SIZE MAX_MTU #else - #define RECORD_SIZE 128 + #define RECORD_SIZE 128 #endif #endif @@ -1255,7 +1255,7 @@ struct WOLFSSL_CIPHER { }; -typedef struct OCSP_Entry OCSP_Entry; +typedef struct OcspEntry OcspEntry; #ifdef NO_SHA #define OCSP_DIGEST_SIZE SHA256_DIGEST_SIZE @@ -1263,17 +1263,17 @@ typedef struct OCSP_Entry OCSP_Entry; #define OCSP_DIGEST_SIZE SHA_DIGEST_SIZE #endif -#ifdef NO_ASN +#ifdef NO_ASN /* no_asn won't have */ typedef struct CertStatus CertStatus; #endif -struct OCSP_Entry { - OCSP_Entry* next; /* next entry */ - byte issuerHash[OCSP_DIGEST_SIZE]; /* issuer hash */ - byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */ - CertStatus* status; /* OCSP response list */ - int totalStatus; /* number on list */ +struct OcspEntry { + OcspEntry* next; /* next entry */ + byte issuerHash[OCSP_DIGEST_SIZE]; /* issuer hash */ + byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */ + CertStatus* status; /* OCSP response list */ + int totalStatus; /* number on list */ }; @@ -1284,7 +1284,7 @@ struct OCSP_Entry { /* wolfSSL OCSP controller */ struct WOLFSSL_OCSP { WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */ - OCSP_Entry* ocspList; /* OCSP response list */ + OcspEntry* ocspList; /* OCSP response list */ wolfSSL_Mutex ocspLock; /* OCSP list lock */ }; @@ -1307,8 +1307,8 @@ typedef struct CRL_Entry CRL_Entry; /* Complete CRL */ struct CRL_Entry { CRL_Entry* next; /* next entry */ - byte issuerHash[CRL_DIGEST_SIZE]; /* issuer hash */ - /* byte crlHash[CRL_DIGEST_SIZE]; raw crl data hash */ + byte issuerHash[CRL_DIGEST_SIZE]; /* issuer hash */ + /* byte crlHash[CRL_DIGEST_SIZE]; raw crl data hash */ /* restore the hash here if needed for optimized comparisons */ byte lastDate[MAX_DATE_SIZE]; /* last date updated */ byte nextDate[MAX_DATE_SIZE]; /* next update date */ @@ -1456,18 +1456,19 @@ typedef struct Keys { -/* RFC 6066 TLS Extensions */ +/** TLS Extensions - RFC 6066 */ #ifdef HAVE_TLS_EXTENSIONS typedef enum { - SERVER_NAME_INDICATION = 0x0000, - MAX_FRAGMENT_LENGTH = 0x0001, - TRUNCATED_HMAC = 0x0004, - ELLIPTIC_CURVES = 0x000a, - SESSION_TICKET = 0x0023, - SECURE_RENEGOTIATION = 0xff01, - WOLFSSL_QSH = 0x0018, /* Quantum-Safe-Hybrid */ - WOLFSSL_ALPN = 0x0010 /* Application-Layer Protocol Name */ + TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */ + TLSX_MAX_FRAGMENT_LENGTH = 0x0001, + TLSX_TRUNCATED_HMAC = 0x0004, + 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, + TLSX_RENEGOTIATION_INFO = 0xff01 } TLSX_Type; typedef struct TLSX { @@ -1495,19 +1496,21 @@ WOLFSSL_LOCAL word16 TLSX_WriteResponse(WOLFSSL* ssl, byte* output); WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, Suites *suites); -#elif defined(HAVE_SNI) \ - || defined(HAVE_MAX_FRAGMENT) \ - || defined(HAVE_TRUNCATED_HMAC) \ - || defined(HAVE_SUPPORTED_CURVES) \ - || defined(HAVE_SECURE_RENEGOTIATION) \ - || defined(HAVE_SESSION_TICKET) \ - || defined(HAVE_ALPN) +#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) \ + || defined(HAVE_SESSION_TICKET) \ + || defined(HAVE_SECURE_RENEGOTIATION) #error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined. #endif /* HAVE_TLS_EXTENSIONS */ -/* Server Name Indication */ +/** Server Name Indication - RFC 6066 (session 3) */ #ifdef HAVE_SNI typedef struct SNI { @@ -1535,7 +1538,7 @@ WOLFSSL_LOCAL int TLSX_SNI_GetFromBuffer(const byte* buffer, word32 bufferSz, #endif /* HAVE_SNI */ -/* Application-layer Protocol Name */ +/* Application-Layer Protocol Negotiation - RFC 7301 */ #ifdef HAVE_ALPN typedef struct ALPN { char* protocol_name; /* ALPN protocol name */ @@ -1554,19 +1557,40 @@ WOLFSSL_LOCAL int TLSX_ALPN_SetOptions(TLSX** extensions, const byte option); #endif /* HAVE_ALPN */ -/* Maximum Fragment Length */ +/** Maximum Fragment Length Negotiation - RFC 6066 (session 4) */ #ifdef HAVE_MAX_FRAGMENT WOLFSSL_LOCAL int TLSX_UseMaxFragment(TLSX** extensions, byte mfl); #endif /* HAVE_MAX_FRAGMENT */ +/** Truncated HMAC - RFC 6066 (session 7) */ #ifdef HAVE_TRUNCATED_HMAC 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; + byte options; + union { + OcspRequest ocsp; + } request; +} CertificateStatusRequest; + +WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions, + byte status_type, byte options); +WOLFSSL_LOCAL int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert); +WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions); +WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl); + +#endif + +/** Supported Elliptic Curves - RFC 4492 (session 4) */ #ifdef HAVE_SUPPORTED_CURVES typedef struct EllipticCurve { @@ -1583,6 +1607,7 @@ WOLFSSL_LOCAL int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, #endif /* HAVE_SUPPORTED_CURVES */ +/** Renegotiation Indication - RFC 5746 */ #ifdef HAVE_SECURE_RENEGOTIATION enum key_cache_state { @@ -1593,7 +1618,6 @@ enum key_cache_state { SCR_CACHE_COMPLETE /* complete restore to real keys */ }; - /* Additional Conection State according to rfc5746 section 3.1 */ typedef struct SecureRenegotiation { byte enabled; /* secure_renegotiation flag in rfc */ @@ -1609,6 +1633,7 @@ WOLFSSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions); #endif /* HAVE_SECURE_RENEGOTIATION */ +/** Session Ticket - RFC 5077 (session 3.2) */ #ifdef HAVE_SESSION_TICKET typedef struct SessionTicket { @@ -1617,13 +1642,15 @@ typedef struct SessionTicket { word16 size; } SessionTicket; -WOLFSSL_LOCAL int TLSX_UseSessionTicket(TLSX** extensions, +WOLFSSL_LOCAL int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket); WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime, byte* data, word16 size); WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket); + #endif /* HAVE_SESSION_TICKET */ +/** Quantum-Safe-Hybrid - draft-whyte-qsh-tls12-00 */ #ifdef HAVE_QSH typedef struct QSHScheme { @@ -1753,7 +1780,7 @@ struct WOLFSSL_CTX { CallbackEccSign EccSignCb; /* User EccSign Callback handler */ CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */ #endif /* HAVE_ECC */ - #ifndef NO_RSA + #ifndef NO_RSA CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler */ CallbackRsaVerify RsaVerifyCb; /* User RsaVerify Callback handler */ CallbackRsaEnc RsaEncCb; /* User Rsa Public Encrypt handler */ @@ -1803,7 +1830,7 @@ void InitCipherSpecs(CipherSpecs* cs); /* Supported Message Authentication Codes from page 43 */ -enum MACAlgorithm { +enum MACAlgorithm { no_mac, md5_mac, sha_mac, @@ -1817,10 +1844,10 @@ enum MACAlgorithm { /* Supported Key Exchange Protocols */ -enum KeyExchangeAlgorithm { +enum KeyExchangeAlgorithm { no_kea, - rsa_kea, - diffie_hellman_kea, + rsa_kea, + diffie_hellman_kea, fortezza_kea, psk_kea, dhe_psk_kea, @@ -1846,8 +1873,8 @@ enum EccCurves { /* Valid client certificate request types from page 27 */ -enum ClientCertificateType { - rsa_sign = 1, +enum ClientCertificateType { + rsa_sign = 1, dss_sign = 2, rsa_fixed_dh = 3, dss_fixed_dh = 4, @@ -2177,7 +2204,7 @@ struct WOLFSSL_X509_NAME { #define EXTERNAL_SERIAL_SIZE 32 #endif -#ifdef NO_ASN +#ifdef NO_ASN typedef struct DNS_entry DNS_entry; #endif @@ -2295,6 +2322,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; @@ -2446,6 +2474,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 */ @@ -2529,20 +2560,20 @@ typedef struct EncryptedInfo { #ifdef WOLFSSL_CALLBACKS WOLFSSL_LOCAL void InitHandShakeInfo(HandShakeInfo*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void FinishHandShakeInfo(HandShakeInfo*, const WOLFSSL*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void AddPacketName(const char*, HandShakeInfo*); WOLFSSL_LOCAL void InitTimeoutInfo(TimeoutInfo*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void FreeTimeoutInfo(TimeoutInfo*, void*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void AddPacketInfo(const char*, TimeoutInfo*, const byte*, int, void*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void AddLateName(const char*, TimeoutInfo*); - WOLFSSL_LOCAL + WOLFSSL_LOCAL void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info); #endif @@ -2550,10 +2581,10 @@ typedef struct EncryptedInfo { /* Record Layer Header identifier from page 12 */ enum ContentType { no_type = 0, - change_cipher_spec = 20, - alert = 21, - handshake = 22, - application_data = 23 + change_cipher_spec = 20, + alert = 21, + handshake = 22, + application_data = 23 }; @@ -2576,16 +2607,16 @@ typedef struct DtlsHandShakeHeader { enum HandShakeType { no_shake = -1, - hello_request = 0, - client_hello = 1, + hello_request = 0, + client_hello = 1, server_hello = 2, hello_verify_request = 3, /* DTLS addition */ session_ticket = 4, - certificate = 11, + certificate = 11, server_key_exchange = 12, - certificate_request = 13, + certificate_request = 13, server_hello_done = 14, - certificate_verify = 15, + certificate_verify = 15, client_key_exchange = 16, finished = 20, certificate_status = 22, @@ -2685,7 +2716,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength); #endif /* WOLFSSL_DTLS */ #ifndef NO_TLS - + #endif /* NO_TLS */ @@ -2721,4 +2752,3 @@ WOLFSSL_LOCAL int SetKeysSide(WOLFSSL*, enum encrypt_side); #endif #endif /* wolfSSL_INT_H */ - diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index 77a4157eef..dc76ca16e7 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -40,6 +40,8 @@ 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 CheckOcspRequest(WOLFSSL_OCSP* ocsp, + OcspRequest* ocspRequest); #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 356224fe18..5a30c8c818 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -170,35 +170,36 @@ typedef struct WOLFSSL_X509_STORE_CTX { /* Valid Alert types from page 16/17 */ enum AlertDescription { - close_notify = 0, - unexpected_message = 10, - bad_record_mac = 20, - record_overflow = 22, - decompression_failure = 30, - handshake_failure = 40, - no_certificate = 41, - bad_certificate = 42, - unsupported_certificate = 43, - certificate_revoked = 44, - certificate_expired = 45, - certificate_unknown = 46, - illegal_parameter = 47, - decrypt_error = 51, + close_notify = 0, + unexpected_message = 10, + bad_record_mac = 20, + record_overflow = 22, + decompression_failure = 30, + handshake_failure = 40, + no_certificate = 41, + bad_certificate = 42, + unsupported_certificate = 43, + certificate_revoked = 44, + certificate_expired = 45, + certificate_unknown = 46, + illegal_parameter = 47, + decrypt_error = 51, #ifdef WOLFSSL_MYSQL_COMPATIBLE /* catch name conflict for enum protocol with MYSQL build */ - wc_protocol_version = 70, + wc_protocol_version = 70, #else - protocol_version = 70, + protocol_version = 70, #endif - no_renegotiation = 100, - unrecognized_name = 112, - no_application_protocol = 120 + no_renegotiation = 100, + unrecognized_name = 112, /**< RFC 6066, section 3 */ + bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ + no_application_protocol = 120 }; enum AlertLevel { alert_warning = 1, - alert_fatal = 2 + alert_fatal = 2 }; @@ -1353,7 +1354,7 @@ WOLFSSL_API int wolfSSL_SNI_GetFromBuffer( #endif #endif -/* Application-Layer Protocol Name */ +/* Application-Layer Protocol Negotiation */ #ifdef HAVE_ALPN /* ALPN status code */ @@ -1410,6 +1411,29 @@ WOLFSSL_API int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx); #endif #endif +/* Certificate Status Request */ +/* Certificate Status Type */ +enum { + WOLFSSL_CSR_OCSP = 1 +}; + +/* Certificate Status Options (flags) */ +enum { + WOLFSSL_CSR_OCSP_USE_NONCE = 0x01 +}; + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, + unsigned char status_type, unsigned char options); + +WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, + unsigned char status_type, unsigned char options); + +#endif +#endif + /* Elliptic Curves */ enum { WOLFSSL_ECC_SECP160R1 = 0x10, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index b39114fa40..b1a1325148 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -188,7 +188,7 @@ enum Misc_ASN { MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ, #endif MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */ - MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */ + MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */ EIGHTK_BUF = 8192, /* Tmp buffer size */ MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, /* use bigger NTRU size */ @@ -707,28 +707,26 @@ struct OcspResponse { struct OcspRequest { - DecodedCert* cert; + byte issuerHash[KEYID_SIZE]; + byte issuerKeyHash[KEYID_SIZE]; + byte* serial; /* copy of the serial number in source cert */ + int serialSz; + byte* url; /* copy of the extAuthInfo in source cert */ + int urlSz; - byte useNonce; - byte nonce[MAX_OCSP_NONCE_SZ]; - int nonceSz; - - byte* issuerHash; /* pointer to issuerHash in source cert */ - byte* issuerKeyHash; /* pointer to issuerKeyHash in source cert */ - byte* serial; /* pointer to serial number in source cert */ - int serialSz; /* length of the serial number */ - - byte* dest; /* pointer to the destination ASN.1 buffer */ - word32 destSz; /* length of the destination buffer */ + byte nonce[MAX_OCSP_NONCE_SZ]; + int nonceSz; }; WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32); -WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*); +WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*, void*); + +WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte); +WOLFSSL_LOCAL void FreeOcspRequest(OcspRequest*); +WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*, byte*, word32); +WOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest*, byte*, word32); -WOLFSSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*, - byte, byte*, word32); -WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*); WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); @@ -779,4 +777,3 @@ WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*); #endif /* !NO_ASN */ #endif /* WOLF_CRYPT_ASN_H */ - diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 4e79529407..3b9963bb94 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -287,7 +287,8 @@ DYNAMIC_TYPE_HASHES = 46, DYNAMIC_TYPE_SRP = 47, DYNAMIC_TYPE_COOKIE_PWD = 48, - DYNAMIC_TYPE_USER_CRYPTO = 49 + DYNAMIC_TYPE_USER_CRYPTO = 49, + DYNAMIC_TYPE_OCSP_REQUEST = 50 }; /* max error buffer string size */