Merge pull request #8087 from ColtonWilley/x509_store_rewrite

Initial rewrite of X509 STORE to replicate openssl behavior
This commit is contained in:
JacobBarthelmeh
2024-10-23 17:14:40 -06:00
committed by GitHub
9 changed files with 1074 additions and 172 deletions

View File

@ -5535,13 +5535,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
}
}
if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA &&
type != WOLFSSL_TEMP_CA) {
WOLFSSL_MSG("\tCan't add as CA if not actually one");
ret = NOT_CA_ERROR;
}
#ifndef ALLOW_INVALID_CERTSIGN
else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
!cert->selfSigned && (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
type != WOLFSSL_TEMP_CA && !cert->selfSigned &&
(cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
/* Intermediate CA certs are required to have the keyCertSign
* extension set. User loaded root certs are not. */
WOLFSSL_MSG("\tDoesn't have key usage certificate signing");

View File

@ -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, byte 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,22 @@ 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_TEMP_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.
*

View File

@ -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 = X509StoreLoadCertBuffer(lookup->store, curr,
(word32)sz, WOLFSSL_FILETYPE_PEM);
if (ret != WOLFSSL_SUCCESS)
goto end;
curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
@ -14210,6 +14205,9 @@ int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
#if defined(OPENSSL_EXTRA) && \
((defined(SESSION_CERTS) && !defined(WOLFSSL_QT)) || \
defined(WOLFSSL_SIGNER_DER_CERT))
/**
* Find the issuing cert of the input cert. On a self-signed cert this
@ -14280,6 +14278,8 @@ static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
return WOLFSSL_SUCCESS;
}
#endif /* if defined(OPENSSL_EXTRA) && (defined(SESSION_CERTS) || \
defined(WOLFSSL_SIGNER_DER_CERT)) */
void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
{

File diff suppressed because it is too large Load Diff

View File

@ -225,6 +225,7 @@
#include <wolfssl/openssl/modes.h>
#include <wolfssl/openssl/fips_rand.h>
#include <wolfssl/openssl/kdf.h>
#include <wolfssl/openssl/x509_vfy.h>
#ifdef OPENSSL_ALL
#include <wolfssl/openssl/txt_db.h>
#include <wolfssl/openssl/lhash.h>
@ -59555,8 +59556,12 @@ static int test_wolfSSL_X509_LOOKUP_ctrl_file(void)
ExpectNull(X509_STORE_CTX_get0_current_issuer(NULL));
issuer = X509_STORE_CTX_get0_current_issuer(ctx);
ExpectNotNull(issuer);
ExpectNull(issuer);
ExpectIntEQ(X509_verify_cert(ctx), 1);
issuer = X509_STORE_CTX_get0_current_issuer(ctx);
ExpectNotNull(issuer);
caName = X509_get_subject_name(x509Ca);
ExpectNotNull(caName);
issuerName = X509_get_subject_name(issuer);
@ -59565,7 +59570,6 @@ static int test_wolfSSL_X509_LOOKUP_ctrl_file(void)
ExpectIntEQ(cmp, 0);
/* load der format */
X509_free(issuer);
issuer = NULL;
X509_STORE_CTX_free(ctx);
ctx = NULL;
@ -59643,7 +59647,7 @@ static int test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup(void)
return res;
}
static int test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void)
static int test_wolfSSL_X509_STORE_CTX_get_issuer(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
@ -59665,16 +59669,23 @@ static int test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void)
ExpectIntEQ(X509_STORE_CTX_init(ctx, str, x509Svr, NULL), SSL_SUCCESS);
/* Issuer0 is not set until chain is built for verification */
ExpectNull(X509_STORE_CTX_get0_current_issuer(NULL));
ExpectNotNull(issuer = X509_STORE_CTX_get0_current_issuer(ctx));
ExpectNull(issuer = X509_STORE_CTX_get0_current_issuer(ctx));
/* Issuer1 will use the store to make a new issuer */
ExpectIntEQ(X509_STORE_CTX_get1_issuer(&issuer, ctx, x509Svr), 1);
ExpectNotNull(issuer);
X509_free(issuer);
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(issuer = X509_STORE_CTX_get0_current_issuer(ctx));
ExpectNotNull(caName = X509_get_subject_name(x509Ca));
ExpectNotNull(issuerName = X509_get_subject_name(issuer));
#ifdef WOLFSSL_SIGNER_DER_CERT
ExpectIntEQ(X509_NAME_cmp(caName, issuerName), 0);
#endif
X509_free(issuer);
X509_STORE_CTX_free(ctx);
X509_free(x509Svr);
X509_STORE_free(str);
@ -59821,11 +59832,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 +59901,424 @@ 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();
}
static int test_wolfSSL_X509_STORE_CTX_ex10(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
/* Test case 10, ensure partial chain flag works */
ExpectNotNull(store = X509_STORE_new());
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);
/* Fails because chain is incomplete */
ExpectIntNE(X509_verify_cert(ctx), 1);
ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1);
/* Partial chain now OK */
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_STORE_CTX_ex11(X509_STORE_test_data *testData)
{
EXPECT_DECLS;
X509_STORE* store = NULL;
X509_STORE_CTX* ctx = NULL;
STACK_OF(X509)* chain = NULL;
/* Test case 11, test partial chain flag on ctx itself */
ExpectNotNull(store = X509_STORE_new());
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);
/* Fails because chain is incomplete */
ExpectIntNE(X509_verify_cert(ctx), 1);
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_PARTIAL_CHAIN);
/* Partial chain now OK */
ExpectIntEQ(X509_verify_cert(ctx), 1);
ExpectNotNull(chain = X509_STORE_CTX_get_chain(ctx));
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
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;
XMEMSET((void *)&testData, 0, sizeof(X509_STORE_test_data));
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);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex10(&testData), 1);
ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex11(&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 +60421,15 @@ 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 */
/* Root CA in untrusted chain is OK so long as CA has been loaded
* properly */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 1),
TEST_SUCCESS);
/* Still needs properly loaded CA, while including it in untrusted
* list is not an error, it also doesnt count for verify */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 0,
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0), TEST_SUCCESS);
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0),
TEST_SUCCESS);
/* Succeeds because path to loaded CA is available. */
ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1),
TEST_SUCCESS);
@ -80147,7 +80580,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,9 +97992,10 @@ 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),
TEST_DECL(test_wolfSSL_X509_STORE_CTX_get_issuer),
TEST_DECL(test_wolfSSL_X509_STORE_set_flags),
TEST_DECL(test_wolfSSL_X509_LOOKUP_load_file),
TEST_DECL(test_wolfSSL_X509_Name_canon),

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* ssl, void* heap, int x509Free);
#endif /* !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) */
WOLFSSL_LOCAL int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str,
byte *buf, word32 bufLen, int type);
#endif /* !defined NO_CERTS */
/* wolfSSL Sock Addr */

View File

@ -643,8 +643,8 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#define X509_V_FLAG_CRL_CHECK WOLFSSL_CRL_CHECK
#define X509_V_FLAG_CRL_CHECK_ALL WOLFSSL_CRL_CHECKALL
#define X509_V_FLAG_PARTIAL_CHAIN 0
#define X509_V_FLAG_TRUSTED_FIRST 0
#define X509_V_FLAG_PARTIAL_CHAIN WOLFSSL_PARTIAL_CHAIN
#define X509_V_FLAG_TRUSTED_FIRST 0 /* dummy value needed for gRPC port */
#define X509_V_FLAG_USE_CHECK_TIME WOLFSSL_USE_CHECK_TIME
#define X509_V_FLAG_NO_CHECK_TIME WOLFSSL_NO_CHECK_TIME

View File

@ -33,10 +33,13 @@
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
WOLFSSL_API int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx, int purpose);
#endif
#ifdef OPENSSL_EXTRA
WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_flags(WOLFSSL_X509_STORE_CTX *ctx,
unsigned long flags);
#endif
#define X509_STORE_CTX_set_purpose wolfSSL_X509_STORE_CTX_set_purpose
#define X509_STORE_CTX_set_flags wolfSSL_X509_STORE_CTX_set_flags

View File

@ -600,6 +600,10 @@ 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;
word32 numAdded; /* Number of objs in objs that are in certs sk */
};
#define WOLFSSL_ALWAYS_CHECK_SUBJECT 0x1
@ -612,6 +616,7 @@ struct WOLFSSL_X509_STORE {
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
#define WOLFSSL_USE_CHECK_TIME 0x2
#define WOLFSSL_NO_CHECK_TIME 0x200000
#define WOLFSSL_PARTIAL_CHAIN 0x80000
#define WOLFSSL_HOST_NAME_MAX 256
#define WOLFSSL_VPARAM_DEFAULT 0x1
@ -674,7 +679,7 @@ typedef struct WOLFSSL_BUFFER_INFO {
struct WOLFSSL_X509_STORE_CTX {
WOLFSSL_X509_STORE* store; /* Store full of a CA cert chain */
WOLFSSL_X509* current_cert; /* current X509 (OPENSSL_EXTRA) */
#ifdef WOLFSSL_ASIO
#if defined(WOLFSSL_ASIO) || defined(OPENSSL_EXTRA)
WOLFSSL_X509* current_issuer; /* asio dereference */
#endif
WOLFSSL_X509_CHAIN* sesChain; /* pointer to WOLFSSL_SESSION peer chain */
@ -697,6 +702,13 @@ struct WOLFSSL_X509_STORE_CTX {
WOLFSSL_BUFFER_INFO* certs; /* peer certs */
WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */
void* heap;
int flags;
WOLF_STACK_OF(WOLFSSL_X509)* owned; /* Certs owned by this CTX */
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 +3325,9 @@ 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_TEMP_CA = 3 /* Temp intermediate CA, only for use by
* X509_STORE */
};
WOLFSSL_ABI WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl);