From 5de817b0c1ef62213c5b90dd8976b4875358c58b Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Wed, 4 Jan 2023 13:44:12 -0500 Subject: [PATCH] Add wolfSSL_CertManagerLoadCABuffer_ex() Also add unit tests. --- src/ssl.c | 20 +++++++--- tests/api.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ wolfssl/ssl.h | 6 ++- 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 33d70b4160..61925bcd84 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7113,14 +7113,14 @@ static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void) } -/* like load verify locations, 1 for success, < 0 for error */ -int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, int format) +int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* in, long sz, + int format, int userChain, word32 flags) { int ret = WOLFSSL_FATAL_ERROR; WOLFSSL_CTX* tmp; - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer"); + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer_ex"); if (cm == NULL) { WOLFSSL_MSG("No CertManager error"); @@ -7137,7 +7137,8 @@ int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, wolfSSL_CertManagerFree(tmp->cm); tmp->cm = cm; - ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format); + ret = wolfSSL_CTX_load_verify_buffer_ex(tmp, in, sz, format, + userChain, flags); /* don't loose our good one */ tmp->cm = NULL; @@ -7146,6 +7147,15 @@ int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, return ret; } +/* like load verify locations, 1 for success, < 0 for error */ +int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* in, long sz, + int format) +{ + return wolfSSL_CertManagerLoadCABuffer_ex(cm, in, sz, format, 0, + WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS); +} + #ifdef HAVE_CRL int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm, diff --git a/tests/api.c b/tests/api.c index 95b010f5aa..71fda4e00e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1491,6 +1491,76 @@ static int test_cm_load_ca_file(const char* ca_cert_file) return ret; } + +static int test_cm_load_ca_buffer_ex(const byte* cert_buf, size_t cert_sz, + int file_type, word32 flags) +{ + int ret; + WOLFSSL_CERT_MANAGER* cm; + + cm = wolfSSL_CertManagerNew(); + if (cm == NULL) { + fprintf(stderr, "test_cm_load_ca failed\n"); + return -1; + } + + ret = wolfSSL_CertManagerLoadCABuffer_ex(cm, cert_buf, cert_sz, file_type, + 0, flags); + + wolfSSL_CertManagerFree(cm); + + return ret; +} + +static int test_cm_load_ca_file_ex(const char* ca_cert_file, word32 flags) +{ + int ret = 0; + byte* cert_buf = NULL; + size_t cert_sz = 0; +#if defined(WOLFSSL_PEM_TO_DER) + DerBuffer* pDer = NULL; +#endif + + ret = load_file(ca_cert_file, &cert_buf, &cert_sz); + if (ret == 0) { + /* normal test */ + ret = test_cm_load_ca_buffer_ex(cert_buf, cert_sz, + WOLFSSL_FILETYPE_PEM, flags); + + if (ret == WOLFSSL_SUCCESS) { + /* test including null terminator in length */ + byte* tmp = (byte*)realloc(cert_buf, cert_sz+1); + if (tmp == NULL) { + ret = MEMORY_E; + } + else { + cert_buf = tmp; + cert_buf[cert_sz] = '\0'; + ret = test_cm_load_ca_buffer_ex(cert_buf, cert_sz+1, + WOLFSSL_FILETYPE_PEM, flags); + } + + } + + #if defined(WOLFSSL_PEM_TO_DER) + if (ret == WOLFSSL_SUCCESS) { + /* test loading DER */ + ret = wc_PemToDer(cert_buf, cert_sz, CA_TYPE, &pDer, NULL, NULL, NULL); + if (ret == 0 && pDer != NULL) { + ret = test_cm_load_ca_buffer_ex(pDer->buffer, pDer->length, + WOLFSSL_FILETYPE_ASN1, flags); + + wc_FreeDer(&pDer); + } + } + #endif + + } + free(cert_buf); + + return ret; +} + #endif /* !NO_FILESYSTEM && !NO_CERTS */ static int test_wolfSSL_CertManagerCheckOCSPResponse(void) @@ -1891,6 +1961,41 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) return res; } +static int test_wolfSSL_CertManagerLoadCABuffer_ex(void) +{ + int res = TEST_SKIPPED; +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) + const char* ca_cert = "./certs/ca-cert.pem"; + const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem"; + int ret; + + ret = test_cm_load_ca_file_ex(ca_cert, WOLFSSL_LOAD_FLAG_NONE); +#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) + AssertIntEQ(ret, WOLFSSL_FATAL_ERROR); +#elif defined(NO_RSA) + AssertIntEQ(ret, ASN_UNKNOWN_OID_E); +#else + AssertIntEQ(ret, WOLFSSL_SUCCESS); +#endif + + ret = test_cm_load_ca_file_ex(ca_expired_cert, + WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY); +#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) + AssertIntEQ(ret, WOLFSSL_FATAL_ERROR); + res = TEST_RES_CHECK(ret == WOLFSSL_FATAL_ERROR); +#elif defined(NO_RSA) + AssertIntEQ(ret, ASN_UNKNOWN_OID_E); + res = TEST_RES_CHECK(ret == ASN_UNKNOWN_OID_E); +#else + AssertIntEQ(ret, WOLFSSL_SUCCESS); + res = TEST_RES_CHECK(ret == WOLFSSL_SUCCESS); +#endif +#endif + + return res; +} + + static int test_wolfSSL_CertManagerGetCerts(void) { int res = TEST_SKIPPED; @@ -59656,6 +59761,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse), TEST_DECL(test_wolfSSL_CheckOCSPResponse), TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer), + TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer_ex), TEST_DECL(test_wolfSSL_CertManagerGetCerts), TEST_DECL(test_wolfSSL_CertManagerSetVerify), TEST_DECL(test_wolfSSL_CertManagerNameConstraint), diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c2877f4047..39bdee59a0 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3566,8 +3566,12 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx, WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* f, const char* d); + WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* in, long sz, int format, int userChain, + word32 flags); WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, int format); + const unsigned char* in, long sz, int format); + WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm); #ifdef WOLFSSL_TRUST_PEER_CERT WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm);