Improved fingerprint hash comparison

* Allow new hash format 11bbccdd along already supported 11:22:aa:BB
This commit is contained in:
Armin Novak 2021-08-26 08:58:39 +02:00 committed by akallabeth
parent 06c883a709
commit 13f54fc0dd
3 changed files with 58 additions and 20 deletions

View File

@ -56,6 +56,8 @@ extern "C"
FREERDP_API CryptoCert crypto_cert_read(BYTE* data, UINT32 length);
FREERDP_API BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length);
FREERDP_API char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash);
FREERDP_API char* crypto_cert_fingerprint_by_hash_ex(X509* xcert, const char* hash,
BOOL separator);
FREERDP_API char* crypto_cert_fingerprint(X509* xcert);
FREERDP_API BYTE* crypto_cert_pem(X509* xcert, STACK_OF(X509) * chain, size_t* length);
FREERDP_API X509* crypto_cert_from_pem(const char* data, size_t length, BOOL fromFile);

View File

@ -275,11 +275,16 @@ BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length)
}
char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)
{
return crypto_cert_fingerprint_by_hash_ex(xcert, hash, 0);
}
char* crypto_cert_fingerprint_by_hash_ex(X509* xcert, const char* hash, BOOL separator)
{
UINT32 fp_len, i;
size_t pos, size;
BYTE* fp;
char* p;
char* fp_buffer;
char* fp_buffer = NULL;
if (!xcert)
{
WLog_ERR(TAG, "Invalid certificate %p", xcert);
@ -294,23 +299,35 @@ char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)
if (!fp)
return NULL;
fp_buffer = calloc(fp_len * 3 + 1, sizeof(char));
size = fp_len * 3 + 1;
fp_buffer = calloc(size, sizeof(char));
if (!fp_buffer)
goto fail;
p = fp_buffer;
pos = 0;
for (i = 0; i < (fp_len - 1); i++)
{
sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 ":", fp[i]);
p = &fp_buffer[(i + 1) * 3];
int rc;
char* p = &fp_buffer[pos];
if (separator)
rc = sprintf_s(p, size - pos, "%02" PRIx8 ":", fp[i]);
else
rc = sprintf_s(p, size - pos, "%02" PRIx8, fp[i]);
if (rc <= 0)
goto fail;
pos += (size_t)rc;
}
sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 "", fp[i]);
fail:
sprintf_s(&fp_buffer[pos], size - pos, "%02" PRIx8 "", fp[i]);
free(fp);
return fp_buffer;
fail:
free(fp);
free(fp_buffer);
return NULL;
}
static char* crypto_print_name(X509_NAME* name)

View File

@ -1176,6 +1176,33 @@ static BOOL is_accepted(rdpTls* tls, const BYTE* pem, size_t length)
return FALSE;
}
static BOOL compare_fingerprint(const char* fp, const char* hash, CryptoCert cert, BOOL separator)
{
BOOL equal;
char* strhash;
WINPR_ASSERT(fp);
WINPR_ASSERT(hash);
WINPR_ASSERT(cert);
strhash = crypto_cert_fingerprint_by_hash_ex(cert->px509, hash, separator);
if (!strhash)
return FALSE;
equal = (_stricmp(strhash, fp) == 0);
free(strhash);
return equal;
}
static BOOL compare_fingerprint_all(const char* fp, const char* hash, CryptoCert cert)
{
if (compare_fingerprint(fp, hash, cert, FALSE))
return TRUE;
if (compare_fingerprint(fp, hash, cert, TRUE))
return TRUE;
return FALSE;
}
static BOOL is_accepted_fingerprint(CryptoCert cert, const char* CertificateAcceptedFingerprints)
{
BOOL rc = FALSE;
@ -1187,30 +1214,22 @@ static BOOL is_accepted_fingerprint(CryptoCert cert, const char* CertificateAcce
while (cur)
{
char* subcontext = NULL;
BOOL equal;
char* strhash;
const char* h = strtok_s(cur, ":", &subcontext);
const char* fp;
if (!h)
continue;
goto next;
fp = h + strlen(h) + 1;
if (!fp)
continue;
goto next;
strhash = crypto_cert_fingerprint_by_hash(cert->px509, h);
if (!strhash)
continue;
equal = (_stricmp(strhash, fp) == 0);
free(strhash);
if (equal)
if (compare_fingerprint_all(fp, h, cert))
{
rc = TRUE;
break;
}
next:
cur = strtok_s(NULL, ",", &context);
}
free(copy);