Implemented CryptHashCertificate.
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 02592dd..0274467 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c
@@ -22,6 +22,7 @@ #include "winreg.h" #include "wincrypt.h" #include "wine/debug.h" +#include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -267,3 +268,32 @@ } return ret; } + +BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, + DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash) +{ + BOOL ret = TRUE; + HCRYPTHASH hHash = 0; + + TRACE("(%ld, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, + pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); + + if (!hCryptProv) + hCryptProv = CRYPT_GetDefaultProvider(); + if (!Algid) + Algid = CALG_SHA1; + if (ret) + { + ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0); + if (ret) + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); + } + } + return ret; +}
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 551b9ac..20b3e78 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec
@@ -108,7 +108,7 @@ @ stub CryptGetMessageSignerCount @ stub CryptGetOIDFunctionAddress @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) -@ stub CryptHashCertificate +@ stdcall CryptHashCertificate(long long long ptr long ptr ptr) @ stub CryptHashMessage @ stub CryptHashPublicKeyInfo @ stub CryptHashToBeSigned
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h new file mode 100644 index 0000000..9b59353 --- /dev/null +++ b/dlls/crypt32/crypt32_private.h
@@ -0,0 +1,27 @@ +/* + * Copyright 2005 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __CRYPT32_PRIVATE_H__ +#define __CRYPT32_PRIVATE_H__ + +/* Returns a handle to the default crypto provider; loads it if necessary. + * Returns NULL on failure. + */ +HCRYPTPROV CRYPT_GetDefaultProvider(void); + +#endif
diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c index 821dcc3..87bf9b1 100644 --- a/dlls/crypt32/main.c +++ b/dlls/crypt32/main.c
@@ -27,10 +27,32 @@ #include "winreg.h" #include "winnls.h" #include "mssip.h" +#include "crypt32_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); +static HCRYPTPROV hDefProv; + +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_DETACH: + if (hDefProv) CryptReleaseContext(hDefProv, 0); + break; + } + return TRUE; +} + +HCRYPTPROV CRYPT_GetDefaultProvider(void) +{ + if (!hDefProv) + CryptAcquireContextW(&hDefProv, NULL, MS_ENHANCED_PROV_W, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + return hDefProv; +} + /* this function is called by Internet Explorer when it is about to verify a downloaded component */ BOOL WINAPI I_CryptCreateLruCache(DWORD x, DWORD y) {
diff --git a/dlls/crypt32/tests/.cvsignore b/dlls/crypt32/tests/.cvsignore index 227ae6a..835330a 100644 --- a/dlls/crypt32/tests/.cvsignore +++ b/dlls/crypt32/tests/.cvsignore
@@ -1,4 +1,5 @@ Makefile +cert.ok encode.ok main.ok protectdata.ok
diff --git a/dlls/crypt32/tests/Makefile.in b/dlls/crypt32/tests/Makefile.in index 0a62542..8257fe6 100644 --- a/dlls/crypt32/tests/Makefile.in +++ b/dlls/crypt32/tests/Makefile.in
@@ -6,6 +6,7 @@ IMPORTS = crypt32 CTESTS = \ + cert.c \ encode.c \ main.c \ protectdata.c
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c new file mode 100644 index 0000000..c4d8223 --- /dev/null +++ b/dlls/crypt32/tests/cert.c
@@ -0,0 +1,70 @@ +/* + * crypt32 cert functions tests + * + * Copyright 2005 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <stdarg.h> +#include <windef.h> +#include <winbase.h> +#include <winreg.h> +#include <winerror.h> +#include <wincrypt.h> + +#include "wine/test.h" + +static void testCryptHashCert(void) +{ + static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, + 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, + 0x09 }; + static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee, + 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8, + 0xa2 }; + static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:"; + BOOL ret; + BYTE hash[20]; + DWORD hashLen = sizeof(hash); + + /* NULL buffer and nonzero length crashes + ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen); + empty hash length also crashes + ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL); + */ + /* Test empty hash */ + ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL, + &hashLen); + ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError()); + ok(hashLen == sizeof(hash), + "Got unexpected size of hash %ld, expected %d\n", hashLen, sizeof(hash)); + /* Test with empty buffer */ + ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen); + ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError()); + ok(!memcmp(hash, emptyHash, sizeof(emptyHash)), + "Unexpected hash of nothing\n"); + /* Test a known value */ + ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash, + &hashLen); + ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError()); + ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); +} + +START_TEST(cert) +{ + testCryptHashCert(); +}