Skip to content
278 changes: 198 additions & 80 deletions src/internal.c

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions src/ocsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
#endif
int ret;
int validated = 0; /* ocsp validation flag */
#ifndef NO_CERTS
Signer* waivedTail = NULL;
#endif

(void)heap;

Expand All @@ -377,9 +380,12 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
if (ssl != NULL && TLSX_CSR2_IsMulti(ssl->extensions)) {
ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions);
}
#else
(void)ssl;
#endif
#ifndef NO_CERTS
ocspResponse->pendingCAs = SslWaivedCAsJoin(ssl, ocspResponse->pendingCAs,
&waivedTail);
#endif
(void)ssl;
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0, 0);
if (ret != 0) {
ocsp->error = ret;
Expand Down Expand Up @@ -455,6 +461,9 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
wc_UnLockMutex(&ocsp->ocspLock);

end:
#ifndef NO_CERTS
SslWaivedCAsSplit(waivedTail);
#endif
if (ret == 0 && validated == 1) {
WOLFSSL_MSG("New OcspResponse validated");
}
Expand Down
5 changes: 5 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -5827,6 +5827,11 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
#endif
}

#ifndef NO_CERTS
/* Trust for the previous peer must not carry into the next. */
SslWaivedCAsFree(ssl);
#endif

/* reset error */
ssl->error = 0;

Expand Down
76 changes: 76 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -42098,6 +42098,81 @@ static int test_override_alt_cert_chain(void)
}
#endif

#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_PEM_TO_DER) && !defined(WOLFSSL_ALT_CERT_CHAINS)
static int test_chain_ca_no_persist_verify_cb(int preverify,
WOLFSSL_X509_STORE_CTX* store)
{
(void)preverify;
(void)store;
return 1;
}

static int test_chain_ca_no_persist_client_ctx(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;

ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(wolfSSL_CTX_GetCertManager(ctx)),
WOLFSSL_SUCCESS);
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER,
test_chain_ca_no_persist_verify_cb);

return EXPECT_RESULT();
}

static int test_chain_ca_no_persist_server_ctx(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;

ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
"./certs/intermediate/server-chain.pem"), WOLFSSL_SUCCESS);

return EXPECT_RESULT();
}

static int test_chain_ca_no_persist_result(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_CERT_MANAGER* cm = NULL;

ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(wolfSSL_get_SSL_CTX(ssl)));
/* The CA trusted via callback must not be usable as a signer afterwards */
ExpectIntNE(wolfSSL_CertManagerVerify(cm,
"./certs/intermediate/ca-int2-cert.pem", WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);
/* Nor the CA that only verified because the aforementioned one vouched for
* it */
ExpectIntNE(wolfSSL_CertManagerVerify(cm,
"./certs/intermediate/server-int-cert.pem", WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);

return EXPECT_RESULT();
}

static int test_chain_ca_no_persist(void)
{
EXPECT_DECLS;
test_ssl_cbf client_cbs, server_cbs;

XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));

client_cbs.ctx_ready = test_chain_ca_no_persist_client_ctx;
client_cbs.on_result = test_chain_ca_no_persist_result;
server_cbs.ctx_ready = test_chain_ca_no_persist_server_ctx;

ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_SUCCESS);

return EXPECT_RESULT();
}
#else
static int test_chain_ca_no_persist(void)
{
return TEST_SKIPPED;
}
#endif

static int test_rpk_set_xxx_cert_type(void)
{
EXPECT_DECLS;
Expand Down Expand Up @@ -47976,6 +48051,7 @@ TEST_CASE testCases[] = {
/* Can't memory test as client/server Asserts. */
TEST_DECL(test_harden_no_secure_renegotiation),
TEST_DECL(test_override_alt_cert_chain),
TEST_DECL(test_chain_ca_no_persist),
TEST_DECL(test_rpk_set_xxx_cert_type),
TEST_DECL(test_short_session_id),
/* Can't memory test as client/server hangs. */
Expand Down
52 changes: 36 additions & 16 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -25098,15 +25098,16 @@ static int DecodeCertReq(DecodedCert* cert, int* criticalExt)

#endif /* WOLFSSL_ASN_TEMPLATE */

int ParseCert(DecodedCert* cert, int type, int verify, WOLFSSL_CERT_MANAGER* cm)
int ParseCertEx(DecodedCert* cert, int type, int verify,
WOLFSSL_CERT_MANAGER* cm, Signer* extraCa)
{
int ret;
#if (!defined(WC_ASN_NO_HEAP) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
defined(WOLFSSL_DYN_CERT)
char* ptr;
#endif

ret = ParseCertRelative(cert, type, verify, cm, NULL);
ret = ParseCertRelative(cert, type, verify, cm, extraCa);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -25149,6 +25150,11 @@ int ParseCert(DecodedCert* cert, int type, int verify, WOLFSSL_CERT_MANAGER* cm)
return ret;
}

int ParseCert(DecodedCert* cert, int type, int verify, WOLFSSL_CERT_MANAGER* cm)
{
return ParseCertEx(cert, type, verify, cm, NULL);
}

int wc_ParseCert(DecodedCert* cert, int type, int verify,
WOLFSSL_CERT_MANAGER* cm)
{
Expand Down Expand Up @@ -25872,12 +25878,8 @@ static Signer* FindSignerByAkidOrName(WOLFSSL_CERT_MANAGER* cm,
Signer* extraCAList, Signer* cert)
{
Signer* signer = NULL;
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
#ifndef NO_SKID
#ifndef NO_SKID
Signer* exCaSigner;
#endif
#else
(void)extraCAList;
#endif

#ifndef NO_SKID
Expand All @@ -25898,7 +25900,6 @@ static Signer* FindSignerByAkidOrName(WOLFSSL_CERT_MANAGER* cm,
signer = GetCA(cm, cert->issuerNameHash);
#endif

#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
if (signer == NULL && extraCAList != NULL) {
#ifndef NO_SKID
if (cert->authKeyIdSet) {
Expand All @@ -25923,7 +25924,6 @@ static Signer* FindSignerByAkidOrName(WOLFSSL_CERT_MANAGER* cm,
signer = findSignerByName(extraCAList, cert->issuerNameHash);
#endif
}
#endif

return signer;
}
Expand Down Expand Up @@ -26507,11 +26507,30 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify,
if (!cert->selfIssued || (verify != NO_VERIFY && type != CA_TYPE &&
type != TRUSTED_PEER_TYPE)) {
cert->ca = NULL;
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
if (extraCAList != NULL) {
cert->ca = findSignerByName(extraCAList, cert->issuerHash);
}
#endif
if (extraCAList != NULL) {
Comment thread
mattia-moffa marked this conversation as resolved.
Resolved
#ifndef NO_SKID
if (cert->extAuthKeyIdSet) {
Signer* exCa;

for (exCa = extraCAList; exCa != NULL; exCa = exCa->next) {
if (XMEMCMP(exCa->subjectKeyIdHash,
cert->extAuthKeyId,
SIGNER_DIGEST_SIZE) == 0 &&
XMEMCMP(exCa->subjectNameHash, cert->issuerHash,
SIGNER_DIGEST_SIZE) == 0) {
cert->ca = exCa;
break;
}
}
/* AKID is authoritative; do not fall back to name. */
}
else
#endif
{
cert->ca = findSignerByName(extraCAList,
Comment thread
mattia-moffa marked this conversation as resolved.
Resolved
cert->issuerHash);
}
}
#ifndef NO_SKID
if (cert->ca == NULL && cert->extAuthKeyIdSet) {
cert->ca = GetCA(cm, cert->extAuthKeyId);
Expand Down Expand Up @@ -26567,7 +26586,8 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify,
}
#endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
#else
cert->ca = GetCA(cm, cert->issuerHash);
if (cert->ca == NULL)
cert->ca = GetCA(cm, cert->issuerHash);
#endif /* !NO_SKID */

if (cert->ca) {
Expand Down Expand Up @@ -38041,7 +38061,7 @@ static Signer *OcspFindSigner(OcspResponse *resp, WOLFSSL_CERT_MANAGER *cm)
if (s)
return s;
}
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
#ifndef NO_CERTS
if (resp->pendingCAs == NULL)
return NULL;

Expand Down
8 changes: 8 additions & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2997,6 +2997,11 @@ WOLFSSL_LOCAL int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,


#ifndef NO_CERTS
WOLFSSL_LOCAL Signer* SslWaivedCAsJoin(WOLFSSL* ssl, Signer* base,
Signer** pTail);
WOLFSSL_LOCAL void SslWaivedCAsSplit(Signer* tail);
WOLFSSL_LOCAL void SslWaivedCAsFree(WOLFSSL* ssl);

#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
typedef struct ProcPeerCertArgs {
buffer* certs;
Expand Down Expand Up @@ -7320,6 +7325,9 @@ struct WOLFSSL {
#ifdef WOLFSSL_LOCAL_X509_STORE
WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */
#endif
#ifndef NO_CERTS
Signer* waivedCAs; /* callback-accepted chain CAs */
#endif
#ifdef KEEP_PEER_CERT
#ifdef WOLFSSL_DYNAMIC_PEER_CERT
WOLFSSL_X509* peerCert; /* X509 peer cert, NULL when none.
Expand Down
5 changes: 3 additions & 2 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4196,8 +4196,9 @@ enum {

WOLFSSL_USER_CA = 1, /* user added as trusted */
WOLFSSL_CHAIN_CA = 2, /* added to cache from trusted chain */
WOLFSSL_TEMP_CA = 3, /* Temp intermediate CA, only for use by
* X509_STORE */
WOLFSSL_TEMP_CA = 3, /* Temp intermediate CA, scoped to a single
* X509_STORE verification or Certificate
* message */
WOLFSSL_USER_INTER = 4 /* user added intermediate cert */
};

Expand Down
2 changes: 2 additions & 0 deletions wolfssl/wolfcrypt/asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2653,6 +2653,8 @@ WOLFSSL_ASN_API int AddSignature(byte* buf, int bodySz, const byte* sig, int sig
WOLFSSL_LOCAL int ParseCertRelative(DecodedCert* cert, int type, int verify,
WOLFSSL_CERT_MANAGER* cm,
Signer *extraCa);
WOLFSSL_LOCAL int ParseCertEx(DecodedCert* cert, int type, int verify,
WOLFSSL_CERT_MANAGER* cm, Signer* extraCa);
WOLFSSL_LOCAL int DecodeToKey(DecodedCert* cert, int verify);
#ifdef WOLFSSL_ASN_TEMPLATE
WOLFSSL_LOCAL int DecodeCert(DecodedCert* cert, int verify, int* criticalExt);
Expand Down
Loading