diff --git a/tests/api.c b/tests/api.c index 3874969255e..12ac7cd0f9a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4080,6 +4080,35 @@ static int test_wolfSSL_CTX_load_verify_locations(void) return EXPECT_RESULT(); } +/* Load a CA stored in OpenSSL's TRUSTED CERTIFICATE format, as some systems + * ship their CA files. The auxiliary trust data after the certificate must + * not make the CA get rejected. */ +static int test_wolfSSL_CTX_load_verify_locations_trusted_cert(void) +{ + EXPECT_DECLS; +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA) && \ + defined(WOLFSSL_PEM_TO_DER) + WOLFSSL_CTX* ctx = NULL; + WOLFSSL_CERT_MANAGER* cm = NULL; + const char* trusted_cert = "./certs/test/ossl-trusted-cert.pem"; + + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, trusted_cert, NULL), + WOLFSSL_SUCCESS); + + /* The loaded CA is usable, the self signed certificate verifies + * against it. */ + ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(ctx)); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, trusted_cert, + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); + + wolfSSL_CTX_free(ctx); +#endif + + return EXPECT_RESULT(); +} + static int test_wolfSSL_CTX_load_system_CA_certs(void) { int res = TEST_SKIPPED; @@ -46957,6 +46986,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_use_RSAPrivateKey_file), TEST_DECL(test_wolfSSL_CTX_use_PrivateKey), TEST_DECL(test_wolfSSL_CTX_load_verify_locations), + TEST_DECL(test_wolfSSL_CTX_load_verify_locations_trusted_cert), /* Large number of memory allocations. */ TEST_DECL(test_wolfSSL_CTX_load_system_CA_certs), TEST_DECL(test_wolfSSL_CTX_add_extra_chain_cert), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a1d8bae76dc..208cd8e14b9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -27916,6 +27916,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, DerBuffer* der; word32 algId = 0; word32 idx; + int certLen; #ifdef OPENSSL_EXTRA char beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */ char endBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */ @@ -28228,6 +28229,16 @@ int PemToDer(const unsigned char* buff, long longSz, int type, break; } + /* A certificate found under the TRUSTED CERTIFICATE label carries + * auxiliary trust data after it. Keep only the certificate, so it parses + * like one loaded from a CERTIFICATE block. */ + if ((header == BEGIN_TRUSTED_CERT) && (type != TRUSTED_CERT_TYPE)) { + idx = 0; + if (GetSequence(der->buffer, &idx, &certLen, der->length) >= 0) { + der->length = idx + (word32)certLen; + } + } + if ((header == BEGIN_PRIV_KEY #ifdef OPENSSL_EXTRA || header == beginBuf