crypt32: Implement CertGetPublicKeyLength.
This commit is contained in:
parent
ddfba2b459
commit
4f11b1af28
|
@ -772,6 +772,45 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
|
|||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
|
||||
PCERT_PUBLIC_KEY_INFO pPublicKey)
|
||||
{
|
||||
DWORD len = 0;
|
||||
|
||||
TRACE("(%08lx, %p)\n", dwCertEncodingType, pPublicKey);
|
||||
|
||||
if (dwCertEncodingType != X509_ASN_ENCODING)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
if (pPublicKey->Algorithm.pszObjId &&
|
||||
!strcmp(pPublicKey->Algorithm.pszObjId, szOID_RSA_DH))
|
||||
{
|
||||
FIXME("unimplemented for DH public keys\n");
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD size;
|
||||
PBYTE buf;
|
||||
BOOL ret = CryptDecodeObjectEx(dwCertEncodingType,
|
||||
RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
|
||||
pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
|
||||
&size);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)((LPBYTE)buf +
|
||||
sizeof(BLOBHEADER));
|
||||
|
||||
len = rsaPubKey->bitlen;
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
@ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr)
|
||||
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
|
||||
@ stub CertGetPublicKeyLength
|
||||
@ stdcall CertGetPublicKeyLength(long ptr)
|
||||
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
|
||||
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
|
||||
@ stub CertIsRDNAttrsInCertificateName
|
||||
|
|
|
@ -1903,6 +1903,82 @@ static void testAcquireCertPrivateKey(void)
|
|||
CertFreeCertificateContext(cert);
|
||||
}
|
||||
|
||||
static void testGetPublicKeyLength(void)
|
||||
{
|
||||
static char oid_rsa_rsa[] = szOID_RSA_RSA;
|
||||
static char oid_rsa_dh[] = szOID_RSA_DH;
|
||||
static char bogusOID[] = "1.2.3";
|
||||
DWORD ret;
|
||||
CERT_PUBLIC_KEY_INFO info = { { 0 } };
|
||||
BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x02,0x03,0x01,0x00,0x01 };
|
||||
|
||||
/* Crashes
|
||||
ret = CertGetPublicKeyLength(0, NULL);
|
||||
*/
|
||||
/* With an empty public key info */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(0, &info);
|
||||
ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected length 0 and ERROR_FILE_NOT_FOUND, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
|
||||
"Expected length 0 and CRYPT_E_ASN1_EOD, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
/* With a nearly-empty public key info */
|
||||
info.Algorithm.pszObjId = oid_rsa_rsa;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(0, &info);
|
||||
ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected length 0 and ERROR_FILE_NOT_FOUND, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
|
||||
"Expected length 0 and CRYPT_E_ASN1_EOD, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
/* With a bogus key */
|
||||
info.PublicKey.cbData = sizeof(bogusKey);
|
||||
info.PublicKey.pbData = bogusKey;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(0, &info);
|
||||
ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected length 0 and ERROR_FILE_NOT_FOUND, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
||||
"Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
/* With a believable RSA key but a bogus OID */
|
||||
info.Algorithm.pszObjId = bogusOID;
|
||||
info.PublicKey.cbData = sizeof(key);
|
||||
info.PublicKey.pbData = key;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(0, &info);
|
||||
ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected length 0 and ERROR_FILE_NOT_FOUND, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 56, "Expected length 56, got %ld\n", ret);
|
||||
/* An RSA key with the DH OID */
|
||||
info.Algorithm.pszObjId = oid_rsa_dh;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
||||
"Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %ld, %08lx\n",
|
||||
ret, GetLastError());
|
||||
/* With the RSA OID */
|
||||
info.Algorithm.pszObjId = oid_rsa_rsa;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
|
||||
ok(ret == 56, "Expected length 56, got %ld\n", ret);
|
||||
}
|
||||
|
||||
START_TEST(cert)
|
||||
{
|
||||
init_function_pointers();
|
||||
|
@ -1925,4 +2001,5 @@ START_TEST(cert)
|
|||
testCompareCert();
|
||||
testVerifySubjectCert();
|
||||
testAcquireCertPrivateKey();
|
||||
testGetPublicKeyLength();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue