Initial rewrite of X509 STORE to replicate openssl behavior

This commit is contained in:
Colton Willey
2024-10-16 16:34:57 -07:00
committed by Daniel Pouzzner
parent 82273094e0
commit 17c9e92b7f
6 changed files with 821 additions and 100 deletions

View File

@@ -455,11 +455,12 @@ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
return ret; return ret;
} }
int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm) static int wolfSSL_CertManagerUnloadIntermediateCertsEx(WOLFSSL_CERT_MANAGER* cm,
int type)
{ {
int ret = WOLFSSL_SUCCESS; int ret = WOLFSSL_SUCCESS;
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts"); WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCertsEx");
/* Validate parameter. */ /* Validate parameter. */
if (cm == NULL) { if (cm == NULL) {
@@ -471,7 +472,7 @@ int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
} }
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
/* Dispose of CA table. */ /* Dispose of CA table. */
FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, WOLFSSL_CHAIN_CA, FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, type,
cm->heap); cm->heap);
/* Unlock CA table. */ /* Unlock CA table. */
@@ -481,6 +482,20 @@ int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
return ret; return ret;
} }
#if defined(OPENSSL_EXTRA)
static int wolfSSL_CertManagerUnloadTempIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
{
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadTempIntermediateCerts");
return wolfSSL_CertManagerUnloadIntermediateCertsEx(cm, WOLFSSL_INTER_CA);
}
#endif
int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
{
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts");
return wolfSSL_CertManagerUnloadIntermediateCertsEx(cm, WOLFSSL_CHAIN_CA);
}
#ifdef WOLFSSL_TRUST_PEER_CERT #ifdef WOLFSSL_TRUST_PEER_CERT
/* Unload the trusted peers table. /* Unload the trusted peers table.
* *

View File

@@ -5559,7 +5559,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
* size of this subset and its memory usage */ * size of this subset and its memory usage */
#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */ #endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
#if defined(OPENSSL_ALL) #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
/* /*
* Converts a and b to DER and then does an XMEMCMP to check if they match. * Converts a and b to DER and then does an XMEMCMP to check if they match.
* Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't. * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
@@ -7536,7 +7536,6 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
byte* pem = NULL; byte* pem = NULL;
byte* curr = NULL; byte* curr = NULL;
byte* prev = NULL; byte* prev = NULL;
WOLFSSL_X509* x509;
const char* header = NULL; const char* header = NULL;
const char* footer = NULL; const char* footer = NULL;
@@ -7597,12 +7596,8 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
} }
else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 && else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) { XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz, ret = wolfSSL_X509_STORE_load_cert_buffer(lookup->store, curr, sz,
WOLFSSL_FILETYPE_PEM); WOLFSSL_FILETYPE_PEM);
if (x509 == NULL)
goto end;
ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
wolfSSL_X509_free(x509);
if (ret != WOLFSSL_SUCCESS) if (ret != WOLFSSL_SUCCESS)
goto end; goto end;
curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz); curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);

View File

@@ -36,6 +36,17 @@
#ifndef NO_CERTS #ifndef NO_CERTS
#ifdef OPENSSL_EXTRA
static int wolfSSL_X509_STORE_get_issuer_ex(WOLFSSL_X509 **issuer,
WOLFSSL_STACK *certs, WOLFSSL_X509 *x);
static int wolfSSL_X509_STORE_add_ca(WOLFSSL_X509_STORE* store,
WOLFSSL_X509* x509, int type);
#endif
#ifndef WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH
#define WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH 100
#endif
/******************************************************************************* /*******************************************************************************
* START OF X509_STORE_CTX APIs * START OF X509_STORE_CTX APIs
******************************************************************************/ ******************************************************************************/
@@ -78,6 +89,14 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL);
ctx->param = NULL; ctx->param = NULL;
if (ctx->ctxIntermediates != NULL) {
wolfSSL_sk_X509_free(ctx->ctxIntermediates);
}
if (ctx->chain != NULL) {
wolfSSL_sk_X509_free(ctx->chain);
}
#endif #endif
XFREE(ctx, ctx->heap, DYNAMIC_TYPE_X509_CTX); XFREE(ctx, ctx->heap, DYNAMIC_TYPE_X509_CTX);
@@ -97,7 +116,7 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
WOLF_STACK_OF(WOLFSSL_X509)* sk) WOLF_STACK_OF(WOLFSSL_X509)* sk)
{ {
int ret = 0; int ret = 0;
(void)sk; int i = 0;
WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init"); WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
if (ctx != NULL) { if (ctx != NULL) {
@@ -106,51 +125,37 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
ctx->current_cert = x509; ctx->current_cert = x509;
#else #else
if(x509 != NULL){ if(x509 != NULL){
ctx->current_cert = wolfSSL_X509_d2i_ex(NULL, x509->derCert->buffer, ctx->current_cert = wolfSSL_X509_d2i_ex(NULL,
x509->derCert->length, x509->heap); x509->derCert->buffer,
x509->derCert->length,
x509->heap);
if(ctx->current_cert == NULL) if(ctx->current_cert == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} else } else
ctx->current_cert = NULL; ctx->current_cert = NULL;
#endif #endif
ctx->chain = sk;
/* Add intermediate certs, that verify to a loaded CA, to the store */
if (sk != NULL) { if (sk != NULL) {
byte addedAtLeastOne = 1; if (ctx->ctxIntermediates == NULL) {
WOLF_STACK_OF(WOLFSSL_X509)* head = wolfSSL_shallow_sk_dup(sk); ctx->ctxIntermediates = sk_X509_new_null();
if (head == NULL) if (ctx->ctxIntermediates == NULL) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
while (addedAtLeastOne) { }
WOLF_STACK_OF(WOLFSSL_X509)* cur = head; }
WOLF_STACK_OF(WOLFSSL_X509)** prev = &head;
addedAtLeastOne = 0; for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
while (cur) { ret = wolfSSL_sk_X509_push(ctx->ctxIntermediates,
WOLFSSL_X509* cert = cur->data.x509; wolfSSL_sk_X509_value(sk, i));
if (cert != NULL && cert->derCert != NULL && if (ret <= 0) {
wolfSSL_CertManagerVerifyBuffer(store->cm, return WOLFSSL_FAILURE;
cert->derCert->buffer,
cert->derCert->length,
WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
ret = wolfSSL_X509_STORE_add_cert(store, cert);
if (ret < 0) {
wolfSSL_sk_free(head);
return WOLFSSL_FAILURE;
}
addedAtLeastOne = 1;
*prev = cur->next;
wolfSSL_sk_free_node(cur);
cur = *prev;
}
else {
prev = &cur->next;
cur = cur->next;
}
} }
} }
wolfSSL_sk_free(head);
} }
if (ctx->chain != NULL) {
wolfSSL_sk_X509_free(ctx->chain);
ctx->chain = NULL;
}
ctx->sesChain = NULL; ctx->sesChain = NULL;
ctx->domain = NULL; ctx->domain = NULL;
#ifdef HAVE_EX_DATA #ifdef HAVE_EX_DATA
@@ -192,10 +197,14 @@ void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
} }
void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ctx, WOLF_STACK_OF(WOLFSSL_X509) *sk) void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ctx,
WOLF_STACK_OF(WOLFSSL_X509) *sk)
{ {
if (ctx != NULL) { if (ctx != NULL) {
ctx->chain = sk; if (ctx->setTrustedSk != NULL) {
wolfSSL_sk_X509_free(ctx->setTrustedSk);
}
ctx->setTrustedSk = sk;
} }
} }
@@ -255,19 +264,15 @@ static void SetupStoreCtxError(WOLFSSL_X509_STORE_CTX* ctx, int ret)
wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth); wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
} }
/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX static int wolfSSL_X509_verify_cert_ex(WOLFSSL_X509_STORE_CTX* ctx)
* returns 0 on success or < 0 on failure.
*/
int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
{ {
WOLFSSL_ENTER("wolfSSL_X509_verify_cert"); int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL if (ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
&& ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) { ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
int ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm, ctx->current_cert->derCert->buffer,
ctx->current_cert->derCert->buffer, ctx->current_cert->derCert->length,
ctx->current_cert->derCert->length, WOLFSSL_FILETYPE_ASN1);
WOLFSSL_FILETYPE_ASN1);
SetupStoreCtxError(ctx, ret); SetupStoreCtxError(ctx, ret);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
if (ctx->store && ctx->store->verify_cb) if (ctx->store && ctx->store->verify_cb)
@@ -278,9 +283,9 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
if (ret != WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) && if (ret != WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) &&
ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) { ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
/* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
ASN_BEFORE_DATE_E if there are no additional errors found in the ASN_BEFORE_DATE_E if there are no additional errors found in the
cert. Therefore, check if the cert is expired or not yet valid cert. Therefore, check if the cert is expired or not yet valid
in order to return the correct expected error. */ in order to return the correct expected error. */
byte *afterDate = ctx->current_cert->notAfter.data; byte *afterDate = ctx->current_cert->notAfter.data;
byte *beforeDate = ctx->current_cert->notBefore.data; byte *beforeDate = ctx->current_cert->notBefore.data;
@@ -300,10 +305,157 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
#endif #endif
} }
#endif #endif
return ret >= 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
} }
return WOLFSSL_FATAL_ERROR;
return ret;
}
/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
* returns 0 on success or < 0 on failure.
*/
int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
int done = 0;
int added = 0;
int i = 0;
int numInterAdd = 0;
int depth = 0;
WOLFSSL_X509 *issuer = NULL;
WOLFSSL_X509 *orig = NULL;
WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL;
if (ctx == NULL || ctx->store == NULL || ctx->store->cm == NULL
|| ctx->current_cert == NULL || ctx->current_cert->derCert == NULL) {
return WOLFSSL_FATAL_ERROR;
}
certs = ctx->store->certs;
if (ctx->chain != NULL) {
wolfSSL_sk_X509_free(ctx->chain);
}
ctx->chain = wolfSSL_sk_X509_new_null();
if (ctx->setTrustedSk != NULL) {
certs = ctx->setTrustedSk;
}
if (certs == NULL &&
wolfSSL_sk_X509_num(ctx->ctxIntermediates) > 0) {
certs = ctx->ctxIntermediates;
}
else {
/* Add the intermediates provided on init to the list of untrusted
* intermediates to be used */
for (i = 0; i < wolfSSL_sk_X509_num(ctx->ctxIntermediates); i++) {
ret = wolfSSL_sk_X509_push(certs,
wolfSSL_sk_X509_value(ctx->ctxIntermediates, i));
if (ret <= 0) {
return WOLFSSL_FAILURE;
}
numInterAdd++;
}
}
if (ctx->depth > 0) {
depth = ctx->depth + 1;
}
else {
depth = WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH + 1;
}
orig = ctx->current_cert;
while(done == 0 && depth > 0) {
issuer = NULL;
/* Try to find an untrusted issuer first */
ret = wolfSSL_X509_STORE_get_issuer_ex(&issuer, certs,
ctx->current_cert);
if (ret == WOLFSSL_SUCCESS) {
if (ctx->current_cert == issuer) {
wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
break;
}
/* We found our issuer in the non-trusted cert list, add it
* to the CM and verify the current cert against it */
ret = wolfSSL_X509_STORE_add_ca(ctx->store, issuer,
WOLFSSL_INTER_CA);
if (ret != WOLFSSL_SUCCESS) {
goto exit;
}
added = 1;
ret = wolfSSL_X509_verify_cert_ex(ctx);
if (ret != WOLFSSL_SUCCESS) {
goto exit;
}
/* Add it to the current chain and look at the issuer cert next */
wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
ctx->current_cert = issuer;
}
else if (ret == WOLFSSL_FAILURE) {
/* Could not find in untrusted list, only place left is
* a trusted CA in the CM */
ret = wolfSSL_X509_verify_cert_ex(ctx);
if (ret != WOLFSSL_SUCCESS) {
goto exit;
}
/* Cert verified, finish building the chain */
wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
#ifdef WOLFSSL_SIGNER_DER_CERT
x509GetIssuerFromCM(&issuer, ctx->store->cm, ctx->current_cert);
if (issuer != NULL && ctx->store->owned != NULL) {
wolfSSL_sk_X509_push(ctx->store->owned, issuer);
}
#else
if (ctx->setTrustedSk == NULL) {
wolfSSL_X509_STORE_get_issuer_ex(&issuer,
ctx->store->trusted, ctx->current_cert);
}
else {
wolfSSL_X509_STORE_get_issuer_ex(&issuer,
ctx->setTrustedSk, ctx->current_cert);
}
#endif
if (issuer != NULL) {
wolfSSL_sk_X509_push(ctx->chain, issuer);
}
done = 1;
}
else {
goto exit;
}
depth--;
}
exit:
/* Remove additional intermediates from init from the store */
if (ctx != NULL && numInterAdd > 0) {
for (i = 0; i < numInterAdd; i++) {
wolfSSL_sk_X509_pop(ctx->store->certs);
}
}
/* Remove intermediates that were added to CM */
if (ctx != NULL) {
if (ctx->store != NULL) {
if (added == 1) {
wolfSSL_CertManagerUnloadTempIntermediateCerts(ctx->store->cm);
}
}
if (orig != NULL) {
ctx->current_cert = orig;
}
}
return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
} }
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */
@@ -743,7 +895,7 @@ int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
for (node = ctx->chain; node != NULL; node = node->next) { for (node = ctx->chain; node != NULL; node = node->next) {
if (wolfSSL_X509_check_issued(node->data.x509, x) == if (wolfSSL_X509_check_issued(node->data.x509, x) ==
WOLFSSL_X509_V_OK) { WOLFSSL_X509_V_OK) {
*issuer = x; *issuer = node->data.x509;
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
} }
@@ -755,6 +907,31 @@ int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
} }
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
#ifdef OPENSSL_EXTRA
static int wolfSSL_X509_STORE_get_issuer_ex(WOLFSSL_X509 **issuer,
WOLFSSL_STACK * certs, WOLFSSL_X509 *x)
{
int i;
if (issuer == NULL || x == NULL)
return WOLFSSL_FATAL_ERROR;
if (certs != NULL) {
for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
if (wolfSSL_X509_check_issued(wolfSSL_sk_X509_value(certs, i), x) ==
WOLFSSL_X509_V_OK) {
*issuer = wolfSSL_sk_X509_value(certs, i);
return WOLFSSL_SUCCESS;
}
}
}
return WOLFSSL_FAILURE;
}
#endif
/******************************************************************************* /*******************************************************************************
* END OF X509_STORE_CTX APIs * END OF X509_STORE_CTX APIs
******************************************************************************/ ******************************************************************************/
@@ -789,6 +966,17 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
if ((store->cm = wolfSSL_CertManagerNew()) == NULL) if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
goto err_exit; goto err_exit;
if ((store->certs = wolfSSL_sk_X509_new_null()) == NULL)
goto err_exit;
if ((store->owned = wolfSSL_sk_X509_new_null()) == NULL)
goto err_exit;
#if !defined(WOLFSSL_SIGNER_DER_CERT)
if ((store->trusted = wolfSSL_sk_X509_new_null()) == NULL)
goto err_exit;
#endif
#ifdef HAVE_CRL #ifdef HAVE_CRL
store->crl = store->cm->crl; store->crl = store->cm->crl;
#endif #endif
@@ -849,6 +1037,20 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
wolfSSL_CertManagerFree(store->cm); wolfSSL_CertManagerFree(store->cm);
store->cm = NULL; store->cm = NULL;
} }
if (store->certs != NULL) {
wolfSSL_sk_X509_free(store->certs);
store->certs = NULL;
}
if (store->owned != NULL) {
wolfSSL_sk_X509_pop_free(store->owned, wolfSSL_X509_free);
store->owned = NULL;
}
#if !defined(WOLFSSL_SIGNER_DER_CERT)
if (store->trusted != NULL) {
wolfSSL_sk_X509_free(store->trusted);
store->trusted = NULL;
}
#endif
#ifdef OPENSSL_ALL #ifdef OPENSSL_ALL
if (store->objs != NULL) { if (store->objs != NULL) {
wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL); wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
@@ -1010,6 +1212,28 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
return &store->lookup; return &store->lookup;
} }
static int wolfSSL_X509_STORE_add_ca(WOLFSSL_X509_STORE* store,
WOLFSSL_X509* x509, int type)
{
int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
DerBuffer* derCert = NULL;
WOLFSSL_ENTER("wolfSSL_X509_STORE_add_ca");
if (store != NULL && x509 != NULL && x509->derCert != NULL) {
result = AllocDer(&derCert, x509->derCert->length,
x509->derCert->type, NULL);
if (result == 0) {
/* AddCA() frees the buffer. */
XMEMCPY(derCert->buffer,
x509->derCert->buffer, x509->derCert->length);
result = AddCA(store->cm, &derCert, type, VERIFY);
}
}
return result;
}
int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
{ {
int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR); int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
@@ -1017,15 +1241,27 @@ int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert"); WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
if (store != NULL && store->cm != NULL && x509 != NULL if (store != NULL && store->cm != NULL && x509 != NULL
&& x509->derCert != NULL) { && x509->derCert != NULL) {
DerBuffer* derCert = NULL; /* Mimic the openssl behavior, must be self signed to be considered
* trusted, addCA() internals will do additional checks for
result = AllocDer(&derCert, x509->derCert->length, * CA=TRUE */
x509->derCert->type, NULL); if (wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) == 0) {
if (result == 0) { result = wolfSSL_X509_STORE_add_ca(store, x509, WOLFSSL_USER_CA);
/* AddCA() frees the buffer. */ #if !defined(WOLFSSL_SIGNER_DER_CERT)
XMEMCPY(derCert->buffer, if (result == WOLFSSL_SUCCESS && store->trusted != NULL) {
x509->derCert->buffer, x509->derCert->length); result = wolfSSL_sk_X509_push(store->trusted, x509);
result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, VERIFY); result = (result > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FATAL_ERROR;
}
#endif
}
else {
if (store->certs != NULL) {
result = wolfSSL_sk_X509_push(store->certs, x509);
result = (result > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FATAL_ERROR;
}
else {
result = wolfSSL_X509_STORE_add_ca(
store, x509, WOLFSSL_USER_CA);
}
} }
} }
@@ -1065,7 +1301,99 @@ int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
int wolfSSL_X509_STORE_load_cert_buffer(WOLFSSL_X509_STORE *str,
byte *buf, word32 bufLen, int type)
{
int ret = WOLFSSL_FAILURE;
WOLFSSL_X509 *x509 = NULL;
if (str == NULL || buf == NULL) {
return WOLFSSL_FAILURE;
}
/* OpenSSL X509_STORE_load_file fails on DER file, we will as well */
x509 = wolfSSL_X509_load_certificate_buffer(buf, bufLen, type);
if (str->owned != NULL) {
wolfSSL_sk_X509_push(str->owned, x509);
}
ret = wolfSSL_X509_STORE_add_cert(str, x509);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Failed to load file");
ret = WOLFSSL_FAILURE;
}
if (str->owned == NULL) {
wolfSSL_X509_free(x509);
}
return ret;
}
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
static int wolfSSL_X509_STORE_read_file(const char *fname,
StaticBuffer *content, word32 *bytesRead, int *type)
{
int ret = -1;
long sz = 0;
#ifdef HAVE_CRL
const char* header = NULL;
const char* footer = NULL;
#endif
ret = wolfssl_read_file_static(fname, content, NULL, DYNAMIC_TYPE_FILE,
&sz);
if (ret == 0) {
*type = CERT_TYPE;
*bytesRead = (word32)sz;
#ifdef HAVE_CRL
/* Look for CRL header and footer. */
if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
(XSTRNSTR((char*)content->buffer, header, (word32)sz) != NULL)) {
*type = CRL_TYPE;
}
#endif
}
return (ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
}
static int wolfSSL_X509_STORE_load_file(WOLFSSL_X509_STORE *str, const char *fname)
{
int ret = WOLFSSL_SUCCESS;
int type = 0;
#ifndef WOLFSSL_SMALL_STACK
byte stackBuffer[FILE_BUFFER_SIZE];
#endif
StaticBuffer content;
word32 contentLen = 0;
#ifdef WOLFSSL_SMALL_STACK
static_buffer_init(&content);
#else
static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE);
#endif
ret = wolfSSL_X509_STORE_read_file(fname, &content, &contentLen, &type);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Failed to load file");
ret = WOLFSSL_FAILURE;
}
if ((ret == WOLFSSL_SUCCESS) && (type == CERT_TYPE)) {
ret = wolfSSL_X509_STORE_load_cert_buffer(str, content.buffer,
contentLen, WOLFSSL_FILETYPE_PEM);
}
#ifdef HAVE_CRL
else if ((ret == WOLFSSL_SUCCESS) && (type == CRL_TYPE)) {
ret = BufferLoadCRL(str->cm->crl, content.buffer, contentLen,
WOLFSSL_FILETYPE_PEM, 0);
}
#endif
static_buffer_free(&content, NULL, DYNAMIC_TYPE_FILE);
return ret;
}
/* Loads certificate(s) files in pem format into X509_STORE struct from either /* Loads certificate(s) files in pem format into X509_STORE struct from either
* a file or directory. * a file or directory.
* Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs. * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
@@ -1111,10 +1439,7 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
/* Load individual file */ /* Load individual file */
if (file) { if (file) {
/* Try to process file with type DETECT_CERT_TYPE to parse the ret = wolfSSL_X509_STORE_load_file(str, file);
correct certificate header and footer type */
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
NULL, 0, str->cm->crl, 0);
if (ret != WOLFSSL_SUCCESS) { if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Failed to load file"); WOLFSSL_MSG("Failed to load file");
ret = WOLFSSL_FAILURE; ret = WOLFSSL_FAILURE;
@@ -1139,10 +1464,8 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
ret = wc_ReadDirFirst(readCtx, dir, &name); ret = wc_ReadDirFirst(readCtx, dir, &name);
while (ret == 0 && name) { while (ret == 0 && name) {
WOLFSSL_MSG(name); WOLFSSL_MSG(name);
/* Try to process file with type DETECT_CERT_TYPE to parse the
correct certificate header and footer type */ ret = wolfSSL_X509_STORE_load_file(str, name);
ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
NULL, 0, str->cm->crl, 0);
/* Not failing on load errors */ /* Not failing on load errors */
if (ret != WOLFSSL_SUCCESS) if (ret != WOLFSSL_SUCCESS)
WOLFSSL_MSG("Failed to load file in path, continuing"); WOLFSSL_MSG("Failed to load file in path, continuing");
@@ -1185,17 +1508,23 @@ int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
} }
table = store->cm->caTable; table = store->cm->caTable;
if (table){ if (table || (store->certs != NULL)){
if (wc_LockMutex(&store->cm->caLock) == 0){ if (wc_LockMutex(&store->cm->caLock) == 0){
int i = 0; if (table) {
for (i = 0; i < CA_TABLE_SIZE; i++) { int i = 0;
Signer* signer = table[i]; for (i = 0; i < CA_TABLE_SIZE; i++) {
while (signer) { Signer* signer = table[i];
Signer* next = signer->next; while (signer) {
cnt_ret++; Signer* next = signer->next;
signer = next; cnt_ret++;
signer = next;
}
} }
} }
if (store->certs != NULL) {
cnt_ret += wolfSSL_sk_X509_num(store->certs);
}
wc_UnLockMutex(&store->cm->caLock); wc_UnLockMutex(&store->cm->caLock);
} }
} }
@@ -1299,6 +1628,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
WOLFSSL_STACK* ret = NULL; WOLFSSL_STACK* ret = NULL;
WOLFSSL_STACK* cert_stack = NULL; WOLFSSL_STACK* cert_stack = NULL;
WOLFSSL_X509* x509 = NULL; WOLFSSL_X509* x509 = NULL;
int i = 0;
WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects"); WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
if (store == NULL || store->cm == NULL) { if (store == NULL || store->cm == NULL) {
@@ -1329,6 +1659,10 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) #if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
cert_stack = wolfSSL_CertManagerGetCerts(store->cm); cert_stack = wolfSSL_CertManagerGetCerts(store->cm);
for (i = 0; i < wolfSSL_sk_X509_num(store->certs); i++) {
wolfSSL_sk_X509_push(cert_stack,
wolfSSL_sk_X509_value(store->certs, i));
}
/* wolfSSL_sk_X509_pop checks for NULL */ /* wolfSSL_sk_X509_pop checks for NULL */
while ((x509 = wolfSSL_sk_X509_pop(cert_stack)) != NULL) { while ((x509 = wolfSSL_sk_X509_pop(cert_stack)) != NULL) {
WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new(); WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new();

View File

@@ -59821,11 +59821,9 @@ static int test_wolfSSL_X509_STORE_CTX(void)
ExpectNotNull((ctx = X509_STORE_CTX_new())); ExpectNotNull((ctx = X509_STORE_CTX_new()));
ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x5092, sk), 1); ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x5092, sk), 1);
ExpectNull((sk2 = X509_STORE_CTX_get_chain(NULL))); ExpectNull((sk2 = X509_STORE_CTX_get_chain(NULL)));
ExpectNotNull((sk2 = X509_STORE_CTX_get_chain(ctx))); ExpectNull((sk2 = X509_STORE_CTX_get_chain(ctx)));
ExpectIntEQ(sk_num(sk2), 1); /* sanity, make sure chain has 1 cert */
ExpectNull((sk3 = X509_STORE_CTX_get1_chain(NULL))); ExpectNull((sk3 = X509_STORE_CTX_get1_chain(NULL)));
ExpectNotNull((sk3 = X509_STORE_CTX_get1_chain(ctx))); ExpectNull((sk3 = X509_STORE_CTX_get1_chain(ctx)));
ExpectIntEQ(sk_num(sk3), 1); /* sanity, make sure chain has 1 cert */
X509_STORE_CTX_free(ctx); X509_STORE_CTX_free(ctx);
ctx = NULL; ctx = NULL;
X509_STORE_free(str); X509_STORE_free(str);
@@ -59892,6 +59890,373 @@ static int test_wolfSSL_X509_STORE_CTX(void)
return EXPECT_RESULT(); return EXPECT_RESULT();
} }
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
typedef struct {
const char *caFile;
const char *caIntFile;
const char *caInt2File;
const char *leafFile;
X509 *x509Ca;
X509 *x509CaInt;
X509 *x509CaInt2;
X509 *x509Leaf;
STACK_OF(X509)* expectedChain;
} X509_STORE_test_data;
static X509 * test_wolfSSL_X509_STORE_CTX_ex_helper(const char *file)
{
XFILE fp = XBADFILE;
X509 *x = NULL;
fp = XFOPEN(file, "rb");
if (fp == NULL) {
return NULL;
}
x = PEM_read_X509(fp, 0, 0, 0);
XFCLOSE(fp);
return x;
}
static int test_wolfSSL_X509_STORE_CTX_ex1(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
int i = 0;
/* Test case 1, add X509 certs to store and verify */
ExpectNotNull(store = X509_STORE_new());
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex2(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
int i = 0;
/* Test case 2, add certs by filename to store and verify */
ExpectNotNull(store = X509_STORE_new());
ExpectIntEQ(X509_STORE_load_locations(
store, testData->caFile, NULL), 1);
ExpectIntEQ(X509_STORE_load_locations(
store, testData->caIntFile, NULL), 1);
ExpectIntEQ(X509_STORE_load_locations(
store, testData->caInt2File, NULL), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex3(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
int i = 0;
/* Test case 3, mix and match X509 with files */
ExpectNotNull(store = X509_STORE_new());
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
ExpectIntEQ(X509_STORE_load_locations(
store, testData->caFile, NULL), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex4(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
STACK_OF(X509)* inter = NULL;
int i = 0;
/* Test case 4, CA loaded by file, intermediates passed on init */
ExpectNotNull(store = X509_STORE_new());
ExpectIntEQ(X509_STORE_load_locations(
store, testData->caFile, NULL), 1);
ExpectNotNull(inter = sk_X509_new_null());
ExpectIntGE(sk_X509_push(inter, testData->x509CaInt), 1);
ExpectIntGE(sk_X509_push(inter, testData->x509CaInt2), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, inter), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
sk_X509_free(inter);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex5(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
STACK_OF(X509)* trusted = NULL;
int i = 0;
/* Test case 5, manually set trusted stack */
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(trusted = sk_X509_new_null());
ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt), 1);
ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt2), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
X509_STORE_CTX_trusted_stack(ctx, trusted);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
sk_X509_free(trusted);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex6(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
STACK_OF(X509)* trusted = NULL;
STACK_OF(X509)* inter = NULL;
int i = 0;
/* Test case 6, manually set trusted stack will be unified with
* any intermediates provided on init */
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(trusted = sk_X509_new_null());
ExpectNotNull(inter = sk_X509_new_null());
ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
ExpectIntGE(sk_X509_push(inter, testData->x509CaInt), 1);
ExpectIntGE(sk_X509_push(inter, testData->x509CaInt2), 1);
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, inter), 1);
X509_STORE_CTX_trusted_stack(ctx, trusted);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
sk_X509_free(trusted);
sk_X509_free(inter);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex7(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
int i = 0;
/* Test case 7, certs added to store after ctx init are still used */
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex8(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
int i = 0;
/* Test case 8, Only full chain verifies */
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
ExpectIntEQ(sk_X509_num(chain), sk_X509_num(testData->expectedChain));
for (i = 0; i < sk_X509_num(chain); i++) {
ExpectIntEQ(X509_cmp(sk_X509_value(chain, i),
sk_X509_value(testData->expectedChain, i)), 0);
}
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex9(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
X509_STORE_CTX* ctx2 = NULL;
STACK_OF(X509)* trusted = NULL;
/* Test case 9, certs added to store should not be reflected in ctx that
* has been manually set with a trusted stack, but are reflected in ctx
* that has not set trusted stack */
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(ctx = X509_STORE_CTX_new());
ExpectNotNull(ctx2 = X509_STORE_CTX_new());
ExpectNotNull(trusted = sk_X509_new_null());
ExpectIntGE(sk_X509_push(trusted, testData->x509Ca), 1);
ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt), 1);
ExpectIntGE(sk_X509_push(trusted, testData->x509CaInt2), 1);
ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, NULL), 1);
ExpectIntEQ(X509_STORE_CTX_init(ctx2, store, testData->x509Leaf, NULL), 1);
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntNE(X509_verify_cert(ctx2), 1);
X509_STORE_CTX_trusted_stack(ctx, trusted);
/* CTX1 should now verify */
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectIntNE(X509_verify_cert(ctx2), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt), 1);
ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1);
/* CTX2 should now verify */
ExpectIntEQ(X509_verify_cert(ctx2), 1);
X509_STORE_CTX_free(ctx);
X509_STORE_CTX_free(ctx2);
X509_STORE_free(store);
sk_X509_free(trusted);
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_X509_STORE_CTX_ex(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
X509_STORE_test_data testData = {0};
testData.caFile = "./certs/ca-cert.pem";
testData.caIntFile = "./certs/intermediate/ca-int-cert.pem";
testData.caInt2File = "./certs/intermediate/ca-int2-cert.pem";
testData.leafFile = "./certs/intermediate/server-chain.pem";
ExpectNotNull(testData.x509Ca = \
test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caFile));
ExpectNotNull(testData.x509CaInt = \
test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caIntFile));
ExpectNotNull(testData.x509CaInt2 = \
test_wolfSSL_X509_STORE_CTX_ex_helper(testData.caInt2File));
ExpectNotNull(testData.x509Leaf = \
test_wolfSSL_X509_STORE_CTX_ex_helper(testData.leafFile));
ExpectNotNull(testData.expectedChain = sk_X509_new_null());
ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509Leaf), 1);
ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509CaInt2), 1);
ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509CaInt), 1);
ExpectIntGE(sk_X509_push(testData.expectedChain, testData.x509Ca), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex1(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex2(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex3(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex4(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex5(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex6(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex7(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex8(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex9(&testData), 1);
if(testData.x509Ca) {
X509_free(testData.x509Ca);
}
if(testData.x509CaInt) {
X509_free(testData.x509CaInt);
}
if(testData.x509CaInt2) {
X509_free(testData.x509CaInt2);
}
if(testData.x509Leaf) {
X509_free(testData.x509Leaf);
}
if (testData.expectedChain) {
sk_X509_free(testData.expectedChain);
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
* !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) #if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
static int test_X509_STORE_untrusted_load_cert_to_stack(const char* filename, static int test_X509_STORE_untrusted_load_cert_to_stack(const char* filename,
STACK_OF(X509)* chain) STACK_OF(X509)* chain)
@@ -59994,9 +60359,9 @@ static int test_X509_STORE_untrusted(void)
/* Succeeds because path to loaded CA is available. */ /* Succeeds because path to loaded CA is available. */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted2, 1, 0, 1), ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted2, 1, 0, 1),
TEST_SUCCESS); TEST_SUCCESS);
/* Fails because root CA is in the untrusted stack */ /* Root CA in untrusted chain is OK */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 0, ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 1),
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0), TEST_SUCCESS); TEST_SUCCESS);
/* Succeeds because path to loaded CA is available. */ /* Succeeds because path to loaded CA is available. */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1), ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1),
TEST_SUCCESS); TEST_SUCCESS);
@@ -80147,7 +80512,7 @@ static int test_wolfSSL_X509_load_crl_file(void)
#ifdef WC_RSA_PSS #ifdef WC_RSA_PSS
ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm, ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
"certs/rsapss/server-rsapss-cert.pem", WOLFSSL_FILETYPE_PEM), "certs/rsapss/server-rsapss-cert.pem", WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(CRL_CERT_REVOKED)); WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
#endif #endif
} }
/* once feeing store */ /* once feeing store */
@@ -97559,6 +97924,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_TBS), TEST_DECL(test_wolfSSL_TBS),
TEST_DECL(test_wolfSSL_X509_STORE_CTX), TEST_DECL(test_wolfSSL_X509_STORE_CTX),
TEST_DECL(test_wolfSSL_X509_STORE_CTX_ex),
TEST_DECL(test_X509_STORE_untrusted), TEST_DECL(test_X509_STORE_untrusted),
TEST_DECL(test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup), TEST_DECL(test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup),
TEST_DECL(test_wolfSSL_X509_STORE_CTX_get0_current_issuer), TEST_DECL(test_wolfSSL_X509_STORE_CTX_get0_current_issuer),

