Skip to content

Commit 4caef93

Browse files
committed
Implement transient certs
Add wolfSSL_CertManagerUnloadIntermediateCerts API to clear intermediate certs added to store.
1 parent af2b2dd commit 4caef93

6 files changed

Lines changed: 233 additions & 18 deletions

File tree

src/ssl.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5954,6 +5954,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
59545954
cert->permittedNames = NULL;
59555955
cert->excludedNames = NULL;
59565956
#endif
5957+
signer->type = (byte)type;
59575958

59585959
#ifndef NO_SKID
59595960
row = HashSigner(signer->subjectKeyIdHash);
@@ -16355,6 +16356,22 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
1635516356
return wolfSSL_CertManagerUnloadCAs(ctx->cm);
1635616357
}
1635716358

16359+
int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
16360+
{
16361+
WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");
16362+
16363+
if (ctx == NULL)
16364+
return BAD_FUNC_ARG;
16365+
16366+
if (ctx->ref.count > 1) {
16367+
WOLFSSL_MSG("ctx object must have a ref count of 1 before "
16368+
"unloading intermediate certs");
16369+
return BAD_STATE_E;
16370+
}
16371+
16372+
return wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
16373+
}
16374+
1635816375

1635916376
#ifdef WOLFSSL_TRUST_PEER_CERT
1636016377
int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)

src/ssl_certman.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,31 @@ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
457457
return ret;
458458
}
459459

460+
int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
461+
{
462+
int ret = WOLFSSL_SUCCESS;
463+
464+
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts");
465+
466+
/* Validate parameter. */
467+
if (cm == NULL) {
468+
ret = BAD_FUNC_ARG;
469+
}
470+
/* Lock CA table. */
471+
if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
472+
ret = BAD_MUTEX_E;
473+
}
474+
if (ret == WOLFSSL_SUCCESS) {
475+
/* Dispose of CA table. */
476+
FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, WOLFSSL_CHAIN_CA,
477+
cm->heap);
478+
479+
/* Unlock CA table. */
480+
wc_UnLockMutex(&cm->caLock);
481+
}
482+
483+
return ret;
484+
}
460485

