shdocvw: Constify some variables.
[wine] / dlls / wintrust / wintrust_main.c
1 /*
2  * Copyright 2001 Rein Klazes
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winreg.h"
27 #include "guiddef.h"
28 #include "wintrust.h"
29 #include "softpub.h"
30 #include "mscat.h"
31 #include "objbase.h"
32 #include "wintrust_priv.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
36
37
38 /***********************************************************************
39  *              DllMain  (WINTRUST.@)
40  */
41 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
42 {
43     switch(reason)
44     {
45     case DLL_WINE_PREATTACH:
46         return FALSE;  /* prefer native version */
47     case DLL_PROCESS_ATTACH:
48         DisableThreadLibraryCalls( inst );
49         break;
50     }
51     return TRUE;
52 }
53
54 /***********************************************************************
55  *              TrustIsCertificateSelfSigned (WINTRUST.@)
56  */
57 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
58 {
59     BOOL ret;
60
61     TRACE("%p\n", cert);
62     ret = CertCompareCertificateName(cert->dwCertEncodingType,
63      &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
64     return ret;
65 }
66
67 /***********************************************************************
68  *              WinVerifyTrust (WINTRUST.@)
69  *
70  * Verifies an object by calling the specified trust provider.
71  *
72  * PARAMS
73  *   hwnd       [I] Handle to a caller window.
74  *   ActionID   [I] Pointer to a GUID that identifies the action to perform.
75  *   ActionData [I] Information used by the trust provider to verify the object.
76  *
77  * RETURNS
78  *   Success: Zero.
79  *   Failure: A TRUST_E_* error code.
80  *
81  * NOTES
82  *   Trust providers can be found at:
83  *   HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
84  */
85 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
86 {
87     FIXME("%p %s %p\n", hwnd, debugstr_guid(ActionID), ActionData);
88     return ERROR_SUCCESS;
89 }
90
91 /***********************************************************************
92  *              WinVerifyTrustEx (WINTRUST.@)
93  */
94 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
95  WINTRUST_DATA* ActionData )
96 {
97     return WinVerifyTrust(hwnd, ActionID, ActionData);
98 }
99
100 /***********************************************************************
101  *              WTHelperGetProvSignerFromChain (WINTRUST.@)
102  */
103 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
104  CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
105  DWORD idxCounterSigner)
106 {
107     CRYPT_PROVIDER_SGNR *sgnr;
108
109     TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
110      idxCounterSigner);
111
112     if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
113         return NULL;
114     sgnr = &pProvData->pasSigners[idxSigner];
115     if (fCounterSigner)
116     {
117         if (idxCounterSigner >= sgnr->csCounterSigners ||
118          !sgnr->pasCounterSigners)
119             return NULL;
120         sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
121     }
122     TRACE("returning %p\n", sgnr);
123     return sgnr;
124 }
125
126 /***********************************************************************
127  *              WTHelperGetProvCertFromChain (WINTRUST.@)
128  */
129 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
130  CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
131 {
132     CRYPT_PROVIDER_CERT *cert;
133
134     TRACE("(%p %d)\n", pSgnr, idxCert);
135
136     if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
137         return NULL;
138     cert = &pSgnr->pasCertChain[idxCert];
139     TRACE("returning %p\n", cert);
140     return cert;
141 }
142
143 /***********************************************************************
144  *              WTHelperProvDataFromStateData (WINTRUST.@)
145  */
146 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
147 {
148     TRACE("%p\n", hStateData);
149     return (CRYPT_PROVIDER_DATA *)hStateData;
150 }
151
152 static const WCHAR Software_Publishing[] = {
153  'S','o','f','t','w','a','r','e','\\',
154  'M','i','c','r','o','s','o','f','t','\\',
155  'W','i','n','d','o','w','s','\\',
156  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
157  'W','i','n','t','r','u','s','t','\\',
158  'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
159  'S','o','f','t','w','a','r','e',' ',
160  'P','u','b','l','i','s','h','i','n','g',0 };
161 static const WCHAR State[] = { 'S','t','a','t','e',0 };
162
163 /***********************************************************************
164  *              WintrustGetRegPolicyFlags (WINTRUST.@)
165  */
166 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
167 {
168     HKEY key;
169     LONG r;
170
171     TRACE("%p\n", pdwPolicyFlags);
172
173     *pdwPolicyFlags = 0;
174     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
175      KEY_READ, NULL, &key, NULL);
176     if (!r)
177     {
178         DWORD size = sizeof(DWORD);
179
180         r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
181          &size);
182         RegCloseKey(key);
183         if (r)
184         {
185             /* Failed to query, create and return default value */
186             *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
187              WTPF_OFFLINEOKNBU_COM |
188              WTPF_OFFLINEOKNBU_IND |
189              WTPF_OFFLINEOK_COM |
190              WTPF_OFFLINEOK_IND;
191             WintrustSetRegPolicyFlags(*pdwPolicyFlags);
192         }
193     }
194 }
195
196 /***********************************************************************
197  *              WintrustSetRegPolicyFlags (WINTRUST.@)
198  */
199 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
200 {
201     HKEY key;
202     LONG r;
203
204     TRACE("%x\n", dwPolicyFlags);
205
206     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
207      NULL, 0, KEY_WRITE, NULL, &key, NULL);
208     if (!r)
209     {
210         r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
211          sizeof(DWORD));
212         RegCloseKey(key);
213     }
214     if (r) SetLastError(r);
215     return r == ERROR_SUCCESS;
216 }
217
218 /* Utility functions */
219 void * WINAPI WINTRUST_Alloc(DWORD cb)
220 {
221     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
222 }
223
224 void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
225 {
226     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
227 }
228
229 void WINAPI WINTRUST_Free(void *p)
230 {
231     HeapFree(GetProcessHeap(), 0, p);
232 }
233
234 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
235 {
236     BOOL ret = FALSE;
237
238     if (data->chStores)
239         data->pahStores = WINTRUST_ReAlloc(data->pahStores,
240          (data->chStores + 1) * sizeof(HCERTSTORE));
241     else
242     {
243         data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
244         data->chStores = 0;
245     }
246     if (data->pahStores)
247     {
248         data->pahStores[data->chStores++] = CertDuplicateStore(store);
249         ret = TRUE;
250     }
251     else
252         SetLastError(ERROR_OUTOFMEMORY);
253     return ret;
254 }
255
256 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
257  BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
258 {
259     BOOL ret = FALSE;
260
261     if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
262     {
263         SetLastError(ERROR_INVALID_PARAMETER);
264         return FALSE;
265     }
266     if (fCounterSigner)
267     {
268         FIXME("unimplemented for counter signers\n");
269         SetLastError(ERROR_INVALID_PARAMETER);
270         return FALSE;
271     }
272     if (data->csSigners)
273         data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
274          (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
275     else
276     {
277         data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
278         data->csSigners = 0;
279     }
280     if (data->pasSigners)
281     {
282         if (idxSigner < data->csSigners)
283             memmove(&data->pasSigners[idxSigner],
284              &data->pasSigners[idxSigner + 1],
285              (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
286         ret = TRUE;
287         if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
288         {
289             /* The PSDK says psSigner should be allocated using pfnAlloc, but
290              * it doesn't say anything about ownership.  Since callers are
291              * internal, assume ownership is passed, and just store the
292              * pointer.
293              */
294             memcpy(&data->pasSigners[idxSigner], sgnr,
295              sizeof(CRYPT_PROVIDER_SGNR));
296         }
297         else
298             memset(&data->pasSigners[idxSigner], 0,
299              sizeof(CRYPT_PROVIDER_SGNR));
300         data->csSigners++;
301     }
302     else
303         SetLastError(ERROR_OUTOFMEMORY);
304     return ret;
305 }
306
307 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
308  BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
309 {
310     BOOL ret = FALSE;
311
312     if (fCounterSigner)
313     {
314         FIXME("unimplemented for counter signers\n");
315         SetLastError(ERROR_INVALID_PARAMETER);
316         return FALSE;
317     }
318     if (data->pasSigners[idxSigner].csCertChain)
319         data->pasSigners[idxSigner].pasCertChain =
320          WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
321          (data->pasSigners[idxSigner].csCertChain + 1) *
322          sizeof(CRYPT_PROVIDER_CERT));
323     else
324     {
325         data->pasSigners[idxSigner].pasCertChain =
326          WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
327         data->pasSigners[idxSigner].csCertChain = 0;
328     }
329     if (data->pasSigners[idxSigner].pasCertChain)
330     {
331         CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
332          data->pasSigners[idxSigner].csCertChain];
333
334         cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
335         cert->pCert = CertDuplicateCertificateContext(pCert2Add);
336         data->pasSigners[idxSigner].csCertChain++;
337         ret = TRUE;
338     }
339     else
340         SetLastError(ERROR_OUTOFMEMORY);
341     return ret;
342 }