Juan Lang : crypt32: Implement CertGetPublicKeyLength.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Sep 28 05:26:56 CDT 2006
Module: wine
Branch: master
Commit: 4f11b1af28abb2bf8089422cc935ea22b40586c7
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=4f11b1af28abb2bf8089422cc935ea22b40586c7
Author: Juan Lang <juan_lang at yahoo.com>
Date: Wed Sep 27 23:07:26 2006 -0700
crypt32: Implement CertGetPublicKeyLength.
---
dlls/crypt32/cert.c | 39 +++++++++++++++++++++++
dlls/crypt32/crypt32.spec | 2 +
dlls/crypt32/tests/cert.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 117 insertions(+), 1 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index b131f11..185f133 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -772,6 +772,45 @@ BOOL WINAPI CertComparePublicKeyInfo(DWO
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);
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index ab2c947..8da0dad 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -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
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index f1bec9f..398ef15 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -1903,6 +1903,82 @@ static void testAcquireCertPrivateKey(vo
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();
}
More information about the wine-cvs
mailing list