mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #8087 from ColtonWilley/x509_store_rewrite
Initial rewrite of X509 STORE to replicate openssl behavior
This commit is contained in:
@ -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");
|
||||
|
@ -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.
|
||||
*
|
||||
|
16
src/x509.c
16
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 = 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)
|
||||
{
|
||||
|
714
src/x509_str.c
714
src/x509_str.c
File diff suppressed because it is too large
Load Diff
460
tests/api.c
460
tests/api.c
@ -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),
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user