v2: Move the tests to crypt32.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/tests/cert.c | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 745770f0095..3f50fad482c 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -28,6 +28,7 @@ #include <winreg.h> #include <winerror.h> #include <wincrypt.h> +#include <bcrypt.h>
#include "wine/test.h"
@@ -42,10 +43,22 @@ static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx) static BOOL (WINAPI * pCryptAcquireContextA) (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
+static NTSTATUS (WINAPI *pBCryptCloseAlgorithmProvider)(BCRYPT_ALG_HANDLE, ULONG); +static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, + ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE); +static NTSTATUS (WINAPI *pBCryptDestroyKey)(BCRYPT_KEY_HANDLE); +static NTSTATUS (WINAPI *pBCryptFinishHash)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptHashData)(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); +static NTSTATUS (WINAPI *pBCryptGetProperty)(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG); +static NTSTATUS (WINAPI *pBCryptOpenAlgorithmProvider)(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG); +static NTSTATUS (WINAPI *pBCryptVerifySignature)(BCRYPT_KEY_HANDLE, VOID *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG); + static void init_function_pointers(void) { HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll"); + HMODULE hBcrypt = LoadLibraryA("bcrypt.dll");
#define GET_PROC(dll, func) \ p ## func = (void *)GetProcAddress(dll, #func); \ @@ -61,6 +74,16 @@ static void init_function_pointers(void)
GET_PROC(hAdvapi32, CryptAcquireContextA)
+ GET_PROC(hBcrypt, BCryptCloseAlgorithmProvider) + GET_PROC(hBcrypt, BCryptCreateHash) + GET_PROC(hBcrypt, BCryptDestroyHash) + GET_PROC(hBcrypt, BCryptDestroyKey) + GET_PROC(hBcrypt, BCryptFinishHash) + GET_PROC(hBcrypt, BCryptHashData) + GET_PROC(hBcrypt, BCryptGetProperty) + GET_PROC(hBcrypt, BCryptOpenAlgorithmProvider) + GET_PROC(hBcrypt, BCryptVerifySignature) + #undef GET_PROC }
@@ -4237,6 +4260,98 @@ static void testKeyProvInfo(void) CertCloseStore(store, 0); }
+static void test_VerifySignature(void) +{ + PCCERT_CONTEXT cert; + PCERT_SIGNED_CONTENT_INFO info; + DWORD size; + BOOL ret; + HCRYPTPROV prov; + HCRYPTKEY key; + HCRYPTHASH hash; + BYTE hash_value[20], *sig_value; + DWORD hash_len, i; + BCRYPT_KEY_HANDLE bkey; + BCRYPT_HASH_HANDLE bhash; + BCRYPT_ALG_HANDLE alg; + BCRYPT_PKCS1_PADDING_INFO pad; + NTSTATUS status; + + cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert)); + ok(cert != NULL, "CertCreateCertificateContext error %#x\n", GetLastError()); + + /* 1. Verify certificate signature with Crypto API */ + ret = CryptVerifyCertificateSignature(0, cert->dwCertEncodingType, + cert->pbCertEncoded, cert->cbCertEncoded, &cert->pCertInfo->SubjectPublicKeyInfo); + ok(ret, "CryptVerifyCertificateSignature error %#x\n", GetLastError()); + + /* 2. Verify certificate signature with Crypto API manually */ + ret = pCryptAcquireContextA(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContext error %#x\n", GetLastError()); + + ret = CryptImportPublicKeyInfoEx(prov, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key); + ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError()); + + ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_CERT, + cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx error %#x\n", GetLastError()); + + ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash); + ok(ret, "CryptCreateHash error %#x\n", GetLastError()); + + ret = CryptHashData(hash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0); + ok(ret, "CryptHashData error %#x\n", GetLastError()); + + ret = CryptVerifySignatureW(hash, info->Signature.pbData, info->Signature.cbData, key, NULL, 0); + ok(ret, "CryptVerifySignature error %#x\n", GetLastError()); + + CryptDestroyHash(hash); + CryptDestroyKey(key); + CryptReleaseContext(prov, 0); + + /* 3. Verify certificate signature with CNG */ + ret = CryptImportPublicKeyInfoEx2(cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &bkey); + ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError()); + + status = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(!status, "got %#x\n", status); + + status = pBCryptCreateHash(alg, &bhash, NULL, 0, NULL, 0, 0); + ok(!status || broken(status == STATUS_INVALID_PARAMETER) /* Vista */, "got %#x\n", status); + if (status == STATUS_INVALID_PARAMETER) + { + win_skip("broken BCryptCreateHash\n"); + goto done; + } + + status = pBCryptHashData(bhash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0); + ok(!status, "got %#x\n", status); + + status = pBCryptFinishHash(bhash, hash_value, sizeof(hash_value), 0); + ok(!status, "got %#x\n", status); + ok(!memcmp(hash_value, selfSignedSignatureHash, sizeof(hash_value)), "got wrong hash value\n"); + + status = pBCryptGetProperty(bhash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &size, 0); + ok(!status, "got %#x\n", status); + ok(hash_len == sizeof(hash_value), "got %u\n", hash_len); + + sig_value = HeapAlloc(GetProcessHeap(), 0, info->Signature.cbData); + for (i = 0; i < info->Signature.cbData; i++) + sig_value[i] = info->Signature.pbData[info->Signature.cbData - i - 1]; + + pad.pszAlgId = BCRYPT_SHA1_ALGORITHM; + status = pBCryptVerifySignature(bkey, &pad, hash_value, sizeof(hash_value), sig_value, info->Signature.cbData, BCRYPT_PAD_PKCS1); + ok(!status, "got %#x\n", status); + + HeapFree(GetProcessHeap(), 0, sig_value); + pBCryptDestroyHash(bhash); +done: + pBCryptCloseAlgorithmProvider(alg, 0); + + LocalFree(info); + CertFreeCertificateContext(cert); +} + START_TEST(cert) { init_function_pointers(); @@ -4270,4 +4385,5 @@ START_TEST(cert) testAcquireCertPrivateKey(); testGetPublicKeyLength(); testIsRDNAttrsInCertificateName(); + test_VerifySignature(); }