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

crypt32: ComparePublicKeyInfo must ignore the leading zero.

parent d350998c
...@@ -788,6 +788,9 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, ...@@ -788,6 +788,9 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
{
case 0: /* Seems to mean "raw binary bits" */
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData && if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits) pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
{ {
...@@ -799,6 +802,48 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, ...@@ -799,6 +802,48 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
} }
else else
ret = FALSE; 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; return ret;
} }
......
...@@ -2437,6 +2437,9 @@ static void testComparePublicKeyInfo(void) ...@@ -2437,6 +2437,9 @@ static void testComparePublicKeyInfo(void)
static BYTE bits1[] = { 1, 0 }; static BYTE bits1[] = { 1, 0 };
static BYTE bits2[] = { 0 }; static BYTE bits2[] = { 0 };
static BYTE bits3[] = { 1 }; 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 /* crashes
ret = CertComparePublicKeyInfo(0, NULL, NULL); ret = CertComparePublicKeyInfo(0, NULL, NULL);
...@@ -2460,6 +2463,26 @@ static void testComparePublicKeyInfo(void) ...@@ -2460,6 +2463,26 @@ static void testComparePublicKeyInfo(void)
info2.PublicKey.cUnusedBits = 0; info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(0, &info1, &info2); ret = CertComparePublicKeyInfo(0, &info1, &info2);
ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError()); 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 */ /* Even though they compare in their used bits, these do not compare */
info1.PublicKey.cbData = sizeof(bits2); info1.PublicKey.cbData = sizeof(bits2);
info1.PublicKey.pbData = bits2; info1.PublicKey.pbData = bits2;
...@@ -2475,6 +2498,15 @@ static void testComparePublicKeyInfo(void) ...@@ -2475,6 +2498,15 @@ static void testComparePublicKeyInfo(void)
info2.PublicKey.cUnusedBits = 0; info2.PublicKey.cUnusedBits = 0;
ret = CertComparePublicKeyInfo(0, &info1, &info2); ret = CertComparePublicKeyInfo(0, &info1, &info2);
ok(!ret, "Expected keys not to compare\n"); 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) 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