Commit 4f11b1af authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Implement CertGetPublicKeyLength.

parent ddfba2b4
......@@ -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();
}
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