Browse Source

Merge pull request #5730 from philljj/zd15040

Hayden Roche 1 year ago
parent
commit
5d70f3efce
2 changed files with 127 additions and 103 deletions
  1. 89 91
      src/x509.c
  2. 38 12
      tests/api.c

+ 89 - 91
src/x509.c

@@ -2990,48 +2990,113 @@ char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
 }
 
 #ifdef OPENSSL_EXTRA
-unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
+/* Given an X509_NAME, convert it to canonical form and then hash
+ * with the provided hash type. Returns the first 4 bytes of the hash
+ * as unsigned long on success, and 0 otherwise. */
+static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
+    enum wc_HashType hashType)
 {
-#ifndef NO_SHA
-    byte digest[WC_SHA_DIGEST_SIZE];
-    unsigned long ret = 0;
-    unsigned char* canon_name = NULL;
-    int size = 0;
+    unsigned long  hash = 0;
+    unsigned char* canonName = NULL;
+    byte           digest[WC_MAX_DIGEST_SIZE];
+    int            size = 0;
+    int            rc;
+
+    WOLFSSL_ENTER("X509NameHash");
 
-    WOLFSSL_ENTER("wolfSSL_X509_NAME_hash");
     if (name == NULL) {
-        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
+        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
         return 0;
     }
+
     if (name->sz == 0) {
-        WOLFSSL_MSG("nothing to hash in WOLFSSL_X509_NAME");
+        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
         return 0;
     }
 
-    size = wolfSSL_i2d_X509_NAME_canon(name, &canon_name);
+    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
 
-    if (size <= 0){
-        WOLFSSL_MSG("wolfSSL_i2d_X509_NAME_canon error");
+    if (size <= 0 || canonName == NULL) {
+        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
         return 0;
     }
 
-    if (wc_ShaHash((byte*)canon_name, size, digest) != 0) {
-        WOLFSSL_MSG("wc_ShaHash error");
+    rc = wc_Hash(hashType, (const byte*)canonName,(word32)size, digest,
+        sizeof(digest));
+
+    if (rc == 0) {
+        hash = (((unsigned long)digest[3] << 24) |
+                ((unsigned long)digest[2] << 16) |
+                ((unsigned long)digest[1] <<  8) |
+                ((unsigned long)digest[0]));
+    }
+    else if (rc == HASH_TYPE_E) {
+        WOLFSSL_ERROR_MSG("Hash function not compiled in");
+    }
+    else {
+        WOLFSSL_ERROR_MSG("Error hashing name");
+    }
+
+    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
+    return hash;
+}
+
+unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
+{
+    return X509NameHash(name, WC_HASH_TYPE_SHA);
+}
+
+/******************************************************************************
+* wolfSSL_X509_subject_name_hash
+* wolfSSL_X509_issuer_name_hash
+* Compute the hash digest of the subject / issuer name.
+* These functions prefer SHA-1 (if available) for compatibility. Otherwise
+* they use SHA-256.
+*
+* RETURNS:
+* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
+* unsigned long.
+* Otherwise, returns zero.
+*
+* Note:
+* Returns the same hash value as OpenSSL's X509_X_name_hash() API
+* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
+* not available.
+*/
+unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
+{
+    if (x509 == NULL) {
+        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
         return 0;
     }
 
-    XFREE(canon_name, NULL, DYNAMIC_TYPE_OPENSSL);
+    #ifndef NO_SHA
+    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
+    #elif !defined(NO_SHA256)
+    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
+                        WC_HASH_TYPE_SHA256);
+    #else
+    WOLFSSL_ERROR_MSG("Hash function not compiled in");
+    return 0;
+    #endif
+}
+
+unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
+{
+    if (x509 == NULL) {
+        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
+        return 0;
+    }
 
-    ret  =  (unsigned long) digest[0];
-    ret |= ((unsigned long) digest[1]) << 8;
-    ret |= ((unsigned long) digest[2]) << 16;
-    ret |= ((unsigned long) digest[3]) << 24;
-    return ret;
-#else
-    (void)name;
-    WOLFSSL_MSG("wolfSSL_X509_NAME_hash sha support not compiled in");
+    #ifndef NO_SHA
+    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
+    #elif !defined(NO_SHA256)
+    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
+                        WC_HASH_TYPE_SHA256);
+    #else
+    WOLFSSL_ERROR_MSG("Hash function not compiled in");
     return 0;
-#endif
+    #endif
 }
 #endif /* OPENSSL_EXTRA */
 
@@ -4765,73 +4830,6 @@ WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
     return NULL;
 }
 
