From c421445ba94a8c94822ffb8e1ed4f0cc518f6f6e Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 5 Aug 2020 10:35:43 -0700 Subject: [PATCH 1/2] Added no SHA-1 hash support for OPENSSL compatibility. Fix for `./configure --enable-opensslextra --disable-sha`. This allows using SHA2-256 for the hashing including the derived `issuerHash` and `subjectHash`. Adds issuer hash openssl compatibility function `X509_issuer_name_hash`. --- src/ssl.c | 113 ++++++++++++++++++++---------------------- tests/api.c | 29 +++++++++-- wolfssl/openssl/ssl.h | 3 +- wolfssl/ssl.h | 3 +- 4 files changed, 84 insertions(+), 64 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 989d32761..76a6d4ac7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4141,7 +4141,7 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version) static WC_INLINE word32 MakeWordFromHash(const byte* hashID) { return ((word32)hashID[0] << 24) | ((word32)hashID[1] << 16) | - (hashID[2] << 8) | hashID[3]; + ((word32)hashID[2] << 8) | (word32)hashID[3]; } #endif /* !NO_CERTS || !NO_SESSION_CACHE */ @@ -19783,9 +19783,10 @@ WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert) return NULL; } -#if defined(OPENSSL_EXTRA) && !defined(NO_SHA) +#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. @@ -19795,36 +19796,59 @@ WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert) */ unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509) { - word32 ret = 0; - int retHash; + unsigned long ret = 0; + int retHash = NOT_COMPILED_IN; WOLFSSL_X509_NAME *subjectName = NULL; + byte digest[WC_MAX_DIGEST_SIZE]; -#ifdef WOLFSSL_PIC32MZ_HASH - byte digest[PIC32_DIGEST_SIZE]; -#else - byte digest[WC_SHA_DIGEST_SIZE]; -#endif - - if (x509 == NULL){ - return WOLFSSL_FAILURE; + if (x509 == NULL) { + return ret; } subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509); - - if (subjectName != NULL){ + if (subjectName != NULL) { + #ifndef NO_SHA retHash = wc_ShaHash((const byte*)subjectName->name, (word32)subjectName->sz, digest); - - if(retHash != 0){ - WOLFSSL_MSG("Hash of X509 subjectName has failed"); - return WOLFSSL_FAILURE; + #elif !defined(NO_SHA256) + retHash = wc_Sha256Hash((const byte*)subjectName->name, + (word32)subjectName->sz, digest); + #endif + if (retHash == 0) { + ret = (unsigned long)MakeWordFromHash(digest); } - ret = MakeWordFromHash(digest); } - return (unsigned long)ret; + return ret; } -#endif /* OPENSSL_EXTRA && !NO_SHA */ + +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) @@ -20056,7 +20080,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509) #if defined(OPENSSL_ALL) /* Takes two WOLFSSL_X509* certificates and performs a Sha hash of each, if the - * has values are the same, then it will do an XMEMCMP to confirm they are + * hash values are the same, then it will do an XMEMCMP to confirm they are * identical. Returns a 0 when certificates match, returns a negative number * when certificates are not a match. */ @@ -20068,60 +20092,31 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) int retHashB; int outSzA = 0; int outSzB = 0; - - #ifdef WOLFSSL_PIC32MZ_HASH - byte digestA[PIC32_DIGEST_SIZE]; - byte digestB[PIC32_DIGEST_SIZE]; - #else - byte digestA[WC_SHA_DIGEST_SIZE]; - byte digestB[WC_SHA_DIGEST_SIZE]; - #endif + byte digestA[WC_MAX_DIGEST_SIZE]; + byte digestB[WC_MAX_DIGEST_SIZE]; if (a == NULL || b == NULL){ return BAD_FUNC_ARG; } derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA); - if(derA == NULL){ + if (derA == NULL){ WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed"); return WOLFSSL_FATAL_ERROR; } derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB); - if(derB == NULL){ + if (derB == NULL){ WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed"); return WOLFSSL_FATAL_ERROR; } - retHashA = wc_ShaHash(derA, (word32)outSzA, digestA); - if(retHashA != 0){ - WOLFSSL_MSG("Hash of certificate A has failed"); - return WOLFSSL_FATAL_ERROR; - } - retHashB = wc_ShaHash(derB, (word32)outSzB, digestB); - if(retHashB != 0){ - WOLFSSL_MSG("Hash of certificate B has failed"); - return WOLFSSL_FATAL_ERROR; - } - - if (outSzA == outSzB){ - #ifdef WOLFSSL_PIC32MZ_HASH - if(XMEMCMP(digestA, digestB, PIC32_DIGEST_SIZE) != 0){ - return WOLFSSL_FATAL_ERROR; - } - #else - if(XMEMCMP(digestA, digestB, WC_SHA_DIGEST_SIZE) != 0){ - return WOLFSSL_FATAL_ERROR; - } - #endif - else{ - WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0); - return 0; - } - } - else{ + if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) { WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR); return WOLFSSL_FATAL_ERROR; } + + WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0); + return 0; } #endif /* OPENSSL_ALL */ diff --git a/tests/api.c b/tests/api.c index 2468f73ac..efc4a4248 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23051,7 +23051,7 @@ static void test_wolfSSL_X509_INFO(void) static void test_wolfSSL_X509_subject_name_hash(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \ - && !defined(NO_SHA) && !defined(NO_RSA) + && !defined(NO_RSA) && (!defined(NO_SHA) || !defined(NO_SHA256)) X509* x509; X509_NAME* subjectName = NULL; @@ -23063,10 +23063,32 @@ static void test_wolfSSL_X509_subject_name_hash(void) SSL_FILETYPE_PEM)); AssertNotNull(subjectName = wolfSSL_X509_get_subject_name(x509)); - ret = X509_subject_name_hash(x509); + AssertIntNE(ret, 0); - AssertIntNE(ret, WOLFSSL_FAILURE); + X509_free(x509); + printf(resultFmt, passed); + +#endif +} + +static void 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; + + 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); X509_free(x509); printf(resultFmt, passed); @@ -35529,6 +35551,7 @@ void ApiTest(void) test_wolfSSL_X509_NAME(); test_wolfSSL_X509_INFO(); test_wolfSSL_X509_subject_name_hash(); + test_wolfSSL_X509_issuer_name_hash(); test_wolfSSL_DES(); test_wolfSSL_certs(); test_wolfSSL_ASN1_TIME_print(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 289cb3d98..8b5ee139a 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -379,7 +379,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_issuer_name wolfSSL_X509_get_issuer_name +#define X509_issuer_name_hash wolfSSL_X509_issuer_name_hash #define X509_get_subject_name wolfSSL_X509_get_subject_name +#define X509_subject_name_hash wolfSSL_X509_subject_name_hash #define X509_get_pubkey wolfSSL_X509_get_pubkey #define X509_get0_pubkey wolfSSL_X509_get_pubkey #define X509_get_notBefore wolfSSL_X509_get_notBefore @@ -573,7 +575,6 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_X509_REVOKED_value wolfSSL_sk_X509_REVOKED_value #define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents -#define X509_subject_name_hash wolfSSL_X509_subject_name_hash #define X509_check_purpose(...) 0 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index d0abe090b..dac204653 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1331,8 +1331,10 @@ WOLFSSL_API char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME*, char*, int); #endif WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name( WOLFSSL_X509*); +WOLFSSL_API unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509); WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name( WOLFSSL_X509*); +WOLFSSL_API unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509); WOLFSSL_API int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509*, int); WOLFSSL_API int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509*, int); WOLFSSL_API int wolfSSL_X509_get_isCA(WOLFSSL_X509*); @@ -3895,7 +3897,6 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY** pkey, pem_password_cb* cb, void* u); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey( WOLFSSL_EVP_PKEY** pkey, const unsigned char** data, long length); -WOLFSSL_API unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509); #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ From 435eabfb4b2979e68e1815a854f77f2d43de765e Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 6 Aug 2020 07:51:04 -0700 Subject: [PATCH 2/2] Fix build error with unused variables. Added compat function for `X509_add_ext`. --- src/ssl.c | 4 ---- wolfssl/openssl/ssl.h | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 76a6d4ac7..461f7d3c4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20088,12 +20088,8 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) { const byte* derA; const byte* derB; - int retHashA; - int retHashB; int outSzA = 0; int outSzB = 0; - byte digestA[WC_MAX_DIGEST_SIZE]; - byte digestB[WC_MAX_DIGEST_SIZE]; if (a == NULL || b == NULL){ return BAD_FUNC_ARG; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 8b5ee139a..75d2f71d0 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -417,6 +417,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_email_free wolfSSL_X509_email_free #define X509_check_issued wolfSSL_X509_check_issued #define X509_dup wolfSSL_X509_dup +#define X509_add_ext wolfSSL_X509_add_ext #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object #define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data