Hi, This patch implements the cryptographic API functions existing in advapi32.dll. However, there are still issues with some of the M$ providers and the pstores.exe service, so I'm not sure how functional this will be until something can be done about this service. Changelog: Travis Michielsen <tjmichielsen@yahoo.com> Implement advapi32 portion of the CryptoAPI.
Index: include/wincrypt.h =================================================================== RCS file: /home/wine/wine/include/wincrypt.h,v retrieving revision 1.3 diff -u -r1.3 wincrypt.h --- include/wincrypt.h 1999/06/26 14:58:26 1.3 +++ include/wincrypt.h 2002/01/09 21:56:01 @@ -3,17 +3,371 @@ #include "windef.h" -/* FIXME: this whole file plus the implementation */ - /* some typedefs for function parameters */ typedef unsigned int ALG_ID; typedef unsigned long HCRYPTPROV; typedef unsigned long HCRYPTKEY; typedef unsigned long HCRYPTHASH; -/* function declarations */ +/* CSP Structs */ +typedef struct _VTableProvStruc { + DWORD Version; + BOOL (*pFuncVerifyImage)(LPCSTR lpszImage, BYTE *pSigData); + BOOL (*pFuncReturnhWnd)(DWORD *phWnd); + DWORD dwProvType; + BYTE *pbContextInfo; + DWORD cbContextInfo; + LPSTR pszProvName; +} VTableProvStruc, *PVTableProvStruc; + +typedef struct _CRYPTOAPI_BLOB { + DWORD cbData; + BYTE* pbData; +} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB, + CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB, + CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB, + CERT_NAME_BLOB, *PCERT_NAME_BLOB, + CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB, + CERT_BLOB, *PCERT_BLOB, + CRL_BLOB, *PCRL_BLOB, + DATA_BLOB, *PDATA_BLOB, + CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB, + CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB, + CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB, + CRYPT_DER_BLOB, *PCRYPT_DER_BLOB, + CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB; + +typedef struct _PUBLICKEYSTRUC { + BYTE bType; + BYTE bVersion; + WORD reserved; + ALG_ID aiKeyAlg; +} BLOBHEADER, PUBLICKEYSTRUC; + +/* Algorithm IDs */ + +#define GET_ALG_CLASS(x) (x & (7 << 13)) +#define GET_ALG_TYPE(x) (x & (15 << 9)) +#define GET_ALG_SID(x) (x & (511)) + +/* Algorithm Classes */ +#define ALG_CLASS_ANY (0) +#define ALG_CLASS_SIGNATURE (1 << 13) +#define ALG_CLASS_MSG_ENCRYPT (2 << 13) +#define ALG_CLASS_DATA_ENCRYPT (3 << 13) +#define ALG_CLASS_HASH (4 << 13) +#define ALG_CLASS_KEY_EXCHANGE (5 << 13) +/* Algorithm types */ +#define ALG_TYPE_ANY (0) +#define ALG_TYPE_DSS (1 << 9) +#define ALG_TYPE_RSA (2 << 9) +#define ALG_TYPE_BLOCK (3 << 9) +#define ALG_TYPE_STREAM (4 << 9) + +/* SIDs */ +#define ALG_SID_ANY (0) +/* RSA SIDs */ +#define ALG_SID_RSA_ANY 0 +#define ALG_SID_RSA_PKCS 1 +#define ALG_SID_RSA_MSATWORK 2 +#define ALG_SID_RSA_ENTRUST 3 +#define ALG_SID_RSA_PGP 4 +/* DSS SIDs */ +#define ALG_SID_DSS_ANY 0 +#define ALG_SID_DSS_PKCS 1 +#define ALG_SID_DSS_DMS 2 + +/* DES SIDs */ +#define ALG_SID_DES 1 +#define ALG_SID_3DES 3 +#define ALG_SID_DESX 4 +#define ALG_SID_IDEA 5 +#define ALG_SID_CAST 6 +#define ALG_SID_SAFERSK64 7 +#define ALD_SID_SAFERSK128 8 +/* RC2 SIDs */ +#define ALG_SID_RC4 1 +#define ALG_SID_RC2 2 +#define ALG_SID_SEAL 2 +/* Hash SIDs */ +#define ALG_SID_MD2 1 +#define ALG_SID_MD4 2 +#define ALG_SID_MD5 3 +#define ALG_SID_SHA 4 +#define ALG_SID_MAC 5 +#define ALG_SID_RIPEMD 6 +#define ALG_SID_RIPEMD160 7 +#define ALG_SID_SSL3SHAMD5 8 + +/* Algorithm Definitions */ +#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2) +#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4) +#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5) +#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA) +#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC) +#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY) +#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY) +#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY) +#define CALG_DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES) +#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2) +#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4) +#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL) + +/* Provider names */ +#define MS_DEF_PROV_A "Microsoft Base Cryptographic Provider v1.0" +static const WCHAR MS_DEF_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'B','a','s','e',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ', + 'P','r','o','v','i','d','e','r',' ','v','1','.','0',0 }; +#define MS_DEF_PROV WINELIB_NAME_AW(MS_DEF_PROV_) + +#define MS_ENHANCED_PROV_A "Microsoft Enhanced Cryptographic Provider " +static const WCHAR MS_ENHANCED_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'E','n','h','a','n','c','e','d',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ', + 'P','r','o','v','i','d','e','r',' ', 0 }; +#define MS_ENHANCED_PROV WINELIB_NAME_AW(MS_ENHANCED_PROV_) + +#define MS_STRONG_PROV_A "Microsoft Strong Cryptographic Provider" +static const WCHAR MS_STRONG_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'S','t','r','o','n','g',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ', + 'P','r','o','v','i','d','e','r',0 }; +#define MS_STRONG_PROV WINELIB_NAME_AW(MS_STRONG_PROV_) + +#define MS_DEF_RSA_SIG_PROV_A "Microsoft RSA Signature Cryptographic Provider" +static const WCHAR MS_DEF_RSA_SIG_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'R','S','A',' ','S','i','g','n','a','t','u','r','e',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_DEF_RSA_SIG_PROV WINELIB_NAME_AW(MS_DEF_RSA_SIG_PROV_) + +#define MS_DEF_RSA_SCHANNEL_PROV_A "Microsoft RSA SChannel Cryptographic Provider" +static const WCHAR MS_DEF_RSA_SCHANNEL_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'R','S','A',' ','S','C','h','a','n','n','e','l',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_DEF_RSA_SCHANNEL_PROV WINELIB_NAME_AW(MS_DEF_RSA_SCHANNEL_PROV_) + +#define MS_DEF_DSS_PROV_A "Microsoft Base DSS Cryptographic Provider" +static const WCHAR MS_DEF_DSS_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'B','a','s','e',' ','D','S','S',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_DEF_DSS_PROV WINELIB_NAME_AW(MS_DEF_DSS_PROV_) + +#define MS_DEF_DSS_DH_PROV_A "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider" +static const WCHAR MS_DEF_DSS_DH_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'B','a','s','e',' ','D','S','S',' ','a','n','d',' ', + 'D','i','f','f','i','e','-','H','e','l','l','m','a','n',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_DEF_DSS_DH_PROV WINELIB_NAME_AW(MS_DEF_DSS_DH_PROV_) +#define MS_ENH_DSS_DH_PROV_A "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider" +static const WCHAR MS_ENH_DSS_DH_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'E','n','h','a','n','c','e','d',' ','D','S','S',' ','a','n','d',' ', + 'D','i','f','f','i','e','-','H','e','l','l','m','a','n',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_ENH_DSS_DH_PROV WINELIB_NAME_AW(MS_ENH_DSS_DH_PROV_) + +#define MS_DEF_DH_SCHANNEL_PROV_A "Microsoft DH SChannel Cryptographic Provider" +static const WCHAR MS_DEF_DH_SCHANNEL_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'D','H',' ','S','C','h','a','n','n','e','l',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_DEF_DH_SCHANNEL_PROV WINELIB_NAME_AW(MS_DEF_DH_SCHANNEL_PROV_) + +#define MS_SCARD_PROV_A "Microsoft Base Smart Card Cryptographic Provider" +static const WCHAR MS_SCARD_PROV_W[] = { 'M','i','c','r','o','s','o','f','t',' ', + 'B','a','s','e',' ','S','m','a','r','t',' ','C','a','r','d',' ', + 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 }; +#define MS_SCARD_PROV WINELIB_NAME_AW(MS_SCARD_PROV_) + +/* Key Specs*/ +#define AT_KEYEXCHANGE 1 +#define AT_SIGNATURE 2 + +/* Provider Types */ +#define PROV_RSA_FULL 1 +#define PROV_RSA_SIG 2 +#define PROV_DSS 3 +#define PROV_FORTEZZA 4 +#define PROV_MS_EXCHANGE 5 +#define PROV_SSL 6 +#define PROV_RSA_SCHANNEL 12 +#define PROV_DSS_DH 13 +#define PROV_EC_ECDSA_SIG 14 +#define PROV_EC_ECNRA_SIG 15 +#define PROV_EC_ECDSA_FULL 16 +#define PROV_EC_ECNRA_FULL 17 +#define PROV_DH_SCHANNEL 18 +#define PROV_SPYRUS_LYNKS 20 +#define PROV_RNG 21 +#define PROV_INTEL_SEC 22 +#define PROV_REPLACE_OWF 23 +#define PROV_RSA_AES 24 + +/* FLAGS Section */ + +/* Provider Parameters */ +#define PP_ENUMALGS 1 +#define PP_ENUMCONTAINERS 2 +#define PP_IMPTYPE 3 +#define PP_NAME 4 +#define PP_VERSION 5 +#define PP_CONTAINER 6 + +#define CRYPT_FIRST 1 +#define CRYPT_NEXT 2 + +#define CRYPT_IMPL_HARDWARE 1 +#define CRYPT_IMPL_SOFTWARE 2 +#define CRYPT_IMPL_MIXED 3 +#define CRYPT_IMPL_UNKNOWN 4 + +/* CryptAcquireContext */ +#define CRYPT_VERIFYCONTEXT 0xF0000000 +#define CRYPT_NEWKEYSET 0x00000008 +#define CRYPT_MACHINE_KEYSET 0x00000000 +#define CRYPT_DELETEKEYSET 0x00000010 +#define CRYPT_SILENT 0x00000000 + +/* Crypt{Get|Set}Provider */ +#define CRYPT_MACHINE_DEFAULT 0x00000001 +#define CRYPT_USER_DEFAULT 0x00000002 +#define CRYPT_DELETE_DEFAULT 0x00000004 + +/* Crypt{Get/Set}ProvParam */ +#define PP_CLIENT_HWND 1 +#define PP_ENUMALGS 1 +#define PP_ENUMCONTAINERS 2 +#define PP_IMPTYPE 3 +#define PP_NAME 4 +#define PP_VERSION 5 +#define PP_CONTAINER 6 +#define PP_CHANGE_PASSWORD 7 +#define PP_KEYSET_SEC_DESCR 8 +#define PP_KEY_TYPE_SUBTYPE 10 +#define PP_CONTEXT_INFO 11 +#define PP_KEYEXCHANGE_KEYSIZE 12 +#define PP_SIGNATURE_KEYSIZE 13 +#define PP_KEYEXCHANGE_ALG 14 +#define PP_SIGNATURE_ALG 15 +#define PP_PROVTYPE 16 +#define PP_KEYSTORAGE 17 +#define PP_SYM_KEYSIZE 19 +#define PP_SESSION_KEYSIZE 20 +#define PP_UI_PROMPT 21 +#define PP_ENUMALGS_EX 22 +#define PP_DELETEKEY 24 +#define PP_ENUMMANDROOTS 25 +#define PP_ENUMELECTROOTS 26 +#define PP_KEYSET_TYPE 27 +#define PP_ADMIN_PIN 31 +#define PP_KEYEXCHANGE_PIN 32 +#define PP_SIGNATURE_PIN 33 +#define PP_SIG_KEYSIZE_INC 34 +#define PP_KEYX_KEYSIZE_INC 35 +#define PP_UNIQUE_CONTAINER 36 +#define PP_SGC_INFO 37 +#define PP_USE_HARDWARE_RNG 38 +#define PP_KEYSPEC 39 +#define PP_ENUMEX_SIGNING_PROT 40 + +/* CryptSignHash/CryptVerifySignature */ +#define CRYPT_NOHASHOID 0x00000001 +#define CRYPT_TYPE2_FORMAT 0x00000002 +#define CRYPT_X931_FORMAT 0x00000004 + +/* Crypt*Key */ +#define CRYPT_EXPORTABLE 0x00000001 +#define CRYPT_USER_PROTECTED 0x00000002 +#define CRYPT_CREATE_SALT 0x00000004 +#define CRYPT_UPDATE_KEY 0x00000008 +#define CRYPT_NO_SALT 0x00000010 +#define CRYPT_PREGEN 0x00000040 +#define CRYPT_ARCHIVABLE 0x00004000 +#define CRYPT_SSL2_FALLBACK 0x00000002 +#define CRYPT_DESTROYKEY 0x00000004 +#define CRYPT_OAEP 0x00000040 + +/* Blob Types */ +#define SIMPLEBLOB 0x1 +#define PUBLICKEYBLOB 0x6 +#define PRIVATEKEYBLOB 0x7 +#define PLAINTEXTKEYBLOB 0x8 +#define OPAQUEKEYBLOB 0x9 +#define PUBLICKEYBLOBEX 0xA +#define SYMMETRICWRAPKEYBLOB 0xB + +/* function declarations */ +/* advapi32.dll */ BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, - LPCSTR pszProvider, DWORD dwProvType, + LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags); +BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer, + LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags); +#define CryptAcquireContext WINELIB_NAME_AW(CryptAcquireContext) +BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer); +BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags); +BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, + DWORD dwFlags, HCRYPTHASH *phHash); +BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, + DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); +BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, + DWORD dwFlags, HCRYPTKEY *phKey); +BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash); +BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey); +BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey); +BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved, + DWORD dwFlags, HCRYPTHASH *phHash); +BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, + DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen); +BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved, + DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName); +BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved, + DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName); +#define CryptEnumProviders WINELIB_NAME_AW(CryptEnumProviders) +BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved, + DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName); +BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved, + DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName); +#define CryptEnumProviderTypes WINELIB_NAME_AW(CryptEnumProviderTypes) +BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, + DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); +BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey); +BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, + DWORD *pdwDataLen, DWORD dwFlags); +BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, + DWORD *pdwDataLen, DWORD dwFlags); +BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, + DWORD *pdwDataLen, DWORD dwFlags); +BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved, + DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName); +BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved, + DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName); +#define CryptGetDefaultProvider WINELIB_NAME_AW(CryptGetDefaultProvider) +BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey); +BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags); +BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags); +BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, + HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey); +BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags); +BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, + DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen); +/*BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, + DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen);*/ +#define CryptSignHashW(hHash, dwKeySpec, sDescription, dwFlags, pbSignature, pdwSigLen) \\ + CryptSignHashA(hHash, dwKeySpec, (LPCSTR)sDescription, dwFlags, pbSignature, pdwSigLen) +#define CryptSignHash WINELIB_NAME_AW(CryptSignHash) +BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags); +BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags); +BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType); +BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType); +#define CryptSetProvider WINELIB_NAME_AW(CryptSetProvider) +BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags); +BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags); +#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx) +BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags); +BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, + HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags); +/*BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, + HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags);*/ +#define CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, sDescription, dwFlags) \\ + CryptVerifySignatureA(hHash, pbSignature, dwSigLen, hPubKey, (LPCSTR)sDescription, dwFlags) +#define CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature) + #endif Index: dlls/advapi32/advapi32.spec =================================================================== RCS file: /home/wine/wine/dlls/advapi32/advapi32.spec,v retrieving revision 1.17 diff -u -r1.17 advapi32.spec --- dlls/advapi32/advapi32.spec 2001/09/12 17:09:56 1.17 +++ dlls/advapi32/advapi32.spec 2002/01/09 21:56:01 @@ -4,7 +4,7 @@ import kernel32.dll import ntdll.dll -debug_channels (advapi reg) +debug_channels (advapi reg crypt) @ stub AbortSystemShutdownA @ stub AbortSystemShutdownW @@ -44,7 +44,7 @@ @ stdcall CryptDecrypt(long long long long ptr ptr) CryptDecrypt @ stdcall CryptDeriveKey(long long long long ptr) CryptDeriveKey @ stdcall CryptDestroyHash(long) CryptDestroyHash -@ stdcall CryptDestroyKey(long) CryptDestroyHash +@ stdcall CryptDestroyKey(long) CryptDestroyKey @ stdcall CryptDuplicateHash(long ptr long ptr) CryptDuplicateHash @ stdcall CryptDuplicateKey(long ptr long ptr) CryptDuplicateKey @ stdcall CryptEncrypt(long long long long ptr ptr long) CryptEncrypt @@ -65,8 +65,8 @@ @ stdcall CryptHashSessionKey(long long long) CryptHashSessionKey @ stdcall CryptImportKey(long ptr long long long ptr) CryptImportKey @ stdcall CryptReleaseContext(long long) CryptReleaseContext -@ stdcall CryptSignHashA(long long str long ptr ptr) CryptSignHashA -@ stdcall CryptSignHashW(long long wstr long ptr ptr) CryptSignHashW +@ stdcall CryptSignHashA(long long ptr long ptr ptr) CryptSignHashA +@ stdcall CryptSignHashW(long long ptr long ptr ptr) CryptSignHashA @ stdcall CryptSetHashParam(long long ptr long) CryptSetHashParam @ stdcall CryptSetKeyParam(long long ptr long) CryptSetKeyParam @ stdcall CryptSetProviderA(str long) CryptSetProviderA @@ -74,8 +74,8 @@ @ stdcall CryptSetProviderExA(str long ptr long) CryptSetProviderExA @ stdcall CryptSetProviderExW(wstr long ptr long) CryptSetProviderExW @ stdcall CryptSetProvParam(long long ptr long) CryptSetProvParam -@ stdcall CryptVerifySignatureA(long ptr long long str long) CryptVerifySignatureA -@ stdcall CryptVerifySignatureW(long ptr long long wstr long) CryptVerifySignatureW +@ stdcall CryptVerifySignatureA(long ptr long long ptr long) CryptVerifySignatureA +@ stdcall CryptVerifySignatureW(long ptr long long ptr long) CryptVerifySignatureA @ stub DeleteAce @ stdcall DeleteService(long) DeleteService @ stdcall DeregisterEventSource(long) DeregisterEventSource Index: dlls/advapi32/crypt.c =================================================================== RCS file: /home/wine/wine/dlls/advapi32/crypt.c,v retrieving revision 1.15 diff -u -r1.15 crypt.c --- dlls/advapi32/crypt.c 2001/10/09 21:48:39 1.15 +++ dlls/advapi32/crypt.c 2002/01/09 21:56:02 @@ -1,24 +1,230 @@ /* * dlls/advapi32/crypt.c */ + +/////////////////////// +// +// TODO: +// - Reference counting +// - Thread-safing +// - Signature checking + #include <time.h> #include <stdlib.h> +#include <stdio.h> +#include "wine/unicode.h" +#include "crypt.h" +#include "winnls.h" +#include "wincrypt.h" #include "windef.h" #include "winerror.h" -#include "wincrypt.h" +#include "winreg.h" +#include "winbase.h" +#include "winuser.h" #include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(crypt); + +HWND crypt_hWindow = 0; + +#define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;} + +#define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size)) +#define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer)) + +static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName) +{ + const PSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\"; + PSTR keyname; + + keyname = CRYPT_Alloc(strlen(KEYSTR) + strlen(pProvName) +1); + if (keyname) + { + strcpy(keyname, KEYSTR); + strcpy(keyname + strlen(KEYSTR), pProvName); + } else + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return keyname; +} + +static inline PSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user) +{ + const PSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX"; + const PSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX"; + PSTR keyname; + PSTR ptr; + + keyname = CRYPT_Alloc( (user ? strlen(USERSTR) : strlen(MACHINESTR)) +1); + if (keyname) + { + user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR); + ptr = keyname + strlen(keyname); + *(--ptr) = (dwType % 10) + '0'; + *(--ptr) = (dwType / 10) + '0'; + *(--ptr) = (dwType / 100) + '0'; + } else + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return keyname; +} + +/* CRYPT_UnicodeTOANSI + * wstr - unicode string + * str - pointer to ANSI string + * strsize - size of buffer pointed to by str or -1 if we have to do the allocation + * + * returns TRUE if unsuccessfull, FALSE otherwise. + * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call + */ +static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize) +{ + int count; + + if (!wstr) + { + *str = NULL; + return TRUE; + } + count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + count = count < strsize ? count : strsize; + if (strsize == -1) + *str = CRYPT_Alloc(count * sizeof(CHAR)); + if (*str) + { + WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL); + return TRUE; + } + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; +} + +/* CRYPT_ANSITOUnicode + * str - ANSI string + * wstr - pointer to unicode string + * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation + */ +static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize) +{ + int wcount; + + if (!str) + { + *wstr = NULL; + return TRUE; + } + wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + wcount = wcount < wstrsize/sizeof(WCHAR) ? wcount : wstrsize/sizeof(WCHAR); + if (wstrsize == -1) + *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR)); + if (*wstr) + { + MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount); + return TRUE; + } + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; +} -DEFAULT_DEBUG_CHANNEL(advapi); +//These next 2 functions are used by the VTableProvStruc structure +BOOL CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData) +{ + if (!lpszImage || !pData) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + //FIXME: Actually verify the image! + return TRUE; +} + +BOOL CRYPT_ReturnhWnd(DWORD *phWnd) +{ + if (!phWnd) + return FALSE; + *phWnd = crypt_hWindow; + return TRUE; +} + +#define CRYPT_GetProvFunc(name) \ + if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error +#define CRYPT_GetProvFuncOpt(name) \ + provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name) +PCRYPTPROV CRYPT_LoadProvider(PSTR pImage) +{ + PCRYPTPROV provider; + DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY; + + if ( !(provider = CRYPT_Alloc(sizeof(CRYPTPROV))) ) goto error; + if ( !(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))) ) goto error; + if ( !(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))) ) goto error; + if ( !(provider->hModule = LoadLibraryA(pImage)) ) + { + errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL; + goto error; + } + errorcode = NTE_PROVIDER_DLL_FAIL; + CRYPT_GetProvFunc(CPAcquireContext); + CRYPT_GetProvFunc(CPCreateHash); + CRYPT_GetProvFunc(CPDecrypt); + CRYPT_GetProvFunc(CPDeriveKey); + CRYPT_GetProvFunc(CPDestroyHash); + CRYPT_GetProvFunc(CPDestroyKey); + CRYPT_GetProvFuncOpt(CPDuplicateHash); + CRYPT_GetProvFuncOpt(CPDuplicateKey); + CRYPT_GetProvFunc(CPEncrypt); + CRYPT_GetProvFunc(CPExportKey); + CRYPT_GetProvFunc(CPGenKey); + CRYPT_GetProvFunc(CPGenRandom); + CRYPT_GetProvFunc(CPGetHashParam); + CRYPT_GetProvFunc(CPGetKeyParam); + CRYPT_GetProvFunc(CPGetProvParam); + CRYPT_GetProvFunc(CPGetUserKey); + CRYPT_GetProvFunc(CPHashData); + CRYPT_GetProvFunc(CPHashSessionKey); + CRYPT_GetProvFunc(CPImportKey); + CRYPT_GetProvFunc(CPReleaseContext); + CRYPT_GetProvFunc(CPSetHashParam); + CRYPT_GetProvFunc(CPSetKeyParam); + CRYPT_GetProvFunc(CPSetProvParam); + CRYPT_GetProvFunc(CPSignHash); + CRYPT_GetProvFunc(CPVerifySignature); + + //FIXME: Not sure what the pbContextInfo field is for + // Does it need memory allocation? + provider->pVTable->Version = 3; + provider->pVTable->pFuncVerifyImage = CRYPT_VerifyImage; + provider->pVTable->pFuncReturnhWnd = CRYPT_ReturnhWnd; + provider->pVTable->dwProvType = 0; + provider->pVTable->pbContextInfo = NULL; + provider->pVTable->cbContextInfo = 0; + provider->pVTable->pszProvName = NULL; + return provider; + +error: + SetLastError(errorcode); + if (provider) + { + if (provider->hModule) + FreeLibrary(provider->hModule); + CRYPT_Free(provider->pVTable); + CRYPT_Free(provider->pFuncs); + CRYPT_Free(provider); + } + return NULL; +} +#undef CRYPT_GetProvFunc +#undef CRYPT_GetProvFuncOpt + + /****************************************************************************** * CryptAcquireContextA (ADVAPI32.@) * Acquire a crypto provider context handle. * * PARAMS * phProv: Pointer to HCRYPTPROV for the output. - * pszContainer: FIXME (unknown) - * pszProvider: FIXME (unknown) + * pszContainer: Key Container Name + * pszProvider: Cryptographic Service Provider Name * dwProvType: Crypto provider type to get a handle. * dwFlags: flags for the operation * @@ -27,8 +233,111 @@ BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags) { - FIXME("(%p, %s, %s, %ld, %08lx): stub!\n", phProv, pszContainer, + PCRYPTPROV pProv = NULL; + HKEY key; + PSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL; +// BYTE* signature; + DWORD keytype, type, len;//, siglen; + + TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv, pszContainer, pszProvider, dwProvType, dwFlags); + + if (!phProv || !dwProvType) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (dwProvType > MAXPROVTYPES) + { + SetLastError(NTE_BAD_PROV_TYPE); + return FALSE; + } + + if (!pszProvider) + { + //No CSP name specified so try the user default CSP first + // then try the machine default CSP + if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if (RegOpenKeyA(HKEY_CURRENT_USER, keyname, &key)) + { + CRYPT_Free(keyname); + if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key)) goto error; + } + CRYPT_Free(keyname); + RegQueryValueExA(key, "Name", NULL, &keytype, NULL, &len); + if (!len || keytype != REG_SZ || !(provname = CRYPT_Alloc(len))) goto error; + RegQueryValueExA(key, "Name", NULL, NULL, provname, &len); + RegCloseKey(key); + } else { + if ( !(provname = CRYPT_Alloc(strlen(pszProvider) +1)) ) + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + strcpy(provname, pszProvider); + } + + keyname = CRYPT_GetProvKeyName(provname); + if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key)) goto error; + CRYPT_Free(keyname); + len = sizeof(DWORD); + RegQueryValueExA(key, "Type", NULL, NULL, (BYTE*)&type, &len); + if (type != dwProvType) + { + SetLastError(NTE_BAD_PROV_TYPE); + goto error; + } + + RegQueryValueExA(key, "Image Path", NULL, &keytype, NULL, &len); + if (keytype != REG_SZ || !(temp = CRYPT_Alloc(len))) goto error; + RegQueryValueExA(key, "Image Path", NULL, NULL, temp, &len); + + RegCloseKey(key); + len = ExpandEnvironmentStringsA(temp, NULL, 0); + if ( !(imagepath = CRYPT_Alloc(len)) ) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto error; + } + if (!ExpandEnvironmentStringsA(temp, imagepath, len)) goto error; + +// if (!CRYPT_VerifyImage(imagepath, signature)) goto error; + pProv = CRYPT_LoadProvider(imagepath); + CRYPT_Free(temp); + CRYPT_Free(imagepath); + if (!pProv) goto error; + + if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, (CHAR*)pszContainer, dwFlags, pProv->pVTable)) + { + //MSDN: When this flag is set, the value returned in phProv is undefined, + // and thus, the CryptReleaseContext function need not be called afterwards. + //Therefore, we must clean up everything now. + if (dwFlags & CRYPT_DELETEKEYSET) + { + FreeLibrary(pProv->hModule); + CRYPT_Free(provname); + CRYPT_Free(pProv->pFuncs); + CRYPT_Free(pProv); + } else { + pProv->pVTable->pszProvName = provname; + pProv->pVTable->dwProvType = dwProvType; + *phProv = (HCRYPTPROV)pProv; + } + return TRUE; + } + //FALLTHROUGH TO ERROR IF FALSE - CSP internal error! +error: + if (pProv) + { + FreeLibrary(pProv->hModule); + CRYPT_Free(pProv->pVTable); + CRYPT_Free(pProv->pFuncs); + CRYPT_Free(pProv); + } + CRYPT_Free(provname); + CRYPT_Free(temp); + CRYPT_Free(imagepath); + CRYPT_Free(keyname); return FALSE; } @@ -38,54 +347,79 @@ BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags) { - FIXME("(%p, %s, %s, %ld, %08lx): stub!\n", phProv, debugstr_w(pszContainer), + PSTR pProvider = NULL, pContainer = NULL; + BOOL ret = FALSE; + + TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv, debugstr_w(pszContainer), debugstr_w(pszProvider), dwProvType, dwFlags); - return FALSE; + + if ( !CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if ( !CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1) ) + { + CRYPT_Free(pContainer); + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + } + + ret = CryptAcquireContextA(phProv, pContainer, pProvider, dwProvType, dwFlags); + + if (pContainer) + CRYPT_Free(pContainer); + if (pProvider) + CRYPT_Free(pProvider); + + return ret; } /****************************************************************************** - * CryptGenRandom (ADVAPI32.@) + * CryptContextAddRef (ADVAPI32.@) */ -BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) +BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags) { - DWORD i; - - FIXME("(0x%lx, %ld, %p): stub!\n", hProv, dwLen, pbBuffer); - /* - FIXME: Currently this function is just a stub, it is missing functionality in - the following (major) ways: - (1) It makes no use of the passed in HCRYPTPROV handle. (ie. it doesn't - use a cryptographic service provider (CSP) - (2) It doesn't use the values in the passed in pbBuffer to further randomize - its internal seed. - (3) MSDN mentions that this function produces "cryptographically random" - data, which is "... far more random than the data generated by the typical - random number generator such as the one shipped with your C compiler". - We are currently using the C runtime rand() function. ^_^ + FIXME("(0x%lx, %p, %08lx): stub!\n", hProv, pdwReserved, dwFlags); + return FALSE; + //InterlockIncrement?? +} - See MSDN documentation for CryptGenRandom for more information. - */ +/****************************************************************************** + * CryptReleaseContext (ADVAPI32.@) + */ +BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) +{ + PCRYPTPROV pProv = (PCRYPTPROV)hProv; + BOOL ret; - if (dwLen <= 0) - return FALSE; + TRACE("(0x%lx, %08ld)\n", hProv, dwFlags); - srand(time(NULL)); - for (i=0; i<dwLen; i++) + if (!pProv) { - *pbBuffer = (BYTE)(rand() % 256); - pbBuffer++; + SetLastError(NTE_BAD_UID); + return FALSE; } - - return TRUE; + //FIXME: Decrement the counter here first if possible + ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags); + FreeLibrary(pProv->hModule); +// CRYPT_Free(pProv->pVTable->pContextInfo); + CRYPT_Free(pProv->pVTable->pszProvName); + CRYPT_Free(pProv->pVTable); + CRYPT_Free(pProv->pFuncs); + CRYPT_Free(pProv); + return ret; } /****************************************************************************** - * CryptContextAddRef (ADVAPI32.@) + * CryptGenRandom (ADVAPI32.@) */ -BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags) +BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) { - FIXME("(0x%lx, %p, %08lx): stub!\n", hProv, pdwReserved, dwFlags); - return FALSE; + PCRYPTPROV prov = (PCRYPTPROV)hProv; + + TRACE("(0x%lx, %ld, %p)\n", hProv, dwLen, pbBuffer); + + if (!hProv) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + + return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); } /****************************************************************************** @@ -94,7 +428,30 @@ BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash) { - FIXME("(0x%lx, 0x%x, 0x%lx, %08lx, %p): stub!\n", hProv, Algid, hKey, dwFlags, phHash); + PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTHASH hash; + + TRACE("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv, Algid, hKey, dwFlags, phHash); + + if (!prov) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!phHash) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if (dwFlags) + CRYPT_ReturnLastError(NTE_BAD_FLAGS); + if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + hash->pProvider = prov; + + *phHash = (HCRYPTHASH)hash; + if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid, + key ? key->hPrivate : 0, 0, &hash->hPrivate)) + return TRUE; + + //CSP error! + CRYPT_Free(hash); return FALSE; } @@ -104,8 +461,18 @@ BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) { - FIXME("(0x%lx, 0x%lx, %d, %08lx, %p, %p): stub!\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); - return FALSE; + PCRYPTPROV prov; + PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + + TRACE("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); + + if (!key || !pbData || !pdwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = key->pProvider; + return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, + Final, dwFlags, pbData, pdwDataLen); } /****************************************************************************** @@ -114,7 +481,25 @@ BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey) { - FIXME("(0x%lx, %d, 0x%ld, %08ld, %p): stub!\n", hProv, Algid, hBaseData, dwFlags, phKey); + PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTHASH hash = (PCRYPTHASH)hBaseData; + PCRYPTKEY key; + + TRACE("(0x%lx, %d, 0x%ld, %08ld, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey); + + if (!prov || !hash) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!phKey) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + key->pProvider = prov; + if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate)) + return TRUE; + + //CSP error! + CRYPT_Free(key); return FALSE; } @@ -123,8 +508,19 @@ */ BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) { - FIXME("(0x%lx): stub!\n", hHash); - return FALSE; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTPROV prov; + BOOL ret; + + TRACE("(0x%lx)\n", hHash); + + if (!hash) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + + prov = hash->pProvider; + ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate); + CRYPT_Free(hash); + return ret; } /****************************************************************************** @@ -132,8 +528,19 @@ */ BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey) { - FIXME("(0x%lx): stub!\n", hKey); - return FALSE; + PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTPROV prov; + BOOL ret; + + TRACE("(0x%lx)\n", hKey); + + if (!key) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + + prov = key->pProvider; + ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate); + CRYPT_Free(key); + return ret; } /****************************************************************************** @@ -142,7 +549,29 @@ BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash) { - FIXME("(0x%lx, %p, %08ld, %p): stub!\n", hHash, pdwReserved, dwFlags, phHash); + PCRYPTPROV prov; + PCRYPTHASH orghash, newhash; + + TRACE("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash); + + orghash = (PCRYPTHASH)hHash; + if (!orghash || pdwReserved || !phHash) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = orghash->pProvider; + if (!prov->pFuncs->pCPDuplicateHash) + CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED); + + if ( !(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + newhash->pProvider = prov; + if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate)) + { + *phHash = (HCRYPTHASH)newhash; + return TRUE; + } + CRYPT_Free(newhash); return FALSE; } @@ -151,7 +580,29 @@ */ BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey) { - FIXME("(0x%lx, %p, %08ld, %p): stub!\n", hKey, pdwReserved, dwFlags, phKey); + PCRYPTPROV prov; + PCRYPTKEY orgkey, newkey; + + TRACE("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey); + + orgkey = (PCRYPTKEY)hKey; + if (!orgkey || pdwReserved || !phKey) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = orgkey->pProvider; + if (!prov->pFuncs->pCPDuplicateKey) + CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED); + + if ( !(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + newkey->pProvider = prov; + if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate)) + { + *phKey = (HCRYPTKEY)newkey; + return TRUE; + } + CRYPT_Free(newkey); return FALSE; } @@ -161,8 +612,18 @@ BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) { - FIXME("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld): stub!\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); - return FALSE; + PCRYPTPROV prov; + PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + + TRACE("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); + + if (!key || !pdwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = key->pProvider; + return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, + Final, dwFlags, pbData, pdwDataLen, dwBufLen); } /****************************************************************************** @@ -171,9 +632,37 @@ BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName) { - FIXME("(%ld, %p, %ld, %p, %p, %p): stub!\n", dwIndex, pdwReserved, dwFlags, + HKEY hKey; + + TRACE("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, pdwProvType, pszProvName, pcbProvName); - return FALSE; + + if (pdwReserved || !pcbProvName) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if (dwFlags) CRYPT_ReturnLastError(NTE_BAD_FLAGS); + + if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey)) + CRYPT_ReturnLastError(NTE_FAIL); + + if (!pszProvName) + { + DWORD numkeys; + RegQueryInfoKeyA(hKey, NULL, NULL, NULL, &numkeys, pcbProvName, NULL, NULL, NULL, NULL, NULL, NULL); + (*pcbProvName)++; + if (dwIndex >= numkeys) + CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS); + } else { + DWORD size = sizeof(DWORD); + HKEY subkey; + if (RegEnumKeyA(hKey, dwIndex, pszProvName, *pcbProvName)) + return FALSE; + if (RegOpenKeyA(hKey, pszProvName, &subkey)) + return FALSE; + if (RegQueryValueExA(subkey, "Type", NULL, NULL, (BYTE*)pdwProvType, &size)) + return FALSE; + RegCloseKey(subkey); + } + RegCloseKey(hKey); + return TRUE; } /****************************************************************************** @@ -182,9 +671,24 @@ BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName) { - FIXME("(%ld, %p, %08ld, %p, %p, %p): stub!\n", dwIndex, pdwReserved, dwFlags, + PSTR str = NULL; + DWORD strlen; + BOOL ret;// = FALSE; + + TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, pdwProvType, pszProvName, pcbProvName); - return FALSE; + + strlen = *pcbProvName / sizeof(WCHAR); + if ( pszProvName && (str = CRYPT_Alloc(strlen)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + ret = CryptEnumProvidersA(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen); + if (str) + { + CRYPT_ANSIToUnicode(str, &pszProvName, *pcbProvName); + CRYPT_Free(str); + } + *pcbProvName = strlen * sizeof(WCHAR); + return ret; } /****************************************************************************** @@ -193,8 +697,39 @@ BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName) { - FIXME("(%ld, %p, %08ld, %p, %p, %p): stub!\n", dwIndex, pdwReserved, dwFlags, pdwProvType, pszTypeName, pcbTypeName); - return FALSE; + HKEY hKey, hSubkey; + DWORD keylen, numkeys; + PSTR keyname, ch; + + TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, + dwFlags, pdwProvType, pszTypeName, pcbTypeName); + + if (pdwReserved || !pdwProvType || !pcbTypeName) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if (dwFlags) CRYPT_ReturnLastError(NTE_BAD_FLAGS); + + if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey)) + return FALSE; + + RegQueryInfoKeyA(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL); + if (dwIndex >= numkeys) + CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS); + keylen++; + if ( !(keyname = CRYPT_Alloc(keylen)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if ( RegEnumKeyA(hKey, dwIndex, keyname, keylen) ) + return FALSE; + RegOpenKeyA(hKey, keyname, &hSubkey); + ch = keyname + strlen(keyname); + //Convert "Type 000" to 0, etc/ + *pdwProvType = *(--ch) - '0'; + *pdwProvType += (*(--ch) - '0') * 10; + *pdwProvType += (*(--ch) - '0') * 100; + CRYPT_Free(keyname); + RegQueryValueA(hSubkey, "TypeName", pszTypeName, pcbTypeName); + RegCloseKey(hSubkey); + RegCloseKey(hKey); + return TRUE; } /****************************************************************************** @@ -203,9 +738,23 @@ BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName) { - FIXME("(%ld, %p, %08ld, %p, %p, %p): stub!\n", dwIndex, pdwReserved, dwFlags, + PSTR str = NULL; + DWORD strlen; + BOOL ret; + + TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, pdwProvType, pszTypeName, pcbTypeName); - return FALSE; + strlen = *pcbTypeName / sizeof(WCHAR); + if ( pszTypeName && (str = CRYPT_Alloc(strlen)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + ret = CryptEnumProviderTypesA(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen); + if (str) + { + CRYPT_ANSIToUnicode(str, &pszTypeName, *pcbTypeName); + CRYPT_Free(str); + } + *pcbTypeName = strlen * sizeof(WCHAR); + return ret; } /****************************************************************************** @@ -214,8 +763,17 @@ BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) { - FIXME("(0x%lx, 0x%lx, %ld, %08ld, %p, %p): stub!\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen); - return FALSE; + PCRYPTPROV prov; + PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey; + + TRACE("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen); + + if (!key || pdwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = key->pProvider; + return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0, + dwBlobType, dwFlags, pbData, pdwDataLen); } /****************************************************************************** @@ -223,7 +781,26 @@ */ BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) { - FIXME("(0x%lx, %d, %08ld, %p): stub!\n", hProv, Algid, dwFlags, phKey); + PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTKEY key; + + TRACE("(0x%lx, %d, %08ld, %p)\n", hProv, Algid, dwFlags, phKey); + + if (!prov) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!phKey) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + key->pProvider = prov; + + *phKey = (HCRYPTKEY)key; + if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate)) + return TRUE; + + //CSP error! + CRYPT_Free(key); return FALSE; } @@ -233,8 +810,31 @@ BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName) { - FIXME("(%ld, %p, %ld, %p, %p): stub!\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName); - return FALSE; + HKEY hKey; + PSTR keyname; + + if (pdwReserved || !pcbProvName) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT)) + CRYPT_ReturnLastError(NTE_BAD_FLAGS); + if (dwProvType < 0 || dwProvType > 999) + CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE); + if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey)) + { + CRYPT_Free(keyname); + CRYPT_ReturnLastError(NTE_PROV_TYPE_NOT_DEF); + } + CRYPT_Free(keyname); + if (RegQueryValueExA(hKey, "Name", NULL, NULL, pszProvName, pcbProvName)) + { + if (GetLastError() != ERROR_MORE_DATA) + SetLastError(NTE_PROV_TYPE_ENTRY_BAD); + return FALSE; + } + RegCloseKey(hKey); + return TRUE; } /****************************************************************************** @@ -243,8 +843,23 @@ BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName) { - FIXME("(%ld, %p, %08ld, %p, %p): stub!\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName); - return FALSE; + PSTR str = NULL; + DWORD strlen; + BOOL ret = FALSE; + + TRACE("(%ld, %p, %08ld, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName); + + strlen = *pcbProvName / sizeof(WCHAR); + if ( pszProvName && !(str = CRYPT_Alloc(strlen)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + ret = CryptGetDefaultProviderA(dwProvType, pdwReserved, dwFlags, str, &strlen); + if (str) + { + CRYPT_ANSIToUnicode(str, &pszProvName, *pcbProvName); + CRYPT_Free(str); + } + *pcbProvName = strlen * sizeof(WCHAR); + return ret; } /****************************************************************************** @@ -253,8 +868,17 @@ BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { - FIXME("(0x%lx, %ld, %p, %p, %08ld): stub!\n", hHash, dwParam, pbData, pdwDataLen, dwFlags); - return FALSE; + PCRYPTPROV prov; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + + TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags); + + if (!hash || !pdwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = hash->pProvider; + return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam, + pbData, pdwDataLen, dwFlags); } /****************************************************************************** @@ -263,8 +887,17 @@ BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { - FIXME("(0x%lx, %ld, %p, %p, %08ld): stub!\n", hKey, dwParam, pbData, pdwDataLen, dwFlags); - return FALSE; + PCRYPTPROV prov; + PCRYPTKEY key = (PCRYPTKEY)hKey; + + TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags); + + if (!key || !pdwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = key->pProvider; + return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam, + pbData, pdwDataLen, dwFlags); } /****************************************************************************** @@ -273,8 +906,11 @@ BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) { - FIXME("(0x%lx, %ld, %p, %p, %08ld): stub!\n", hProv, dwParam, pbData, pdwDataLen, dwFlags); - return FALSE; + PCRYPTPROV prov = (PCRYPTPROV)hProv; + + TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags); + + return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags); } /****************************************************************************** @@ -282,7 +918,26 @@ */ BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) { - FIXME("(0x%lx, %ld, %p): stub!\n", hProv, dwKeySpec, phUserKey); + PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTKEY key; + + TRACE("(0x%lx, %ld, %p)\n", hProv, dwKeySpec, phUserKey); + + if (!prov) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!phUserKey) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + key->pProvider = prov; + + *phUserKey = (HCRYPTKEY)key; + if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate)) + return TRUE; + + //CSP Error + CRYPT_Free(key); return FALSE; } @@ -291,8 +946,18 @@ */ BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags) { - FIXME("(0x%lx, %p, %ld, %08ld): stub!\n", hHash, pbData, dwDataLen, dwFlags); - return FALSE; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTPROV prov; + + TRACE("(0x%lx, %p, %ld, %08ld)\n", hHash, pbData, dwDataLen, dwFlags); + + if (!hash) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!pbData || !dwDataLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = hash->pProvider; + return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags); } /****************************************************************************** @@ -300,8 +965,17 @@ */ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags) { - FIXME("(0x%lx, 0x%lx, %08ld): stub!\n", hHash, hKey, dwFlags); - return FALSE; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTKEY key = (PCRYPTKEY)hKey; + PCRYPTPROV prov; + + TRACE("(0x%lx, 0x%lx, %08ld)\n", hHash, hKey, dwFlags); + + if (!hash || !key) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + + prov = hash->pProvider; + return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags); } /****************************************************************************** @@ -310,37 +984,58 @@ BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) { - FIXME("(0x%lx, %p, %ld, 0x%lx, %08ld, %p): stub!\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); - return FALSE; -} + PCRYPTPROV prov = (PCRYPTPROV)hProv; + PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey; -/****************************************************************************** - * CryptReleaseContext (ADVAPI32.@) - */ -BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) -{ - FIXME("(0x%lx, %08ld): stub!\n", hProv, dwFlags); + TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); + + if (!prov || !pbData || !dwDataLen || !phKey) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + + importkey->pProvider = prov; + if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen, + pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate)) + { + *phKey = (HCRYPTKEY)importkey; + return TRUE; + } + + CRYPT_Free(importkey); return FALSE; } /****************************************************************************** + * CryptSignHashA + * + * Note: Since the sDesciption (string) is supposed to be NULL and + * is only retained for compatibility no string conversions are required + * and only one implementation is required for both ANSI and Unicode. + * We still need to export both: + * * CryptSignHashA (ADVAPI32.@) + * CryptSignHashW (ADVAPI32.@) */ BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) { - FIXME("(0x%lx, %ld, %s, %08ld, %p, %p): stub!\n", hHash, dwKeySpec, sDescription, dwFlags, pbSignature, pdwSigLen); - return FALSE; -} + PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTPROV prov; -/****************************************************************************** - * CryptSignHashW (ADVAPI32.@) - */ -BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, - DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) -{ - FIXME("(0x%lx, %ld, %s, %08ld, %p, %p): stub!\n", hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen); - return FALSE; + TRACE("(0x%lx, %ld, %08ld, %p, %p)\n", hHash, dwKeySpec, dwFlags, pbSignature, pdwSigLen); + if (sDescription) + WARN("The sDescription parameter is not supported (and no longer used). Ignoring."); + + if (!hash) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!pdwSigLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = hash->pProvider; + return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, NULL, + dwFlags, pbSignature, pdwSigLen); } /****************************************************************************** @@ -348,17 +1043,35 @@ */ BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags) { - FIXME("(0x%lx, %ld, %p, %08ld): stub!\n", hHash, dwParam, pbData, dwFlags); - return FALSE; + PCRYPTPROV prov; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + + TRACE("(0x%lx, %ld, %p, %08ld)\n", hHash, dwParam, pbData, dwFlags); + + if (!hash || !pbData) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = hash->pProvider; + return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate, + dwParam, pbData, dwFlags); } /****************************************************************************** - * CryptSetKeyParam (ADVAPI32.@) + * CryptGetKeyParam (ADVAPI32.@) */ BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags) { - FIXME("(%lx, %lx, %p, %lx): stub!\n", hKey, dwParam, pbData, dwFlags); - return FALSE; + PCRYPTPROV prov; + PCRYPTKEY key = (PCRYPTKEY)hKey; + + TRACE("(0x%lx, %ld, %p, %08ld)\n", hKey, dwParam, pbData, dwFlags); + + if (!key || !pbData) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = key->pProvider; + return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate, + dwParam, pbData, dwFlags); } /****************************************************************************** @@ -366,8 +1079,8 @@ */ BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType) { - FIXME("(%s, %ld): stub!\n", pszProvName, dwProvType); - return FALSE; + TRACE("(%s, %ld)\n", pszProvName, dwProvType); + return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); } /****************************************************************************** @@ -375,8 +1088,8 @@ */ BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType) { - FIXME("(%s, %ld): stub!\n", debugstr_w(pszProvName), dwProvType); - return FALSE; + TRACE("(%s, %ld)\n", debugstr_w(pszProvName), dwProvType); + return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); } /****************************************************************************** @@ -384,8 +1097,44 @@ */ BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) { - FIXME("(%s, %ld, %p, %08ld): stub!\n", pszProvName, dwProvType, pdwReserved, dwFlags); - return FALSE; + HKEY hKey; + PSTR keyname; + + TRACE("(%s, %ld, %p, %08ld)\n", pszProvName, dwProvType, pdwReserved, dwFlags); + + if (!pszProvName || pdwReserved) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + if (dwProvType < 0 || dwProvType > MAXPROVTYPES) + CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE); + if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT) + || dwFlags == CRYPT_DELETE_DEFAULT) + CRYPT_ReturnLastError(NTE_BAD_FLAGS); + + if (dwFlags & CRYPT_DELETE_DEFAULT) + { + if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + RegDeleteKeyA( (dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, keyname); + CRYPT_Free(keyname); + return TRUE; + } + + if ( !(keyname = CRYPT_GetProvKeyName(pszProvName)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &hKey)) + { + CRYPT_Free(keyname); + CRYPT_ReturnLastError(NTE_BAD_PROVIDER); + } + CRYPT_Free(keyname); + RegCloseKey(hKey); + if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) ) + CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY); + RegCreateKeyA( (dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, keyname, &hKey); + CRYPT_Free(keyname); + if (RegSetValueExA(hKey, "Name", 0, REG_SZ, pszProvName, strlen(pszProvName) +1)) + return FALSE; + return TRUE; } /****************************************************************************** @@ -393,8 +1142,17 @@ */ BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) { - FIXME("(%s, %ld, %p, %08ld): stub!\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags); - return FALSE; + BOOL ret = FALSE; + PSTR str = NULL; + + TRACE("(%s, %ld, %p, %08ld)\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags); + + if (CRYPT_UnicodeToANSI(pszProvName, &str, -1)) + { + ret = CryptSetProviderExA(str, dwProvType, pdwReserved, dwFlags); + CRYPT_Free(str); + } + return ret; } /****************************************************************************** @@ -402,28 +1160,62 @@ */ BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags) { - FIXME("(0x%lx, %ld, %p, %08ld): stub!\n", hProv, dwParam, pbData, dwFlags); - return FALSE; + PCRYPTPROV prov = (PCRYPTPROV)hProv; + + TRACE("(0x%lx, %ld, %p, %08ld)\n", hProv, dwParam, pbData, dwFlags); + + if (!prov) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (dwFlags & PP_USE_HARDWARE_RNG) + { + FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); + FIXME("\tLetting the CSP decide.\n"); + } + if (dwFlags & PP_CLIENT_HWND) + { + //FIXME: Should verify the parameter + if (pbData /*&& IsWindow((HWND)pbData)*/) + { + crypt_hWindow = (HWND)(pbData); + return TRUE; + } else { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + } + //All other flags go to the CSP + return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags); } /****************************************************************************** + * CryptVerifySignatureA + * + * Note: Since the sDesciption (string) is supposed to be NULL and + * is only retained for compatibility no string conversions are required + * and only one implementation is required for both ANSI and Unicode. + * We still need to export both: + * * CryptVerifySignatureA (ADVAPI32.@) + * CryptVerifySignatureW (ADVAPI32.@) */ BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags) { - FIXME("(0x%lx, %p, %ld, 0x%lx, %s, %08ld): stub!\n", hHash, pbSignature, - dwSigLen, hPubKey, sDescription, dwFlags); - return FALSE; -} - -/****************************************************************************** - * CryptVerifySignatureW (ADVAPI32.@) - */ -BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen, - HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) -{ - FIXME("(0x%lx, %p, %ld, 0x%lx, %s, %08ld): stub!\n", hHash, pbSignature, - dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags); - return FALSE; + PCRYPTHASH hash = (PCRYPTHASH)hHash; + PCRYPTKEY key = (PCRYPTKEY)hPubKey; + PCRYPTPROV prov; + + TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld)\n", hHash, pbSignature, + dwSigLen, hPubKey, dwFlags); + if (sDescription) + WARN("The sDescription parameter is not supported (and no longer used). Ignoring."); + + if (!hash || !key) + CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); + if (!pbSignature || !dwSigLen) + CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); + + prov = hash->pProvider; + return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen, + key->hPrivate, NULL, dwFlags); }
/* * dlls/advapi32/winecrypt.h * * Driver routines * * Copyright 2001 - Travis Michielsen */ #ifndef __WINE_CRYPT_H #define __WINE_CRYPT_H #include "wincrypt.h" typedef struct tagPROVFUNCS { BOOL (*pCPAcquireContext)(HCRYPTPROV *phProv, LPSTR pszContainer, DWORD dwFlags, PVTableProvStruc pVTable); BOOL (*pCPCreateHash)(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash); BOOL (*pCPDecrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); BOOL (*pCPDeriveKey)(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey); BOOL (*pCPDestroyHash)(HCRYPTPROV hProv, HCRYPTHASH hHash); BOOL (*pCPDestroyKey)(HCRYPTPROV hProv, HCRYPTKEY hKey); BOOL (*pCPDuplicateHash)(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash); BOOL (*pCPDuplicateKey)(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey); BOOL (*pCPEncrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen); BOOL (*pCPExportKey)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); BOOL (*pCPGenKey)(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey); BOOL (*pCPGenRandom)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer); BOOL (*pCPGetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags); BOOL (*pCPGetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags); BOOL (*pCPGetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags); BOOL (*pCPGetUserKey)(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey); BOOL (*pCPHashData)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags); BOOL (*pCPHashSessionKey)(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags); BOOL (*pCPImportKey)(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey); BOOL (*pCPReleaseContext)(HCRYPTPROV hProv, DWORD dwFlags); BOOL (*pCPSetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags); BOOL (*pCPSetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags); BOOL (*pCPSetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags); BOOL (*pCPSignHash)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen); BOOL (*pCPVerifySignature)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags); } PROVFUNCS, *PPROVFUNCS; typedef struct tagCRYPTPROV { HMODULE hModule; PPROVFUNCS pFuncs; HCRYPTPROV hPrivate; //CSP's handle - Should not be given to application under any circumstances! PVTableProvStruc pVTable; } CRYPTPROV, *PCRYPTPROV; typedef struct tagCRYPTKEY { PCRYPTPROV pProvider; HCRYPTKEY hPrivate; //CSP's handle - Should not be given to application under any circumstances! } CRYPTKEY, *PCRYPTKEY; typedef struct tagCRYPTHASH { PCRYPTPROV pProvider; HCRYPTHASH hPrivate; //CSP's handle - Should not be given to application under any circumstances! } CRYPTHASH, *PCRYPTHASH; #define MAXPROVTYPES 999 #endif // __WINE_CRYPT_H_