Skip to content

Commit

Permalink
Merge pull request #6575 from julek-wolfssl/zd/15258
Browse files Browse the repository at this point in the history
Properly enforce the pathLenConstraint of the BasicConstraints extension
  • Loading branch information
dgarske committed Jul 7, 2023
2 parents 52b5adb + 2cf9165 commit 9599ddd
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 179 deletions.
11 changes: 8 additions & 3 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -12653,7 +12653,9 @@ 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
Expand Down Expand Up @@ -13864,7 +13866,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) && \
Expand All @@ -13879,7 +13881,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);
}
Expand Down Expand Up @@ -14085,6 +14087,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 */
Expand Down
17 changes: 12 additions & 5 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
57 changes: 56 additions & 1 deletion tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion tests/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 119 additions & 0 deletions tests/utils.c
Original file line number Diff line number Diff line change
@@ -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 */
Loading

0 comments on commit 9599ddd

Please sign in to comment.