2 * Copyright 2006 Juan Lang
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.
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.
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
25 #include "wine/debug.h"
26 #include "crypt32_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
30 PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
31 const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
33 PCRL_CONTEXT crl = NULL;
35 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
36 PCRL_INFO crlInfo = NULL;
39 TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCrlEncoded,
42 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
44 SetLastError(E_INVALIDARG);
47 /* First try to decode it as a signed crl. */
48 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT, pbCrlEncoded,
49 cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&signedCrl, &size);
53 ret = CryptDecodeObjectEx(dwCertEncodingType,
54 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
55 signedCrl->ToBeSigned.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
56 (BYTE *)&crlInfo, &size);
59 /* Failing that, try it as an unsigned crl */
63 ret = CryptDecodeObjectEx(dwCertEncodingType,
64 X509_CERT_CRL_TO_BE_SIGNED, pbCrlEncoded, cbCrlEncoded,
65 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
66 (BYTE *)&crlInfo, &size);
72 crl = (PCRL_CONTEXT)Context_CreateDataContext(sizeof(CRL_CONTEXT));
75 data = CryptMemAlloc(cbCrlEncoded);
82 memcpy(data, pbCrlEncoded, cbCrlEncoded);
83 crl->dwCertEncodingType = dwCertEncodingType;
84 crl->pbCrlEncoded = data;
85 crl->cbCrlEncoded = cbCrlEncoded;
86 crl->pCrlInfo = crlInfo;
91 return (PCCRL_CONTEXT)crl;
94 BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
95 DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded,
96 DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext)
98 PCCRL_CONTEXT crl = CertCreateCRLContext(dwCertEncodingType,
99 pbCrlEncoded, cbCrlEncoded);
102 TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType,
103 pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext);
107 ret = CertAddCRLContextToStore(hCertStore, crl, dwAddDisposition,
109 CertFreeCRLContext(crl);
116 typedef BOOL (*CrlCompareFunc)(PCCRL_CONTEXT pCrlContext, DWORD dwType,
117 DWORD dwFlags, const void *pvPara);
119 static BOOL compare_crl_any(PCCRL_CONTEXT pCrlContext, DWORD dwType,
120 DWORD dwFlags, const void *pvPara)
125 static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType,
126 DWORD dwFlags, const void *pvPara)
132 PCCERT_CONTEXT issuer = (PCCERT_CONTEXT)pvPara;
134 ret = CertCompareCertificateName(issuer->dwCertEncodingType,
135 &issuer->pCertInfo->Issuer, &pCrlContext->pCrlInfo->Issuer);
142 static BOOL compare_crl_existing(PCCRL_CONTEXT pCrlContext, DWORD dwType,
143 DWORD dwFlags, const void *pvPara)
149 PCCRL_CONTEXT crl = (PCCRL_CONTEXT)pvPara;
151 ret = CertCompareCertificateName(pCrlContext->dwCertEncodingType,
152 &pCrlContext->pCrlInfo->Issuer, &crl->pCrlInfo->Issuer);
159 PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore,
160 DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType,
161 const void *pvFindPara, PCCRL_CONTEXT pPrevCrlContext)
164 CrlCompareFunc compare;
166 TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType,
167 dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext);
172 compare = compare_crl_any;
174 case CRL_FIND_ISSUED_BY:
175 compare = compare_crl_issued_by;
177 case CRL_FIND_EXISTING:
178 compare = compare_crl_existing;
181 FIXME("find type %08lx unimplemented\n", dwFindType);
187 BOOL matches = FALSE;
189 ret = pPrevCrlContext;
191 ret = CertEnumCRLsInStore(hCertStore, ret);
193 matches = compare(ret, dwFindType, dwFindFlags, pvFindPara);
194 } while (ret != NULL && !matches);
196 SetLastError(CRYPT_E_NOT_FOUND);
200 SetLastError(CRYPT_E_NOT_FOUND);
206 PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
208 TRACE("(%p)\n", pCrlContext);
209 Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
213 static void CrlDataContext_Free(void *context)
215 PCRL_CONTEXT crlContext = (PCRL_CONTEXT)context;
217 CryptMemFree(crlContext->pbCrlEncoded);
218 LocalFree(crlContext->pCrlInfo);
221 BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
223 TRACE("(%p)\n", pCrlContext);
226 Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
227 CrlDataContext_Free);
231 DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
234 PCONTEXT_PROPERTY_LIST properties = Context_GetProperties(
235 (void *)pCRLContext, sizeof(CRL_CONTEXT));
238 TRACE("(%p, %ld)\n", pCRLContext, dwPropId);
241 ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
247 static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
248 DWORD dwFlags, const void *pvData);
250 static BOOL CRLContext_GetHashProp(void *context, DWORD dwPropId,
251 ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
254 BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
258 CRYPT_DATA_BLOB blob = { *pcbData, pvData };
260 ret = CRLContext_SetProperty(context, dwPropId, 0, &blob);
265 static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
266 void *pvData, DWORD *pcbData)
268 PCCRL_CONTEXT pCRLContext = (PCCRL_CONTEXT)context;
269 PCONTEXT_PROPERTY_LIST properties =
270 Context_GetProperties(context, sizeof(CRL_CONTEXT));
272 CRYPT_DATA_BLOB blob;
274 TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData);
277 ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
284 *pcbData = blob.cbData;
287 else if (*pcbData < blob.cbData)
289 SetLastError(ERROR_MORE_DATA);
290 *pcbData = blob.cbData;
294 memcpy(pvData, blob.pbData, blob.cbData);
295 *pcbData = blob.cbData;
301 /* Implicit properties */
304 case CERT_SHA1_HASH_PROP_ID:
305 ret = CRLContext_GetHashProp(context, dwPropId, CALG_SHA1,
306 pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
309 case CERT_MD5_HASH_PROP_ID:
310 ret = CRLContext_GetHashProp(context, dwPropId, CALG_MD5,
311 pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
315 SetLastError(CRYPT_E_NOT_FOUND);
318 TRACE("returning %d\n", ret);
322 BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
323 DWORD dwPropId, void *pvData, DWORD *pcbData)
327 TRACE("(%p, %ld, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData);
332 case CERT_CERT_PROP_ID:
333 case CERT_CRL_PROP_ID:
334 case CERT_CTL_PROP_ID:
335 SetLastError(E_INVALIDARG);
338 case CERT_ACCESS_STATE_PROP_ID:
341 *pcbData = sizeof(DWORD);
344 else if (*pcbData < sizeof(DWORD))
346 SetLastError(ERROR_MORE_DATA);
347 *pcbData = sizeof(DWORD);
353 CertStore_GetAccessState(pCRLContext->hCertStore);
358 ret = CRLContext_GetProperty((void *)pCRLContext, dwPropId, pvData,
364 static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
365 DWORD dwFlags, const void *pvData)
367 PCONTEXT_PROPERTY_LIST properties =
368 Context_GetProperties(context, sizeof(CERT_CONTEXT));
371 TRACE("(%p, %ld, %08lx, %p)\n", context, dwPropId, dwFlags, pvData);
377 ContextPropertyList_RemoveProperty(properties, dwPropId);
384 case CERT_AUTO_ENROLL_PROP_ID:
385 case CERT_CTL_USAGE_PROP_ID: /* same as CERT_ENHKEY_USAGE_PROP_ID */
386 case CERT_DESCRIPTION_PROP_ID:
387 case CERT_FRIENDLY_NAME_PROP_ID:
388 case CERT_HASH_PROP_ID:
389 case CERT_KEY_IDENTIFIER_PROP_ID:
390 case CERT_MD5_HASH_PROP_ID:
391 case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
392 case CERT_PUBKEY_ALG_PARA_PROP_ID:
393 case CERT_PVK_FILE_PROP_ID:
394 case CERT_SIGNATURE_HASH_PROP_ID:
395 case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
396 case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
397 case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
398 case CERT_ENROLLMENT_PROP_ID:
399 case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
400 case CERT_RENEWAL_PROP_ID:
402 PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
404 ret = ContextPropertyList_SetProperty(properties, dwPropId,
405 blob->pbData, blob->cbData);
408 case CERT_DATE_STAMP_PROP_ID:
409 ret = ContextPropertyList_SetProperty(properties, dwPropId,
410 (LPBYTE)pvData, sizeof(FILETIME));
413 FIXME("%ld: stub\n", dwPropId);
417 TRACE("returning %d\n", ret);
421 BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
422 DWORD dwPropId, DWORD dwFlags, const void *pvData)
426 TRACE("(%p, %ld, %08lx, %p)\n", pCRLContext, dwPropId, dwFlags, pvData);
428 /* Handle special cases for "read-only"/invalid prop IDs. Windows just
429 * crashes on most of these, I'll be safer.
434 case CERT_ACCESS_STATE_PROP_ID:
435 case CERT_CERT_PROP_ID:
436 case CERT_CRL_PROP_ID:
437 case CERT_CTL_PROP_ID:
438 SetLastError(E_INVALIDARG);
441 ret = CRLContext_SetProperty((void *)pCRLContext, dwPropId, dwFlags,
443 TRACE("returning %d\n", ret);
447 LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify,
457 GetSystemTime(&sysTime);
458 SystemTimeToFileTime(&sysTime, &fileTime);
459 pTimeToVerify = &fileTime;
461 if ((ret = CompareFileTime(pTimeToVerify, &pCrlInfo->ThisUpdate)) >= 0)
463 ret = CompareFileTime(pTimeToVerify, &pCrlInfo->NextUpdate);