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