mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
Initial rewrite of X509 STORE to replicate openssl behavior
This commit is contained in:
committed by
Daniel Pouzzner
parent
82273094e0
commit
17c9e92b7f
@@ -455,11 +455,12 @@ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
|
||||
static int wolfSSL_CertManagerUnloadIntermediateCertsEx(WOLFSSL_CERT_MANAGER* cm,
|
||||
int type)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts");
|
||||
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCertsEx");
|
||||
|
||||
/* Validate parameter. */
|
||||
if (cm == NULL) {
|
||||
@@ -471,7 +472,7 @@ int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
/* Dispose of CA table. */
|
||||
FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, WOLFSSL_CHAIN_CA,
|
||||
FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, type,
|
||||
cm->heap);
|
||||
|
||||
/* Unlock CA table. */
|
||||
@@ -481,6 +482,20 @@ int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
|
||||
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
|
||||
/* Unload the trusted peers table.
|
||||
*
|
||||
|
11
src/x509.c
11
src/x509.c
@@ -5559,7 +5559,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
|
||||
* size of this subset and its memory usage */
|
||||
#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.
|
||||
* 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* curr = NULL;
|
||||
byte* prev = NULL;
|
||||
WOLFSSL_X509* x509;
|
||||
const char* header = 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 &&
|
||||
XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
|
||||
x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (x509 == NULL)
|
||||
goto end;
|
||||
ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
|
||||
wolfSSL_X509_free(x509);
|
||||
ret = wolfSSL_X509_STORE_load_cert_buffer(lookup->store, curr, sz,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
goto end;
|
||||
curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
|
||||
|
494
src/x509_str.c
494
src/x509_str.c
@@ -36,6 +36,17 @@
|
||||
|
||||
#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
|
||||
******************************************************************************/
|
||||
@@ -78,6 +89,14 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
|
||||
#ifdef OPENSSL_EXTRA
|
||||
XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL);
|
||||
ctx->param = NULL;
|
||||
|
||||
if (ctx->ctxIntermediates != NULL) {
|
||||
wolfSSL_sk_X509_free(ctx->ctxIntermediates);
|
||||
}
|
||||
|
||||
if (ctx->chain != NULL) {
|
||||
wolfSSL_sk_X509_free(ctx->chain);
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
(void)sk;
|
||||
int i = 0;
|
||||
WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
|
||||
|
||||
if (ctx != NULL) {
|
||||
@@ -106,51 +125,37 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
|
||||
ctx->current_cert = x509;
|
||||
#else
|
||||
if(x509 != NULL){
|
||||
ctx->current_cert = wolfSSL_X509_d2i_ex(NULL, x509->derCert->buffer,
|
||||
x509->derCert->length, x509->heap);
|
||||
ctx->current_cert = wolfSSL_X509_d2i_ex(NULL,
|
||||
x509->derCert->buffer,
|
||||
x509->derCert->length,
|
||||
x509->heap);
|
||||
if(ctx->current_cert == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
} else
|
||||
ctx->current_cert = NULL;
|
||||
#endif
|
||||
|
||||
ctx->chain = sk;
|
||||
/* Add intermediate certs, that verify to a loaded CA, to the store */
|
||||
if (sk != NULL) {
|
||||
byte addedAtLeastOne = 1;
|
||||
WOLF_STACK_OF(WOLFSSL_X509)* head = wolfSSL_shallow_sk_dup(sk);
|
||||
if (head == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
while (addedAtLeastOne) {
|
||||
WOLF_STACK_OF(WOLFSSL_X509)* cur = head;
|
||||
WOLF_STACK_OF(WOLFSSL_X509)** prev = &head;
|
||||
addedAtLeastOne = 0;
|
||||
while (cur) {
|
||||
WOLFSSL_X509* cert = cur->data.x509;
|
||||
if (cert != NULL && cert->derCert != NULL &&
|
||||
wolfSSL_CertManagerVerifyBuffer(store->cm,
|
||||
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;
|
||||
}
|
||||
if (ctx->ctxIntermediates == NULL) {
|
||||
ctx->ctxIntermediates = sk_X509_new_null();
|
||||
if (ctx->ctxIntermediates == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
|
||||
ret = wolfSSL_sk_X509_push(ctx->ctxIntermediates,
|
||||
wolfSSL_sk_X509_value(sk, i));
|
||||
if (ret <= 0) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
wolfSSL_sk_free(head);
|
||||
}
|
||||
|
||||
if (ctx->chain != NULL) {
|
||||
wolfSSL_sk_X509_free(ctx->chain);
|
||||
ctx->chain = NULL;
|
||||
}
|
||||
ctx->sesChain = NULL;
|
||||
ctx->domain = NULL;
|
||||
#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) {
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
static int wolfSSL_X509_verify_cert_ex(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
|
||||
&& ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
|
||||
int ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
|
||||
ctx->current_cert->derCert->buffer,
|
||||
ctx->current_cert->derCert->length,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
if (ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
|
||||
ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
|
||||
ctx->current_cert->derCert->buffer,
|
||||
ctx->current_cert->derCert->length,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
SetupStoreCtxError(ctx, ret);
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
|
||||
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) &&
|
||||
ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
|
||||
/* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
|
||||
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
|
||||
in order to return the correct expected error. */
|
||||
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
|
||||
in order to return the correct expected error. */
|
||||
byte *afterDate = ctx->current_cert->notAfter.data;
|
||||
byte *beforeDate = ctx->current_cert->notBefore.data;
|
||||
|
||||
@@ -300,10 +305,157 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
|
||||
#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 */
|
||||
@@ -743,7 +895,7 @@ int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
|
||||
for (node = ctx->chain; node != NULL; node = node->next) {
|
||||
if (wolfSSL_X509_check_issued(node->data.x509, x) ==
|
||||
WOLFSSL_X509_V_OK) {
|
||||
*issuer = x;
|
||||
*issuer = node->data.x509;
|
||||
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 */
|
||||
|
||||
#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
|
||||
******************************************************************************/
|
||||
@@ -789,6 +966,17 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
|
||||
if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
|
||||
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
|
||||
store->crl = store->cm->crl;
|
||||
#endif
|
||||
@@ -849,6 +1037,20 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
|
||||
wolfSSL_CertManagerFree(store->cm);
|
||||
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
|
||||
if (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;
|
||||
}
|
||||
|
||||
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 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");
|
||||
if (store != NULL && store->cm != NULL && x509 != NULL
|
||||
&& x509->derCert != NULL) {
|
||||
DerBuffer* 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, WOLFSSL_USER_CA, VERIFY);
|
||||
/* Mimic the openssl behavior, must be self signed to be considered
|
||||
* trusted, addCA() internals will do additional checks for
|
||||
* CA=TRUE */
|
||||
if (wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) == 0) {
|
||||
result = wolfSSL_X509_STORE_add_ca(store, x509, WOLFSSL_USER_CA);
|
||||
#if !defined(WOLFSSL_SIGNER_DER_CERT)
|
||||
if (result == WOLFSSL_SUCCESS && store->trusted != NULL) {
|
||||
result = wolfSSL_sk_X509_push(store->trusted, x509);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
* a file or directory.
|
||||
* 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 */
|
||||
if (file) {
|
||||
/* Try to process file with type DETECT_CERT_TYPE to parse the
|
||||
correct certificate header and footer type */
|
||||
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
|
||||
NULL, 0, str->cm->crl, 0);
|
||||
ret = wolfSSL_X509_STORE_load_file(str, file);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to load file");
|
||||
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);
|
||||
while (ret == 0 && name) {
|
||||
WOLFSSL_MSG(name);
|
||||
/* Try to process file with type DETECT_CERT_TYPE to parse the
|
||||
correct certificate header and footer type */
|
||||
ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
|
||||
NULL, 0, str->cm->crl, 0);
|
||||
|
||||
ret = wolfSSL_X509_STORE_load_file(str, name);
|
||||
/* Not failing on load errors */
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
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;
|
||||
if (table){
|
||||
if (table || (store->certs != NULL)){
|
||||
if (wc_LockMutex(&store->cm->caLock) == 0){
|
||||
int i = 0;
|
||||
for (i = 0; i < CA_TABLE_SIZE; i++) {
|
||||
Signer* signer = table[i];
|
||||
while (signer) {
|
||||
Signer* next = signer->next;
|
||||
cnt_ret++;
|
||||
signer = next;
|
||||
if (table) {
|
||||
int i = 0;
|
||||
for (i = 0; i < CA_TABLE_SIZE; i++) {
|
||||
Signer* signer = table[i];
|
||||
while (signer) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1299,6 +1628,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
|
||||
WOLFSSL_STACK* ret = NULL;
|
||||
WOLFSSL_STACK* cert_stack = NULL;
|
||||
WOLFSSL_X509* x509 = NULL;
|
||||
int i = 0;
|
||||
WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
|
||||
|
||||
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)
|
||||
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 */
|
||||
while ((x509 = wolfSSL_sk_X509_pop(cert_stack)) != NULL) {
|
||||
WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new();
|
||||
|
382
tests/api.c
382
tests/api.c
@@ -59821,11 +59821,9 @@ static int test_wolfSSL_X509_STORE_CTX(void)
|
||||
ExpectNotNull((ctx = X509_STORE_CTX_new()));
|
||||
ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x5092, sk), 1);
|
||||
ExpectNull((sk2 = X509_STORE_CTX_get_chain(NULL)));
|
||||
ExpectNotNull((sk2 = X509_STORE_CTX_get_chain(ctx)));
|
||||
ExpectIntEQ(sk_num(sk2), 1); /* sanity, make sure chain has 1 cert */
|
||||
ExpectNull((sk2 = X509_STORE_CTX_get_chain(ctx)));
|
||||
ExpectNull((sk3 = X509_STORE_CTX_get1_chain(NULL)));
|
||||
ExpectNotNull((sk3 = X509_STORE_CTX_get1_chain(ctx)));
|
||||
ExpectIntEQ(sk_num(sk3), 1); /* sanity, make sure chain has 1 cert */
|
||||
ExpectNull((sk3 = X509_STORE_CTX_get1_chain(ctx)));
|
||||
X509_STORE_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
X509_STORE_free(str);
|
||||
@@ -59892,6 +59890,373 @@ static int test_wolfSSL_X509_STORE_CTX(void)
|
||||
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)
|
||||
static int test_X509_STORE_untrusted_load_cert_to_stack(const char* filename,
|
||||
STACK_OF(X509)* chain)
|
||||
@@ -59994,9 +60359,9 @@ static int test_X509_STORE_untrusted(void)
|
||||
/* Succeeds because path to loaded CA is available. */
|
||||
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted2, 1, 0, 1),
|
||||
TEST_SUCCESS);
|
||||
/* Fails because root CA is in the untrusted stack */
|
||||
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 0,
|
||||
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0), TEST_SUCCESS);
|
||||
/* Root CA in untrusted chain is OK */
|
||||
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 1),
|
||||
TEST_SUCCESS);
|
||||
/* Succeeds because path to loaded CA is available. */
|
||||
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1),
|
||||
TEST_SUCCESS);
|
||||
@@ -80147,7 +80512,7 @@ static int test_wolfSSL_X509_load_crl_file(void)
|
||||
#ifdef WC_RSA_PSS
|
||||
ExpectIntEQ(wolfSSL_CertManagerVerify(store->cm,
|
||||
"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
|
||||
}
|
||||
/* once feeing store */
|
||||
@@ -97559,6 +97924,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfSSL_TBS),
|
||||
|
||||
TEST_DECL(test_wolfSSL_X509_STORE_CTX),
|
||||
TEST_DECL(test_wolfSSL_X509_STORE_CTX_ex),
|
||||
TEST_DECL(test_X509_STORE_untrusted),
|
||||
TEST_DECL(test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup),
|
||||
TEST_DECL(test_wolfSSL_X509_STORE_CTX_get0_current_issuer),
|
||||
|
@@ -2756,6 +2756,8 @@ WOLFSSL_LOCAL int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt,
|
||||
WOLFSSL_LOCAL void CleanupStoreCtxCallback(WOLFSSL_X509_STORE_CTX* store,
|
||||
WOLFSSL* ssl, void* heap, int x509Free);
|
||||
#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 */
|
||||
|
||||
/* wolfSSL Sock Addr */
|
||||
|
@@ -600,6 +600,9 @@ struct WOLFSSL_X509_STORE {
|
||||
WOLFSSL_X509_CRL *crl; /* points to cm->crl */
|
||||
#endif
|
||||
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
|
||||
@@ -697,6 +700,11 @@ struct WOLFSSL_X509_STORE_CTX {
|
||||
WOLFSSL_BUFFER_INFO* certs; /* peer certs */
|
||||
WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */
|
||||
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;
|
||||
@@ -3313,7 +3321,8 @@ enum {
|
||||
WOLFSSL_DTLSV1_3 = 7,
|
||||
|
||||
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);
|
||||
|
Reference in New Issue
Block a user