Commit c235656a authored by Michael Karcher's avatar Michael Karcher Committed by Alexandre Julliard

crypt32: ComparePublicKeyInfo must ignore the leading zero.

parent d350998c
......@@ -788,17 +788,62 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
{
if (pPublicKey2->PublicKey.cbData)
ret = !memcmp(pPublicKey1->PublicKey.pbData,
pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
case 0: /* Seems to mean "raw binary bits" */
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
{
if (pPublicKey2->PublicKey.cbData)
ret = !memcmp(pPublicKey1->PublicKey.pbData,
pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
else
ret = TRUE;
}
else
ret = TRUE;
}
else
ret = FALSE;
break;
default:
WARN("Unknown encoding type %08x\n", dwCertEncodingType);
/* FALLTHROUGH */
case X509_ASN_ENCODING:
{
BLOBHEADER *pblob1, *pblob2;
DWORD length;
ret = FALSE;
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
0, NULL, &length))
{
pblob1 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
0, pblob1, &length))
{
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
0, NULL, &length))
{
pblob2 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
0, pblob2, &length))
{
/* The RSAPUBKEY structure directly follows the BLOBHEADER */
RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
*pk2 = (LPVOID)(pblob2 + 1);
ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
&& !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
}
CryptMemFree(pblob2);
}
}
CryptMemFree(pblob1);
}
break;
}
}
return ret;
}
......
......@@ -2437,6 +2437,9 @@ static void testComparePublicKeyInfo(void)
static BYTE bits1[] = { 1, 0 };
static BYTE bits2[] = { 0 };
static BYTE bits3[] = { 1 };
static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 };
static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 };
static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 };
/* crashes
ret = CertComparePublicKeyInfo(0, NULL, NULL);
......@@ -2460,6 +2463,26 @@ static void testComparePublicKeyInfo(void)
info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(0, &info1, &info2);
ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
info2.Algorithm.pszObjId = oid_rsa_rsa;
info1.PublicKey.cbData = sizeof(bits4);
info1.PublicKey.pbData = bits4;
info1.PublicKey.cUnusedBits = 0;
info2.PublicKey.cbData = sizeof(bits5);
info2.PublicKey.pbData = bits5;
info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(0, &info1, &info2);
ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
ok(ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
info1.PublicKey.cUnusedBits = 1;
info2.PublicKey.cUnusedBits = 5;
ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
ok(ret, "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
info1.PublicKey.cUnusedBits = 0;
info2.PublicKey.cUnusedBits = 0;
info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
/* Even though they compare in their used bits, these do not compare */
info1.PublicKey.cbData = sizeof(bits2);
info1.PublicKey.pbData = bits2;
......@@ -2475,6 +2498,15 @@ static void testComparePublicKeyInfo(void)
info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(0, &info1, &info2);
ok(!ret, "Expected keys not to compare\n");
/* ASN.1 encoded non-comparing case */
info1.PublicKey.cbData = sizeof(bits5);
info1.PublicKey.pbData = bits5;
info1.PublicKey.cUnusedBits = 0;
info2.PublicKey.cbData = sizeof(bits6);
info2.PublicKey.pbData = bits6;
info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
}
static void testHashPublicKeyInfo(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment