crypt32: ComparePublicKeyInfo must ignore the leading zero.
This commit is contained in:
parent
d350998cec
commit
c235656aeb
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue