1 /* 2 * Copyright 2002 Mike McCormack for CodeWeavers 3 * Copyright 2005 Juan Lang 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "config.h" 21 #include <stdarg.h> 22 #include <stdio.h> 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "wincrypt.h" 27 #include "winreg.h" 28 #include "winuser.h" 29 #include "i_cryptasn1tls.h" 30 #include "crypt32_private.h" 31 #include "wine/debug.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 34 35 static HCRYPTPROV hDefProv; 36 HINSTANCE hInstance; 37 38 static CRITICAL_SECTION prov_param_cs; 39 static CRITICAL_SECTION_DEBUG prov_param_cs_debug = 40 { 41 0, 0, &prov_param_cs, 42 { &prov_param_cs_debug.ProcessLocksList, 43 &prov_param_cs_debug.ProcessLocksList }, 44 0, 0, { (DWORD_PTR)(__FILE__ ": prov_param_cs") } 45 }; 46 static CRITICAL_SECTION prov_param_cs = { &prov_param_cs_debug, -1, 0, 0, 0, 0 }; 47 48 BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) 49 { 50 switch (fdwReason) 51 { 52 case DLL_PROCESS_ATTACH: 53 hInstance = hInst; 54 DisableThreadLibraryCalls(hInst); 55 init_empty_store(); 56 crypt_oid_init(); 57 break; 58 case DLL_PROCESS_DETACH: 59 if (pvReserved) break; 60 crypt_oid_free(); 61 crypt_sip_free(); 62 default_chain_engine_free(); 63 if (hDefProv) CryptReleaseContext(hDefProv, 0); 64 break; 65 } 66 return TRUE; 67 } 68 69 static HCRYPTPROV CRYPT_GetDefaultProvider(void) 70 { 71 if (!hDefProv) 72 { 73 HCRYPTPROV prov; 74 75 if (!CryptAcquireContextW(&prov, NULL, MS_ENH_RSA_AES_PROV_W, 76 PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) 77 return hDefProv; 78 InterlockedCompareExchangePointer((PVOID *)&hDefProv, (PVOID)prov, 79 NULL); 80 if (hDefProv != prov) 81 CryptReleaseContext(prov, 0); 82 } 83 return hDefProv; 84 } 85 86 typedef void * HLRUCACHE; 87 88 /* this function is called by Internet Explorer when it is about to verify a 89 * downloaded component. The first parameter appears to be a pointer to an 90 * unknown type, native fails unless it points to a buffer of at least 20 bytes. 91 * The second parameter appears to be an out parameter, whatever it's set to is 92 * passed (by cryptnet.dll) to I_CryptFlushLruCache. 93 */ 94 BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out) 95 { 96 FIXME("(%p, %p): stub!\n", unknown, out); 97 *out = (void *)0xbaadf00d; 98 return TRUE; 99 } 100 101 BOOL WINAPI I_CryptFindLruEntry(DWORD unk0, DWORD unk1) 102 { 103 FIXME("(%08x, %08x): stub!\n", unk0, unk1); 104 return FALSE; 105 } 106 107 BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2) 108 { 109 FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2); 110 return FALSE; 111 } 112 113 BOOL WINAPI I_CryptCreateLruEntry(HLRUCACHE h, DWORD unk0, DWORD unk1) 114 { 115 FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); 116 return FALSE; 117 } 118 119 DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) 120 { 121 FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); 122 return 0; 123 } 124 125 HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) 126 { 127 FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); 128 return h; 129 } 130 131 LPVOID WINAPI CryptMemAlloc(ULONG cbSize) 132 { 133 return HeapAlloc(GetProcessHeap(), 0, cbSize); 134 } 135 136 LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize) 137 { 138 return HeapReAlloc(GetProcessHeap(), 0, pv, cbSize); 139 } 140 141 VOID WINAPI CryptMemFree(LPVOID pv) 142 { 143 HeapFree(GetProcessHeap(), 0, pv); 144 } 145 146 DWORD WINAPI I_CryptAllocTls(void) 147 { 148 return TlsAlloc(); 149 } 150 151 LPVOID WINAPI I_CryptDetachTls(DWORD dwTlsIndex) 152 { 153 LPVOID ret; 154 155 ret = TlsGetValue(dwTlsIndex); 156 TlsSetValue(dwTlsIndex, NULL); 157 return ret; 158 } 159 160 LPVOID WINAPI I_CryptGetTls(DWORD dwTlsIndex) 161 { 162 return TlsGetValue(dwTlsIndex); 163 } 164 165 BOOL WINAPI I_CryptSetTls(DWORD dwTlsIndex, LPVOID lpTlsValue) 166 { 167 return TlsSetValue(dwTlsIndex, lpTlsValue); 168 } 169 170 BOOL WINAPI I_CryptFreeTls(DWORD dwTlsIndex, DWORD unknown) 171 { 172 BOOL ret; 173 174 TRACE("(%d, %d)\n", dwTlsIndex, unknown); 175 176 ret = TlsFree(dwTlsIndex); 177 if (!ret) SetLastError( E_INVALIDARG ); 178 return ret; 179 } 180 181 BOOL WINAPI I_CryptGetOssGlobal(DWORD x) 182 { 183 FIXME("%08x\n", x); 184 return FALSE; 185 } 186 187 static BOOL is_supported_algid(HCRYPTPROV prov, ALG_ID algid) 188 { 189 PROV_ENUMALGS prov_algs; 190 DWORD size = sizeof(prov_algs); 191 BOOL ret = FALSE; 192 193 /* This enumeration is not thread safe */ 194 EnterCriticalSection(&prov_param_cs); 195 if (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size, CRYPT_FIRST)) 196 { 197 do 198 { 199 if (prov_algs.aiAlgid == algid) 200 { 201 ret = TRUE; 202 break; 203 } 204 } while (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size, CRYPT_NEXT)); 205 } 206 LeaveCriticalSection(&prov_param_cs); 207 return ret; 208 } 209 210 HCRYPTPROV WINAPI DECLSPEC_HOTPATCH I_CryptGetDefaultCryptProv(ALG_ID algid) 211 { 212 HCRYPTPROV prov, defprov; 213 214 TRACE("(%08x)\n", algid); 215 216 defprov = CRYPT_GetDefaultProvider(); 217 218 if (algid && !is_supported_algid(defprov, algid)) 219 { 220 DWORD i = 0, type, size; 221 222 while (CryptEnumProvidersW(i, NULL, 0, &type, NULL, &size)) 223 { 224 WCHAR *name = CryptMemAlloc(size); 225 if (name) 226 { 227 if (CryptEnumProvidersW(i, NULL, 0, &type, name, &size)) 228 { 229 if (CryptAcquireContextW(&prov, NULL, name, type, CRYPT_VERIFYCONTEXT)) 230 { 231 if (is_supported_algid(prov, algid)) 232 { 233 CryptMemFree(name); 234 return prov; 235 } 236 CryptReleaseContext(prov, 0); 237 } 238 } 239 CryptMemFree(name); 240 } 241 i++; 242 } 243 244 SetLastError(E_INVALIDARG); 245 return 0; 246 } 247 248 CryptContextAddRef(defprov, NULL, 0); 249 return defprov; 250 } 251 252 BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name, 253 DWORD *value) 254 { 255 static const WCHAR safer[] = { 256 'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\', 257 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m', 258 'C','e','r','t','i','f','i','c','a','t','e','s','\\', 259 'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r','\\', 260 'S','a','f','e','r',0 }; 261 HKEY key; 262 LONG rc; 263 BOOL ret = FALSE; 264 265 TRACE("(%s, %p)\n", debugstr_w(name), value); 266 267 *value = 0; 268 rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, safer, &key); 269 if (rc == ERROR_SUCCESS) 270 { 271 DWORD size = sizeof(DWORD); 272 273 if (!RegQueryValueExW(key, name, NULL, NULL, (LPBYTE)value, &size)) 274 ret = TRUE; 275 RegCloseKey(key); 276 } 277 return ret; 278 } 279 280 DWORD WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z) 281 { 282 static int ret = 8; 283 ret++; 284 FIXME("%08x %08x %08x, return value %d\n", x, y, z,ret); 285 return ret; 286 } 287 288 BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t x, DWORD y, void* z) 289 { 290 FIXME("(%p %08x %p): stub\n", x, y, z); 291 return TRUE; 292 } 293 294 BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE x) 295 { 296 FIXME("(%08x): stub\n", x); 297 return TRUE; 298 } 299 300 ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE x) 301 { 302 FIXME("(%08x): stub\n", x); 303 return NULL; 304 } 305 306 ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE x) 307 { 308 FIXME("(%08x): stub\n", x); 309 return NULL; 310 } 311 312 BOOL WINAPI CryptProtectMemory(void *data, DWORD len, DWORD flags) 313 { 314 static int fixme_once; 315 if (!fixme_once++) FIXME("(%p %u %08x): stub\n", data, len, flags); 316 return TRUE; 317 } 318 319 BOOL WINAPI CryptUnprotectMemory(void *data, DWORD len, DWORD flags) 320 { 321 static int fixme_once; 322 if (!fixme_once++) FIXME("(%p %u %08x): stub\n", data, len, flags); 323 return TRUE; 324 } 325