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..78b6c520a 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 WOLFSSL_FILETYPE_PEM or WOLFSSL_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) @@ -6563,7 +6562,7 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, const char* header = NULL; const char* footer = NULL; - if (type != X509_FILETYPE_PEM) + if (type != WOLFSSL_FILETYPE_PEM) return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE); fp = XFOPEN(file, "rb"); @@ -6800,7 +6799,7 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl) /* @param **ret return value of the control command */ /* @return WOLFSSL_SUCCESS on successful, othewise WOLFSSL_FAILURE */ /* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/ -/* yet implemented. It retutns WOLFSSL_NOT_IMPLEMENTED */ +/* yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED */ /* when those control commands are passed. */ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) @@ -6817,7 +6816,7 @@ int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd, WOLFSSL_SUCCESS : WOLFSSL_FAILURE; break; case WOLFSSL_X509_L_ADD_DIR: - /* store directory loaction to use it later */ + /* store directory location to use it later */ #if !defined(NO_WOLFSSL_DIR) lret = x509AddCertDir(ctx->dirs, argc, argl); #else @@ -7417,7 +7416,8 @@ 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 == WOLFSSL_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..9a8127dc6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -50593,7 +50593,7 @@ static int test_wolfSSL_SMIME_write_PKCS7(void) #endif /* !NO_BIO */ /* Test of X509 store use outside of SSL context w/ CRL lookup (ALWAYS - returns 0) */ + * returns 0) */ static int test_X509_STORE_No_SSL_CTX(void) { #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ @@ -50601,16 +50601,17 @@ static int test_X509_STORE_No_SSL_CTX(void) (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"; - XFILE fp; - X509_LOOKUP *lookup; + X509_STORE * store; + X509_STORE_CTX * storeCtx; + X509_CRL * crl; + X509 * ca; + X509 * 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_pem"; + XFILE fp; + X509_LOOKUP * lookup; printf(testingFmt, "test_X509_STORE_No_SSL_CTX"); @@ -50622,7 +50623,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, @@ -50632,7 +50634,7 @@ static int test_X509_STORE_No_SSL_CTX(void) SSL_SUCCESS); /* Add CRL to store NOT containing the verified certificate, which - forces use of the CRL lookup directory */ + * 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, @@ -50647,7 +50649,7 @@ static int test_X509_STORE_No_SSL_CTX(void) AssertIntEQ(X509_STORE_CTX_init(storeCtx, store, cert, NULL), SSL_SUCCESS); /* Perform verification, which should NOT indicate CRL missing due to the - store CM's X509 store pointer being NULL */ + * store CM's X509 store pointer being NULL */ AssertIntNE(X509_verify_cert(storeCtx), CRL_MISSING); X509_CRL_free(crl); @@ -50663,6 +50665,122 @@ static int test_X509_STORE_No_SSL_CTX(void) return 0; } +/* Test of X509 store use outside of SSL context w/ CRL lookup, 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; + X509 * 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 +60919,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,