forked from wolfSSL/wolfssl
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:
@ -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
180
src/ssl.c
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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 },
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user