Browse Source

Support ASN1/DER CRLs in LoadCertByIssuer.

This fixes hash based dir lookup of ASN1/DER CRLs in OpenSSL
compatible API. The function wolfSSL_X509_load_crl_file is
called with entry->dir_type, rather than hardcoded filetype.

A new test crl was added, and existing crl 0fdb2da4.r0 was
reorganized to a new dir.

Also, completes the stub wolfSSL_X509_LOOKUP_add_dir. A new
test function test_X509_LOOKUP_add_dir was added to tests/api.c
jordan 1 year ago
parent
commit
81ed2a60b4
8 changed files with 132 additions and 17 deletions
  1. BIN
      certs/crl/hash_der/0fdb2da4.r0
  2. 0 0
      certs/crl/hash_pem/0fdb2da4.r0
  3. 1 1
      certs/crl/include.am
  4. 1 1
      src/internal.c
  5. 9 10
      src/x509.c
  6. 119 2
      tests/api.c
  7. 1 0
      wolfssl/openssl/ssl.h
  8. 1 3
      wolfssl/ssl.h

BIN
certs/crl/hash_der/0fdb2da4.r0


+ 0 - 0
certs/crl/0fdb2da4.r0 → certs/crl/hash_pem/0fdb2da4.r0


+ 1 - 1
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 \

+ 1 - 1
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;

+ 9 - 10
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 <hash>.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");

+ 119 - 2
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),

+ 1 - 0
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
 

+ 1 - 3
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,