Fix X509 subject and issuer name_hash mismatch

Use WOLFSSL_ERROR_MSG for errors, don't leak canonName, and better
error handling and comments.
This commit is contained in:
jordan
2022-10-26 10:25:05 -05:00
parent 8b7668f771
commit be07401856

View File

@@ -2993,43 +2993,44 @@ char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name) unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
{ {
#ifndef NO_SHA #ifndef NO_SHA
byte digest[WC_SHA_DIGEST_SIZE]; unsigned long hash = 0;
unsigned long ret = 0; unsigned char* canonName = NULL;
unsigned char* canon_name = NULL; byte digest[WC_SHA_DIGEST_SIZE];
int size = 0; int size = 0;
WOLFSSL_ENTER("wolfSSL_X509_NAME_hash"); WOLFSSL_ENTER("wolfSSL_X509_NAME_hash");
if (name == NULL) { if (name == NULL) {
WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL"); WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
return 0; return 0;
} }
if (name->sz == 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; return 0;
} }
size = wolfSSL_i2d_X509_NAME_canon(name, &canon_name); size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
if (size <= 0){ if (size <= 0 || canonName == NULL) {
WOLFSSL_MSG("wolfSSL_i2d_X509_NAME_canon error"); WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
return 0; return 0;
} }
if (wc_ShaHash((byte*)canon_name, size, digest) != 0) { if (wc_ShaHash((byte*)canonName, size, digest) == 0) {
WOLFSSL_MSG("wc_ShaHash error"); /* 4 bytes in little endian as unsigned long */
return 0; hash = (((unsigned long)digest[3] << 24) |
((unsigned long)digest[2] << 16) |
((unsigned long)digest[1] << 8) |
((unsigned long)digest[0]));
}
else {
WOLFSSL_ERROR_MSG("wc_ShaHash error");
} }
XFREE(canon_name, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
return hash;
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 #else
(void)name; (void)name;
WOLFSSL_MSG("wolfSSL_X509_NAME_hash sha support not compiled in"); WOLFSSL_ERROR_MSG("wolfSSL_X509_NAME_hash sha support not compiled in");
return 0; return 0;
#endif #endif
} }
@@ -4770,14 +4771,18 @@ WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
* wolfSSL_X509_subject_name_hash * wolfSSL_X509_subject_name_hash
* wolfSSL_X509_issuer_name_hash * wolfSSL_X509_issuer_name_hash
* Compute the hash digest of the subject / issuer name. * Compute the hash digest of the subject / issuer name.
* These functions prefers SHA-1 (if available) for compatibility. * These functions prefer SHA-1 (if available) for compatibility. Otherwise
* they use SHA-256.
* *
* RETURNS: * RETURNS:
* The first 4 bytes of SHA hash in little endian order as unsigned long. * The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
* unsigned long.
* Otherwise, returns zero. * Otherwise, returns zero.
*
* Note: * Note:
* Returns the same hash value as OpenSSL's X509_X_name_hash() API * Returns the same hash value as OpenSSL's X509_X_name_hash() API
* if SHA-1 support is compiled in. * 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) unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
{ {
@@ -4786,41 +4791,51 @@ unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
unsigned char* canonName = NULL; unsigned char* canonName = NULL;
byte digest[WC_MAX_DIGEST_SIZE]; byte digest[WC_MAX_DIGEST_SIZE];
int size = 0; int size = 0;
int retHash = NOT_COMPILED_IN;
if (x509 == NULL) { if (x509 == NULL) {
WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
return 0; return 0;
} }
subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509); subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509);
if (subjectName == NULL) { if (subjectName == NULL) {
WOLFSSL_MSG("wolfSSL_X509_get_subject_name error"); WOLFSSL_ERROR_MSG("wolfSSL_X509_get_subject_name error");
return 0; return 0;
} }
size = wolfSSL_i2d_X509_NAME_canon(subjectName, &canonName); size = wolfSSL_i2d_X509_NAME_canon(subjectName, &canonName);
if (size <= 0 || canonName == NULL){ if (size <= 0 || canonName == NULL){
WOLFSSL_MSG("wolfSSL_i2d_X509_NAME_canon error"); WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
return 0; return 0;
} }
#ifndef NO_SHA #ifndef NO_SHA
if (wc_ShaHash((const byte*)canonName, (word32)size, digest) != 0) { retHash = wc_ShaHash((const byte*)canonName, (word32)size, digest);
WOLFSSL_MSG("wc_ShaHash error");
return 0;
}
#elif !defined(NO_SHA256) #elif !defined(NO_SHA256)
if (wc_Sha256Hash((const byte*)canonName, (word32)size, digest) != 0) { retHash = wc_Sha256Hash((const byte*)canonName, (word32)size, digest);
WOLFSSL_MSG("wc_Sha256Hash error"); #else
return 0; retHash = NOT_COMPILED_IN;
}
#endif #endif
hash = (unsigned long) digest[0]; if (retHash == 0) {
hash |= ((unsigned long) digest[1]) << 8; /* 4 bytes in little endian as unsigned long */
hash |= ((unsigned long) digest[2]) << 16; hash = (((unsigned long)digest[3] << 24) |
hash |= ((unsigned long) digest[3]) << 24; ((unsigned long)digest[2] << 16) |
((unsigned long)digest[1] << 8) |
((unsigned long)digest[0]));
}
else {
#ifndef NO_SHA
WOLFSSL_ERROR_MSG("wc_ShaHash error");
#elif !defined(NO_SHA256)
WOLFSSL_ERROR_MSG("wc_Sha256Hash error");
#else
WOLFSSL_ERROR_MSG("wolfSSL_X509_subject_name_hash not compiled in");
#endif
}
XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
@@ -4834,41 +4849,51 @@ unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
unsigned char* canonName = NULL; unsigned char* canonName = NULL;
byte digest[WC_MAX_DIGEST_SIZE]; byte digest[WC_MAX_DIGEST_SIZE];
int size = 0; int size = 0;
int retHash = NOT_COMPILED_IN;
if (x509 == NULL) { if (x509 == NULL) {
WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
return 0; return 0;
} }
issuerName = wolfSSL_X509_get_issuer_name((WOLFSSL_X509*)x509); issuerName = wolfSSL_X509_get_issuer_name((WOLFSSL_X509*)x509);
if (issuerName == NULL) { if (issuerName == NULL) {
WOLFSSL_MSG("wolfSSL_X509_get_issuer_name error"); WOLFSSL_ERROR_MSG("wolfSSL_X509_get_issuer_name error");
return 0; return 0;
} }
size = wolfSSL_i2d_X509_NAME_canon(issuerName, &canonName); size = wolfSSL_i2d_X509_NAME_canon(issuerName, &canonName);
if (size <= 0 || canonName == NULL){ if (size <= 0 || canonName == NULL){
WOLFSSL_MSG("wolfSSL_i2d_X509_NAME_canon error"); WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
return 0; return 0;
} }
#ifndef NO_SHA #ifndef NO_SHA
if (wc_ShaHash((const byte*)canonName, (word32)size, digest) != 0) { retHash = wc_ShaHash((const byte*)canonName, (word32)size, digest);
WOLFSSL_MSG("wc_ShaHash error");
return 0;
}
#elif !defined(NO_SHA256) #elif !defined(NO_SHA256)
if (wc_Sha256Hash((const byte*)canonName, (word32)size, digest) != 0) { retHash = wc_Sha256Hash((const byte*)canonName, (word32)size, digest);
WOLFSSL_MSG("wc_ShaHash error"); #else
return 0; retHash = NOT_COMPILED_IN;
}
#endif #endif
hash = (unsigned long) digest[0]; if (retHash == 0) {
hash |= ((unsigned long) digest[1]) << 8; /* 4 bytes in little endian as unsigned long */
hash |= ((unsigned long) digest[2]) << 16; hash = (((unsigned long)digest[3] << 24) |
hash |= ((unsigned long) digest[3]) << 24; ((unsigned long)digest[2] << 16) |
((unsigned long)digest[1] << 8) |
((unsigned long)digest[0]));
}
else {
#ifndef NO_SHA
WOLFSSL_ERROR_MSG("wc_ShaHash error");
#elif !defined(NO_SHA256)
WOLFSSL_ERROR_MSG("wc_Sha256Hash error");
#else
WOLFSSL_ERROR_MSG("wolfSSL_X509_issuer_name_hash not compiled in");
#endif
}
XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);