View File

@@ -2756,6 +2756,8 @@ WOLFSSL_LOCAL int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt,
WOLFSSL_LOCAL void CleanupStoreCtxCallback(WOLFSSL_X509_STORE_CTX* store, WOLFSSL_LOCAL void CleanupStoreCtxCallback(WOLFSSL_X509_STORE_CTX* store,
WOLFSSL* ssl, void* heap, int x509Free); WOLFSSL* ssl, void* heap, int x509Free);
#endif /* !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) */ #endif /* !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) */
WOLFSSL_LOCAL int wolfSSL_X509_STORE_load_cert_buffer(WOLFSSL_X509_STORE *str,
byte *buf, word32 bufLen, int type);
#endif /* !defined NO_CERTS */ #endif /* !defined NO_CERTS */
/* wolfSSL Sock Addr */ /* wolfSSL Sock Addr */

View File

@@ -600,6 +600,9 @@ struct WOLFSSL_X509_STORE {
WOLFSSL_X509_CRL *crl; /* points to cm->crl */ WOLFSSL_X509_CRL *crl; /* points to cm->crl */
#endif #endif
wolfSSL_Ref ref; wolfSSL_Ref ref;
WOLF_STACK_OF(WOLFSSL_X509)* certs;
WOLF_STACK_OF(WOLFSSL_X509)* trusted;
WOLF_STACK_OF(WOLFSSL_X509)* owned;
}; };
#define WOLFSSL_ALWAYS_CHECK_SUBJECT 0x1 #define WOLFSSL_ALWAYS_CHECK_SUBJECT 0x1
@@ -697,6 +700,11 @@ struct WOLFSSL_X509_STORE_CTX {
WOLFSSL_BUFFER_INFO* certs; /* peer certs */ WOLFSSL_BUFFER_INFO* certs; /* peer certs */
WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */ WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */
void* heap; void* heap;
WOLF_STACK_OF(WOLFSSL_X509)* ctxIntermediates; /* Intermediates specified
* on store ctx init */
WOLF_STACK_OF(WOLFSSL_X509)* setTrustedSk;/* A trusted stack override
* set with
* X509_STORE_CTX_trusted_stack*/
}; };
typedef char* WOLFSSL_STRING; typedef char* WOLFSSL_STRING;
@@ -3313,7 +3321,8 @@ enum {
WOLFSSL_DTLSV1_3 = 7, WOLFSSL_DTLSV1_3 = 7,
WOLFSSL_USER_CA = 1, /* user added as trusted */ WOLFSSL_USER_CA = 1, /* user added as trusted */
WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */ WOLFSSL_CHAIN_CA = 2, /* added to cache from trusted chain */
WOLFSSL_INTER_CA = 3 /* Intermediate CA */
}; };
WOLFSSL_ABI WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl);