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
This commit is contained in:
parent
fb0c769d6c
commit
d2642e329d
@ -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 */
|
||||
|
17
src/ssl.c
17
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
57
tests/api.c
57
tests/api.c
@ -382,6 +382,9 @@
|
||||
#endif
|
||||
#include <wolfssl/certs_test.h>
|
||||
|
||||
#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;
|
||||
|
@ -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
|
||||
|
119
tests/utils.c
Normal file
119
tests/utils.c
Normal file
@ -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 <config.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <tests/unit.h>
|
||||
|
||||
#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 <direct.h>
|
||||
#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 */
|
@ -45,6 +45,8 @@
|
||||
#include <examples/server/server.h>
|
||||
#include <examples/client/client.h>
|
||||
|
||||
#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 <direct.h>
|
||||
#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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user