xref: /reactos/dll/win32/crypt32/main.c (revision 4567e13e)
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