461486
#ifdef WOLFSSL_TRUST_PEER_CERT
462487
/* Unload the trusted peers table.

tests/api.c

Lines changed: 163 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ typedef struct test_ssl_cbf {
441441
ctx_cb ctx_ready;
442442
ssl_cb ssl_ready;
443443
ssl_cb on_result;
444+
ctx_cb on_ctx_cleanup;
444445
ssl_cb on_cleanup;
445446
hs_cb on_handshake;
446447
WOLFSSL_CTX* ctx;
@@ -6149,8 +6150,10 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
61496150
int c_sharedCtx = 0;
61506151
int s_sharedCtx = 0;
61516152
#endif
6152-
const char* certFile = svrCertFile;
6153-
const char* keyFile = svrKeyFile;
6153+
const char* clientCertFile = cliCertFile;
6154+
const char* clientKeyFile = cliKeyFile;
6155+
const char* serverCertFile = svrCertFile;
6156+
const char* serverKeyFile = svrKeyFile;
61546157

61556158
/********************************
61566159
* Create WOLFSSL_CTX for client.
@@ -6182,13 +6185,19 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
61826185
else
61836186
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
61846187
caCertFile, 0), WOLFSSL_SUCCESS);
6188+
if (ctx->c_cb.certPemFile != NULL) {
6189+
clientCertFile = ctx->c_cb.certPemFile;
6190+
}
6191+
if (ctx->c_cb.keyPemFile != NULL) {
6192+
clientKeyFile = ctx->c_cb.keyPemFile;
6193+
}
61856194
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
61866195
if (!c_sharedCtx)
61876196
#endif
61886197
{
61896198
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx,
6190-
cliCertFile), WOLFSSL_SUCCESS);
6191-
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, cliKeyFile,
6199+
clientCertFile), WOLFSSL_SUCCESS);
6200+
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile,
61926201
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
61936202
}
61946203
#ifdef HAVE_CRL
@@ -6255,23 +6264,23 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
62556264
wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack);
62566265
#endif
62576266
if (ctx->s_cb.certPemFile != NULL) {
6258-
certFile = ctx->s_cb.certPemFile;
6267+
serverCertFile = ctx->s_cb.certPemFile;
62596268
}
62606269
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
62616270
if (!s_sharedCtx)
62626271
#endif
62636272
{
62646273
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx,
6265-
certFile), WOLFSSL_SUCCESS);
6274+
serverCertFile), WOLFSSL_SUCCESS);
62666275
}
62676276
if (ctx->s_cb.keyPemFile != NULL) {
6268-
keyFile = ctx->s_cb.keyPemFile;
6277+
serverKeyFile = ctx->s_cb.keyPemFile;
62696278
}
62706279
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
62716280
if (!s_sharedCtx)
62726281
#endif
62736282
{
6274-
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, keyFile,
6283+
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile,
62756284
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
62766285
}
62776286
if (ctx->s_ciphers != NULL) {
@@ -6295,9 +6304,9 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
62956304
#endif
62966305
)
62976306
{
6298-
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl, cliCertFile),
6299-
WOLFSSL_SUCCESS);
6300-
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, cliKeyFile,
6307+
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl,
6308+
clientCertFile), WOLFSSL_SUCCESS);
6309+
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile,
63016310
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
63026311
}
63036312
if (ctx->c_cb.ssl_ready != NULL) {
@@ -6316,9 +6325,9 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
63166325
#endif
63176326
)
63186327
{
6319-
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl, certFile),
6320-
WOLFSSL_SUCCESS);
6321-
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, keyFile,
6328+
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl,
6329+
serverCertFile), WOLFSSL_SUCCESS);
6330+
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile,
63226331
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
63236332
}
63246333
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
@@ -6400,7 +6409,7 @@ static int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
64006409
}
64016410
}
64026411

6403-
if (!handshake_complete) {
6412+
if (!handshake_complete || failing_c || failing_s) {
64046413
return TEST_FAIL;
64056414
}
64066415

@@ -6468,14 +6477,20 @@ static void test_ssl_memio_cleanup(test_ssl_memio_ctx* ctx)
64686477
wolfSSL_shutdown(ctx->c_ssl);
64696478
wolfSSL_free(ctx->s_ssl);
64706479
wolfSSL_free(ctx->c_ssl);
6471-
if (!ctx->s_cb.isSharedCtx) {
6472-
wolfSSL_CTX_free(ctx->s_ctx);
6473-
ctx->s_ctx = NULL;
6480+
if (ctx->c_cb.on_ctx_cleanup != NULL) {
6481+
ctx->c_cb.on_ctx_cleanup(ctx->c_ctx);
64746482
}
64756483
if (!ctx->c_cb.isSharedCtx) {
64766484
wolfSSL_CTX_free(ctx->c_ctx);
64776485
ctx->c_ctx = NULL;
64786486
}
6487+
if (ctx->s_cb.on_ctx_cleanup != NULL) {
6488+
ctx->s_cb.on_ctx_cleanup(ctx->s_ctx);
6489+
}
6490+
if (!ctx->s_cb.isSharedCtx) {
6491+
wolfSSL_CTX_free(ctx->s_ctx);
6492+
ctx->s_ctx = NULL;
6493+
}
64796494

64806495
if (!ctx->s_cb.ticNoInit) {
64816496
#if defined(HAVE_SESSION_TICKET) && \
@@ -69972,6 +69987,135 @@ static int test_get_signature_nid(void)
6997269987
return EXPECT_RESULT();
6997369988
}
6997469989

69990+
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
69991+
static word32 test_tls_cert_store_unchanged_HashCaTable(Signer** caTable)
69992+
{
69993+
#ifndef NO_MD5
69994+
enum wc_HashType hashType = WC_HASH_TYPE_MD5;
69995+
#elif !defined(NO_SHA)
69996+
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
69997+
#elif !defined(NO_SHA256)
69998+
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
69999+
#else
70000+
#error "We need a digest to hash the Signer object"
70001+
#endif
70002+
byte hashBuf[WC_MAX_DIGEST_SIZE];
70003+
wc_HashAlg hash;
70004+
size_t i;
70005+
70006+
AssertIntEQ(wc_HashInit(&hash, hashType), 0);
70007+
for (i = 0; i < CA_TABLE_SIZE; i++) {
70008+
Signer* cur;
70009+
for (cur = caTable[i]; cur != NULL; cur = cur->next)
70010+
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)cur,
70011+
sizeof(*cur)), 0);
70012+
}
70013+
AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
70014+
AssertIntEQ(wc_HashFree(&hash, hashType), 0);
70015+
70016+
return MakeWordFromHash(hashBuf);
70017+
}
70018+
70019+
static word32 test_tls_cert_store_unchanged_before_hashes[2];
70020+
static size_t test_tls_cert_store_unchanged_before_hashes_idx = 0;
70021+
static word32 test_tls_cert_store_unchanged_after_hashes[2];
70022+
static size_t test_tls_cert_store_unchanged_after_hashes_idx = 0;
70023+
70024+
static int test_tls_cert_store_unchanged_ctx_ready(WOLFSSL_CTX* ctx)
70025+
{
70026+
EXPECT_DECLS;
70027+
70028+
ExpectIntNE(test_tls_cert_store_unchanged_before_hashes
70029+
[test_tls_cert_store_unchanged_before_hashes_idx++] =
70030+
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
70031+
70032+
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER |
70033+
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
70034+
70035+
return EXPECT_RESULT();
70036+
}
70037+
70038+
static int test_tls_cert_store_unchanged_ctx_cleanup(WOLFSSL_CTX* ctx)
70039+
{
70040+
EXPECT_DECLS;
70041+
ExpectIntEQ(wolfSSL_CTX_UnloadIntermediateCerts(ctx), WOLFSSL_SUCCESS);
70042+
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
70043+
[test_tls_cert_store_unchanged_after_hashes_idx++] =
70044+
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
70045+
70046+
return EXPECT_RESULT();
70047+
}
70048+
70049+
/*
70050+
static int test_tls_cert_store_unchanged_on_hs(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
70051+
{
70052+
EXPECT_DECLS;
70053+
70054+
(void)ssl;
70055+
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
70056+
[test_tls_cert_store_unchanged_after_hashes_idx++] =
70057+
test_tls_cert_store_unchanged_HashCaTable((*ctx)->cm->caTable), 0);
70058+
70059+
return EXPECT_RESULT();
70060+
}
70061+
*/
70062+
70063+
static int test_tls_cert_store_unchanged_ssl_ready(WOLFSSL* ssl)
70064+
{
70065+
EXPECT_DECLS;
70066+
WOLFSSL_CTX* ctx;
70067+
70068+
ExpectNotNull(ctx = wolfSSL_get_SSL_CTX(ssl));
70069+
70070+
return EXPECT_RESULT();
70071+
}
70072+
#endif
70073+
70074+
static int test_tls_cert_store_unchanged(void)
70075+
{
70076+
EXPECT_DECLS;
70077+
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
70078+
test_ssl_cbf client_cbf;
70079+
test_ssl_cbf server_cbf;
70080+
70081+
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
70082+
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
70083+
70084+
XMEMSET(test_tls_cert_store_unchanged_before_hashes, 0,
70085+
sizeof(test_tls_cert_store_unchanged_before_hashes));
70086+
XMEMSET(test_tls_cert_store_unchanged_after_hashes, 0,
70087+
sizeof(test_tls_cert_store_unchanged_after_hashes));
70088+
70089+
client_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
70090+
server_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
70091+
70092+
client_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
70093+
server_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
70094+
70095+
/* TODO add API to allow clearing/not storing certs while connections are
70096+
* still active.
70097+
client_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
70098+
server_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
70099+
*/
70100+
70101+
client_cbf.on_ctx_cleanup = test_tls_cert_store_unchanged_ctx_cleanup;
70102+
server_cbf.on_ctx_cleanup = test_tls_cert_store_unchanged_ctx_cleanup;
70103+
70104+
client_cbf.certPemFile = "certs/intermediate/client-chain.pem";
70105+
server_cbf.certPemFile = "certs/intermediate/server-chain.pem";
70106+
70107+
server_cbf.caPemFile = caCertFile;
70108+
70109+
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
70110+
&server_cbf, NULL), TEST_SUCCESS);
70111+
70112+
ExpectBufEQ(test_tls_cert_store_unchanged_before_hashes,
70113+
test_tls_cert_store_unchanged_after_hashes,
70114+
sizeof(test_tls_cert_store_unchanged_after_hashes));
70115+
#endif
70116+
return EXPECT_RESULT();
70117+
}
70118+
6997570119
/*----------------------------------------------------------------------------*
6997670120
| Main
6997770121
*----------------------------------------------------------------------------*/
@@ -71281,6 +71425,7 @@ TEST_CASE testCases[] = {
7128171425
TEST_DECL(test_write_dup),
7128271426
TEST_DECL(test_read_write_hs),
7128371427
TEST_DECL(test_get_signature_nid),
71428+
TEST_DECL(test_tls_cert_store_unchanged),
7128471429
/* This test needs to stay at the end to clean up any caches allocated. */
7128571430
TEST_DECL(test_wolfSSL_Cleanup)
7128671431
};

