Implemented CryptHashCertificate.
[wine] / dlls / crypt32 / cert.c
1 /*
2  * Copyright 2002 Mike McCormack for CodeWeavers
3  * Copyright 2004,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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #include "winreg.h"
23 #include "wincrypt.h"
24 #include "wine/debug.h"
25 #include "crypt32_private.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28
29 #define WINE_CRYPTCERTSTORE_MAGIC 0x74726563
30
31 typedef struct WINE_CRYPTCERTSTORE
32 {
33     DWORD dwMagic;
34 } WINECRYPT_CERTSTORE;
35
36
37 /*
38  * CertOpenStore
39  *
40  * System Store CA is
41  *  HKLM\\Software\\Microsoft\\SystemCertificates\\CA\\
42  *    Certificates\\<compressed guid>
43  *         "Blob" = REG_BINARY
44  *    CRLs\\<compressed guid>
45  *         "Blob" = REG_BINARY
46  *    CTLs\\<compressed guid>
47  *         "Blob" = REG_BINARY
48  */
49 HCERTSTORE WINAPI CertOpenStore( LPCSTR lpszStoreProvider,
50               DWORD dwMsgAndCertEncodingType, HCRYPTPROV hCryptProv, 
51               DWORD dwFlags, const void* pvPara )
52 {
53     WINECRYPT_CERTSTORE *hcs;
54
55     FIXME("%s %08lx %08lx %08lx %p stub\n", debugstr_a(lpszStoreProvider),
56           dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
57
58     if( lpszStoreProvider == CERT_STORE_PROV_SYSTEM_A )
59     {
60         FIXME("pvPara = %s\n", debugstr_a( (LPCSTR) pvPara ) );
61     }
62     else if ( lpszStoreProvider == CERT_STORE_PROV_SYSTEM_W )
63     {
64         FIXME("pvPara = %s\n", debugstr_w( (LPCWSTR) pvPara ) );
65     }
66
67     hcs = HeapAlloc( GetProcessHeap(), 0, sizeof (WINECRYPT_CERTSTORE) );
68     if( !hcs )
69         return NULL;
70
71     hcs->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
72
73     return (HCERTSTORE) hcs;
74 }
75
76 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV hProv,
77  LPCSTR szSubSystemProtocol)
78 {
79     return CertOpenStore( CERT_STORE_PROV_SYSTEM_A, 0, 0,
80      CERT_SYSTEM_STORE_CURRENT_USER | CERT_SYSTEM_STORE_LOCAL_MACHINE |
81      CERT_SYSTEM_STORE_USERS, szSubSystemProtocol );
82 }
83
84 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV hProv,
85  LPCWSTR szSubSystemProtocol)
86 {
87     return CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, 0,
88      CERT_SYSTEM_STORE_CURRENT_USER | CERT_SYSTEM_STORE_LOCAL_MACHINE |
89      CERT_SYSTEM_STORE_USERS, szSubSystemProtocol );
90 }
91
92 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
93 {
94     FIXME("(%p,%p)\n", hCertStore, pPrev);
95     return NULL;
96 }
97
98 BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
99              DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags)
100 {
101     FIXME("(%p,%ld,%ld,%ld,%p,%08lx) stub!\n", hCertStore, 
102           dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
103     return TRUE;
104 }
105
106 PCCRL_CONTEXT WINAPI CertCreateCRLContext( DWORD dwCertEncodingType,
107   const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
108 {
109     PCRL_CONTEXT pcrl;
110     BYTE* data;
111
112     TRACE("%08lx %p %08lx\n", dwCertEncodingType, pbCrlEncoded, cbCrlEncoded);
113
114     pcrl = HeapAlloc( GetProcessHeap(), 0, sizeof (CRL_CONTEXT) );
115     if( !pcrl )
116         return NULL;
117
118     data = HeapAlloc( GetProcessHeap(), 0, cbCrlEncoded );
119     if( !data )
120     {
121         HeapFree( GetProcessHeap(), 0, pcrl );
122         return NULL;
123     }
124
125     pcrl->dwCertEncodingType = dwCertEncodingType;
126     pcrl->pbCrlEncoded       = data;
127     pcrl->cbCrlEncoded       = cbCrlEncoded;
128     pcrl->pCrlInfo           = NULL;
129     pcrl->hCertStore         = 0;
130
131     return pcrl;
132 }
133
134 BOOL WINAPI CertAddCRLContextToStore( HCERTSTORE hCertStore,
135              PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
136              PCCRL_CONTEXT* ppStoreContext )
137 {
138     FIXME("%p %p %08lx %p\n", hCertStore, pCrlContext,
139           dwAddDisposition, ppStoreContext);
140     return TRUE;
141 }
142
143 BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
144 {
145     FIXME("%p\n", pCrlContext );
146
147     return TRUE;
148 }
149
150 BOOL WINAPI CertCloseStore( HCERTSTORE hCertStore, DWORD dwFlags )
151 {
152     WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
153
154     FIXME("%p %08lx\n", hCertStore, dwFlags );
155     if( ! hCertStore )
156         return FALSE;
157
158     if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
159         return FALSE;
160
161     hcs->dwMagic = 0;
162     HeapFree( GetProcessHeap(), 0, hCertStore );
163
164     return TRUE;
165 }
166
167 BOOL WINAPI CertFreeCertificateContext( PCCERT_CONTEXT pCertContext )
168 {
169     FIXME("%p stub\n", pCertContext);
170     return TRUE;
171 }
172
173 PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
174                 DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType,
175                 const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
176 {
177     FIXME("stub: %p %ld %ld %ld %p %p\n", hCertStore, dwCertEncodingType,
178         dwFlags, dwType, pvPara, pPrevCertContext);
179     SetLastError(CRYPT_E_NOT_FOUND);
180     return NULL;
181 }
182
183 PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr,
184  CRYPT_ATTRIBUTE rgAttr[])
185 {
186     PCRYPT_ATTRIBUTE ret = NULL;
187     DWORD i;
188
189     TRACE("%s %ld %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
190
191     if (!cAttr)
192         return NULL;
193     if (!pszObjId)
194     {
195         SetLastError(ERROR_INVALID_PARAMETER);
196         return NULL;
197     }
198
199     for (i = 0; !ret && i < cAttr; i++)
200         if (rgAttr[i].pszObjId && !strcmp(pszObjId, rgAttr[i].pszObjId))
201             ret = &rgAttr[i];
202     return ret;
203 }
204
205 PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions,
206  CERT_EXTENSION rgExtensions[])
207 {
208     PCERT_EXTENSION ret = NULL;
209     DWORD i;
210
211     TRACE("%s %ld %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
212
213     if (!cExtensions)
214         return NULL;
215     if (!pszObjId)
216     {
217         SetLastError(ERROR_INVALID_PARAMETER);
218         return NULL;
219     }
220
221     for (i = 0; !ret && i < cExtensions; i++)
222         if (rgExtensions[i].pszObjId && !strcmp(pszObjId,
223          rgExtensions[i].pszObjId))
224             ret = &rgExtensions[i];
225     return ret;
226 }
227
228 PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName)
229 {
230     PCERT_RDN_ATTR ret = NULL;
231     DWORD i, j;
232
233     TRACE("%s %p\n", debugstr_a(pszObjId), pName);
234
235     if (!pszObjId)
236     {
237         SetLastError(ERROR_INVALID_PARAMETER);
238         return NULL;
239     }
240
241     for (i = 0; !ret && i < pName->cRDN; i++)
242         for (j = 0; !ret && j < pName->rgRDN[i].cRDNAttr; j++)
243             if (pName->rgRDN[i].rgRDNAttr[j].pszObjId && !strcmp(pszObjId,
244              pName->rgRDN[i].rgRDNAttr[j].pszObjId))
245                 ret = &pName->rgRDN[i].rgRDNAttr[j];
246     return ret;
247 }
248
249 LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify,
250  PCERT_INFO pCertInfo)
251 {
252     FILETIME fileTime;
253     LONG ret;
254
255     if (!pTimeToVerify)
256     {
257         SYSTEMTIME sysTime;
258
259         GetSystemTime(&sysTime);
260         SystemTimeToFileTime(&sysTime, &fileTime);
261         pTimeToVerify = &fileTime;
262     }
263     if ((ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotBefore)) >= 0)
264     {
265         ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotAfter);
266         if (ret < 0)
267             ret = 0;
268     }
269     return ret;
270 }
271
272 BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
273  DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
274  DWORD *pcbComputedHash)
275 {
276     BOOL ret = TRUE;
277     HCRYPTHASH hHash = 0;
278
279     TRACE("(%ld, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags,
280      pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
281
282     if (!hCryptProv)
283         hCryptProv = CRYPT_GetDefaultProvider();
284     if (!Algid)
285         Algid = CALG_SHA1;
286     if (ret)
287     {
288         ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
289         if (ret)
290         {
291             ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0);
292             if (ret)
293                 ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
294                  pcbComputedHash, 0);
295             CryptDestroyHash(hHash);
296         }
297     }
298     return ret;
299 }