-#if defined(OPENSSL_EXTRA) && (!defined(NO_SHA) || !defined(NO_SHA256))
-/******************************************************************************
-* wolfSSL_X509_subject_name_hash - compute the hash digest of the raw subject name
-* This function prefers SHA-1 (if available) for compatibility
-*
-* RETURNS:
-* The beginning of the hash digest. Otherwise, returns zero.
-* Note:
-* Returns a different hash value from OpenSSL's X509_subject_name_hash() API
-* depending on the subject name.
-*/
-unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
-{
-    unsigned long ret = 0;
-    int retHash = NOT_COMPILED_IN;
-    WOLFSSL_X509_NAME *subjectName = NULL;
-    byte digest[WC_MAX_DIGEST_SIZE];
-
-    if (x509 == NULL) {
-        return ret;
-    }
-
-    subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509);
-    if (subjectName != NULL) {
-    #ifndef NO_SHA
-        retHash = wc_ShaHash((const byte*)subjectName->name,
-                             (word32)subjectName->sz, digest);
-    #elif !defined(NO_SHA256)
-        retHash = wc_Sha256Hash((const byte*)subjectName->name,
-                                (word32)subjectName->sz, digest);
-    #endif
-        if (retHash == 0) {
-            ret = (unsigned long)MakeWordFromHash(digest);
-        }
-    }
-
-    return ret;
-}
-
-unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
-{
-    unsigned long ret = 0;
-    int retHash = NOT_COMPILED_IN;
-    WOLFSSL_X509_NAME *issuerName = NULL;
-    byte digest[WC_MAX_DIGEST_SIZE];
-
-    if (x509 == NULL) {
-        return ret;
-    }
-
-    issuerName = wolfSSL_X509_get_issuer_name((WOLFSSL_X509*)x509);
-    if (issuerName != NULL) {
-    #ifndef NO_SHA
-        retHash = wc_ShaHash((const byte*)issuerName->name,
-                             (word32)issuerName->sz, digest);
-    #elif !defined(NO_SHA256)
-        retHash = wc_Sha256Hash((const byte*)issuerName->name,
-                                (word32)issuerName->sz, digest);
-    #endif
-        if (retHash == 0) {
-            ret = (unsigned long)MakeWordFromHash(digest);
-        }
-    }
-    return ret;
-}
-#endif /* OPENSSL_EXTRA && (!NO_SHA || !NO_SHA256) */
-
 WOLFSSL_ABI
 WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
 {

+ 38 - 12
tests/api.c

@@ -31472,25 +31472,38 @@ static int test_wolfSSL_X509_subject_name_hash(void)
 {
 #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
     && !defined(NO_RSA) && (!defined(NO_SHA) || !defined(NO_SHA256))
-
     X509* x509;
     X509_NAME* subjectName = NULL;
-    unsigned long ret = 0;
+    unsigned long ret1 = 0;
+    unsigned long ret2 = 0;
 
     printf(testingFmt, "wolfSSL_X509_subject_name_hash()");
 
     AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                 SSL_FILETYPE_PEM));
-
     AssertNotNull(subjectName = wolfSSL_X509_get_subject_name(x509));
-    ret = X509_subject_name_hash(x509);
-    AssertIntNE(ret, 0);
+
+    /* These two
+     *   - X509_subject_name_hash(x509)
+     *   - X509_NAME_hash(X509_get_subject_name(x509))
+     *  should give the same hash, if !defined(NO_SHA) is true. */
+
+    ret1 = X509_subject_name_hash(x509);
+    AssertIntNE(ret1, 0);
+
+#if !defined(NO_SHA)
+    ret2 = X509_NAME_hash(X509_get_subject_name(x509));
+    AssertIntNE(ret2, 0);
+
+    AssertIntEQ(ret1, ret2);
+#else
+    (void) ret2;
+#endif
 
     X509_free(x509);
     printf(resultFmt, passed);
 
 #endif
-
     return 0;
 }
 
@@ -31498,25 +31511,38 @@ static int test_wolfSSL_X509_issuer_name_hash(void)
 {
 #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
     && !defined(NO_RSA) && (!defined(NO_SHA) || !defined(NO_SHA256))
-
     X509* x509;
     X509_NAME* issuertName = NULL;
-    unsigned long ret = 0;
+    unsigned long ret1 = 0;
+    unsigned long ret2 = 0;
 
     printf(testingFmt, "wolfSSL_X509_issuer_name_hash()");
 
     AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
                 SSL_FILETYPE_PEM));
-
     AssertNotNull(issuertName = wolfSSL_X509_get_issuer_name(x509));
-    ret = X509_issuer_name_hash(x509);
-    AssertIntNE(ret, 0);
+
+    /* These two
+     *   - X509_issuer_name_hash(x509)
+     *   - X509_NAME_hash(X509_get_issuer_name(x509))
+     *  should give the same hash, if !defined(NO_SHA) is true. */
+
+    ret1 = X509_issuer_name_hash(x509);
+    AssertIntNE(ret1, 0);
+
+#if !defined(NO_SHA)
+    ret2 = X509_NAME_hash(X509_get_issuer_name(x509));
+    AssertIntNE(ret2, 0);
+
+    AssertIntEQ(ret1, ret2);
+#else
+    (void) ret2;
+#endif
 
     X509_free(x509);
     printf(resultFmt, passed);
 
 #endif
-
     return 0;
 }