From d8da3e83ff5bcb0e406c508de58cd081a7434bad Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Fri, 8 Aug 2008 10:25:43 -0700 Subject: [PATCH] crypt32: Implement CryptHashToBeSigned. --- dlls/crypt32/cert.c | 40 +++++++++++++++++++++++++++++++++++++-- dlls/crypt32/tests/cert.c | 5 ----- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 0dc10c0e651..7eedd524add 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1534,9 +1534,45 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash) { - FIXME("(%08lx, %08x, %p, %d, %p, %d): stub\n", hCryptProv, dwCertEncodingType, + BOOL ret; + CERT_SIGNED_CONTENT_INFO *info; + DWORD size; + + TRACE("(%08lx, %08x, %p, %d, %p, %d)\n", hCryptProv, dwCertEncodingType, pbEncoded, cbEncoded, pbComputedHash, *pcbComputedHash); - return FALSE; + + ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT, + pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, (void *)&info, &size); + if (ret) + { + PCCRYPT_OID_INFO oidInfo; + HCRYPTHASH hHash; + + if (!hCryptProv) + hCryptProv = CRYPT_GetDefaultProvider(); + oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, + info->SignatureAlgorithm.pszObjId, 0); + if (!oidInfo) + { + SetLastError(NTE_BAD_ALGID); + ret = FALSE; + } + else + { + ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, info->ToBeSigned.pbData, + info->ToBeSigned.cbData, 0); + if (ret) + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); + } + } + LocalFree(info); + } + return ret; } BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index ce3bf882879..118b6b09301 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -2575,33 +2575,28 @@ static void testHashToBeSigned(void) "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); /* Can't sign anything: has to be asn.1 encoded, at least */ SetLastError(0xdeadbeef); ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1), NULL, &size); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG, "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); /* Can't be empty, either */ SetLastError(0xdeadbeef); ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert, sizeof(emptyCert), NULL, &size); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT, "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError()); /* Signing a cert works */ ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert, sizeof(md5SignedEmptyCert), NULL, &size); - todo_wine { ok(ret, "CryptHashToBeSigned failed: %08x\n", GetLastError()); ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size); ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert, sizeof(md5SignedEmptyCert), hash, &size); ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n"); - } } static void testCompareCert(void)