From d2642e329ddf0828cc3628adb0de92010df760a9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 5 Jul 2023 10:28:32 +0200 Subject: [PATCH] Properly enforce the pathLenConstraint of the BasicConstraints extension - move the testsuite file helps into a new tests/utils.c file so that they can be used across all tests - dump the raw TLS stream when WOLFSSL_DUMP_MEMIO_STREAM is defined so that it can be examined in Wireshark --- src/internal.c | 10 ++- src/ssl.c | 17 +++-- src/tls.c | 3 +- tests/api.c | 57 +++++++++++++++- tests/include.am | 3 +- tests/utils.c | 119 +++++++++++++++++++++++++++++++++ testsuite/testsuite.c | 87 +----------------------- wolfcrypt/src/asn.c | 117 ++++++++++---------------------- wolfssl/wolfcrypt/asn.h | 2 - wolfssl/wolfcrypt/asn_public.h | 3 +- 10 files changed, 240 insertions(+), 178 deletions(-) create mode 100644 tests/utils.c diff --git a/src/internal.c b/src/internal.c index 13360f93a..1b8182918 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12653,7 +12653,8 @@ void DoCertFatalAlert(WOLFSSL* ssl, int ret) alertWhy = bad_certificate; if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) { alertWhy = certificate_expired; - } else if (ret == ASN_NO_SIGNER_E) { + } else if (ret == ASN_NO_SIGNER_E || ret == ASN_PATHLEN_INV_E || + ret == ASN_PATHLEN_SIZE_E) { alertWhy = unknown_ca; } #ifdef OPENSSL_EXTRA @@ -13864,7 +13865,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* select last certificate */ args->certIdx = args->count - 1; - ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, + ret = ProcessPeerCertParse(ssl, args, CHAIN_CERT_TYPE, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \ @@ -13879,7 +13880,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, FreeDecodedCert(args->dCert); args->dCertInit = 0; /* once again */ - ret = ProcessPeerCertParse(ssl, args, CERT_TYPE, + ret = ProcessPeerCertParse(ssl, args, CHAIN_CERT_TYPE, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); } @@ -14085,6 +14086,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (!ssl->options.verifyNone) { WOLFSSL_ERROR_VERBOSE(ret); DoCertFatalAlert(ssl, ret); + args->lastErr = ret; + break; /* We sent a fatal alert. + * No point continuing. */ } if (args->lastErr == 0) { args->lastErr = ret; /* save error from last time */ diff --git a/src/ssl.c b/src/ssl.c index 917f47f65..ceef3767f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6122,9 +6122,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) signer->nameLen = cert->subjectCNLen; signer->name = cert->subjectCN; } - signer->pathLength = cert->pathLength; signer->maxPathLen = cert->maxPathLen; - signer->pathLengthSet = cert->pathLengthSet; signer->selfSigned = cert->selfSigned; #ifndef IGNORE_NAME_CONSTRAINTS signer->permittedNames = cert->permittedNames; @@ -6543,7 +6541,8 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff, } /* we may have a user cert chain, try to consume */ - if ((type == CERT_TYPE || type == CA_TYPE) && (info->consumed < sz)) { + if ((type == CERT_TYPE || type == CHAIN_CERT_TYPE || type == CA_TYPE) && + (info->consumed < sz)) { #ifdef WOLFSSL_SMALL_STACK byte staticBuffer[1]; /* force heap usage */ #else @@ -7347,6 +7346,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, if (ctx == NULL && ssl == NULL) return BAD_FUNC_ARG; + /* This API does not handle CHAIN_CERT_TYPE */ + if (type == CHAIN_CERT_TYPE) + return BAD_FUNC_ARG; + #ifdef WOLFSSL_SMALL_STACK info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap, DYNAMIC_TYPE_ENCRYPTEDINFO); @@ -7424,8 +7427,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, * Remainder are processed using ProcessUserChain and are loaded into * ssl->buffers.certChain. */ if (userChain) { - ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info, - verify); + ret = ProcessUserChain(ctx, buff, sz, format, CHAIN_CERT_TYPE, ssl, + used, info, verify); if (ret == ASN_NO_PEM_HEADER) { /* Additional chain is optional */ unsigned long pemErr = 0; CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr); @@ -9430,6 +9433,10 @@ int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file, return ret; } + /* Some configurations like OPENSSL_COMPATIBLE_DEFAULTS may turn off + * verification by default. Let's restore our desired defaults. */ + wolfSSL_CTX_set_verify(tmp, WOLFSSL_VERIFY_DEFAULT, NULL); + /* for tmp use */ wolfSSL_CertManagerFree(tmp->cm); tmp->cm = cm; diff --git a/src/tls.c b/src/tls.c index 442a66535..9aee4ffd2 100644 --- a/src/tls.c +++ b/src/tls.c @@ -10101,7 +10101,8 @@ static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (ret == 0) ret = TLSX_PskKeyModes_Use(ssl, modes); - WOLFSSL_ERROR_VERBOSE(ret); + if (ret != 0) + WOLFSSL_ERROR_VERBOSE(ret); return ret; } diff --git a/tests/api.c b/tests/api.c index 2e0c906eb..79b8d5860 100644 --- a/tests/api.c +++ b/tests/api.c @@ -382,6 +382,9 @@ #endif #include +#define WOLFSSL_TEST_UTILS_INCLUDED +#include "tests/utils.c" + #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ #define wc_ecc_key_get_priv(key) (&((key)->k)) @@ -478,6 +481,12 @@ typedef struct test_ssl_memio_ctx { int test_wolfSSL_client_server_nofail_memio(test_ssl_cbf* client_cb, test_ssl_cbf* server_cb, test_cbType client_on_handshake); +#ifdef WOLFSSL_DUMP_MEMIO_STREAM +const char* currentTestName; +char tmpDirName[16]; +int tmpDirNameSet = 0; +#endif + /*----------------------------------------------------------------------------* | Constants *----------------------------------------------------------------------------*/ @@ -5169,6 +5178,24 @@ static WC_INLINE int test_ssl_memio_write_cb(WOLFSSL *ssl, char *data, int sz, XMEMCPY(buf + *len, data, sz); *len += sz; +#ifdef WOLFSSL_DUMP_MEMIO_STREAM + { + /* This can be imported into Wireshark by transforming the file with + * od -Ax -tx1 -v test_output.dump > test_output.dump.hex + * And then loading test_output.dump.hex into Wireshark using the + * "Import from Hex Dump..." option ion and selecting the TCP + * encapsulation option. */ + char dump_file_name[64]; + WOLFSSL_BIO *dump_file; + sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName); + dump_file = wolfSSL_BIO_new_file(dump_file_name, "a"); + if (dump_file != NULL) { + (void)wolfSSL_BIO_write(dump_file, data, sz); + wolfSSL_BIO_free(dump_file); + } + } +#endif + return sz; } @@ -37558,7 +37585,7 @@ static WC_INLINE int test_wolfSSL_check_domain_verify_cb(int preverify, ExpectIntEQ(X509_STORE_CTX_get_error(store), 0); ExpectIntEQ(preverify, 1); ExpectIntGT(++test_wolfSSL_check_domain_verify_count, 0); - return EXPECT_RESULT() == TEST_SUCCESS; + return EXPECT_SUCCESS(); } static int test_wolfSSL_check_domain_client_cb(WOLFSSL* ssl) @@ -63424,10 +63451,26 @@ int ApiTest(void) #endif } + #ifdef WOLFSSL_DUMP_MEMIO_STREAM + if (res == 0) { + if (create_tmp_dir(tmpDirName, sizeof(tmpDirName) - 1) == NULL) { + printf("failed to create tmp dir\n"); + res = 1; + } + else { + tmpDirNameSet = 1; + } + } + #endif + if (res == 0) { for (i = 0; i < TEST_CASE_CNT; ++i) { EXPECT_DECLS; + #ifdef WOLFSSL_DUMP_MEMIO_STREAM + currentTestName = testCases[i].name; + #endif + /* When not testing all cases then skip if not marked for running. */ if (!testAll && !testCases[i].run) { @@ -63492,6 +63535,18 @@ int ApiTest(void) fflush(stdout); } +#ifdef WOLFSSL_DUMP_MEMIO_STREAM + if (tmpDirNameSet) { + printf("\nBinary dumps of the memio streams can be found in the\n" + "%s directory. This can be imported into\n" + "Wireshark by transforming the file with\n" + "\tod -Ax -tx1 -v stream.dump > stream.dump.hex\n" + "And then loading test_output.dump.hex into Wireshark using\n" + "the \"Import from Hex Dump...\" option and selecting the\n" + "TCP encapsulation option.\n", tmpDirName); + } +#endif + printf(" End API Tests\n"); fflush(stdout); return res; diff --git a/tests/include.am b/tests/include.am index 132c2fc59..8291fcb63 100644 --- a/tests/include.am +++ b/tests/include.am @@ -69,5 +69,6 @@ EXTRA_DIST += tests/unit.h \ tests/test-sm2.conf \ tests/NCONF_test.cnf \ tests/test-tls-downgrade.conf \ - tests/TXT_DB.txt + tests/TXT_DB.txt \ + tests/utils.c DISTCLEANFILES+= tests/.libs/unit.test diff --git a/tests/utils.c b/tests/utils.c new file mode 100644 index 000000000..bd5c9271b --- /dev/null +++ b/tests/utils.c @@ -0,0 +1,119 @@ +/* utils.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#if !defined(WOLFSSL_TEST_UTILS_INCLUDED) + #ifndef WOLFSSL_IGNORE_FILE_WARN + #warning utils.c does not need to be compiled separately + #endif +#else + +#ifndef NO_FILESYSTEM + +#ifdef _MSC_VER +#include +#endif + +#define TMP_DIR_PREFIX "tmpDir-" +/* len is length of tmpDir name, assuming + * len does not include null terminating character */ +char* create_tmp_dir(char *tmpDir, int len) +{ + if (len < (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) + return NULL; + + XMEMCPY(tmpDir, TMP_DIR_PREFIX, XSTR_SIZEOF(TMP_DIR_PREFIX)); + + if (mymktemp(tmpDir, len, len - XSTR_SIZEOF(TMP_DIR_PREFIX)) == NULL) + return NULL; + +#ifdef _MSC_VER + if (_mkdir(tmpDir) != 0) + return NULL; +#else + if (mkdir(tmpDir, 0700) != 0) + return NULL; +#endif + + return tmpDir; +} + +int rem_dir(const char* dirName) +{ +#ifdef _MSC_VER + if (_rmdir(dirName) != 0) + return -1; +#else + if (rmdir(dirName) != 0) + return -1; +#endif + return 0; +} + +int rem_file(const char* fileName) +{ +#ifdef _MSC_VER + if (_unlink(fileName) != 0) + return -1; +#else + if (unlink(fileName) != 0) + return -1; +#endif + return 0; +} + +int copy_file(const char* in, const char* out) +{ + byte buf[100]; + XFILE inFile = XBADFILE; + XFILE outFile = XBADFILE; + size_t sz; + int ret = -1; + + inFile = XFOPEN(in, "rb"); + if (inFile == XBADFILE) + goto cleanup; + + outFile = XFOPEN(out, "wb"); + if (outFile == XBADFILE) + goto cleanup; + + while ((sz = XFREAD(buf, 1, sizeof(buf), inFile)) != 0) { + if (XFWRITE(buf, 1, sz, outFile) != sz) + goto cleanup; + } + + ret = 0; +cleanup: + if (inFile != XBADFILE) + XFCLOSE(inFile); + if (outFile != XBADFILE) + XFCLOSE(outFile); + return ret; +} +#endif /* !NO_FILESYSTEM */ + +#endif /* WOLFSSL_TEST_UTILS_INCLUDED */ diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 8240bd330..5976b8d29 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -45,6 +45,8 @@ #include #include +#define WOLFSSL_TEST_UTILS_INCLUDED +#include "tests/utils.c" #ifndef NO_SHA256 void file_test(const char* file, byte* check); @@ -718,90 +720,7 @@ void join_thread(THREAD_TYPE thread) #endif } -#ifndef NO_FILESYSTEM - -#ifdef _MSC_VER -#include -#endif - -#define TMP_DIR_PREFIX "tmpDir-" -/* len is length of tmpDir name, assuming - * len does not include null terminating character */ -char* create_tmp_dir(char *tmpDir, int len) -{ - if (len < (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) - return NULL; - - XMEMCPY(tmpDir, TMP_DIR_PREFIX, XSTR_SIZEOF(TMP_DIR_PREFIX)); - - if (mymktemp(tmpDir, len, len - XSTR_SIZEOF(TMP_DIR_PREFIX)) == NULL) - return NULL; - -#ifdef _MSC_VER - if (_mkdir(tmpDir) != 0) - return NULL; -#else - if (mkdir(tmpDir, 0700) != 0) - return NULL; -#endif - - return tmpDir; -} - -int rem_dir(const char* dirName) -{ -#ifdef _MSC_VER - if (_rmdir(dirName) != 0) - return -1; -#else - if (rmdir(dirName) != 0) - return -1; -#endif - return 0; -} - -int rem_file(const char* fileName) -{ -#ifdef _MSC_VER - if (_unlink(fileName) != 0) - return -1; -#else - if (unlink(fileName) != 0) - return -1; -#endif - return 0; -} - -int copy_file(const char* in, const char* out) -{ - byte buf[100]; - XFILE inFile = XBADFILE; - XFILE outFile = XBADFILE; - size_t sz; - int ret = -1; - - inFile = XFOPEN(in, "rb"); - if (inFile == XBADFILE) - goto cleanup; - - outFile = XFOPEN(out, "wb"); - if (outFile == XBADFILE) - goto cleanup; - - while ((sz = XFREAD(buf, 1, sizeof(buf), inFile)) != 0) { - if (XFWRITE(buf, 1, sz, outFile) != sz) - goto cleanup; - } - - ret = 0; -cleanup: - if (inFile != XBADFILE) - XFCLOSE(inFile); - if (outFile != XBADFILE) - XFCLOSE(outFile); - return ret; -} -#endif /* !NO_FILESYSTEM */ +#endif /* SINGLE_THREADED */ #ifndef NO_SHA256 /* Create SHA-256 hash of the file based on filename. diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 76a975a57..74d1c6a16 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -18332,6 +18332,10 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert) WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E); ret = ASN_PARSE_E; } + if ((ret == 0) && cert->pathLength > WOLFSSL_MAX_PATH_LEN) { + WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E); + ret = ASN_PATHLEN_SIZE_E; + } /* Store CA boolean and whether a path length was seen. */ if (ret == 0) { /* isCA in certificate is a 1 bit of a byte. */ @@ -22550,6 +22554,17 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } #endif + #ifndef ALLOW_INVALID_CERTSIGN + /* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.9 + * If the cA boolean is not asserted, then the keyCertSign bit in the + * key usage extension MUST NOT be asserted. */ + if (!cert->isCA && cert->extKeyUsageSet && + (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) { + WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E); + return KEYUSAGE_E; + } + #endif + #ifndef NO_SKID if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL && cert->pubKeySize > 0) { @@ -22614,93 +22629,32 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } } - if (cert->selfSigned) { - cert->maxPathLen = WOLFSSL_MAX_PATH_LEN; - } else { - /* RFC 5280 Section 4.2.1.9: - * - * load/receive check - * - * 1) Is CA boolean set? - * No - SKIP CHECK - * Yes - Check key usage - * 2) Is Key usage extension present? - * No - goto 3 - * Yes - check keyCertSign assertion - * 2.a) Is keyCertSign asserted? - * No - goto 4 - * Yes - goto 3 - * 3) Is pathLen set? - * No - goto 4 - * Yes - check pathLen against maxPathLen. - * 3.a) Is pathLen less than maxPathLen? - * No - goto 4 - * Yes - set maxPathLen to pathLen and EXIT - * 4) Is maxPathLen > 0? - * Yes - Reduce by 1 - * No - ERROR - */ + /* Set to WOLFSSL_MAX_PATH_LEN by default in InitDecodedCert_ex */ + if (cert->pathLengthSet) + cert->maxPathLen = cert->pathLength; - if (cert->ca && cert->pathLengthSet) { - int checkPathLen = 0; - int decrementMaxPathLen = 0; - cert->maxPathLen = cert->pathLength; - if (cert->isCA) { - WOLFSSL_MSG("\tCA boolean set"); - if (cert->extKeyUsageSet) { - WOLFSSL_MSG("\tExtension Key Usage Set"); - if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) { - checkPathLen = 1; - } - else { - decrementMaxPathLen = 1; - } - } - else { - checkPathLen = 1; - } /* !cert->ca check */ - } /* cert is not a CA (assuming entity cert) */ - - if (checkPathLen && cert->pathLengthSet) { - if (cert->pathLength < cert->ca->maxPathLen) { - WOLFSSL_MSG("\tmaxPathLen status: set to pathLength"); - cert->maxPathLen = cert->pathLength; - } - else { - decrementMaxPathLen = 1; - } - } - - if (decrementMaxPathLen && cert->ca->maxPathLen > 0) { - WOLFSSL_MSG("\tmaxPathLen status: reduce by 1"); - cert->maxPathLen = (byte)(cert->ca->maxPathLen - 1); - if (verify != NO_VERIFY && type != CA_TYPE && - type != TRUSTED_PEER_TYPE) { - WOLFSSL_MSG("\tmaxPathLen status: OK"); - } - } else if (decrementMaxPathLen && cert->ca->maxPathLen == 0) { + if (!cert->selfSigned) { + if (/* Need to perform a pathlen check on anything that will be used + * to sign certificates later on. Otherwise, pathLen doesn't + * mean anything. */ + type != CERT_TYPE && cert->isCA && cert->extKeyUsageSet && + (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0 && + /* Nothing to check if we don't have the issuer of this cert. */ + cert->ca) { + if (cert->ca->maxPathLen == 0) { + /* This cert CAN NOT be used as an intermediate cert. The + * issuer does not allow it. */ cert->maxPathLen = 0; - if (verify != NO_VERIFY && type != CA_TYPE && - type != TRUSTED_PEER_TYPE) { + if (verify != NO_VERIFY) { WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0"); WOLFSSL_MSG("\tmaxPathLen status: ERROR"); WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E); return ASN_PATHLEN_INV_E; } } - } else if (cert->ca && cert->isCA) { - /* case where cert->pathLength extension is not set */ - if (cert->ca->maxPathLen > 0) { - cert->maxPathLen = (byte)(cert->ca->maxPathLen - 1); - } else { - cert->maxPathLen = 0; - if (verify != NO_VERIFY && type != CA_TYPE && - type != TRUSTED_PEER_TYPE) { - WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0"); - WOLFSSL_MSG("\tmaxPathLen status: ERROR"); - WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E); - return ASN_PATHLEN_INV_E; - } + else { + cert->maxPathLen = min(cert->ca->maxPathLen - 1, + cert->maxPathLen); } } } @@ -23107,6 +23061,7 @@ int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap) /* Determine dynamic type */ switch (type) { case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break; + case CHAIN_CERT_TYPE: case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break; case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break; case DSA_TYPE: dynType = DYNAMIC_TYPE_DSA; break; @@ -23271,6 +23226,7 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) switch (type) { case CA_TYPE: /* same as below */ case TRUSTED_PEER_TYPE: + case CHAIN_CERT_TYPE: case CERT_TYPE: if (header) *header = BEGIN_CERT; if (footer) *footer = END_CERT; @@ -24330,7 +24286,8 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz, return BAD_FUNC_ARG; } - if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) { + if (type != CERT_TYPE && type != CHAIN_CERT_TYPE && type != CA_TYPE && + type != CERTREQ_TYPE) { WOLFSSL_MSG("Bad cert type"); return BAD_FUNC_ARG; } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 6bc2785d7..a69206415 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1935,8 +1935,6 @@ struct Signer { word32 keyOID; /* key type */ word16 keyUsage; byte maxPathLen; - byte pathLength; - byte pathLengthSet : 1; byte selfSigned : 1; const byte* publicKey; int nameLen; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 49b7ec03f..faf0a89e4 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -175,7 +175,8 @@ enum CertType { SPHINCS_SMALL_LEVEL1_TYPE, SPHINCS_SMALL_LEVEL3_TYPE, SPHINCS_SMALL_LEVEL5_TYPE, - ECC_PARAM_TYPE + ECC_PARAM_TYPE, + CHAIN_CERT_TYPE };