Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/bcrypt/tests/Makefile.in | 2 +- dlls/bcrypt/tests/bcrypt.c | 121 ++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/tests/Makefile.in b/dlls/bcrypt/tests/Makefile.in index 1bf7d2c48f1..b0f3e57f3ed 100644 --- a/dlls/bcrypt/tests/Makefile.in +++ b/dlls/bcrypt/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = bcrypt.dll -IMPORTS = bcrypt user32 advapi32 +IMPORTS = bcrypt user32 advapi32 crypt32
C_SRCS = \ bcrypt.c diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 456727d04a9..58fc52f55c6 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -24,6 +24,7 @@ #include <windows.h> #include <bcrypt.h> #include <ncrypt.h> +#include <wincrypt.h>
#include "wine/test.h"
@@ -2741,6 +2742,125 @@ static void test_SecretAgreement(void) ok(status == STATUS_SUCCESS, "got %08x\n", status); }
+/* Copied from dlls/crypt32/tests/cert.c */ +static const BYTE selfSignedCert[] = { + 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49, + 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, + 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, + 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30, + 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31, + 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, + 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, + 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4, + 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b, + 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0, + 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96, + 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79, + 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, + 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41, + 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66, + 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a, + 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7, + 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f, + 0xa8, 0x76, 0x57, 0x92, 0x36 }; +static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6, + 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d }; + +HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID); + +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, sig_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()); + + prov = I_CryptGetDefaultCryptProv(0); + ok(prov, "hCryptProv can't be NULL\n"); + 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); + CryptDestroyHash(hash); + CryptDestroyKey(key); + CryptReleaseContext(prov, 0); + + /* 2. Verify certificate signature with CNG */ + ret = CryptImportPublicKeyInfoEx2(cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &bkey); + ok(ret, "CryptImportPublicKeyInfoEx error %#x\n", GetLastError()); + + status = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(!status, "got %#x\n", status); + + status = BCryptCreateHash(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 = BCryptHashData(bhash, info->ToBeSigned.pbData, info->ToBeSigned.cbData, 0); + ok(!status, "got %#x\n", status); + + status = BCryptFinishHash(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 = BCryptGetProperty(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_len = info->Signature.cbData; + sig_value = CryptMemAlloc(sig_len); + 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 = BCryptVerifySignature(bkey, &pad, hash_value, sizeof(hash_value), sig_value, sig_len, BCRYPT_PAD_PKCS1); + ok(!status, "got %#x\n", status); + + CryptMemFree(sig_value); + BCryptDestroyHash(bhash); +done: + BCryptCloseAlgorithmProvider(alg, 0); + + LocalFree(info); + CertFreeCertificateContext(cert); +} + START_TEST(bcrypt) { HMODULE module; @@ -2808,6 +2928,7 @@ START_TEST(bcrypt) test_BcryptDeriveKeyCapi(); test_DSA(); test_SecretAgreement(); + test_VerifySignature();
FreeLibrary(module); }