forked from wolfSSL/wolfssl
Implement transient certs
Add wolfSSL_CertManagerUnloadIntermediateCerts API to clear intermediate certs added to store.
This commit is contained in:
17
src/ssl.c
17
src/ssl.c
@ -5954,6 +5954,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
||||
cert->permittedNames = NULL;
|
||||
cert->excludedNames = NULL;
|
||||
#endif
|
||||
signer->type = (byte)type;
|
||||
|
||||
#ifndef NO_SKID
|
||||
row = HashSigner(signer->subjectKeyIdHash);
|
||||
@ -16355,6 +16356,22 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
return wolfSSL_CertManagerUnloadCAs(ctx->cm);
|
||||
}
|
||||
|
||||
int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (ctx->ref.count > 1) {
|
||||
WOLFSSL_MSG("ctx object must have a ref count of 1 before "
|
||||
"unloading intermediate certs");
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
return wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
|
||||
|
@ -457,6 +457,31 @@ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_CertManagerUnloadIntermediateCerts(WOLFSSL_CERT_MANAGER* cm)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_CertManagerUnloadIntermediateCerts");
|
||||
|
||||
/* Validate parameter. */
|
||||
if (cm == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
/* Lock CA table. */
|
||||
if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) {
|
||||
ret = BAD_MUTEX_E;
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
/* Dispose of CA table. */
|
||||
FreeSignerTableType(cm->caTable, CA_TABLE_SIZE, WOLFSSL_CHAIN_CA,
|
||||
cm->heap);
|
||||
|
||||
/* Unlock CA table. */
|
||||
wc_UnLockMutex(&cm->caLock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
/* Unload the trusted peers table.
|
||||
|
181
tests/api.c
181
tests/api.c
@ -441,6 +441,7 @@ typedef struct test_ssl_cbf {
|
||||
ctx_cb ctx_ready;
|
||||
ssl_cb ssl_ready;
|
||||
ssl_cb on_result;
|
||||
ctx_cb on_ctx_cleanup;
|
||||
ssl_cb on_cleanup;
|
||||
hs_cb on_handshake;
|
||||
WOLFSSL_CTX* ctx;
|
||||
@ -6149,8 +6150,10 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
|
||||
int c_sharedCtx = 0;
|
||||
int s_sharedCtx = 0;
|
||||
#endif
|
||||
const char* certFile = svrCertFile;
|
||||
const char* keyFile = svrKeyFile;
|
||||
const char* clientCertFile = cliCertFile;
|
||||
const char* clientKeyFile = cliKeyFile;
|
||||
const char* serverCertFile = svrCertFile;
|
||||
const char* serverKeyFile = svrKeyFile;
|
||||
|
||||
/********************************
|
||||
* Create WOLFSSL_CTX for client.
|
||||
@ -6182,13 +6185,19 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
|
||||
else
|
||||
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
|
||||
caCertFile, 0), WOLFSSL_SUCCESS);
|
||||
if (ctx->c_cb.certPemFile != NULL) {
|
||||
clientCertFile = ctx->c_cb.certPemFile;
|
||||
}
|
||||
if (ctx->c_cb.keyPemFile != NULL) {
|
||||
clientKeyFile = ctx->c_cb.keyPemFile;
|
||||
}
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
|
||||
if (!c_sharedCtx)
|
||||
#endif
|
||||
{
|
||||
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx,
|
||||
cliCertFile), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, cliKeyFile,
|
||||
clientCertFile), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
||||
}
|
||||
#ifdef HAVE_CRL
|
||||
@ -6255,23 +6264,23 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
|
||||
wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack);
|
||||
#endif
|
||||
if (ctx->s_cb.certPemFile != NULL) {
|
||||
certFile = ctx->s_cb.certPemFile;
|
||||
serverCertFile = ctx->s_cb.certPemFile;
|
||||
}
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
|
||||
if (!s_sharedCtx)
|
||||
#endif
|
||||
{
|
||||
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx,
|
||||
certFile), WOLFSSL_SUCCESS);
|
||||
serverCertFile), WOLFSSL_SUCCESS);
|
||||
}
|
||||
if (ctx->s_cb.keyPemFile != NULL) {
|
||||
keyFile = ctx->s_cb.keyPemFile;
|
||||
serverKeyFile = ctx->s_cb.keyPemFile;
|
||||
}
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
|
||||
if (!s_sharedCtx)
|
||||
#endif
|
||||
{
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, keyFile,
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
||||
}
|
||||
if (ctx->s_ciphers != NULL) {
|
||||
@ -6295,9 +6304,9 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl, cliCertFile),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, cliKeyFile,
|
||||
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl,
|
||||
clientCertFile), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
||||
}
|
||||
if (ctx->c_cb.ssl_ready != NULL) {
|
||||
@ -6316,9 +6325,9 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl, certFile),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, keyFile,
|
||||
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl,
|
||||
serverCertFile), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
||||
}
|
||||
#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,
|
||||
}
|
||||
}
|
||||
|
||||
if (!handshake_complete) {
|
||||
if (!handshake_complete || failing_c || failing_s) {
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
@ -6468,14 +6477,20 @@ static void test_ssl_memio_cleanup(test_ssl_memio_ctx* ctx)
|
||||
wolfSSL_shutdown(ctx->c_ssl);
|
||||
wolfSSL_free(ctx->s_ssl);
|
||||
wolfSSL_free(ctx->c_ssl);
|
||||
if (!ctx->s_cb.isSharedCtx) {
|
||||
wolfSSL_CTX_free(ctx->s_ctx);
|
||||
ctx->s_ctx = NULL;
|
||||
if (ctx->c_cb.on_ctx_cleanup != NULL) {
|
||||
ctx->c_cb.on_ctx_cleanup(ctx->c_ctx);
|
||||
}
|
||||
if (!ctx->c_cb.isSharedCtx) {
|
||||
wolfSSL_CTX_free(ctx->c_ctx);
|
||||
ctx->c_ctx = NULL;
|
||||
}
|
||||
if (ctx->s_cb.on_ctx_cleanup != NULL) {
|
||||
ctx->s_cb.on_ctx_cleanup(ctx->s_ctx);
|
||||
}
|
||||
if (!ctx->s_cb.isSharedCtx) {
|
||||
wolfSSL_CTX_free(ctx->s_ctx);
|
||||
ctx->s_ctx = NULL;
|
||||
}
|
||||
|
||||
if (!ctx->s_cb.ticNoInit) {
|
||||
#if defined(HAVE_SESSION_TICKET) && \
|
||||
@ -69972,6 +69987,135 @@ static int test_get_signature_nid(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
|
||||
static word32 test_tls_cert_store_unchanged_HashCaTable(Signer** caTable)
|
||||
{
|
||||
#ifndef NO_MD5
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_MD5;
|
||||
#elif !defined(NO_SHA)
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
|
||||
#elif !defined(NO_SHA256)
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
|
||||
#else
|
||||
#error "We need a digest to hash the Signer object"
|
||||
#endif
|
||||
byte hashBuf[WC_MAX_DIGEST_SIZE];
|
||||
wc_HashAlg hash;
|
||||
size_t i;
|
||||
|
||||
AssertIntEQ(wc_HashInit(&hash, hashType), 0);
|
||||
for (i = 0; i < CA_TABLE_SIZE; i++) {
|
||||
Signer* cur;
|
||||
for (cur = caTable[i]; cur != NULL; cur = cur->next)
|
||||
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)cur,
|
||||
sizeof(*cur)), 0);
|
||||
}
|
||||
AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
|
||||
AssertIntEQ(wc_HashFree(&hash, hashType), 0);
|
||||
|
||||
return MakeWordFromHash(hashBuf);
|
||||
}
|
||||
|
||||
static word32 test_tls_cert_store_unchanged_before_hashes[2];
|
||||
static size_t test_tls_cert_store_unchanged_before_hashes_idx = 0;
|
||||
static word32 test_tls_cert_store_unchanged_after_hashes[2];
|
||||
static size_t test_tls_cert_store_unchanged_after_hashes_idx = 0;
|
||||
|
||||
static int test_tls_cert_store_unchanged_ctx_ready(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
|
||||
ExpectIntNE(test_tls_cert_store_unchanged_before_hashes
|
||||
[test_tls_cert_store_unchanged_before_hashes_idx++] =
|
||||
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
|
||||
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER |
|
||||
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_tls_cert_store_unchanged_ctx_cleanup(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
ExpectIntEQ(wolfSSL_CTX_UnloadIntermediateCerts(ctx), WOLFSSL_SUCCESS);
|
||||
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
|
||||
[test_tls_cert_store_unchanged_after_hashes_idx++] =
|
||||
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*
|
||||
static int test_tls_cert_store_unchanged_on_hs(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
|
||||
(void)ssl;
|
||||
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
|
||||
[test_tls_cert_store_unchanged_after_hashes_idx++] =
|
||||
test_tls_cert_store_unchanged_HashCaTable((*ctx)->cm->caTable), 0);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
*/
|
||||
|
||||
static int test_tls_cert_store_unchanged_ssl_ready(WOLFSSL* ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX* ctx;
|
||||
|
||||
ExpectNotNull(ctx = wolfSSL_get_SSL_CTX(ssl));
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_tls_cert_store_unchanged(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
|
||||
test_ssl_cbf client_cbf;
|
||||
test_ssl_cbf server_cbf;
|
||||
|
||||
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
|
||||
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
|
||||
|
||||
XMEMSET(test_tls_cert_store_unchanged_before_hashes, 0,
|
||||
sizeof(test_tls_cert_store_unchanged_before_hashes));
|
||||
XMEMSET(test_tls_cert_store_unchanged_after_hashes, 0,
|
||||
sizeof(test_tls_cert_store_unchanged_after_hashes));
|
||||
|
||||
client_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
|
||||
server_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
|
||||
|
||||
client_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
|
||||
server_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
|
||||
|
||||
/* TODO add API to allow clearing/not storing certs while connections are
|
||||
* still active.
|
||||
client_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
|
||||
server_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
|
||||
*/
|
||||
|
||||
client_cbf.on_ctx_cleanup = test_tls_cert_store_unchanged_ctx_cleanup;
|
||||
server_cbf.on_ctx_cleanup = test_tls_cert_store_unchanged_ctx_cleanup;
|
||||
|
||||
client_cbf.certPemFile = "certs/intermediate/client-chain.pem";
|
||||
server_cbf.certPemFile = "certs/intermediate/server-chain.pem";
|
||||
|
||||
server_cbf.caPemFile = caCertFile;
|
||||
|
||||
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
|
||||
&server_cbf, NULL), TEST_SUCCESS);
|
||||
|
||||
ExpectBufEQ(test_tls_cert_store_unchanged_before_hashes,
|
||||
test_tls_cert_store_unchanged_after_hashes,
|
||||
sizeof(test_tls_cert_store_unchanged_after_hashes));
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -71281,6 +71425,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_write_dup),
|
||||
TEST_DECL(test_read_write_hs),
|
||||
TEST_DECL(test_get_signature_nid),
|
||||
TEST_DECL(test_tls_cert_store_unchanged),
|
||||
/* This test needs to stay at the end to clean up any caches allocated. */
|
||||
TEST_DECL(test_wolfSSL_Cleanup)
|
||||
};
|
||||
|
@ -23610,6 +23610,28 @@ void FreeSignerTable(Signer** table, int rows, void* heap)
|
||||
}
|
||||
}
|
||||
|
||||
void FreeSignerTableType(Signer** table, int rows, byte type, void* heap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
Signer* signer = table[i];
|
||||
Signer** next = &table[i];
|
||||
|
||||
while (signer) {
|
||||
if (signer->type == type) {
|
||||
*next = signer->next;
|
||||
FreeSigner(signer, heap);
|
||||
signer = *next;
|
||||
}
|
||||
else {
|
||||
next = &signer->next;
|
||||
signer = signer->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
/* Free an individual trusted peer cert.
|
||||
*
|
||||
|
@ -3063,6 +3063,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
|
||||
#ifndef NO_CERTS
|
||||
/* SSL_CTX versions */
|
||||
WOLFSSL_API int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx);
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
WOLFSSL_API int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx);
|
||||
#ifdef WOLFSSL_LOCAL_X509_STORE
|
||||
@ -3617,6 +3618,8 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
|
||||
const unsigned char* buff, long sz, int format);
|
||||
|
||||
WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm);
|
||||
WOLFSSL_API int wolfSSL_CertManagerUnloadIntermediateCerts(
|
||||
WOLFSSL_CERT_MANAGER* cm);
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers(
|
||||
WOLFSSL_CERT_MANAGER* cm);
|
||||
|
@ -2022,6 +2022,7 @@ struct Signer {
|
||||
byte *sapkiDer;
|
||||
int sapkiLen;
|
||||
#endif /* WOLFSSL_DUAL_ALG_CERTS */
|
||||
byte type;
|
||||
|
||||
Signer* next;
|
||||
};
|
||||
@ -2167,6 +2168,8 @@ WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
|
||||
WOLFSSL_LOCAL Signer* MakeSigner(void* heap);
|
||||
WOLFSSL_LOCAL void FreeSigner(Signer* signer, void* heap);
|
||||
WOLFSSL_LOCAL void FreeSignerTable(Signer** table, int rows, void* heap);
|
||||
WOLFSSL_LOCAL void FreeSignerTableType(Signer** table, int rows, byte type,
|
||||
void* heap);
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
WOLFSSL_LOCAL void FreeTrustedPeer(TrustedPeerCert* tp, void* heap);
|
||||
WOLFSSL_LOCAL void FreeTrustedPeerTable(TrustedPeerCert** table, int rows,
|
||||
|
Reference in New Issue
Block a user