diff --git a/certs/crl/hash_der/0fdb2da4.r0 b/certs/crl/hash_der/0fdb2da4.r0 new file mode 100644 index 000000000..4ad517125 Binary files /dev/null and b/certs/crl/hash_der/0fdb2da4.r0 differ diff --git a/certs/crl/0fdb2da4.r0 b/certs/crl/hash_pem/0fdb2da4.r0 similarity index 100% rename from certs/crl/0fdb2da4.r0 rename to certs/crl/hash_pem/0fdb2da4.r0 diff --git a/certs/crl/include.am b/certs/crl/include.am index e3e862337..c3fbdb8a6 100644 --- a/certs/crl/include.am +++ b/certs/crl/include.am @@ -3,7 +3,7 @@ # EXTRA_DIST += \ - certs/crl/0fdb2da4.r0 \ + certs/crl/hash_pem/0fdb2da4.r0 \ certs/crl/crl.pem \ certs/crl/cliCrl.pem \ certs/crl/eccSrvCRL.pem \ diff --git a/src/internal.c b/src/internal.c index d95ed8827..4672bfb9a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12712,7 +12712,7 @@ int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) else if (type == X509_LU_CRL) { #if defined(HAVE_CRL) ret = wolfSSL_X509_load_crl_file(&store->lookup, filename, - WOLFSSL_FILETYPE_PEM); + entry->dir_type); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("failed to load CRL"); break; diff --git a/src/x509.c b/src/x509.c index 1ce1e6e37..9c090748f 100644 --- a/src/x509.c +++ b/src/x509.c @@ -6536,17 +6536,16 @@ const char* wolfSSL_X509_verify_cert_error_string(long err) #ifdef OPENSSL_EXTRA -#ifndef NO_WOLFSSL_STUB +/* Add directory path that will be used for loading certs and CRLs + * which have the .rn name format. + * type may be X509_FILETYPE_PEM or X509_FILETYPE_ASN1. + * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */ int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir, - long len) + long type) { - (void)lookup; - (void)dir; - (void)len; - WOLFSSL_STUB("X509_LOOKUP_add_dir"); - return 0; + return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type, + NULL); } -#endif int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, const char* file, long type) @@ -7396,7 +7395,7 @@ WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, return ret; } - if (type == WOLFSSL_FILETYPE_PEM) { + if (type == X509_FILETYPE_PEM) { do { crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL); if (crl == NULL) { @@ -7417,7 +7416,7 @@ WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx, } while(crl == NULL); ret = count; - } else if (type == WOLFSSL_FILETYPE_ASN1) { + } else if (type == X509_FILETYPE_ASN1) { crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL); if (crl == NULL) { WOLFSSL_MSG("Load crl failed"); diff --git a/tests/api.c b/tests/api.c index 8b3b6bf82..3fa546ef3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -50608,7 +50608,7 @@ static int test_X509_STORE_No_SSL_CTX(void) const char cliCrlPem[] = "./certs/crl/cliCrl.pem"; const char srvCert[] = "./certs/server-cert.pem"; const char caCert[] = "./certs/ca-cert.pem"; - const char caDir[] = "./certs/crl"; + const char caDir[] = "./certs/crl/hash_pem/"; XFILE fp; X509_LOOKUP *lookup; @@ -50622,7 +50622,8 @@ static int test_X509_STORE_No_SSL_CTX(void) AssertIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS); /* Add CRL lookup directory to store - NOTE: test uses ./certs/crl/0fdb2da4.r0, which is a copy of crl.pem */ + NOTE: test uses ./certs/crl/hash_pem/0fdb2da4.r0, which is a copy + of crl.pem */ AssertNotNull((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()))); AssertIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR, caDir, @@ -50663,6 +50664,121 @@ static int test_X509_STORE_No_SSL_CTX(void) return 0; } +/* Basically the same test as test_X509_STORE_No_SSL_CTX, but with + * X509_LOOKUP_add_dir and X509_FILETYPE_ASN1. */ +static int test_X509_LOOKUP_add_dir(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_DIR) && defined(HAVE_CRL) && \ + (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \ + (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) + + X509_STORE * store; + X509_STORE_CTX * storeCtx; + X509_CRL * crl; + X509 *ca, * cert; + const char cliCrlPem[] = "./certs/crl/cliCrl.pem"; + const char srvCert[] = "./certs/server-cert.pem"; + const char caCert[] = "./certs/ca-cert.pem"; + const char caDir[] = "./certs/crl/hash_der/"; + XFILE fp; + X509_LOOKUP * lookup; + + printf(testingFmt, "test_X509_LOOKUP_add_dir"); + + AssertNotNull(store = (X509_STORE *)X509_STORE_new()); + + /* Set up store with CA */ + AssertNotNull((ca = wolfSSL_X509_load_certificate_file(caCert, + SSL_FILETYPE_PEM))); + AssertIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS); + + /* Add CRL lookup directory to store. + Test uses ./certs/crl/hash_der/0fdb2da4.r0, which is a copy + of crl.der */ + AssertNotNull((lookup = X509_STORE_add_lookup(store, + X509_LOOKUP_hash_dir()))); + + AssertIntEQ(X509_LOOKUP_add_dir(lookup, caDir, X509_FILETYPE_ASN1), + SSL_SUCCESS); + + AssertIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK), + SSL_SUCCESS); + + /* Add CRL to store NOT containing the verified certificate, which + forces use of the CRL lookup directory */ + fp = XFOPEN(cliCrlPem, "rb"); + AssertTrue((fp != XBADFILE)); + AssertNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, + NULL, NULL)); + XFCLOSE(fp); + AssertIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS); + + /* Create verification context outside of an SSL session */ + AssertNotNull((storeCtx = X509_STORE_CTX_new())); + AssertNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert, + SSL_FILETYPE_PEM))); + AssertIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS); + + /* Perform verification, which should NOT return CRL missing */ + AssertIntNE(X509_verify_cert(storeCtx), CRL_MISSING); + + X509_CRL_free(crl); + X509_STORE_free(store); + X509_STORE_CTX_free(storeCtx); + X509_free(cert); + X509_free(ca); + + /* Now repeat the same, but look for X509_FILETYPE_PEM. + * We should get CRL_MISSING at the end, because the lookup + * dir has only ASN1 CRLs. */ + + AssertNotNull(store = (X509_STORE *)X509_STORE_new()); + + AssertNotNull((ca = wolfSSL_X509_load_certificate_file(caCert, + SSL_FILETYPE_PEM))); + AssertIntEQ(X509_STORE_add_cert(store, ca), SSL_SUCCESS); + + AssertNotNull((lookup = X509_STORE_add_lookup(store, + X509_LOOKUP_hash_dir()))); + + AssertIntEQ(X509_LOOKUP_add_dir(lookup, caDir, X509_FILETYPE_PEM), + SSL_SUCCESS); + + AssertIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK), + SSL_SUCCESS); + + fp = XFOPEN(cliCrlPem, "rb"); + AssertTrue((fp != XBADFILE)); + AssertNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, + NULL, NULL)); + XFCLOSE(fp); + AssertIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS); + + AssertNotNull((storeCtx = X509_STORE_CTX_new())); + AssertNotNull((cert = wolfSSL_X509_load_certificate_file(srvCert, + SSL_FILETYPE_PEM))); + AssertIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS); + + /* Now we SHOULD get CRL_MISSING, because we looked for PEM + in dir containing only ASN1/DER. */ + AssertIntEQ(X509_verify_cert(storeCtx), CRL_MISSING); + + X509_CRL_free(crl); + X509_STORE_free(store); + X509_STORE_CTX_free(storeCtx); + X509_free(cert); + X509_free(ca); + + printf(resultFmt, passed); + +#endif + + return 0; +} + + + /*----------------------------------------------------------------------------* | Certificate Failure Checks *----------------------------------------------------------------------------*/ @@ -60801,6 +60917,7 @@ TEST_CASE testCases[] = { /* OpenSSL compatibility outside SSL context w/ CRL lookup directory */ TEST_DECL(test_X509_STORE_No_SSL_CTX), + TEST_DECL(test_X509_LOOKUP_add_dir), /* wolfCrypt ASN tests */ TEST_DECL(test_wc_CreateEncryptedPKCS8Key), diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6a913203f..d074caef5 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -243,6 +243,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define TLSv1_3_client_method wolfTLSv1_3_client_method #define TLS_method wolfSSLv23_method +#define X509_FILETYPE_PEM WOLFSSL_FILETYPE_PEM #define X509_FILETYPE_ASN1 WOLFSSL_FILETYPE_ASN1 #define X509_FILETYPE_DEFAULT WOLFSSL_FILETYPE_DEFAULT diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b939b3d50..c0e27b301 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1927,7 +1927,7 @@ WOLFSSL_API int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509, unsigned char int* bufSz); WOLFSSL_API int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509); -WOLFSSL_API int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup,const char* dir,long len); +WOLFSSL_API int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup,const char* dir,long type); WOLFSSL_API int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, const char* file, long type); WOLFSSL_API WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void); @@ -2377,8 +2377,6 @@ enum { */ SSL_MODE_RELEASE_BUFFERS = -1, /* For libwebsockets build. No current use. */ - X509_FILETYPE_PEM = 8, - /* Not all of these are actually used in wolfSSL. Some are included to * satisfy OpenSSL compatibility consumers to prevent compilation errors. */ X509_V_OK = 0,