fix for return values of write_ex/read_ex, propogate PARAMS, handle CRL with load_verify_locations, fix for get verified/unverified chain

This commit is contained in:
JacobBarthelmeh
2025-01-09 01:29:24 -07:00
parent 689c61cc7e
commit c6974a921d
6 changed files with 150 additions and 82 deletions

View File

@ -7785,6 +7785,11 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
return MEMORY_E;
}
XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
/* pass on PARAM flags value from ctx to ssl */
wolfSSL_X509_VERIFY_PARAM_set_flags(wolfSSL_get0_param(ssl),
(unsigned long)wolfSSL_X509_VERIFY_PARAM_get_flags(
wolfSSL_CTX_get0_param(ctx)));
#endif
if (ctx->suites == NULL) {
@ -8733,6 +8738,7 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
* isn't allocated separately. */
wolfSSL_sk_CIPHER_free(ssl->supportedCiphers);
wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL);
#ifdef KEEP_OUR_CERT
wolfSSL_sk_X509_pop_free(ssl->ourCertChain, NULL);
#endif
@ -14997,6 +15003,25 @@ static int ProcessPeerCertsChainCRLCheck(WOLFSSL* ssl, ProcPeerCertArgs* args)
}
#endif
#ifdef OPENSSL_EXTRA
/* account for verify params flag set */
static int AdjustCMForParams(WOLFSSL* ssl)
{
int flags, ret = WOLFSSL_SUCCESS;
WOLFSSL_X509_VERIFY_PARAM* param;
param = wolfSSL_get0_param(ssl);
flags = wolfSSL_X509_VERIFY_PARAM_get_flags(param);
if ((flags & WOLFSSL_CRL_CHECK) == WOLFSSL_CRL_CHECK ||
(flags & WOLFSSL_CRL_CHECKALL) == WOLFSSL_CRL_CHECKALL) {
ret = wolfSSL_CertManagerEnableCRL(SSL_CM(ssl), flags &
(WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL));
}
return ret;
}
#endif
int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
word32 totalSz)
{
@ -15065,6 +15090,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#endif
}
#ifdef OPENSSL_EXTRA
/* account for verify params flag set */
AdjustCMForParams(ssl);
#endif
switch (ssl->options.asyncState)
{
case TLS_ASYNC_BEGIN:

180
src/ssl.c
View File

@ -3089,7 +3089,7 @@ int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, int sz, size_t* wr)
int ret;
ret = wolfSSL_write(ssl, data, sz);
if (ret > 0 && wr != NULL) {
if (ret >= 0 && wr != NULL) {
*wr = (size_t)ret;
ret = 1;
}
@ -3206,6 +3206,7 @@ int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
}
/* returns 0 on failure and on no read */
int wolfSSL_read_ex(WOLFSSL* ssl, void* data, int sz, size_t* rd)
{
int ret;
@ -3214,6 +3215,8 @@ int wolfSSL_read_ex(WOLFSSL* ssl, void* data, int sz, size_t* rd)
if (ret > 0 && rd != NULL) {
*rd = (size_t)ret;
}
if (ret <= 0) ret = 0;
return ret;
}
@ -12691,63 +12694,6 @@ cleanup:
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
defined(WOLFSSL_WPAS_SMALL))
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
/**
* Implemented in a similar way that ngx_ssl_ocsp_validate does it when
* SSL_get0_verified_chain is not available.
* @param ssl WOLFSSL object to extract certs from
* @return Stack of verified certs
*/
WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
{
WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
WOLFSSL_X509* peerCert = NULL;
WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
if (ssl == NULL || ssl->ctx == NULL) {
WOLFSSL_MSG("Bad parameter");
return NULL;
}
peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
if (peerCert == NULL) {
WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
return NULL;
}
/* wolfSSL_get_peer_certificate returns a copy. We want the internal
* member so that we don't have to worry about free'ing it. We call
* wolfSSL_get_peer_certificate so that we don't have to worry about
* setting up the internal pointer. */
wolfSSL_X509_free(peerCert);
peerCert = (WOLFSSL_X509*)&ssl->peerCert;
chain = wolfSSL_get_peer_cert_chain(ssl);
if (chain == NULL) {
WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
return NULL;
}
storeCtx = wolfSSL_X509_STORE_CTX_new();
if (storeCtx == NULL) {
WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
return NULL;
}
if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
peerCert, chain) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
wolfSSL_X509_STORE_CTX_free(storeCtx);
return NULL;
}
if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
wolfSSL_X509_STORE_CTX_free(storeCtx);
return NULL;
}
wolfSSL_X509_STORE_CTX_free(storeCtx);
return chain;
}
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx)
{
if (ctx == NULL) {
@ -14331,12 +14277,13 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
/* Try to populate if NULL or empty */
if (ssl->peerCertChain == NULL ||
wolfSSL_sk_X509_num(ssl->peerCertChain) == 0)
wolfSSL_sk_X509_num(ssl->peerCertChain) == 0) {
wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
}
return ssl->peerCertChain;
}
#ifndef WOLFSSL_QT
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
WOLFSSL_X509 *x);
/**
@ -14379,13 +14326,14 @@ static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
}
return ret;
}
#endif /* !WOLFSSL_QT */
/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
based off of the ssl session chain. Attempts to place CA certificates
at the bottom of the stack. Returns stack of WOLFSSL_X509 certs or
NULL on failure */
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
or ssl->verifiedChain based off of the ssl session chain. Attempts to place
CA certificates at the bottom of the stack for a verified chain. Returns
stack of WOLFSSL_X509 certs or NULL on failure */
static WOLF_STACK_OF(WOLFSSL_X509)* CreatePeerCertChain(WOLFSSL* ssl,
int verifiedFlag)
{
WOLFSSL_STACK* sk;
WOLFSSL_X509* x509;
@ -14407,9 +14355,8 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
}
ret = DecodeToX509(x509, ssl->session->chain.certs[i].buffer,
ssl->session->chain.certs[i].length);
#if !defined(WOLFSSL_QT)
if (ret == 0 && i == ssl->session->chain.count-1) {
/* On the last element in the chain try to add the CA chain
if (ret == 0 && i == ssl->session->chain.count-1 && verifiedFlag) {
/* On the last element in the verified chain try to add the CA chain
* first if we have one for this cert */
SSL_CM_WARNING(ssl);
if (PushCAx509Chain(SSL_CM(ssl), x509, sk)
@ -14417,7 +14364,6 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
ret = WOLFSSL_FATAL_ERROR;
}
}
#endif
if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) <= 0) {
WOLFSSL_MSG("Error decoding cert");
@ -14430,19 +14376,93 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
if (sk == NULL) {
WOLFSSL_MSG("Null session chain");
}
#if defined(OPENSSL_ALL)
else if (ssl->options.side == WOLFSSL_SERVER_END) {
/* to be compliant with openssl
first element is kept as peer cert on server side.*/
wolfSSL_sk_X509_pop(sk);
}
#endif
if (ssl->peerCertChain != NULL)
wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
/* This is Free'd when ssl is Free'd */
ssl->peerCertChain = sk;
return sk;
}
/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
returns the stack on success and NULL on failure */
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
{
WOLFSSL_STACK* sk;
WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
if ((ssl == NULL) || (ssl->session->chain.count == 0))
return NULL;
sk = CreatePeerCertChain(ssl, 0);
if (sk != NULL) {
if (ssl->peerCertChain != NULL)
wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
/* This is Free'd when ssl is Free'd */
ssl->peerCertChain = sk;
}
return sk;
}
/**
* Implemented in a similar way that ngx_ssl_ocsp_validate does it when
* SSL_get0_verified_chain is not available.
* @param ssl WOLFSSL object to extract certs from
* @return Stack of verified certs
*/
WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
{
WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
WOLFSSL_X509* peerCert = NULL;
WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
if (ssl == NULL || ssl->ctx == NULL) {
WOLFSSL_MSG("Bad parameter");
return NULL;
}
peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
if (peerCert == NULL) {
WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
return NULL;
}
/* wolfSSL_get_peer_certificate returns a copy. We want the internal
* member so that we don't have to worry about free'ing it. We call
* wolfSSL_get_peer_certificate so that we don't have to worry about
* setting up the internal pointer. */
wolfSSL_X509_free(peerCert);
peerCert = (WOLFSSL_X509*)&ssl->peerCert;
chain = CreatePeerCertChain((WOLFSSL*)ssl, 1);
if (chain == NULL) {
WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
return NULL;
}
if (ssl->verifiedChain != NULL) {
wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL);
}
((WOLFSSL*)ssl)->verifiedChain = chain;
storeCtx = wolfSSL_X509_STORE_CTX_new();
if (storeCtx == NULL) {
WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
return NULL;
}
if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
peerCert, chain) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
wolfSSL_X509_STORE_CTX_free(storeCtx);
return NULL;
}
if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
wolfSSL_X509_STORE_CTX_free(storeCtx);
return NULL;
}
wolfSSL_X509_STORE_CTX_free(storeCtx);
return chain;
}
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
#ifndef NO_CERTS

View File

@ -2803,9 +2803,26 @@ int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
}
if (file != NULL) {
#ifdef HAVE_CRL
/* handle CRL type being passed in */
WOLFSSL_CRL crl;
XMEMSET(&crl, 0, sizeof(WOLFSSL_CRL));
crl.cm = ctx->cm;
/* Load the PEM formatted CA file. */
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
NULL, 0, &crl, verify);
/* found a good CRL, add it to ctx->cm */
if (ret == 1 && crl.crlList != NULL) {
wolfSSL_X509_STORE_add_crl(wolfSSL_CTX_get_cert_store(ctx), &crl);
}
#else
/* Load the PEM formatted CA file. No CRL support, only expecting
* CA's */
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
NULL, verify);
#endif
#ifndef NO_WOLFSSL_DIR
if (ret == 1) {
/* Include success in overall count. */

View File

@ -93244,7 +93244,7 @@ static int error_test(void)
{ -9, WC_SPAN1_FIRST_E + 1 },
#endif
{ -124, -124 },
{ -166, -169 },
{ -167, -169 },
{ -300, -300 },
{ -334, -336 },
{ -346, -349 },

View File

@ -2777,7 +2777,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void)
int last;
} missing[] = {
{ -124, -124 },
{ -166, -169 },
{ -167, -169 },
{ WC_SPAN1_LAST_E - 1, WC_SPAN2_FIRST_E + 1 },
{ WC_SPAN2_LAST_E - 1, WC_SPAN2_MIN_CODE_E }
};

View File

@ -6227,6 +6227,7 @@ struct WOLFSSL {
#if defined(OPENSSL_EXTRA)
WOLFSSL_STACK* supportedCiphers; /* Used in wolfSSL_get_ciphers_compat */
WOLFSSL_STACK* peerCertChain; /* Used in wolfSSL_get_peer_cert_chain */
WOLFSSL_STACK* verifiedChain; /* peer cert chain to CA */
#ifdef KEEP_OUR_CERT
WOLFSSL_STACK* ourCertChain; /* Used in wolfSSL_add1_chain_cert */
#endif