wolfcrypt/src/asn.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23610,6 +23610,28 @@ void FreeSignerTable(Signer** table, int rows, void* heap)
2361023610
}
2361123611
}
2361223612

23613+
void FreeSignerTableType(Signer** table, int rows, byte type, void* heap)
23614+
{
23615+
int i;
23616+
23617+
for (i = 0; i < rows; i++) {
23618+
Signer* signer = table[i];
23619+
Signer** next = &table[i];
23620+
23621+
while (signer) {
23622+
if (signer->type == type) {
23623+
*next = signer->next;
23624+
FreeSigner(signer, heap);
23625+
signer = *next;
23626+
}
23627+
else {
23628+
next = &signer->next;
23629+
signer = signer->next;
23630+
}
23631+
}
23632+
}
23633+
}
23634+
2361323635
#ifdef WOLFSSL_TRUST_PEER_CERT
2361423636
/* Free an individual trusted peer cert.
2361523637
*

wolfssl/ssl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3063,6 +3063,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
30633063
#ifndef NO_CERTS
30643064
/* SSL_CTX versions */
30653065
WOLFSSL_API int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx);
3066+
WOLFSSL_API int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx);
30663067
#ifdef WOLFSSL_TRUST_PEER_CERT
30673068
WOLFSSL_API int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx);
30683069
#ifdef WOLFSSL_LOCAL_X509_STORE
@@ -3617,6 +3618,8 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
36173618
const unsigned char* buff, long sz, int format);
36183619

36193620
WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm);
3621+
WOLFSSL_API int wolfSSL_CertManagerUnloadIntermediateCerts(
3622+
WOLFSSL_CERT_MANAGER* cm);
36203623
#ifdef WOLFSSL_TRUST_PEER_CERT
36213624
WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers(
36223625
WOLFSSL_CERT_MANAGER* cm);

wolfssl/wolfcrypt/asn.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,7 @@ struct Signer {
20222022
byte *sapkiDer;
20232023
int sapkiLen;
20242024
#endif /* WOLFSSL_DUAL_ALG_CERTS */
2025+
byte type;
20252026

20262027
Signer* next;
20272028
};
@@ -2167,6 +2168,8 @@ WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
21672168
WOLFSSL_LOCAL Signer* MakeSigner(void* heap);
21682169
WOLFSSL_LOCAL void FreeSigner(Signer* signer, void* heap);
21692170
WOLFSSL_LOCAL void FreeSignerTable(Signer** table, int rows, void* heap);
2171+
WOLFSSL_LOCAL void FreeSignerTableType(Signer** table, int rows, byte type,
2172+
void* heap);
21702173
#ifdef WOLFSSL_TRUST_PEER_CERT
21712174
WOLFSSL_LOCAL void FreeTrustedPeer(TrustedPeerCert* tp, void* heap);
21722175
WOLFSSL_LOCAL void FreeTrustedPeerTable(TrustedPeerCert** table, int rows,

0 commit comments

Comments
 (0)