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;
|
alertWhy = bad_certificate;
|
||||||
if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) {
|
if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) {
|
||||||
alertWhy = certificate_expired;
|
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;
|
alertWhy = unknown_ca;
|
||||||
}
|
}
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
@ -13864,7 +13865,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
/* select last certificate */
|
/* select last certificate */
|
||||||
args->certIdx = args->count - 1;
|
args->certIdx = args->count - 1;
|
||||||
|
|
||||||
ret = ProcessPeerCertParse(ssl, args, CERT_TYPE,
|
ret = ProcessPeerCertParse(ssl, args, CHAIN_CERT_TYPE,
|
||||||
!ssl->options.verifyNone ? VERIFY : NO_VERIFY,
|
!ssl->options.verifyNone ? VERIFY : NO_VERIFY,
|
||||||
&subjectHash, &alreadySigner);
|
&subjectHash, &alreadySigner);
|
||||||
#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
|
#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
|
||||||
@ -13879,7 +13880,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
FreeDecodedCert(args->dCert);
|
FreeDecodedCert(args->dCert);
|
||||||
args->dCertInit = 0;
|
args->dCertInit = 0;
|
||||||
/* once again */
|
/* once again */
|
||||||
ret = ProcessPeerCertParse(ssl, args, CERT_TYPE,
|
ret = ProcessPeerCertParse(ssl, args, CHAIN_CERT_TYPE,
|
||||||
!ssl->options.verifyNone ? VERIFY : NO_VERIFY,
|
!ssl->options.verifyNone ? VERIFY : NO_VERIFY,
|
||||||
&subjectHash, &alreadySigner);
|
&subjectHash, &alreadySigner);
|
||||||
}
|
}
|
||||||
@ -14085,6 +14086,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (!ssl->options.verifyNone) {
|
if (!ssl->options.verifyNone) {
|
||||||
WOLFSSL_ERROR_VERBOSE(ret);
|
WOLFSSL_ERROR_VERBOSE(ret);
|
||||||
DoCertFatalAlert(ssl, ret);
|
DoCertFatalAlert(ssl, ret);
|
||||||
|
args->lastErr = ret;
|
||||||
|
break; /* We sent a fatal alert.
|
||||||
|
* No point continuing. */
|
||||||
}
|
}
|
||||||
if (args->lastErr == 0) {
|
if (args->lastErr == 0) {
|
||||||
args->lastErr = ret; /* save error from last time */
|
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->nameLen = cert->subjectCNLen;
|
||||||
signer->name = cert->subjectCN;
|
signer->name = cert->subjectCN;
|
||||||
}
|
}
|
||||||
signer->pathLength = cert->pathLength;
|
|
||||||
signer->maxPathLen = cert->maxPathLen;
|
signer->maxPathLen = cert->maxPathLen;
|
||||||
signer->pathLengthSet = cert->pathLengthSet;
|
|
||||||
signer->selfSigned = cert->selfSigned;
|
signer->selfSigned = cert->selfSigned;
|
||||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||||
signer->permittedNames = cert->permittedNames;
|
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 */
|
/* 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
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte staticBuffer[1]; /* force heap usage */
|
byte staticBuffer[1]; /* force heap usage */
|
||||||
#else
|
#else
|
||||||
@ -7347,6 +7346,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
if (ctx == NULL && ssl == NULL)
|
if (ctx == NULL && ssl == NULL)
|
||||||
return BAD_FUNC_ARG;
|
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
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
|
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
|
||||||
DYNAMIC_TYPE_ENCRYPTEDINFO);
|
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
|
* Remainder are processed using ProcessUserChain and are loaded into
|
||||||
* ssl->buffers.certChain. */
|
* ssl->buffers.certChain. */
|
||||||
if (userChain) {
|
if (userChain) {
|
||||||
ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info,
|
ret = ProcessUserChain(ctx, buff, sz, format, CHAIN_CERT_TYPE, ssl,
|
||||||
verify);
|
used, info, verify);
|
||||||
if (ret == ASN_NO_PEM_HEADER) { /* Additional chain is optional */
|
if (ret == ASN_NO_PEM_HEADER) { /* Additional chain is optional */
|
||||||
unsigned long pemErr = 0;
|
unsigned long pemErr = 0;
|
||||||
CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr);
|
CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr);
|
||||||
@ -9430,6 +9433,10 @@ int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
|
|||||||
return ret;
|
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 */
|
/* for tmp use */
|
||||||
wolfSSL_CertManagerFree(tmp->cm);
|
wolfSSL_CertManagerFree(tmp->cm);
|
||||||
tmp->cm = cm;
|
tmp->cm = cm;
|
||||||
|
@ -10101,7 +10101,8 @@ static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, const byte* input, word16 length,
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = TLSX_PskKeyModes_Use(ssl, modes);
|
ret = TLSX_PskKeyModes_Use(ssl, modes);
|
||||||
|
|
||||||
WOLFSSL_ERROR_VERBOSE(ret);
|
if (ret != 0)
|
||||||
|
WOLFSSL_ERROR_VERBOSE(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
tests/api.c
57
tests/api.c
@ -382,6 +382,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <wolfssl/certs_test.h>
|
#include <wolfssl/certs_test.h>
|
||||||
|
|
||||||
|
#define WOLFSSL_TEST_UTILS_INCLUDED
|
||||||
|
#include "tests/utils.c"
|
||||||
|
|
||||||
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
|
||||||
/* FIPS build has replaced ecc.h. */
|
/* FIPS build has replaced ecc.h. */
|
||||||
#define wc_ecc_key_get_priv(key) (&((key)->k))
|
#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,
|
int test_wolfSSL_client_server_nofail_memio(test_ssl_cbf* client_cb,
|
||||||
test_ssl_cbf* server_cb, test_cbType client_on_handshake);
|
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
|
| 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);
|
XMEMCPY(buf + *len, data, sz);
|
||||||
*len += 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;
|
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(X509_STORE_CTX_get_error(store), 0);
|
||||||
ExpectIntEQ(preverify, 1);
|
ExpectIntEQ(preverify, 1);
|
||||||
ExpectIntGT(++test_wolfSSL_check_domain_verify_count, 0);
|
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)
|
static int test_wolfSSL_check_domain_client_cb(WOLFSSL* ssl)
|
||||||
@ -63424,10 +63451,26 @@ int ApiTest(void)
|
|||||||
#endif
|
#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) {
|
if (res == 0) {
|
||||||
for (i = 0; i < TEST_CASE_CNT; ++i) {
|
for (i = 0; i < TEST_CASE_CNT; ++i) {
|
||||||
EXPECT_DECLS;
|
EXPECT_DECLS;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
|
||||||
|
currentTestName = testCases[i].name;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* When not testing all cases then skip if not marked for running.
|
/* When not testing all cases then skip if not marked for running.
|
||||||
*/
|
*/
|
||||||
if (!testAll && !testCases[i].run) {
|
if (!testAll && !testCases[i].run) {
|
||||||
@ -63492,6 +63535,18 @@ int ApiTest(void)
|
|||||||
fflush(stdout);
|
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");
|
printf(" End API Tests\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return res;
|
return res;
|
||||||
|
@ -69,5 +69,6 @@ EXTRA_DIST += tests/unit.h \
|
|||||||
tests/test-sm2.conf \
|
tests/test-sm2.conf \
|
||||||
tests/NCONF_test.cnf \
|
tests/NCONF_test.cnf \
|
||||||
tests/test-tls-downgrade.conf \
|
tests/test-tls-downgrade.conf \
|
||||||
tests/TXT_DB.txt
|
tests/TXT_DB.txt \
|
||||||
|
tests/utils.c
|
||||||
DISTCLEANFILES+= tests/.libs/unit.test
|
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/server/server.h>
|
||||||
#include <examples/client/client.h>
|
#include <examples/client/client.h>
|
||||||
|
|
||||||
|
#define WOLFSSL_TEST_UTILS_INCLUDED
|
||||||
|
#include "tests/utils.c"
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
void file_test(const char* file, byte* check);
|
void file_test(const char* file, byte* check);
|
||||||
@ -718,90 +720,7 @@ void join_thread(THREAD_TYPE thread)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FILESYSTEM
|
#endif /* SINGLE_THREADED */
|
||||||
|
|
||||||
#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 */
|
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
/* Create SHA-256 hash of the file based on filename.
|
/* 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);
|
WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
|
||||||
ret = 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. */
|
/* Store CA boolean and whether a path length was seen. */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* isCA in certificate is a 1 bit of a byte. */
|
/* 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
|
#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
|
#ifndef NO_SKID
|
||||||
if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
|
if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
|
||||||
cert->pubKeySize > 0) {
|
cert->pubKeySize > 0) {
|
||||||
@ -22614,93 +22629,32 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cert->selfSigned) {
|
/* Set to WOLFSSL_MAX_PATH_LEN by default in InitDecodedCert_ex */
|
||||||
cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;
|
if (cert->pathLengthSet)
|
||||||
} else {
|
cert->maxPathLen = cert->pathLength;
|
||||||
/* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (cert->ca && cert->pathLengthSet) {
|
if (!cert->selfSigned) {
|
||||||
int checkPathLen = 0;
|
if (/* Need to perform a pathlen check on anything that will be used
|
||||||
int decrementMaxPathLen = 0;
|
* to sign certificates later on. Otherwise, pathLen doesn't
|
||||||
cert->maxPathLen = cert->pathLength;
|
* mean anything. */
|
||||||
if (cert->isCA) {
|
type != CERT_TYPE && cert->isCA && cert->extKeyUsageSet &&
|
||||||
WOLFSSL_MSG("\tCA boolean set");
|
(cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0 &&
|
||||||
if (cert->extKeyUsageSet) {
|
/* Nothing to check if we don't have the issuer of this cert. */
|
||||||
WOLFSSL_MSG("\tExtension Key Usage Set");
|
cert->ca) {
|
||||||
if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
|
if (cert->ca->maxPathLen == 0) {
|
||||||
checkPathLen = 1;
|
/* This cert CAN NOT be used as an intermediate cert. The
|
||||||
}
|
* issuer does not allow it. */
|
||||||
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) {
|
|
||||||
cert->maxPathLen = 0;
|
cert->maxPathLen = 0;
|
||||||
if (verify != NO_VERIFY && type != CA_TYPE &&
|
if (verify != NO_VERIFY) {
|
||||||
type != TRUSTED_PEER_TYPE) {
|
|
||||||
WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
|
WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
|
||||||
WOLFSSL_MSG("\tmaxPathLen status: ERROR");
|
WOLFSSL_MSG("\tmaxPathLen status: ERROR");
|
||||||
WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
|
WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
|
||||||
return ASN_PATHLEN_INV_E;
|
return ASN_PATHLEN_INV_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cert->ca && cert->isCA) {
|
else {
|
||||||
/* case where cert->pathLength extension is not set */
|
cert->maxPathLen = min(cert->ca->maxPathLen - 1,
|
||||||
if (cert->ca->maxPathLen > 0) {
|
cert->maxPathLen);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23107,6 +23061,7 @@ int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
|
|||||||
/* Determine dynamic type */
|
/* Determine dynamic type */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break;
|
case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break;
|
||||||
|
case CHAIN_CERT_TYPE:
|
||||||
case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
|
case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
|
||||||
case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break;
|
case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break;
|
||||||
case DSA_TYPE: dynType = DYNAMIC_TYPE_DSA; 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) {
|
switch (type) {
|
||||||
case CA_TYPE: /* same as below */
|
case CA_TYPE: /* same as below */
|
||||||
case TRUSTED_PEER_TYPE:
|
case TRUSTED_PEER_TYPE:
|
||||||
|
case CHAIN_CERT_TYPE:
|
||||||
case CERT_TYPE:
|
case CERT_TYPE:
|
||||||
if (header) *header = BEGIN_CERT;
|
if (header) *header = BEGIN_CERT;
|
||||||
if (footer) *footer = END_CERT;
|
if (footer) *footer = END_CERT;
|
||||||
@ -24330,7 +24286,8 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz,
|
|||||||
return BAD_FUNC_ARG;
|
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");
|
WOLFSSL_MSG("Bad cert type");
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
@ -1935,8 +1935,6 @@ struct Signer {
|
|||||||
word32 keyOID; /* key type */
|
word32 keyOID; /* key type */
|
||||||
word16 keyUsage;
|
word16 keyUsage;
|
||||||
byte maxPathLen;
|
byte maxPathLen;
|
||||||
byte pathLength;
|
|
||||||
byte pathLengthSet : 1;
|
|
||||||
byte selfSigned : 1;
|
byte selfSigned : 1;
|
||||||
const byte* publicKey;
|
const byte* publicKey;
|
||||||
int nameLen;
|
int nameLen;
|
||||||
|
@ -175,7 +175,8 @@ enum CertType {
|
|||||||
SPHINCS_SMALL_LEVEL1_TYPE,
|
SPHINCS_SMALL_LEVEL1_TYPE,
|
||||||
SPHINCS_SMALL_LEVEL3_TYPE,
|
SPHINCS_SMALL_LEVEL3_TYPE,
|
||||||
SPHINCS_SMALL_LEVEL5_TYPE,
|
SPHINCS_SMALL_LEVEL5_TYPE,
|
||||||
ECC_PARAM_TYPE
|
ECC_PARAM_TYPE,
|
||||||
|
CHAIN_CERT_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user