Browse Source

Merge branch csr into 'master'

Moisés Guimarães 8 years ago
parent
commit
21d70636dc
16 changed files with 1337 additions and 631 deletions
  1. 5 5
      .gitignore
  2. 117 96
      configure.ac
  3. 24 5
      examples/client/client.c
  4. 1 1
      examples/server/server.c
  5. 1 0
      pull_to_vagrant.sh
  6. 168 25
      src/internal.c
  7. 167 115
      src/ocsp.c
  8. 46 10
      src/ssl.c
  9. 404 88
      src/tls.c
  10. 138 76
      wolfcrypt/src/asn.c
  11. 110 108
      wolfssl/error-ssl.h
  12. 92 62
      wolfssl/internal.h
  13. 2 0
      wolfssl/ocsp.h
  14. 45 21
      wolfssl/ssl.h
  15. 15 18
      wolfssl/wolfcrypt/asn.h
  16. 2 1
      wolfssl/wolfcrypt/types.h

+ 5 - 5
.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

+ 117 - 96
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 "---"

+ 24 - 5
examples/client/client.c

@@ -310,7 +310,7 @@ static void Usage(void)
 #endif
     printf("-b <num>    Benchmark <num> connections and print stats\n");
 #ifdef HAVE_ALPN
-    printf("-L <str>    Application-Layer Protocole Name ({C,F}:<list>)\n");
+    printf("-L <str>    Application-Layer Protocol Negotiation ({C,F}:<list>)\n");
 #endif
     printf("-B <num>    Benchmark throughput using <num> 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 <url>    Perform OCSP lookup using <url> 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
-

+ 1 - 1
examples/server/server.c

@@ -200,7 +200,7 @@ static void Usage(void)
                                  DEFAULT_MIN_DHKEY_BITS);
 #endif
 #ifdef HAVE_ALPN
-    printf("-L <str>    Application-Layer Protocole Name ({C,F}:<list>)\n");
+    printf("-L <str>    Application-Layer Protocol Negotiation ({C,F}:<list>)\n");
 #endif
     printf("-d          Disable client cert check\n");
     printf("-b          Bind to any interface instead of localhost only\n");

+ 1 - 0
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/

+ 168 - 25
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,

+ 167 - 115
src/ocsp.c

@@ -34,59 +34,68 @@
 #include <wolfssl/ocsp.h>
 #include <wolfssl/internal.h>
 
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#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;
 }
 
 

+ 46 - 10
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 */
-

+ 404 - 88
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);

+ 138 - 76
wolfcrypt/src/asn.c

@@ -43,7 +43,11 @@
 
 #include <wolfssl/wolfcrypt/random.h>
 #include <wolfssl/wolfcrypt/hash.h>
-
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
 
 #ifndef NO_RC4
     #include <wolfssl/wolfcrypt/arc4.h>
@@ -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)
         {

+ 110 - 108
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 !!!!! */
 

+ 92 - 62
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 */
-

+ 2 - 0
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" */

+ 45 - 21
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,

+ 15 - 18
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 */
-

+ 2 - 1
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 */