ReactOS 0.4.17-dev-444-g71ee754
cert.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2006 Juan Lang
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
20#include <assert.h>
21#include <stdarg.h>
22
23#include "ntstatus.h"
24#define WIN32_NO_STATUS
25#include "windef.h"
26#include "winbase.h"
27#include "winternl.h"
28#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
29#include "wincrypt.h"
30#include "snmp.h"
31#include "bcrypt.h"
32#include "winnls.h"
33#include "rpc.h"
34#include "wine/debug.h"
35#include "crypt32_private.h"
36
38
39/* Internal version of CertGetCertificateContextProperty that gets properties
40 * directly from the context (or the context it's linked to, depending on its
41 * type.) Doesn't handle special-case properties, since they are handled by
42 * CertGetCertificateContextProperty, and are particular to the store in which
43 * the property exists (which is separate from the context.)
44 */
46 void *pvData, DWORD *pcbData);
47
48/* Internal version of CertSetCertificateContextProperty that sets properties
49 * directly on the context (or the context it's linked to, depending on its
50 * type.) Doesn't handle special cases, since they're handled by
51 * CertSetCertificateContextProperty anyway.
52 */
54 DWORD dwFlags, const void *pvData);
55
57 DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded,
58 DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
59{
61 pbCertEncoded, cbCertEncoded);
62 BOOL ret;
63
64 TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType,
65 pbCertEncoded, cbCertEncoded, dwAddDisposition, ppCertContext);
66
67 if (cert)
68 {
70 dwAddDisposition, ppCertContext);
72 }
73 else
74 ret = FALSE;
75 return ret;
76}
77
79 const BYTE *pbCertEncoded, DWORD cbCertEncoded)
80{
81 HCERTSTORE store;
82 BOOL ret = FALSE;
83
84 TRACE("(%s, %p, %ld)\n", debugstr_a(pszCertStoreName), pbCertEncoded,
85 cbCertEncoded);
86
87 store = CertOpenSystemStoreA(0, pszCertStoreName);
88 if (store)
89 {
91 pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL);
92 CertCloseStore(store, 0);
93 }
94 return ret;
95}
96
98 const BYTE *pbCertEncoded, DWORD cbCertEncoded)
99{
100 HCERTSTORE store;
101 BOOL ret = FALSE;
102
103 TRACE("(%s, %p, %ld)\n", debugstr_w(pszCertStoreName), pbCertEncoded,
104 cbCertEncoded);
105
106 store = CertOpenSystemStoreW(0, pszCertStoreName);
107 if (store)
108 {
110 pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL);
111 CertCloseStore(store, 0);
112 }
113 return ret;
114}
115
117
119{
121
122 CryptMemFree(cert->ctx.pbCertEncoded);
123 LocalFree(cert->ctx.pCertInfo);
124}
125
127{
128 cert_t *cert;
129
130 if(use_link) {
132 if(!cert)
133 return NULL;
134 }else {
135 const cert_t *cloned = (const cert_t*)context;
136 DWORD size = 0;
137 BOOL res;
138
140 if(!cert)
141 return NULL;
142
143 Context_CopyProperties(&cert->ctx, &cloned->ctx);
144
145 cert->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType;
146 cert->ctx.pbCertEncoded = CryptMemAlloc(cloned->ctx.cbCertEncoded);
147 memcpy(cert->ctx.pbCertEncoded, cloned->ctx.pbCertEncoded, cloned->ctx.cbCertEncoded);
148 cert->ctx.cbCertEncoded = cloned->ctx.cbCertEncoded;
149
150 /* FIXME: We don't need to decode the object here, we could just clone cert info. */
151 res = CryptDecodeObjectEx(cert->ctx.dwCertEncodingType, X509_CERT_TO_BE_SIGNED,
152 cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
153 &cert->ctx.pCertInfo, &size);
154 if(!res) {
156 return NULL;
157 }
158 }
159
160 cert->ctx.hCertStore = store;
161 return &cert->base;
162}
163
164static const context_vtbl_t cert_vtbl = {
165 Cert_free,
167};
168
170 DWORD add_disposition, BOOL use_link, PCCERT_CONTEXT *ret_context)
171{
172 const CERT_CONTEXT *existing = NULL;
173 BOOL ret = TRUE, inherit_props = FALSE;
174 context_t *new_context = NULL;
175
176 switch (add_disposition)
177 {
179 break;
186 {
187 BYTE hashToAdd[20];
188 DWORD size = sizeof(hashToAdd);
189
191 hashToAdd, &size);
192 if (ret)
193 {
194 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
195
196 existing = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0,
198 }
199 break;
200 }
201 default:
202 FIXME("Unimplemented add disposition %ld\n", add_disposition);
204 return FALSE;
205 }
206
207 switch (add_disposition)
208 {
210 break;
212 if (existing)
213 {
214 TRACE("found matching certificate, not adding\n");
216 return FALSE;
217 }
218 break;
220 break;
222 if (use_link)
223 FIXME("CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: semi-stub for links\n");
224 if (existing)
225 inherit_props = TRUE;
226 break;
228 if(use_link)
229 FIXME("CERT_STORE_ADD_USE_EXISTING: semi-stub for links\n");
230 if (existing)
231 {
232 Context_CopyProperties(existing, cert);
233 if (ret_context)
234 *ret_context = CertDuplicateCertificateContext(existing);
235 return TRUE;
236 }
237 break;
239 if (existing && CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
240 {
241 TRACE("existing certificate is newer, not adding\n");
243 return FALSE;
244 }
245 break;
247 if (existing)
248 {
249 if (CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
250 {
251 TRACE("existing certificate is newer, not adding\n");
253 return FALSE;
254 }
255 inherit_props = TRUE;
256 }
257 break;
258 }
259
260 /* FIXME: We have tests that this works, but what should we really do in this case? */
261 if(!store) {
262 if(ret_context)
264 return TRUE;
265 }
266
267 ret = store->vtbl->certs.addContext(store, context_from_ptr(cert), existing ? context_from_ptr(existing) : NULL,
268 (ret_context || inherit_props) ? &new_context : NULL, use_link);
269 if(!ret)
270 return FALSE;
271
272 if(inherit_props)
273 Context_CopyProperties(context_ptr(new_context), existing);
274
275 if(ret_context)
276 *ret_context = context_ptr(new_context);
277 else if(new_context)
278 Context_Release(new_context);
279
280 TRACE("returning %d\n", ret);
281 return ret;
282}
283
285 DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
286{
287 WINECRYPT_CERTSTORE *store = hCertStore;
288
289 TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext);
290
291 return add_cert_to_store(store, pCertContext, dwAddDisposition, FALSE, ppStoreContext);
292}
293
295 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
296 PCCERT_CONTEXT *ppCertContext)
297{
298 static int calls;
299 WINECRYPT_CERTSTORE *store = (WINECRYPT_CERTSTORE*)hCertStore;
300
301 if (!(calls++))
302 FIXME("(%p, %p, %08lx, %p): semi-stub\n", hCertStore, pCertContext,
303 dwAddDisposition, ppCertContext);
305 return FALSE;
306 if (store->type == StoreTypeCollection)
307 {
309 return FALSE;
310 }
311 return add_cert_to_store(hCertStore, pCertContext, dwAddDisposition, TRUE, ppCertContext);
312}
313
315 const BYTE *pbCertEncoded, DWORD cbCertEncoded)
316{
317 cert_t *cert = NULL;
318 BYTE *data = NULL;
319 BOOL ret;
320 PCERT_INFO certInfo = NULL;
321 DWORD size = 0;
322
323 TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCertEncoded,
324 cbCertEncoded);
325
326 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
327 {
329 return NULL;
330 }
331
332 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_TO_BE_SIGNED,
333 pbCertEncoded, cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
334 &certInfo, &size);
335 if (!ret)
336 return NULL;
337
339 if (!cert)
340 return NULL;
341 data = CryptMemAlloc(cbCertEncoded);
342 if (!data)
343 {
344 Context_Release(&cert->base);
345 return NULL;
346 }
347
348 memcpy(data, pbCertEncoded, cbCertEncoded);
349 cert->ctx.dwCertEncodingType = dwCertEncodingType;
350 cert->ctx.pbCertEncoded = data;
351 cert->ctx.cbCertEncoded = cbCertEncoded;
352 cert->ctx.pCertInfo = certInfo;
353 cert->ctx.hCertStore = &empty_store;
354
355 return &cert->ctx;
356}
357
359{
360 TRACE("(%p)\n", pCertContext);
361
362 if (!pCertContext)
363 return NULL;
364
365 Context_AddRef(&cert_from_ptr(pCertContext)->base);
366 return pCertContext;
367}
368
370{
371 TRACE("(%p)\n", pCertContext);
372
373 if (pCertContext)
374 Context_Release(&cert_from_ptr(pCertContext)->base);
375 return TRUE;
376}
377
379 DWORD dwPropId)
380{
381 cert_t *cert = cert_from_ptr(pCertContext);
382 DWORD ret;
383
384 TRACE("(%p, %ld)\n", pCertContext, dwPropId);
385
386 if (cert->base.properties)
387 ret = ContextPropertyList_EnumPropIDs(cert->base.properties, dwPropId);
388 else
389 ret = 0;
390 return ret;
391}
392
394 ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
395 DWORD *pcbData)
396{
397 BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
398 pcbData);
399 if (ret && pvData)
400 {
402
403 ret = CertContext_SetProperty(cert, dwPropId, 0, &blob);
404 }
405 return ret;
406}
407
408static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb,
409 DWORD cb)
410{
411 BOOL ret = TRUE;
412
413 if (!pvData)
414 *pcbData = cb;
415 else if (*pcbData < cb)
416 {
418 *pcbData = cb;
419 ret = FALSE;
420 }
421 else
422 {
423 memcpy(pvData, pb, cb);
424 *pcbData = cb;
425 }
426 return ret;
427}
428
430{
431 dst->cbSize = sizeof(*dst);
432 dst->hCryptProv = src->hCryptProv;
433 dst->dwKeySpec = src->dwKeySpec;
434}
435
436/*
437 * Fix offsets in a continuous block of memory of CRYPT_KEY_PROV_INFO with
438 * its associated data.
439 */
441{
442 BYTE *data;
443 DWORD i;
444
445 data = (BYTE *)(info + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * info->cProvParam;
446
447 if (info->pwszContainerName)
448 {
449 info->pwszContainerName = (LPWSTR)data;
450 data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
451 }
452
453 if (info->pwszProvName)
454 {
455 info->pwszProvName = (LPWSTR)data;
456 data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
457 }
458
459 info->rgProvParam = info->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(info + 1) : NULL;
460
461 for (i = 0; i < info->cProvParam; i++)
462 {
463 info->rgProvParam[i].pbData = info->rgProvParam[i].cbData ? data : NULL;
464 data += info->rgProvParam[i].cbData;
465 }
466}
467
468/*
469 * Copy to a continuous block of memory of CRYPT_KEY_PROV_INFO with
470 * its associated data.
471 */
473{
474 BYTE *data;
475 DWORD i;
476
477 data = (BYTE *)(to + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * from->cProvParam;
478
479 if (from->pwszContainerName)
480 {
482 lstrcpyW((LPWSTR)data, from->pwszContainerName);
483 data += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
484 }
485 else
487
488 if (from->pwszProvName)
489 {
490 to->pwszProvName = (LPWSTR)data;
491 lstrcpyW((LPWSTR)data, from->pwszProvName);
492 data += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
493 }
494 else
495 to->pwszProvName = NULL;
496
497 to->dwProvType = from->dwProvType;
498 to->dwFlags = from->dwFlags;
499 to->cProvParam = from->cProvParam;
500 to->rgProvParam = from->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(to + 1) : NULL;
501 to->dwKeySpec = from->dwKeySpec;
502
503 for (i = 0; i < from->cProvParam; i++)
504 {
505 to->rgProvParam[i].dwParam = from->rgProvParam[i].dwParam;
506 to->rgProvParam[i].dwFlags = from->rgProvParam[i].dwFlags;
507 to->rgProvParam[i].cbData = from->rgProvParam[i].cbData;
508 to->rgProvParam[i].pbData = from->rgProvParam[i].cbData ? data : NULL;
509 memcpy(data, from->rgProvParam[i].pbData, from->rgProvParam[i].cbData);
510 data += from->rgProvParam[i].cbData;
511 }
512}
513
515 void *pvData, DWORD *pcbData)
516{
517 BOOL ret;
519
520 TRACE("(%p, %ld, %p, %p)\n", cert, dwPropId, pvData, pcbData);
521
522 if (cert->base.properties)
523 ret = ContextPropertyList_FindProperty(cert->base.properties, dwPropId, &blob);
524 else
525 ret = FALSE;
526 if (ret)
527 {
529 if (dwPropId == CERT_KEY_CONTEXT_PROP_ID)
530 {
531 CRYPT_ConvertKeyContext((const struct store_CERT_KEY_CONTEXT *)blob.pbData, &ctx);
532 blob.pbData = (BYTE *)&ctx;
533 blob.cbData = ctx.cbSize;
534 }
535 ret = CertContext_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
536 }
537 else
538 {
539 /* Implicit properties */
540 switch (dwPropId)
541 {
544 cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
545 pcbData);
546 break;
549 cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
550 pcbData);
551 break;
554 cert->ctx.pCertInfo->Subject.pbData,
555 cert->ctx.pCertInfo->Subject.cbData,
556 pvData, pcbData);
557 break;
560 cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
561 cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
562 pvData, pcbData);
563 break;
566 cert->ctx.pCertInfo->SerialNumber.pbData,
567 cert->ctx.pCertInfo->SerialNumber.cbData,
568 pvData, pcbData);
569 break;
571 ret = CryptHashToBeSigned(0, cert->ctx.dwCertEncodingType,
572 cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
573 pcbData);
574 if (ret && pvData)
575 {
577
578 ret = CertContext_SetProperty(cert, dwPropId, 0, &blob);
579 }
580 break;
582 {
584 szOID_SUBJECT_KEY_IDENTIFIER, cert->ctx.pCertInfo->cExtension,
585 cert->ctx.pCertInfo->rgExtension);
586
587 if (ext)
588 {
590 DWORD size = sizeof(value);
591
593 szOID_SUBJECT_KEY_IDENTIFIER, ext->Value.pbData,
594 ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &value,
595 &size);
596 if (ret)
597 {
599 value.cbData);
600 CertContext_SetProperty(cert, dwPropId, 0, &value);
601 }
602 }
603 else
605 break;
606 }
607 default:
609 }
610 }
611 TRACE("returning %d\n", ret);
612 return ret;
613}
614
616 DWORD dwPropId, void *pvData, DWORD *pcbData)
617{
618 cert_t *cert = cert_from_ptr(pCertContext);
619 BOOL ret;
620
621 TRACE("(%p, %ld, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData);
622
623 switch (dwPropId)
624 {
625 case 0:
627 case CERT_CRL_PROP_ID:
628 case CERT_CTL_PROP_ID:
630 ret = FALSE;
631 break;
633 ret = CertGetStoreProperty(cert->ctx.hCertStore, dwPropId, pvData, pcbData);
634 break;
636 {
637 CERT_KEY_CONTEXT keyContext;
638 DWORD size = sizeof(keyContext);
639
641 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
642 if (ret)
644 sizeof(keyContext.hCryptProv));
645 break;
646 }
649 if (ret && pvData)
651 break;
652 default:
654 pcbData);
655 }
656
657 TRACE("returning %d\n", ret);
658 return ret;
659}
660
661/*
662 * Create a continuous block of memory for CRYPT_KEY_PROV_INFO with
663 * its associated data, and add it to the certificate properties.
664 */
666{
668 DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i;
669 BOOL ret;
670
671 if (info->pwszContainerName)
672 size += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
673 if (info->pwszProvName)
674 size += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
675
676 for (i = 0; i < info->cProvParam; i++)
677 size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
678
679 prop = CryptMemAlloc(size);
680 if (!prop)
681 {
683 return FALSE;
684 }
685
687
689 CryptMemFree(prop);
690
691 return ret;
692}
693
695 const CERT_KEY_CONTEXT *keyContext)
696{
698
699 ctx.cbSize = sizeof(ctx);
700 ctx.hCryptProv = keyContext->hCryptProv;
701 ctx.dwKeySpec = keyContext->dwKeySpec;
702
704 (const BYTE *)&ctx, ctx.cbSize);
705}
706
708 DWORD dwFlags, const void *pvData)
709{
710 BOOL ret;
711
712 TRACE("(%p, %ld, %08lx, %p)\n", cert, dwPropId, dwFlags, pvData);
713
714 if (!cert->base.properties)
715 ret = FALSE;
716 else if (dwPropId >= CERT_FIRST_USER_PROP_ID && dwPropId <= CERT_LAST_USER_PROP_ID)
717 {
718 if (pvData)
719 {
720 const CRYPT_DATA_BLOB *blob = pvData;
721 ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId, blob->pbData, blob->cbData);
722 }
723 else
724 {
725 ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
726 ret = TRUE;
727 }
728 }
729 else
730 {
731 switch (dwPropId)
732 {
734 case CERT_CTL_USAGE_PROP_ID: /* same as CERT_ENHKEY_USAGE_PROP_ID */
752 {
753 if (pvData)
754 {
755 const CRYPT_DATA_BLOB *blob = pvData;
756
757 ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
758 blob->pbData, blob->cbData);
759 }
760 else
761 {
762 ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
763 ret = TRUE;
764 }
765 break;
766 }
768 if (pvData)
769 ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
770 pvData, sizeof(FILETIME));
771 else
772 {
773 ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
774 ret = TRUE;
775 }
776 break;
778 if (pvData)
779 {
780 const CERT_KEY_CONTEXT *keyContext = pvData;
781
782 if (keyContext->cbSize != sizeof(CERT_KEY_CONTEXT))
783 {
785 ret = FALSE;
786 }
787 else
789 }
790 else
791 {
792 ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
793 ret = TRUE;
794 }
795 break;
797 if (pvData)
799 else
800 {
801 ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
802 ret = TRUE;
803 }
804 break;
806 {
807 CERT_KEY_CONTEXT keyContext;
808 DWORD size = sizeof(keyContext);
809
811 &keyContext, &size);
812 if (ret)
813 {
815 CryptReleaseContext(keyContext.hCryptProv, 0);
816 }
817 keyContext.cbSize = sizeof(keyContext);
818 if (pvData)
819 keyContext.hCryptProv = *(const HCRYPTPROV *)pvData;
820 else
821 {
822 keyContext.hCryptProv = 0;
823 keyContext.dwKeySpec = AT_SIGNATURE;
824 }
826 0, &keyContext);
827 break;
828 }
829 default:
830 FIXME("%ld: stub\n", dwPropId);
831 ret = FALSE;
832 }
833 }
834 TRACE("returning %d\n", ret);
835 return ret;
836}
837
839 DWORD dwPropId, DWORD dwFlags, const void *pvData)
840{
841 BOOL ret;
842
843 TRACE("(%p, %ld, %08lx, %p)\n", pCertContext, dwPropId, dwFlags, pvData);
844
845 /* Handle special cases for "read-only"/invalid prop IDs. Windows just
846 * crashes on most of these, I'll be safer.
847 */
848 switch (dwPropId)
849 {
850 case 0:
853 case CERT_CRL_PROP_ID:
854 case CERT_CTL_PROP_ID:
856 return FALSE;
857 }
858 ret = CertContext_SetProperty(cert_from_ptr(pCertContext), dwPropId, dwFlags,
859 pvData);
860 TRACE("returning %d\n", ret);
861 return ret;
862}
863
864/* Acquires the private key using the key provider info, retrieving info from
865 * the certificate if info is NULL. The acquired provider is returned in
866 * *phCryptProv, and the key spec for the provider is returned in *pdwKeySpec.
867 */
869 PCRYPT_KEY_PROV_INFO info, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec)
870{
871 DWORD size = 0;
872 BOOL allocated = FALSE, ret = TRUE;
873
874 if (!info)
875 {
878 if (ret)
879 {
881 if (info)
882 {
885 allocated = TRUE;
886 }
887 else
888 {
890 ret = FALSE;
891 }
892 }
893 else
895 }
896 if (ret)
897 {
898 ret = CryptAcquireContextW(phCryptProv, info->pwszContainerName,
899 info->pwszProvName, info->dwProvType, (dwFlags & CRYPT_ACQUIRE_SILENT_FLAG) ? CRYPT_SILENT : 0);
900 if (ret)
901 {
902 DWORD i;
903
904 for (i = 0; i < info->cProvParam; i++)
905 {
906 CryptSetProvParam(*phCryptProv,
907 info->rgProvParam[i].dwParam, info->rgProvParam[i].pbData,
908 info->rgProvParam[i].dwFlags);
909 }
910 *pdwKeySpec = info->dwKeySpec;
911 }
912 else
914 }
915 if (allocated)
917 return ret;
918}
919
922 DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
923{
924 BOOL ret = FALSE, cache = FALSE;
926 CERT_KEY_CONTEXT keyContext;
927 DWORD size;
928 PCCERT_CONTEXT cert_in_store = NULL;
929
930 TRACE("(%p, %08lx, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved,
931 phCryptProv, pdwKeySpec, pfCallerFreeProv);
932
934 {
935 DWORD size = 0;
936
939
940 if (!ret)
941 {
942 HCERTSTORE hstore;
943
946 if (hstore)
947 {
948 cert_in_store = CertFindCertificateInStore(hstore, pCert->dwCertEncodingType, 0,
949 CERT_FIND_EXISTING, pCert, NULL);
950 if (cert_in_store)
951 {
953 if (ret)
954 pCert = cert_in_store;
955 else
956 {
957 CertFreeCertificateContext(cert_in_store);
958 cert_in_store = NULL;
959 }
960 }
961
962 CertCloseStore(hstore, 0);
963 }
964 }
965
966 if (ret)
967 {
971 if (ret)
973 }
974 }
976 cache = TRUE;
977 *phCryptProv = 0;
978 if (cache)
979 {
980 size = sizeof(keyContext);
982 &keyContext, &size);
983 if (ret)
984 {
985 *phCryptProv = keyContext.hCryptProv;
986 if (pdwKeySpec)
987 *pdwKeySpec = keyContext.dwKeySpec;
988 if (pfCallerFreeProv)
989 *pfCallerFreeProv = FALSE;
990 }
991 }
992 if (!*phCryptProv)
993 {
995 &keyContext.hCryptProv, &keyContext.dwKeySpec);
996 if (ret)
997 {
998 *phCryptProv = keyContext.hCryptProv;
999 if (pdwKeySpec)
1000 *pdwKeySpec = keyContext.dwKeySpec;
1001 if (cache)
1002 {
1003 keyContext.cbSize = sizeof(keyContext);
1005 CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext))
1006 {
1007 if (pfCallerFreeProv)
1008 *pfCallerFreeProv = FALSE;
1009 }
1010 }
1011 else
1012 {
1013 if (pfCallerFreeProv)
1014 *pfCallerFreeProv = TRUE;
1015 }
1016 }
1017 }
1019 if (cert_in_store)
1020 CertFreeCertificateContext(cert_in_store);
1021 if (ret) SetLastError(0);
1022 return ret;
1023}
1024
1026 const CRYPT_KEY_PROV_INFO *keyProvInfo)
1027{
1028 HCRYPTPROV csp;
1029 BOOL matches = FALSE;
1030
1031 if (CryptAcquireContextW(&csp, keyProvInfo->pwszContainerName,
1032 keyProvInfo->pwszProvName, keyProvInfo->dwProvType, keyProvInfo->dwFlags))
1033 {
1034 DWORD size;
1035
1036 /* Need to sign something to verify the sig. What to sign? Why not
1037 * the certificate itself?
1038 */
1042 {
1043 BYTE *certEncoded = CryptMemAlloc(size);
1044
1045 if (certEncoded)
1046 {
1049 pCert->pCertInfo, &pCert->pCertInfo->SignatureAlgorithm,
1050 NULL, certEncoded, &size))
1051 {
1052 if (size == pCert->cbCertEncoded &&
1053 !memcmp(certEncoded, pCert->pbCertEncoded, size))
1054 matches = TRUE;
1055 }
1056 CryptMemFree(certEncoded);
1057 }
1058 }
1059 CryptReleaseContext(csp, 0);
1060 }
1061 return matches;
1062}
1063
1065 CRYPT_KEY_PROV_INFO *keyProvInfo)
1066{
1068 WCHAR containerW[MAX_PATH];
1069 BOOL matches;
1070
1071 MultiByteToWideChar(CP_ACP, 0, container, -1, containerW, ARRAY_SIZE(containerW));
1072 /* We make a copy of the CRYPT_KEY_PROV_INFO because the caller expects
1073 * keyProvInfo->pwszContainerName to be NULL or a heap-allocated container
1074 * name.
1075 */
1076 copy = *keyProvInfo;
1077 copy.pwszContainerName = containerW;
1079 if (matches)
1080 {
1081 keyProvInfo->pwszContainerName =
1082 CryptMemAlloc((lstrlenW(containerW) + 1) * sizeof(WCHAR));
1083 if (keyProvInfo->pwszContainerName)
1084 {
1085 lstrcpyW(keyProvInfo->pwszContainerName, containerW);
1086 keyProvInfo->dwKeySpec = AT_SIGNATURE;
1087 }
1088 else
1089 matches = FALSE;
1090 }
1091 return matches;
1092}
1093
1094/* Searches the provider named keyProvInfo.pwszProvName for a container whose
1095 * private key matches pCert's public key. Upon success, updates keyProvInfo
1096 * with the matching container's info (free keyProvInfo.pwszContainerName upon
1097 * success.)
1098 * Returns TRUE if found, FALSE if not.
1099 */
1101 CRYPT_KEY_PROV_INFO *keyProvInfo)
1102{
1103 HCRYPTPROV defProvider;
1104 BOOL ret, found = FALSE;
1105 char containerA[MAX_PATH];
1106
1107 assert(keyProvInfo->pwszContainerName == NULL);
1108 if ((ret = CryptAcquireContextW(&defProvider, NULL,
1109 keyProvInfo->pwszProvName, keyProvInfo->dwProvType,
1110 keyProvInfo->dwFlags | CRYPT_VERIFYCONTEXT)))
1111 {
1112 DWORD enumFlags = keyProvInfo->dwFlags | CRYPT_FIRST;
1113
1114 while (ret && !found)
1115 {
1116 DWORD size = sizeof(containerA);
1117
1119 (BYTE *)containerA, &size, enumFlags);
1120 if (ret)
1121 found = container_matches_cert(pCert, containerA, keyProvInfo);
1122 if (enumFlags & CRYPT_FIRST)
1123 {
1124 enumFlags &= ~CRYPT_FIRST;
1125 enumFlags |= CRYPT_NEXT;
1126 }
1127 }
1128 CryptReleaseContext(defProvider, 0);
1129 }
1130 return found;
1131}
1132
1134{
1135 BOOL found = FALSE, ret = TRUE;
1136 DWORD index = 0, cbProvName = 0;
1137 CRYPT_KEY_PROV_INFO keyProvInfo;
1138
1139 TRACE("(%p, %08lx)\n", pCert, dwFlags);
1140
1141 memset(&keyProvInfo, 0, sizeof(keyProvInfo));
1142 while (ret && !found)
1143 {
1144 DWORD size = 0;
1145
1146 ret = CryptEnumProvidersW(index, NULL, 0, &keyProvInfo.dwProvType,
1147 NULL, &size);
1148 if (ret)
1149 {
1150 if (size <= cbProvName)
1152 &keyProvInfo.dwProvType, keyProvInfo.pwszProvName, &size);
1153 else
1154 {
1155 CryptMemFree(keyProvInfo.pwszProvName);
1156 keyProvInfo.pwszProvName = CryptMemAlloc(size);
1157 if (keyProvInfo.pwszProvName)
1158 {
1159 cbProvName = size;
1161 &keyProvInfo.dwProvType, keyProvInfo.pwszProvName, &size);
1162 if (ret)
1163 {
1165 keyProvInfo.dwFlags |= CRYPT_SILENT;
1169 {
1170 keyProvInfo.dwFlags |= CRYPT_USER_KEYSET;
1171 found = find_key_prov_info_in_provider(pCert,
1172 &keyProvInfo);
1173 }
1174 if (!found)
1175 {
1179 {
1180 keyProvInfo.dwFlags &= ~CRYPT_USER_KEYSET;
1181 keyProvInfo.dwFlags |= CRYPT_MACHINE_KEYSET;
1182 found = find_key_prov_info_in_provider(pCert,
1183 &keyProvInfo);
1184 }
1185 }
1186 }
1187 }
1188 else
1189 ret = FALSE;
1190 }
1191 index++;
1192 }
1193 }
1194 if (found)
1196 0, &keyProvInfo);
1197 CryptMemFree(keyProvInfo.pwszProvName);
1198 CryptMemFree(keyProvInfo.pwszContainerName);
1199 return found;
1200}
1201
1203{
1204 BOOL matches = FALSE;
1205 DWORD size;
1206
1208 NULL, &size))
1209 {
1210 CRYPT_KEY_PROV_INFO *keyProvInfo = CryptMemAlloc(size);
1211
1212 if (keyProvInfo)
1213 {
1215 CERT_KEY_PROV_INFO_PROP_ID, keyProvInfo, &size))
1216 matches = key_prov_info_matches_cert(pCert, keyProvInfo);
1217 CryptMemFree(keyProvInfo);
1218 }
1219 }
1220 return matches;
1221}
1222
1224 DWORD dwFlags, void *pvReserved)
1225{
1226 BOOL matches;
1227
1228 TRACE("(%p, %08lx, %p)\n", pCert, dwFlags, pvReserved);
1229
1231 if (!matches)
1233 return matches;
1234}
1235
1237 PCERT_INFO pCertId1, PCERT_INFO pCertId2)
1238{
1239 BOOL ret;
1240
1241 TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2);
1242
1243 ret = CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer,
1244 &pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber,
1245 &pCertId2->SerialNumber);
1246 TRACE("returning %d\n", ret);
1247 return ret;
1248}
1249
1251 PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
1252{
1253 BOOL ret;
1254
1255 TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2);
1256
1257 if (pCertName1->cbData == pCertName2->cbData)
1258 {
1259 if (pCertName1->cbData)
1260 ret = !memcmp(pCertName1->pbData, pCertName2->pbData,
1261 pCertName1->cbData);
1262 else
1263 ret = TRUE;
1264 }
1265 else
1266 ret = FALSE;
1267 TRACE("returning %d\n", ret);
1268 return ret;
1269}
1270
1271/* Returns the number of significant bytes in pInt, where a byte is
1272 * insignificant if it's a leading 0 for positive numbers or a leading 0xff
1273 * for negative numbers. pInt is assumed to be little-endian.
1274 */
1276{
1277 DWORD ret = pInt->cbData;
1278
1279 while (ret > 1)
1280 {
1281 if (pInt->pbData[ret - 2] <= 0x7f && pInt->pbData[ret - 1] == 0)
1282 ret--;
1283 else if (pInt->pbData[ret - 2] >= 0x80 && pInt->pbData[ret - 1] == 0xff)
1284 ret--;
1285 else
1286 break;
1287 }
1288 return ret;
1289}
1290
1292 PCRYPT_INTEGER_BLOB pInt2)
1293{
1294 BOOL ret;
1295 DWORD cb1, cb2;
1296
1297 TRACE("(%p, %p)\n", pInt1, pInt2);
1298
1299 cb1 = CRYPT_significantBytes(pInt1);
1300 cb2 = CRYPT_significantBytes(pInt2);
1301 if (cb1 == cb2)
1302 {
1303 if (cb1)
1304 ret = !memcmp(pInt1->pbData, pInt2->pbData, cb1);
1305 else
1306 ret = TRUE;
1307 }
1308 else
1309 ret = FALSE;
1310 TRACE("returning %d\n", ret);
1311 return ret;
1312}
1313
1315 PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2)
1316{
1317 BOOL ret;
1318
1319 TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
1320
1321 /* RSA public key data should start with ASN_SEQUENCE,
1322 * otherwise it's not a RSA_CSP_PUBLICKEYBLOB.
1323 */
1324 if (!pPublicKey1->PublicKey.cbData || pPublicKey1->PublicKey.pbData[0] != ASN_SEQUENCE)
1325 dwCertEncodingType = 0;
1326
1327 switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
1328 {
1329 case 0: /* Seems to mean "raw binary bits" */
1330 if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
1331 pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
1332 {
1333 if (pPublicKey2->PublicKey.cbData)
1334 ret = !memcmp(pPublicKey1->PublicKey.pbData,
1335 pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
1336 else
1337 ret = TRUE;
1338 }
1339 else
1340 ret = FALSE;
1341 break;
1342 default:
1343 WARN("Unknown encoding type %08lx\n", dwCertEncodingType);
1344 /* FALLTHROUGH */
1345 case X509_ASN_ENCODING:
1346 {
1347 BLOBHEADER *pblob1, *pblob2;
1348 DWORD length;
1349 ret = FALSE;
1350 if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
1351 pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
1352 CRYPT_DECODE_ALLOC_FLAG, &pblob1, &length))
1353 {
1354 if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
1355 pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
1356 CRYPT_DECODE_ALLOC_FLAG, &pblob2, &length))
1357 {
1358 /* The RSAPUBKEY structure directly follows the BLOBHEADER */
1359 RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
1360 *pk2 = (LPVOID)(pblob2 + 1);
1361 ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
1362 && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
1363
1364 LocalFree(pblob2);
1365 }
1366 LocalFree(pblob1);
1367 }
1368
1369 break;
1370 }
1371 }
1372 return ret;
1373}
1374
1376 PCERT_PUBLIC_KEY_INFO pPublicKey)
1377{
1378 DWORD len = 0;
1379
1380 TRACE("(%08lx, %p)\n", dwCertEncodingType, pPublicKey);
1381
1382 if (GET_CERT_ENCODING_TYPE(dwCertEncodingType) != X509_ASN_ENCODING)
1383 {
1385 return 0;
1386 }
1387 if (pPublicKey->Algorithm.pszObjId &&
1388 !strcmp(pPublicKey->Algorithm.pszObjId, szOID_RSA_DH))
1389 {
1390 FIXME("unimplemented for DH public keys\n");
1392 }
1393 else
1394 {
1396 DWORD size;
1397 PBYTE buf;
1398 BOOL ret;
1399
1401 if (info)
1402 {
1403 HCRYPTKEY key;
1404
1405 TRACE("public key algid %#x (%s)\n", info->Algid, debugstr_a(pPublicKey->Algorithm.pszObjId));
1406
1407 ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->Algid), dwCertEncodingType, pPublicKey, &key);
1408 if (ret)
1409 {
1410 size = sizeof(len);
1413 return len;
1414 }
1415 /* fallback to RSA */
1416 }
1417
1418 ret = CryptDecodeObjectEx(dwCertEncodingType,
1421 &size);
1422
1423 if (ret)
1424 {
1425 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
1426
1427 len = rsaPubKey->bitlen;
1428 LocalFree(buf);
1429 }
1430 }
1431 return len;
1432}
1433
1434typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
1435 DWORD dwFlags, const void *pvPara);
1436
1438 DWORD dwFlags, const void *pvPara)
1439{
1440 BOOL ret;
1441 BYTE hash[16];
1442 DWORD size = sizeof(hash);
1443
1446 if (ret)
1447 {
1448 const CRYPT_HASH_BLOB *pHash = pvPara;
1449
1450 if (size == pHash->cbData)
1451 ret = !memcmp(pHash->pbData, hash, size);
1452 else
1453 ret = FALSE;
1454 }
1455 return ret;
1456}
1457
1459 DWORD dwFlags, const void *pvPara)
1460{
1461 BOOL ret;
1462 BYTE hash[20];
1463 DWORD size = sizeof(hash);
1464
1467 if (ret)
1468 {
1469 const CRYPT_HASH_BLOB *pHash = pvPara;
1470
1471 if (size == pHash->cbData)
1472 ret = !memcmp(pHash->pbData, hash, size);
1473 else
1474 ret = FALSE;
1475 }
1476 return ret;
1477}
1478
1479static BOOL compare_cert_by_name(PCCERT_CONTEXT pCertContext, DWORD dwType,
1480 DWORD dwFlags, const void *pvPara)
1481{
1482 CERT_NAME_BLOB *blob = (CERT_NAME_BLOB *)pvPara, *toCompare;
1483 BOOL ret;
1484
1485 if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_SUBJECT_FLAG)
1486 toCompare = &pCertContext->pCertInfo->Subject;
1487 else if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_ISSUER_FLAG)
1488 toCompare = &pCertContext->pCertInfo->Issuer;
1489 else
1490 {
1491 ERR("dwType %08lx doesn't specify SUBJECT or ISSUER\n", dwType);
1492 return FALSE;
1493 }
1494 ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
1495 toCompare, blob);
1496 return ret;
1497}
1498
1500 DWORD dwType, DWORD dwFlags, const void *pvPara)
1501{
1502 CERT_PUBLIC_KEY_INFO *publicKey = (CERT_PUBLIC_KEY_INFO *)pvPara;
1503 BOOL ret;
1504
1506 &pCertContext->pCertInfo->SubjectPublicKeyInfo, publicKey);
1507 return ret;
1508}
1509
1511 DWORD dwType, DWORD dwFlags, const void *pvPara)
1512{
1513 CERT_INFO *pCertInfo = (CERT_INFO *)pvPara;
1514 BOOL ret;
1515
1516 /* Matching serial number and subject match.. */
1518 &pCertContext->pCertInfo->Subject, &pCertInfo->Issuer);
1519 if (ret)
1521 &pCertInfo->SerialNumber);
1522 else
1523 {
1524 /* failing that, if the serial number and issuer match, we match */
1526 &pCertInfo->SerialNumber);
1527 if (ret)
1529 &pCertContext->pCertInfo->Issuer, &pCertInfo->Issuer);
1530 }
1531 TRACE("returning %d\n", ret);
1532 return ret;
1533}
1534
1536 DWORD dwFlags, const void *pvPara)
1537{
1538 CERT_ID *id = (CERT_ID *)pvPara;
1539 BOOL ret;
1540
1541 switch (id->dwIdChoice)
1542 {
1545 &pCertContext->pCertInfo->Issuer, &id->IssuerSerialNumber.Issuer);
1546 if (ret)
1548 &id->IssuerSerialNumber.SerialNumber);
1549 break;
1550 case CERT_ID_SHA1_HASH:
1551 ret = compare_cert_by_sha1_hash(pCertContext, dwType, dwFlags,
1552 &id->HashId);
1553 break;
1555 {
1556 DWORD size = 0;
1557
1560 if (ret && size == id->KeyId.cbData)
1561 {
1563
1564 if (buf)
1565 {
1568 ret = !memcmp(buf, id->KeyId.pbData, size);
1570 }
1571 else
1572 ret = FALSE;
1573 }
1574 else
1575 ret = FALSE;
1576 break;
1577 }
1578 default:
1579 ret = FALSE;
1580 break;
1581 }
1582 return ret;
1583}
1584
1586 DWORD dwFlags, const void *pvPara)
1587{
1588 PCCERT_CONTEXT toCompare = pvPara;
1589 return CertCompareCertificate(pCertContext->dwCertEncodingType,
1590 pCertContext->pCertInfo, toCompare->pCertInfo);
1591}
1592
1594 DWORD dwFlags, const void *pvPara)
1595{
1596 const CRYPT_HASH_BLOB *hash = pvPara;
1597 DWORD size = 0;
1598 BOOL ret;
1599
1602 if (ret && size == hash->cbData)
1603 {
1605
1606 if (buf)
1607 {
1610 ret = !memcmp(buf, hash->pbData, size);
1612 }
1613 else
1614 ret = FALSE;
1615 }
1616 else
1617 ret = FALSE;
1618 return ret;
1619}
1620
1623 const void *pvPara)
1624{
1625 BOOL matches = FALSE;
1627
1628 ret = prev;
1629 do {
1631 if (ret)
1632 matches = compare(ret, dwType, dwFlags, pvPara);
1633 } while (ret != NULL && !matches);
1634 return ret;
1635}
1636
1638 DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev);
1639
1641 DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1642{
1643 return CertEnumCertificatesInStore(store, prev);
1644}
1645
1647 DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1648{
1649 BOOL ret;
1650 PCCERT_CONTEXT found = NULL, subject = pvPara;
1652 DWORD size;
1653
1655 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
1656 {
1658
1659 ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
1660 X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
1662 &info, &size);
1663 if (ret)
1664 {
1665 CERT_ID id;
1666
1667 if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
1668 {
1669 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1670 memcpy(&id.IssuerSerialNumber.Issuer, &info->CertIssuer,
1671 sizeof(CERT_NAME_BLOB));
1672 memcpy(&id.IssuerSerialNumber.SerialNumber,
1673 &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
1674 }
1675 else if (info->KeyId.cbData)
1676 {
1677 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1678 memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
1679 }
1680 else
1681 ret = FALSE;
1682 if (ret)
1683 found = cert_compare_certs_in_store(store, prev,
1684 compare_cert_by_cert_id, dwType, dwFlags, &id);
1685 LocalFree(info);
1686 }
1687 }
1689 subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
1690 {
1692
1693 ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
1694 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
1696 &info, &size);
1697 if (ret)
1698 {
1699 CERT_ID id;
1700
1701 if (info->AuthorityCertIssuer.cAltEntry &&
1702 info->AuthorityCertSerialNumber.cbData)
1703 {
1704 PCERT_ALT_NAME_ENTRY directoryName = NULL;
1705 DWORD i;
1706
1707 for (i = 0; !directoryName &&
1708 i < info->AuthorityCertIssuer.cAltEntry; i++)
1709 if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
1711 directoryName =
1712 &info->AuthorityCertIssuer.rgAltEntry[i];
1713 if (directoryName)
1714 {
1715 id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1716 memcpy(&id.IssuerSerialNumber.Issuer,
1717 &directoryName->DirectoryName, sizeof(CERT_NAME_BLOB));
1718 memcpy(&id.IssuerSerialNumber.SerialNumber,
1719 &info->AuthorityCertSerialNumber,
1720 sizeof(CRYPT_INTEGER_BLOB));
1721 }
1722 else
1723 {
1724 FIXME("no supported name type in authority key id2\n");
1725 ret = FALSE;
1726 }
1727 }
1728 else if (info->KeyId.cbData)
1729 {
1730 id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1731 memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
1732 }
1733 else
1734 ret = FALSE;
1735 if (ret)
1736 found = cert_compare_certs_in_store(store, prev,
1737 compare_cert_by_cert_id, dwType, dwFlags, &id);
1738 LocalFree(info);
1739 }
1740 }
1741 else
1742 found = cert_compare_certs_in_store(store, prev,
1744 dwFlags, &subject->pCertInfo->Issuer);
1745 return found;
1746}
1747
1749 DWORD dwType, DWORD dwFlags, const void *pvPara)
1750{
1752 DWORD len;
1753 BOOL ret = FALSE;
1754
1755 if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_SUBJECT_FLAG)
1756 name = &pCertContext->pCertInfo->Subject;
1757 else
1758 name = &pCertContext->pCertInfo->Issuer;
1759 len = CertNameToStrW(pCertContext->dwCertEncodingType, name,
1761 if (len)
1762 {
1763 LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
1764
1765 if (str)
1766 {
1767 CertNameToStrW(pCertContext->dwCertEncodingType, name,
1769 wcslwr(str);
1770 if (wcsstr(str, pvPara))
1771 ret = TRUE;
1773 }
1774 }
1775 return ret;
1776}
1777
1779 DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1780{
1781 PCCERT_CONTEXT found = NULL;
1782
1783 TRACE("%s\n", debugstr_a(pvPara));
1784
1785 if (pvPara)
1786 {
1787 int len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
1788 LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
1789
1790 if (str)
1791 {
1792 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, str, len);
1793 wcslwr(str);
1794 found = cert_compare_certs_in_store(store, prev,
1797 }
1798 }
1799 else
1800 found = find_cert_any(store, dwType, dwFlags, NULL, prev);
1801 return found;
1802}
1803
1805 DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1806{
1807 PCCERT_CONTEXT found = NULL;
1808
1809 TRACE("%s\n", debugstr_w(pvPara));
1810
1811 if (pvPara)
1812 {
1813 DWORD len = lstrlenW(pvPara);
1814 LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR));
1815
1816 if (str)
1817 {
1818 wcscpy( str, pvPara );
1819 wcslwr( str );
1820 found = cert_compare_certs_in_store(store, prev,
1823 }
1824 }
1825 else
1826 found = find_cert_any(store, dwType, dwFlags, NULL, prev);
1827 return found;
1828}
1829
1831 DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara,
1832 PCCERT_CONTEXT pPrevCertContext)
1833{
1837 CERT_ID cert_id;
1838
1839 TRACE("(%p, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore, dwCertEncodingType,
1840 dwFlags, dwType, pvPara, pPrevCertContext);
1841
1842 switch (dwType >> CERT_COMPARE_SHIFT)
1843 {
1844 case CERT_COMPARE_ANY:
1846 break;
1849 break;
1852 break;
1853 case CERT_COMPARE_NAME:
1855 break;
1858 break;
1861 break;
1864 break;
1867 break;
1870 cert_id.KeyId = *(const CRYPT_HASH_BLOB *)pvPara;
1871 pvPara = &cert_id;
1872 /* fall through */
1875 break;
1878 break;
1881 break;
1884 break;
1885 default:
1886 FIXME("find type %08lx unimplemented\n", dwType);
1887 }
1888
1889 if (find)
1890 ret = find(hCertStore, dwType, dwFlags, pvPara, pPrevCertContext);
1891 else if (compare)
1892 ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
1893 compare, dwType, dwFlags, pvPara);
1894 else
1895 ret = NULL;
1896 if (!ret)
1898 TRACE("returning %p\n", ret);
1899 return ret;
1900}
1901
1903 DWORD dwCertEncodingType, PCERT_INFO pCertId)
1904{
1905 TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId);
1906
1907 if (!pCertId)
1908 {
1910 return NULL;
1911 }
1912 return CertFindCertificateInStore(hCertStore, dwCertEncodingType, 0,
1913 CERT_FIND_SUBJECT_CERT, pCertId, NULL);
1914}
1915
1917 PCCERT_CONTEXT pIssuer, DWORD *pdwFlags)
1918{
1919 static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
1921
1922 if (*pdwFlags & ~supportedFlags)
1923 {
1925 return FALSE;
1926 }
1927 if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
1928 {
1929 DWORD flags = 0;
1930 PCCRL_CONTEXT crl = CertGetCRLFromStore(pSubject->hCertStore, pSubject,
1931 NULL, &flags);
1932
1933 /* FIXME: what if the CRL has expired? */
1934 if (crl)
1935 {
1937 pSubject->pCertInfo, 1, (PCRL_INFO *)&crl->pCrlInfo))
1938 *pdwFlags &= CERT_STORE_REVOCATION_FLAG;
1939 }
1940 else
1941 *pdwFlags |= CERT_STORE_NO_CRL_FLAG;
1942 }
1943 if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
1944 {
1945 if (0 == CertVerifyTimeValidity(NULL, pSubject->pCertInfo))
1946 *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
1947 }
1948 if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
1949 {
1951 CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubject,
1952 CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)pIssuer, 0, NULL))
1953 *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
1954 }
1955 return TRUE;
1956}
1957
1959 PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
1960 DWORD *pdwFlags)
1961{
1963
1964 TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext,
1965 pPrevIssuerContext, *pdwFlags);
1966
1967 if (!pSubjectContext)
1968 {
1970 return NULL;
1971 }
1972
1973 ret = CertFindCertificateInStore(hCertStore,
1974 pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
1975 pSubjectContext, pPrevIssuerContext);
1976 if (ret)
1977 {
1978 if (!CertVerifySubjectCertificateContext(pSubjectContext, ret,
1979 pdwFlags))
1980 {
1982 ret = NULL;
1983 }
1984 if (CRYPT_IsCertificateSelfSigned(pSubjectContext))
1985 {
1987 ret = NULL;
1989 }
1990 }
1991 TRACE("returning %p\n", ret);
1992 return ret;
1993}
1994
2001
2004
2005BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType,
2006 DWORD cContext, PVOID rgpvContext[], DWORD dwFlags,
2008{
2009 BOOL ret;
2010
2011 TRACE("(%08lx, %ld, %ld, %p, %08lx, %p, %p)\n", dwEncodingType, dwRevType,
2012 cContext, rgpvContext, dwFlags, pRevPara, pRevStatus);
2013
2014 if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) &&
2015 pRevStatus->cbSize != sizeof(CERT_REVOCATION_STATUS))
2016 {
2018 return FALSE;
2019 }
2020 if (cContext)
2021 {
2022 static HCRYPTOIDFUNCSET set = NULL;
2023 DWORD size;
2024
2025 if (!set)
2027 ret = CryptGetDefaultOIDDllList(set, dwEncodingType, NULL, &size);
2028 if (ret)
2029 {
2030 if (size == 1)
2031 {
2032 /* empty list */
2034 ret = FALSE;
2035 }
2036 else
2037 {
2038 LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR)), ptr;
2039
2040 if (dllList)
2041 {
2042 ret = CryptGetDefaultOIDDllList(set, dwEncodingType,
2043 dllList, &size);
2044 if (ret)
2045 {
2046 for (ptr = dllList; ret && *ptr;
2047 ptr += lstrlenW(ptr) + 1)
2048 {
2050 HCRYPTOIDFUNCADDR hFunc;
2051
2053 dwEncodingType, ptr, 0, (void **)&func, &hFunc);
2054 if (ret)
2055 {
2056 ret = func(dwEncodingType, dwRevType, cContext,
2057 rgpvContext, dwFlags, pRevPara, pRevStatus);
2059 }
2060 }
2061 }
2062 CryptMemFree(dllList);
2063 }
2064 else
2065 {
2067 ret = FALSE;
2068 }
2069 }
2070 }
2071 }
2072 else
2073 ret = TRUE;
2074 return ret;
2075}
2076
2078 CRYPT_ATTRIBUTE rgAttr[])
2079{
2081 DWORD i;
2082
2083 TRACE("%s %ld %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
2084
2085 if (!cAttr)
2086 return NULL;
2087 if (!pszObjId)
2088 {
2090 return NULL;
2091 }
2092
2093 for (i = 0; !ret && i < cAttr; i++)
2094 if (rgAttr[i].pszObjId && !strcmp(pszObjId, rgAttr[i].pszObjId))
2095 ret = &rgAttr[i];
2096 return ret;
2097}
2098
2100 CERT_EXTENSION rgExtensions[])
2101{
2103 DWORD i;
2104
2105 TRACE("%s %ld %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
2106
2107 if (!cExtensions)
2108 return NULL;
2109 if (!pszObjId)
2110 {
2112 return NULL;
2113 }
2114
2115 for (i = 0; !ret && i < cExtensions; i++)
2116 if (rgExtensions[i].pszObjId && !strcmp(pszObjId,
2117 rgExtensions[i].pszObjId))
2118 ret = &rgExtensions[i];
2119 return ret;
2120}
2121
2123{
2125 DWORD i, j;
2126
2127 TRACE("%s %p\n", debugstr_a(pszObjId), pName);
2128
2129 if (!pszObjId)
2130 {
2132 return NULL;
2133 }
2134
2135 for (i = 0; !ret && i < pName->cRDN; i++)
2136 for (j = 0; !ret && j < pName->rgRDN[i].cRDNAttr; j++)
2137 if (pName->rgRDN[i].rgRDNAttr[j].pszObjId && !strcmp(pszObjId,
2138 pName->rgRDN[i].rgRDNAttr[j].pszObjId))
2139 ret = &pName->rgRDN[i].rgRDNAttr[j];
2140 return ret;
2141}
2142
2144 const CERT_RDN_ATTR *attr)
2145{
2146 DWORD i, j;
2147 BOOL match = FALSE;
2148
2149 for (i = 0; !match && i < name->cRDN; i++)
2150 {
2151 for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
2152 {
2153 if (!strcmp(name->rgRDN[i].rgRDNAttr[j].pszObjId,
2154 attr->pszObjId) &&
2155 name->rgRDN[i].rgRDNAttr[j].dwValueType ==
2156 attr->dwValueType)
2157 {
2159 {
2160 LPCWSTR nameStr =
2161 (LPCWSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData;
2162 LPCWSTR attrStr = (LPCWSTR)attr->Value.pbData;
2163
2164 if (attr->Value.cbData !=
2165 name->rgRDN[i].rgRDNAttr[j].Value.cbData)
2166 match = FALSE;
2168 match = !wcsnicmp(nameStr, attrStr,
2169 attr->Value.cbData / sizeof(WCHAR));
2170 else
2171 match = !wcsncmp(nameStr, attrStr,
2172 attr->Value.cbData / sizeof(WCHAR));
2173 TRACE("%s : %s => %d\n",
2174 debugstr_wn(nameStr, attr->Value.cbData / sizeof(WCHAR)),
2175 debugstr_wn(attrStr, attr->Value.cbData / sizeof(WCHAR)),
2176 match);
2177 }
2178 else
2179 {
2180 LPCSTR nameStr =
2181 (LPCSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData;
2182 LPCSTR attrStr = (LPCSTR)attr->Value.pbData;
2183
2184 if (attr->Value.cbData !=
2185 name->rgRDN[i].rgRDNAttr[j].Value.cbData)
2186 match = FALSE;
2188 match = !_strnicmp(nameStr, attrStr,
2189 attr->Value.cbData);
2190 else
2191 match = !strncmp(nameStr, attrStr, attr->Value.cbData);
2192 TRACE("%s : %s => %d\n",
2193 debugstr_an(nameStr, attr->Value.cbData),
2194 debugstr_an(attrStr, attr->Value.cbData), match);
2195 }
2196 }
2197 }
2198 }
2199 return match;
2200}
2201
2203 DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN)
2204{
2206 LPCSTR type;
2207 DWORD size;
2208 BOOL ret;
2209
2210 TRACE("(%08lx, %08lx, %p, %p)\n", dwCertEncodingType, dwFlags, pCertName,
2211 pRDN);
2212
2214 X509_NAME;
2215 if ((ret = CryptDecodeObjectEx(dwCertEncodingType, type, pCertName->pbData,
2216 pCertName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &name, &size)))
2217 {
2218 DWORD i;
2219
2220 for (i = 0; ret && i < pRDN->cRDNAttr; i++)
2222 if (!ret)
2224 LocalFree(name);
2225 }
2226 return ret;
2227}
2228
2230 PCERT_INFO pCertInfo)
2231{
2232 FILETIME fileTime;
2233 LONG ret;
2234
2235 if (!pTimeToVerify)
2236 {
2237 GetSystemTimeAsFileTime(&fileTime);
2238 pTimeToVerify = &fileTime;
2239 }
2240 if ((ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotBefore)) >= 0)
2241 {
2242 ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotAfter);
2243 if (ret < 0)
2244 ret = 0;
2245 }
2246 return ret;
2247}
2248
2250 PCERT_INFO pIssuerInfo)
2251{
2252 TRACE("(%p, %p)\n", pSubjectInfo, pIssuerInfo);
2253
2254 return CertVerifyTimeValidity(&pSubjectInfo->NotBefore, pIssuerInfo) == 0
2255 && CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0;
2256}
2257
2259 DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
2260 DWORD *pcbComputedHash)
2261{
2262 BOOL ret = TRUE;
2263 HCRYPTHASH hHash = 0;
2264
2265 TRACE("(%08Ix, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags,
2266 pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
2267
2268 if (!hCryptProv)
2269 hCryptProv = I_CryptGetDefaultCryptProv(Algid);
2270 if (!Algid)
2271 Algid = CALG_SHA1;
2272 if (ret)
2273 {
2274 ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
2275 if (ret)
2276 {
2277 ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0);
2278 if (ret)
2279 ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2280 pcbComputedHash, 0);
2281 CryptDestroyHash(hHash);
2282 }
2283 }
2284 return ret;
2285}
2286
2288 void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
2289 DWORD *pcbComputedHash)
2290{
2292 BCRYPT_ALG_HANDLE alg = NULL;
2294 DWORD hash_len;
2295 DWORD hash_len_size;
2296
2297 TRACE("(%s, %08lx, %p, %p, %ld, %p, %p)\n", debugstr_w(pwszCNGHashAlgid),
2298 dwFlags, pvReserved, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
2299
2300 if ((status = BCryptOpenAlgorithmProvider(&alg, pwszCNGHashAlgid, NULL, 0)))
2301 {
2304 goto done;
2305 }
2306
2307 if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
2308 goto done;
2309
2310 if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &hash_len_size, 0)))
2311 goto done;
2312
2313 if (!pbComputedHash)
2314 {
2315 *pcbComputedHash = hash_len;
2316 goto done;
2317 }
2318
2319 if (*pcbComputedHash < hash_len)
2320 {
2322 goto done;
2323 }
2324
2325 *pcbComputedHash = hash_len;
2326
2327 if ((status = BCryptHashData(hash, (BYTE *)pbEncoded, cbEncoded, 0)))
2328 goto done;
2329
2330 if ((status = BCryptFinishHash(hash, pbComputedHash, hash_len, 0)))
2331 goto done;
2332
2333done:
2335 if (alg) BCryptCloseAlgorithmProvider(alg, 0);
2337 return !status;
2338}
2339
2341 DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo,
2342 BYTE *pbComputedHash, DWORD *pcbComputedHash)
2343{
2344 BOOL ret = TRUE;
2345 HCRYPTHASH hHash = 0;
2346
2347 TRACE("(%08Ix, %d, %08lx, %ld, %p, %p, %p)\n", hCryptProv, Algid, dwFlags,
2348 dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
2349
2350 if (!hCryptProv)
2351 hCryptProv = I_CryptGetDefaultCryptProv(0);
2352 if (!Algid)
2353 Algid = CALG_MD5;
2354 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
2355 {
2357 return FALSE;
2358 }
2359 if (ret)
2360 {
2361 BYTE *buf;
2362 DWORD size = 0;
2363
2364 ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType,
2366 (LPBYTE)&buf, &size);
2367 if (ret)
2368 {
2369 ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
2370 if (ret)
2371 {
2372 ret = CryptHashData(hHash, buf, size, 0);
2373 if (ret)
2374 ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2375 pcbComputedHash, 0);
2376 CryptDestroyHash(hHash);
2377 }
2378 LocalFree(buf);
2379 }
2380 }
2381 return ret;
2382}
2383
2385 DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
2386 BYTE *pbComputedHash, DWORD *pcbComputedHash)
2387{
2388 BOOL ret;
2390 DWORD size;
2391
2392 TRACE("(%08Ix, %08lx, %p, %ld, %p, %ld)\n", hCryptProv, dwCertEncodingType,
2393 pbEncoded, cbEncoded, pbComputedHash, *pcbComputedHash);
2394
2395 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT,
2396 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
2397 if (ret)
2398 {
2400 HCRYPTHASH hHash;
2401
2402 if (!hCryptProv)
2403 hCryptProv = I_CryptGetDefaultCryptProv(0);
2405 info->SignatureAlgorithm.pszObjId, 0);
2406 if (!oidInfo)
2407 {
2409 ret = FALSE;
2410 }
2411 else
2412 {
2413 ret = CryptCreateHash(hCryptProv, oidInfo->Algid, 0, 0, &hHash);
2414 if (ret)
2415 {
2416 ret = CryptHashData(hHash, info->ToBeSigned.pbData,
2417 info->ToBeSigned.cbData, 0);
2418 if (ret)
2419 ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2420 pcbComputedHash, 0);
2421 CryptDestroyHash(hHash);
2422 }
2423 }
2424 LocalFree(info);
2425 }
2426 return ret;
2427}
2428
2430 DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
2431 DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
2432 const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
2433{
2434 BOOL ret;
2436 HCRYPTHASH hHash;
2437
2438 TRACE("(%08Ix, %ld, %ld, %p, %ld, %p, %p, %p, %p)\n", hCryptProv,
2439 dwKeySpec, dwCertEncodingType, pbEncodedToBeSigned, cbEncodedToBeSigned,
2440 pSignatureAlgorithm, pvHashAuxInfo, pbSignature, pcbSignature);
2441
2443 pSignatureAlgorithm->pszObjId, 0);
2444 if (!info)
2445 {
2447 return FALSE;
2448 }
2449 if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
2450 {
2451 if (!hCryptProv)
2452 hCryptProv = I_CryptGetDefaultCryptProv(0);
2453 ret = CryptCreateHash(hCryptProv, info->Algid, 0, 0, &hHash);
2454 if (ret)
2455 {
2456 ret = CryptHashData(hHash, pbEncodedToBeSigned,
2457 cbEncodedToBeSigned, 0);
2458 if (ret)
2459 ret = CryptGetHashParam(hHash, HP_HASHVAL, pbSignature,
2460 pcbSignature, 0);
2461 CryptDestroyHash(hHash);
2462 }
2463 }
2464 else
2465 {
2466 if (!hCryptProv)
2467 {
2469 ret = FALSE;
2470 }
2471 else
2472 {
2473 ret = CryptCreateHash(hCryptProv, info->Algid, 0, 0, &hHash);
2474 if (ret)
2475 {
2476 ret = CryptHashData(hHash, pbEncodedToBeSigned,
2477 cbEncodedToBeSigned, 0);
2478 if (ret)
2479 ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature,
2480 pcbSignature);
2481 CryptDestroyHash(hHash);
2482 }
2483 }
2484 }
2485 return ret;
2486}
2487
2489 DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType,
2490 const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
2491 const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
2492{
2493 BOOL ret;
2494 DWORD encodedSize, hashSize;
2495
2496 TRACE("(%08Ix, %ld, %ld, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec,
2497 dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo,
2498 pSignatureAlgorithm, pvHashAuxInfo, pbEncoded, pcbEncoded);
2499
2500 ret = CryptEncodeObject(dwCertEncodingType, lpszStructType, pvStructInfo,
2501 NULL, &encodedSize);
2502 if (ret)
2503 {
2504 PBYTE encoded = CryptMemAlloc(encodedSize);
2505
2506 if (encoded)
2507 {
2508 ret = CryptEncodeObject(dwCertEncodingType, lpszStructType,
2509 pvStructInfo, encoded, &encodedSize);
2510 if (ret)
2511 {
2512 ret = CryptSignCertificate(hCryptProv, dwKeySpec,
2513 dwCertEncodingType, encoded, encodedSize, pSignatureAlgorithm,
2514 pvHashAuxInfo, NULL, &hashSize);
2515 if (ret)
2516 {
2517 PBYTE hash = CryptMemAlloc(hashSize);
2518
2519 if (hash)
2520 {
2521 ret = CryptSignCertificate(hCryptProv, dwKeySpec,
2522 dwCertEncodingType, encoded, encodedSize,
2523 pSignatureAlgorithm, pvHashAuxInfo, hash, &hashSize);
2524 if (ret)
2525 {
2526 CERT_SIGNED_CONTENT_INFO info = { { 0 } };
2527
2528 info.ToBeSigned.cbData = encodedSize;
2529 info.ToBeSigned.pbData = encoded;
2530 info.SignatureAlgorithm = *pSignatureAlgorithm;
2531 info.Signature.cbData = hashSize;
2532 info.Signature.pbData = hash;
2533 info.Signature.cUnusedBits = 0;
2534 ret = CryptEncodeObject(dwCertEncodingType,
2535 X509_CERT, &info, pbEncoded, pcbEncoded);
2536 }
2538 }
2539 else
2540 ret = FALSE;
2541 }
2542 }
2543 CryptMemFree(encoded);
2544 }
2545 else
2546 ret = FALSE;
2547 }
2548 return ret;
2549}
2550
2552 DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
2553 PCERT_PUBLIC_KEY_INFO pPublicKey)
2554{
2555 CRYPT_DATA_BLOB blob = { cbEncoded, (BYTE *)pbEncoded };
2556
2557 return CryptVerifyCertificateSignatureEx(hCryptProv, dwCertEncodingType,
2560}
2561
2562static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
2563 CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
2564{
2565 BOOL ret;
2566 HCRYPTKEY key;
2567 ALG_ID pubKeyID, hashID;
2568
2569 hashID = info->Algid;
2570 if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
2571 pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
2572 else
2573 pubKeyID = hashID;
2574 /* Load the default provider if necessary */
2575 if (!hCryptProv)
2576 hCryptProv = I_CryptGetDefaultCryptProv(hashID);
2577 ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
2578 pubKeyInfo, pubKeyID, 0, NULL, &key);
2579 if (ret)
2580 {
2582
2583 ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash);
2584 if (ret)
2585 {
2586 ret = CryptHashData(hash, signedCert->ToBeSigned.pbData,
2587 signedCert->ToBeSigned.cbData, 0);
2588 if (ret)
2590 signedCert->Signature.cbData, key, NULL, 0);
2592 }
2594 }
2595 return ret;
2596}
2597
2599 BYTE **hash_value, DWORD *hash_len)
2600{
2602 BCRYPT_ALG_HANDLE alg = NULL;
2604 DWORD size;
2605
2607 goto done;
2608
2609 if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
2610 goto done;
2611
2612 if ((status = BCryptHashData(hash, signedCert->ToBeSigned.pbData, signedCert->ToBeSigned.cbData, 0)))
2613 goto done;
2614
2615 if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)hash_len, sizeof(*hash_len), &size, 0)))
2616 goto done;
2617
2618 if (!(*hash_value = CryptMemAlloc(*hash_len)))
2619 {
2621 goto done;
2622 }
2623
2624 if ((status = BCryptFinishHash(hash, *hash_value, *hash_len, 0)))
2625 {
2626 CryptMemFree(*hash_value);
2627 goto done;
2628 }
2629
2630done:
2632 if (alg) BCryptCloseAlgorithmProvider(alg, 0);
2634 return status == 0;
2635}
2636
2638{
2639 DWORD blob_magic, ecckey_len, size;
2640 BCRYPT_ALG_HANDLE alg_handle;
2641 BCRYPT_ECCKEY_BLOB *ecckey;
2642 char **ecc_curve;
2644
2645 if (!pubKeyInfo->PublicKey.cbData)
2646 {
2648 return FALSE;
2649 }
2650
2651 if (pubKeyInfo->PublicKey.pbData[0] != 0x4)
2652 {
2653 FIXME("Compressed ECC curves (%02x) not yet supported\n", pubKeyInfo->PublicKey.pbData[0]);
2655 return FALSE;
2656 }
2657
2659 pubKeyInfo->Algorithm.Parameters.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_curve, &size))
2660 return FALSE;
2661
2662 if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256))
2663 {
2664 alg_handle = BCRYPT_ECDSA_P256_ALG_HANDLE;
2665 blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
2666 }
2667 else if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P384))
2668 {
2669 alg_handle = BCRYPT_ECDSA_P384_ALG_HANDLE;
2670 blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
2671 }
2672 else
2673 {
2674 FIXME("Unsupported ecc curve type: %s\n", *ecc_curve);
2675 alg_handle = NULL;
2676 blob_magic = 0;
2677 }
2678 LocalFree(ecc_curve);
2679
2680 if (!alg_handle)
2681 {
2683 return FALSE;
2684 }
2685
2686 ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1;
2687 if (!(ecckey = CryptMemAlloc(ecckey_len)))
2688 return STATUS_NO_MEMORY;
2689
2690 ecckey->dwMagic = blob_magic;
2691 ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2;
2692 memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1);
2693
2694 status = BCryptImportKeyPair(alg_handle, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0);
2695 CryptMemFree(ecckey);
2696
2698 return !status;
2699}
2700
2702{
2703 DWORD size, modulus_len, i;
2704 BLOBHEADER *hdr;
2705 RSAPUBKEY *rsapubkey;
2706 BCRYPT_ALG_HANDLE alg_handle;
2707 BCRYPT_RSAKEY_BLOB *rsakey;
2708 BYTE *s, *d;
2710
2711 if (!info->PublicKey.cbData)
2712 {
2714 return FALSE;
2715 }
2716
2718 info->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &hdr, &size))
2719 {
2720 WARN("CryptDecodeObjectEx failed\n");
2721 return FALSE;
2722 }
2723
2724 if (hdr->aiKeyAlg == CALG_RSA_KEYX)
2725 alg_handle = BCRYPT_RSA_ALG_HANDLE;
2726 else if (hdr->aiKeyAlg == CALG_RSA_SIGN)
2727 alg_handle = BCRYPT_RSA_SIGN_ALG_HANDLE;
2728 else
2729 {
2730 FIXME("Unsupported RSA algorithm: %#x\n", hdr->aiKeyAlg);
2731 LocalFree(hdr);
2733 return FALSE;
2734 }
2735
2736 rsapubkey = (RSAPUBKEY *)(hdr + 1);
2737
2738 modulus_len = size - sizeof(*hdr) - sizeof(*rsapubkey);
2739 if (modulus_len != rsapubkey->bitlen / 8)
2740 FIXME("RSA pubkey has wrong modulus_len %lu\n", modulus_len);
2741
2742 size = sizeof(*rsakey) + sizeof(ULONG) + modulus_len;
2743 if (!(rsakey = CryptMemAlloc(size)))
2744 return STATUS_NO_MEMORY;
2745
2746 rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC;
2747 rsakey->BitLength = rsapubkey->bitlen;
2748 rsakey->cbPublicExp = sizeof(ULONG);
2749 rsakey->cbModulus = modulus_len;
2750 rsakey->cbPrime1 = 0;
2751 rsakey->cbPrime2 = 0;
2752
2753 d = (BYTE *)(rsakey + 1);
2754 /* According to MSDN modulus and pubexp are in LE while
2755 * BCRYPT_RSAKEY_BLOB is supposed to have them in BE format */
2756 *(ULONG *)d = RtlUlongByteSwap(rsapubkey->pubexp);
2757 d += sizeof(ULONG);
2758 s = (BYTE *)(rsapubkey + 1);
2759 for (i = 0; i < modulus_len; i++)
2760 d[i] = s[modulus_len - i - 1];
2761
2762 status = BCryptImportKeyPair(alg_handle, NULL, BCRYPT_RSAPUBLIC_BLOB, key, (BYTE *)rsakey, size, 0);
2763 CryptMemFree(rsakey);
2764
2765 LocalFree(hdr);
2767 return !status;
2768}
2769
2771{
2772 if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
2773 return CNG_ImportECCPubKey(pubKeyInfo, key);
2774
2775 if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_RSA_RSA))
2776 return CNG_ImportRSAPubKey(pubKeyInfo, key);
2777
2778 FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
2780 return FALSE;
2781}
2782
2783static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len)
2784{
2785 CERT_ECC_SIGNATURE *ecc_sig;
2786 DWORD size, r_size, s_size, r_offset, s_offset;
2787 int i;
2788
2789 if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, encoded_sig, encoded_size,
2790 CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size))
2791 return FALSE;
2792
2793 if (!(r_size = ecc_sig->r.cbData) || !(s_size = ecc_sig->s.cbData))
2794 {
2795 LocalFree(ecc_sig);
2797 return FALSE;
2798 }
2799 r_size = s_size = max( r_size, s_size );
2800
2801 *sig_len = r_size + s_size;
2802 if (!(*sig_value = CryptMemAlloc(*sig_len)))
2803 {
2804 LocalFree(ecc_sig);
2806 return FALSE;
2807 }
2808 memset( *sig_value, 0, *sig_len );
2809
2810 r_offset = r_size - ecc_sig->r.cbData;
2811 s_offset = s_size - ecc_sig->s.cbData;
2812
2813 for (i = 0; i < ecc_sig->r.cbData; i++)
2814 (*sig_value)[i + r_offset] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1];
2815 for (i = 0; i < ecc_sig->s.cbData; i++)
2816 (*sig_value)[r_size + i + s_offset] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1];
2817
2818 LocalFree(ecc_sig);
2819 return TRUE;
2820}
2821
2822BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len,
2823 BYTE **sig_value, DWORD *sig_len)
2824{
2825 if (!strcmp(alg_oid, szOID_ECC_PUBLIC_KEY))
2826 return CNG_PrepareSignatureECC(encoded_sig, encoded_sig_len, sig_value, sig_len);
2827
2828 FIXME("Unsupported public key type: %s\n", debugstr_a(alg_oid));
2830 return FALSE;
2831}
2832
2834 BYTE **sig_value, DWORD *sig_len)
2835{
2836 BYTE *encoded_sig;
2837 BOOL ret = FALSE;
2838 int i;
2839
2840 if (!signedCert->Signature.cbData)
2841 {
2843 return FALSE;
2844 }
2845
2846 if (!(encoded_sig = CryptMemAlloc(signedCert->Signature.cbData)))
2847 {
2849 return FALSE;
2850 }
2851
2852 for (i = 0; i < signedCert->Signature.cbData; i++)
2853 encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1];
2854
2855 ret = cng_prepare_signature(pubKeyInfo->Algorithm.pszObjId, encoded_sig, signedCert->Signature.cbData,
2856 sig_value, sig_len);
2857 CryptMemFree(encoded_sig);
2858 return ret;
2859}
2860
2861static BOOL CNG_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
2862 CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
2863{
2865 BYTE *hash_value = NULL, *sig_value;
2866 DWORD hash_len, sig_len;
2868 BOOL ret;
2869
2870 ret = CNG_ImportPubKey(pubKeyInfo, &key);
2871 if (ret)
2872 {
2873 ret = CNG_CalcHash(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len);
2874 if (ret)
2875 {
2876 ret = CNG_PrepareCertSignature(pubKeyInfo, signedCert, &sig_value, &sig_len);
2877 if (ret)
2878 {
2879 status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
2880 if (status)
2881 {
2882 FIXME("Failed to verify signature: %08lx\n", status);
2884 ret = FALSE;
2885 }
2886 CryptMemFree(sig_value);
2887 }
2888 CryptMemFree(hash_value);
2889 }
2891 }
2892
2893 return ret;
2894}
2895
2897 CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
2898{
2900
2902 if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
2903 {
2905 return FALSE;
2906 }
2907
2908 if (info->Algid == CALG_OID_INFO_CNG_ONLY)
2909 return CNG_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
2910 else
2911 return CRYPT_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
2912}
2913
2915 DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
2916 DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
2917{
2918 BOOL ret = TRUE;
2919 CRYPT_DATA_BLOB subjectBlob;
2920
2921 TRACE("(%08Ix, %ld, %ld, %p, %ld, %p, %08lx, %p)\n", hCryptProv,
2922 dwCertEncodingType, dwSubjectType, pvSubject, dwIssuerType, pvIssuer,
2924
2925 switch (dwSubjectType)
2926 {
2928 {
2929 PCRYPT_DATA_BLOB blob = pvSubject;
2930
2931 subjectBlob.pbData = blob->pbData;
2932 subjectBlob.cbData = blob->cbData;
2933 break;
2934 }
2936 {
2937 PCERT_CONTEXT context = pvSubject;
2938
2939 subjectBlob.pbData = context->pbCertEncoded;
2940 subjectBlob.cbData = context->cbCertEncoded;
2941 break;
2942 }
2944 {
2945 PCRL_CONTEXT context = pvSubject;
2946
2947 subjectBlob.pbData = context->pbCrlEncoded;
2948 subjectBlob.cbData = context->cbCrlEncoded;
2949 break;
2950 }
2951 default:
2953 ret = FALSE;
2954 }
2955
2956 if (ret)
2957 {
2958 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
2959 DWORD size = 0;
2960
2961 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT,
2962 subjectBlob.pbData, subjectBlob.cbData,
2964 &signedCert, &size);
2965 if (ret)
2966 {
2967 switch (dwIssuerType)
2968 {
2971 dwCertEncodingType, pvIssuer,
2972 signedCert);
2973 break;
2976 dwCertEncodingType,
2977 &((PCCERT_CONTEXT)pvIssuer)->pCertInfo->SubjectPublicKeyInfo,
2978 signedCert);
2979 break;
2981 FIXME("CRYPT_VERIFY_CERT_SIGN_ISSUER_CHAIN: stub\n");
2982 ret = FALSE;
2983 break;
2985 if (pvIssuer)
2986 {
2988 ret = FALSE;
2989 }
2990 else
2991 {
2992 FIXME("unimplemented for NULL signer\n");
2994 ret = FALSE;
2995 }
2996 break;
2997 default:
2999 ret = FALSE;
3000 }
3001 LocalFree(signedCert);
3002 }
3003 }
3004 return ret;
3005}
3006
3008 PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage)
3009{
3011 BOOL ret = FALSE;
3012
3013 TRACE("(%08lx, %p, %p, %ld)\n", dwCertEncodingType, pCertInfo, pbKeyUsage,
3014 cbKeyUsage);
3015
3017 pCertInfo->rgExtension);
3018 if (ext)
3019 {
3021 DWORD size = sizeof(usage);
3022
3023 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BITS,
3024 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL,
3025 &usage, &size);
3026 if (ret)
3027 {
3028 if (cbKeyUsage < usage.cbData)
3029 ret = FALSE;
3030 else
3031 {
3032 memcpy(pbKeyUsage, usage.pbData, usage.cbData);
3033 if (cbKeyUsage > usage.cbData)
3034 memset(pbKeyUsage + usage.cbData, 0,
3035 cbKeyUsage - usage.cbData);
3036 }
3037 }
3038 }
3039 else
3040 SetLastError(0);
3041 return ret;
3042}
3043
3045 PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage)
3046{
3048 DWORD bytesNeeded;
3049 BOOL ret = TRUE;
3050
3051 if (!pCertContext || !pcbUsage)
3052 {
3054 return FALSE;
3055 }
3056
3057 TRACE("(%p, %08lx, %p, %ld)\n", pCertContext, dwFlags, pUsage, *pcbUsage);
3058
3060 {
3061 DWORD propSize = 0;
3062
3063 if (CertGetCertificateContextProperty(pCertContext,
3064 CERT_ENHKEY_USAGE_PROP_ID, NULL, &propSize))
3065 {
3066 LPBYTE buf = CryptMemAlloc(propSize);
3067
3068 if (buf)
3069 {
3070 if (CertGetCertificateContextProperty(pCertContext,
3071 CERT_ENHKEY_USAGE_PROP_ID, buf, &propSize))
3072 {
3074 X509_ENHANCED_KEY_USAGE, buf, propSize,
3075 CRYPT_ENCODE_ALLOC_FLAG, NULL, &usage, &bytesNeeded);
3076 }
3078 }
3079 }
3080 }
3082 {
3084 pCertContext->pCertInfo->cExtension,
3085 pCertContext->pCertInfo->rgExtension);
3086
3087 if (ext)
3088 {
3090 X509_ENHANCED_KEY_USAGE, ext->Value.pbData, ext->Value.cbData,
3091 CRYPT_ENCODE_ALLOC_FLAG, NULL, &usage, &bytesNeeded);
3092 }
3093 }
3094 if (!usage)
3095 {
3096 /* If a particular location is specified, this should fail. Otherwise
3097 * it should succeed with an empty usage. (This is true on Win2k and
3098 * later, which we emulate.)
3099 */
3100 if (dwFlags)
3101 {
3103 ret = FALSE;
3104 }
3105 else
3106 bytesNeeded = sizeof(CERT_ENHKEY_USAGE);
3107 }
3108
3109 if (ret)
3110 {
3111 if (!pUsage)
3112 *pcbUsage = bytesNeeded;
3113 else if (*pcbUsage < bytesNeeded)
3114 {
3116 *pcbUsage = bytesNeeded;
3117 ret = FALSE;
3118 }
3119 else
3120 {
3121 *pcbUsage = bytesNeeded;
3122 if (usage)
3123 {
3124 DWORD i;
3125 LPSTR nextOID = (LPSTR)((LPBYTE)pUsage +
3126 sizeof(CERT_ENHKEY_USAGE) +
3127 usage->cUsageIdentifier * sizeof(LPSTR));
3128
3129 pUsage->cUsageIdentifier = usage->cUsageIdentifier;
3130 pUsage->rgpszUsageIdentifier = (LPSTR *)((LPBYTE)pUsage +
3131 sizeof(CERT_ENHKEY_USAGE));
3132 for (i = 0; i < usage->cUsageIdentifier; i++)
3133 {
3134 pUsage->rgpszUsageIdentifier[i] = nextOID;
3135 strcpy(nextOID, usage->rgpszUsageIdentifier[i]);
3136 nextOID += strlen(nextOID) + 1;
3137 }
3138 }
3139 else
3140 pUsage->cUsageIdentifier = 0;
3141 }
3142 }
3143 if (usage)
3145 TRACE("returning %d\n", ret);
3146 return ret;
3147}
3148
3150 PCERT_ENHKEY_USAGE pUsage)
3151{
3152 BOOL ret;
3153
3154 TRACE("(%p, %p)\n", pCertContext, pUsage);
3155
3156 if (pUsage)
3157 {
3158 CRYPT_DATA_BLOB blob = { 0, NULL };
3159
3161 pUsage, CRYPT_ENCODE_ALLOC_FLAG, NULL, &blob.pbData, &blob.cbData);
3162 if (ret)
3163 {
3166 LocalFree(blob.pbData);
3167 }
3168 }
3169 else
3172 return ret;
3173}
3174
3176 LPCSTR pszUsageIdentifier)
3177{
3178 BOOL ret;
3179 DWORD size;
3180
3181 TRACE("(%p, %s)\n", pCertContext, debugstr_a(pszUsageIdentifier));
3182
3183 if (CertGetEnhancedKeyUsage(pCertContext,
3185 {
3187
3188 if (usage)
3189 {
3190 ret = CertGetEnhancedKeyUsage(pCertContext,
3192 if (ret)
3193 {
3194 DWORD i;
3195 BOOL exists = FALSE;
3196
3197 /* Make sure usage doesn't already exist */
3198 for (i = 0; !exists && i < usage->cUsageIdentifier; i++)
3199 {
3200 if (!strcmp(usage->rgpszUsageIdentifier[i],
3201 pszUsageIdentifier))
3202 exists = TRUE;
3203 }
3204 if (!exists)
3205 {
3207 sizeof(LPSTR) + strlen(pszUsageIdentifier) + 1);
3208
3209 if (newUsage)
3210 {
3211 LPSTR nextOID;
3212
3213 newUsage->rgpszUsageIdentifier = (LPSTR *)
3214 ((LPBYTE)newUsage + sizeof(CERT_ENHKEY_USAGE));
3215 nextOID = (LPSTR)((LPBYTE)newUsage->rgpszUsageIdentifier
3216 + (usage->cUsageIdentifier + 1) * sizeof(LPSTR));
3217 for (i = 0; i < usage->cUsageIdentifier; i++)
3218 {
3219 newUsage->rgpszUsageIdentifier[i] = nextOID;
3220 strcpy(nextOID, usage->rgpszUsageIdentifier[i]);
3221 nextOID += strlen(nextOID) + 1;
3222 }
3223 newUsage->rgpszUsageIdentifier[i] = nextOID;
3224 strcpy(nextOID, pszUsageIdentifier);
3225 newUsage->cUsageIdentifier = i + 1;
3226 ret = CertSetEnhancedKeyUsage(pCertContext, newUsage);
3227 CryptMemFree(newUsage);
3228 }
3229 else
3230 ret = FALSE;
3231 }
3232 }
3234 }
3235 else
3236 ret = FALSE;
3237 }
3238 else
3239 {
3241 sizeof(LPSTR) + strlen(pszUsageIdentifier) + 1);
3242
3243 if (usage)
3244 {
3245 usage->rgpszUsageIdentifier =
3246 (LPSTR *)((LPBYTE)usage + sizeof(CERT_ENHKEY_USAGE));
3247 usage->rgpszUsageIdentifier[0] = (LPSTR)((LPBYTE)usage +
3248 sizeof(CERT_ENHKEY_USAGE) + sizeof(LPSTR));
3249 strcpy(usage->rgpszUsageIdentifier[0], pszUsageIdentifier);
3250 usage->cUsageIdentifier = 1;
3251 ret = CertSetEnhancedKeyUsage(pCertContext, usage);
3253 }
3254 else
3255 ret = FALSE;
3256 }
3257 return ret;
3258}
3259
3261 LPCSTR pszUsageIdentifier)
3262{
3263 BOOL ret;
3264 DWORD size;
3266
3267 TRACE("(%p, %s)\n", pCertContext, debugstr_a(pszUsageIdentifier));
3268
3269 size = sizeof(usage);
3270 ret = CertGetEnhancedKeyUsage(pCertContext,
3272 if (!ret && GetLastError() == ERROR_MORE_DATA)
3273 {
3275
3276 if (pUsage)
3277 {
3278 ret = CertGetEnhancedKeyUsage(pCertContext,
3280 if (ret)
3281 {
3282 if (pUsage->cUsageIdentifier)
3283 {
3284 DWORD i;
3285 BOOL found = FALSE;
3286
3287 for (i = 0; i < pUsage->cUsageIdentifier; i++)
3288 {
3289 if (!strcmp(pUsage->rgpszUsageIdentifier[i],
3290 pszUsageIdentifier))
3291 found = TRUE;
3292 if (found && i < pUsage->cUsageIdentifier - 1)
3293 pUsage->rgpszUsageIdentifier[i] =
3294 pUsage->rgpszUsageIdentifier[i + 1];
3295 }
3296 pUsage->cUsageIdentifier--;
3297 /* Remove the usage if it's empty */
3298 if (pUsage->cUsageIdentifier)
3299 ret = CertSetEnhancedKeyUsage(pCertContext, pUsage);
3300 else
3301 ret = CertSetEnhancedKeyUsage(pCertContext, NULL);
3302 }
3303 }
3304 CryptMemFree(pUsage);
3305 }
3306 else
3307 ret = FALSE;
3308 }
3309 else
3310 {
3311 /* it fit in an empty usage, therefore there's nothing to remove */
3312 ret = TRUE;
3313 }
3314 return ret;
3315}
3316
3318{
3321};
3322
3323#define BITS_PER_DWORD (sizeof(DWORD) * 8)
3324
3325static void CRYPT_SetBitInField(struct BitField *field, DWORD bit)
3326{
3327 DWORD indexIndex = bit / BITS_PER_DWORD;
3328
3329 if (indexIndex + 1 > field->cIndexes)
3330 {
3331 if (field->cIndexes)
3332 field->indexes = CryptMemRealloc(field->indexes,
3333 (indexIndex + 1) * sizeof(DWORD));
3334 else
3335 field->indexes = CryptMemAlloc(sizeof(DWORD));
3336 if (field->indexes)
3337 {
3338 field->indexes[indexIndex] = 0;
3339 field->cIndexes = indexIndex + 1;
3340 }
3341 }
3342 if (field->indexes)
3343 field->indexes[indexIndex] |= 1 << (bit % BITS_PER_DWORD);
3344}
3345
3347{
3348 BOOL set;
3349 DWORD indexIndex = bit / BITS_PER_DWORD;
3350
3351 assert(field->cIndexes);
3352 set = field->indexes[indexIndex] & (1 << (bit % BITS_PER_DWORD));
3353 return set;
3354}
3355
3357 int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs)
3358{
3359 BOOL ret = TRUE;
3360 DWORD i, cbOIDs = 0;
3361 BOOL allUsagesValid = TRUE;
3362 CERT_ENHKEY_USAGE validUsages = { 0, NULL };
3363
3364 TRACE("(%ld, %p, %d, %p, %ld)\n", cCerts, rghCerts, *cNumOIDs,
3365 rghOIDs, *pcbOIDs);
3366
3367 for (i = 0; i < cCerts; i++)
3368 {
3370 DWORD size = sizeof(usage);
3371
3372 ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, &usage, &size);
3373 /* Success is deliberately ignored: it implies all usages are valid */
3374 if (!ret && GetLastError() == ERROR_MORE_DATA)
3375 {
3377
3378 allUsagesValid = FALSE;
3379 if (pUsage)
3380 {
3381 ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, pUsage, &size);
3382 if (ret)
3383 {
3384 if (!validUsages.cUsageIdentifier)
3385 {
3386 DWORD j;
3387
3388 cbOIDs = pUsage->cUsageIdentifier * sizeof(LPSTR);
3389 validUsages.cUsageIdentifier = pUsage->cUsageIdentifier;
3390 for (j = 0; j < validUsages.cUsageIdentifier; j++)
3391 cbOIDs += lstrlenA(pUsage->rgpszUsageIdentifier[j])
3392 + 1;
3393 validUsages.rgpszUsageIdentifier =
3394 CryptMemAlloc(cbOIDs);
3395 if (validUsages.rgpszUsageIdentifier)
3396 {
3397 LPSTR nextOID = (LPSTR)
3398 ((LPBYTE)validUsages.rgpszUsageIdentifier +
3399 validUsages.cUsageIdentifier * sizeof(LPSTR));
3400
3401 for (j = 0; j < validUsages.cUsageIdentifier; j++)
3402 {
3403 validUsages.rgpszUsageIdentifier[j] = nextOID;
3404 lstrcpyA(validUsages.rgpszUsageIdentifier[j],
3405 pUsage->rgpszUsageIdentifier[j]);
3406 nextOID += lstrlenA(nextOID) + 1;
3407 }
3408 }
3409 }
3410 else
3411 {
3412 struct BitField validIndexes = { 0, NULL };
3413 DWORD j, k, numRemoved = 0;
3414
3415 /* Merge: build a bitmap of all the indexes of
3416 * validUsages.rgpszUsageIdentifier that are in pUsage.
3417 */
3418 for (j = 0; j < pUsage->cUsageIdentifier; j++)
3419 {
3420 for (k = 0; k < validUsages.cUsageIdentifier; k++)
3421 {
3422 if (!strcmp(pUsage->rgpszUsageIdentifier[j],
3423 validUsages.rgpszUsageIdentifier[k]))
3424 {
3425 CRYPT_SetBitInField(&validIndexes, k);
3426 break;
3427 }
3428 }
3429 }
3430 /* Merge by removing from validUsages those that are
3431 * not in the bitmap.
3432 */
3433 for (j = 0; j < validUsages.cUsageIdentifier; j++)
3434 {
3435 if (!CRYPT_IsBitInFieldSet(&validIndexes, j))
3436 {
3437 if (j < validUsages.cUsageIdentifier - 1)
3438 {
3439 memmove(&validUsages.rgpszUsageIdentifier[j],
3440 &validUsages.rgpszUsageIdentifier[j +
3441 numRemoved + 1],
3442 (validUsages.cUsageIdentifier - numRemoved
3443 - j - 1) * sizeof(LPSTR));
3444 cbOIDs -= lstrlenA(
3445 validUsages.rgpszUsageIdentifier[j]) + 1 +
3446 sizeof(LPSTR);
3447 validUsages.cUsageIdentifier--;
3448 numRemoved++;
3449 }
3450 else
3451 validUsages.cUsageIdentifier--;
3452 }
3453 }
3454 CryptMemFree(validIndexes.indexes);
3455 }
3456 }
3457 CryptMemFree(pUsage);
3458 }
3459 }
3460 }
3461 ret = TRUE;
3462 if (allUsagesValid)
3463 {
3464 *cNumOIDs = -1;
3465 *pcbOIDs = 0;
3466 }
3467 else
3468 {
3469 *cNumOIDs = validUsages.cUsageIdentifier;
3470 if (!rghOIDs)
3471 *pcbOIDs = cbOIDs;
3472 else if (*pcbOIDs < cbOIDs)
3473 {
3474 *pcbOIDs = cbOIDs;
3476 ret = FALSE;
3477 }
3478 else
3479 {
3480 LPSTR nextOID = (LPSTR)((LPBYTE)rghOIDs +
3481 validUsages.cUsageIdentifier * sizeof(LPSTR));
3482
3483 *pcbOIDs = cbOIDs;
3484 for (i = 0; i < validUsages.cUsageIdentifier; i++)
3485 {
3486 rghOIDs[i] = nextOID;
3487 lstrcpyA(nextOID, validUsages.rgpszUsageIdentifier[i]);
3488 nextOID += lstrlenA(nextOID) + 1;
3489 }
3490 }
3491 }
3493 TRACE("cNumOIDs: %d\n", *cNumOIDs);
3494 TRACE("returning %d\n", ret);
3495 return ret;
3496}
3497
3498/* Sets the CERT_KEY_PROV_INFO_PROP_ID property of context from pInfo, or, if
3499 * pInfo is NULL, from the attributes of hProv.
3500 */
3502 const CRYPT_KEY_PROV_INFO *pInfo, HCRYPTPROV hProv)
3503{
3504 CRYPT_KEY_PROV_INFO info = { 0 };
3505 BOOL ret;
3506
3507 if (!pInfo)
3508 {
3509 DWORD size;
3510 int len;
3511
3513 if (ret)
3514 {
3516
3517 if (szContainer)
3518 {
3520 (BYTE *)szContainer, &size, 0);
3521 if (ret)
3522 {
3524 NULL, 0);
3525 if (len)
3526 {
3527 info.pwszContainerName = CryptMemAlloc(len *
3528 sizeof(WCHAR));
3530 info.pwszContainerName, len);
3531 }
3532 }
3534 }
3535 }
3537 if (ret)
3538 {
3540
3541 if (szProvider)
3542 {
3544 &size, 0);
3545 if (ret)
3546 {
3548 NULL, 0);
3549 if (len)
3550 {
3551 info.pwszProvName = CryptMemAlloc(len *
3552 sizeof(WCHAR));
3554 info.pwszProvName, len);
3555 }
3556 }
3558 }
3559 }
3560 /* in case no CRYPT_KEY_PROV_INFO given,
3561 * we always use AT_SIGNATURE key spec
3562 */
3563 info.dwKeySpec = AT_SIGNATURE;
3564 size = sizeof(info.dwProvType);
3566 &size, 0);
3567 if (!ret)
3568 info.dwProvType = PROV_RSA_FULL;
3569 pInfo = &info;
3570 }
3571
3573 0, pInfo);
3574
3575 if (pInfo == &info)
3576 {
3577 CryptMemFree(info.pwszContainerName);
3578 CryptMemFree(info.pwszProvName);
3579 }
3580}
3581
3582/* Creates a signed certificate context from the unsigned, encoded certificate
3583 * in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
3584 */
3587{
3589 BOOL ret;
3590 DWORD sigSize = 0;
3591
3593 blob->pbData, blob->cbData, sigAlgo, NULL, NULL, &sigSize);
3594 if (ret)
3595 {
3596 LPBYTE sig = CryptMemAlloc(sigSize);
3597
3599 blob->pbData, blob->cbData, sigAlgo, NULL, sig, &sigSize);
3600 if (ret)
3601 {
3602 CERT_SIGNED_CONTENT_INFO signedInfo;
3603 BYTE *encodedSignedCert = NULL;
3604 DWORD encodedSignedCertSize = 0;
3605
3606 signedInfo.ToBeSigned.cbData = blob->cbData;
3607 signedInfo.ToBeSigned.pbData = blob->pbData;
3608 signedInfo.SignatureAlgorithm = *sigAlgo;
3609 signedInfo.Signature.cbData = sigSize;
3610 signedInfo.Signature.pbData = sig;
3611 signedInfo.Signature.cUnusedBits = 0;
3613 &signedInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL,
3614 &encodedSignedCert, &encodedSignedCertSize);
3615 if (ret)
3616 {
3618 encodedSignedCert, encodedSignedCertSize);
3619 LocalFree(encodedSignedCert);
3620 }
3621 }
3622 CryptMemFree(sig);
3623 }
3624 return context;
3625}
3626
3627/* Copies data from the parameters into info, where:
3628 * pSerialNumber: The serial number. Must not be NULL.
3629 * pSubjectIssuerBlob: Specifies both the subject and issuer for info.
3630 * Must not be NULL
3631 * pSignatureAlgorithm: Optional.
3632 * pStartTime: The starting time of the certificate. If NULL, the current
3633 * system time is used.
3634 * pEndTime: The ending time of the certificate. If NULL, one year past the
3635 * starting time is used.
3636 * pubKey: The public key of the certificate. Must not be NULL.
3637 * pExtensions: Extensions to be included with the certificate. Optional.
3638 */
3639static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNumber,
3640 const CERT_NAME_BLOB *pSubjectIssuerBlob,
3641 const CRYPT_ALGORITHM_IDENTIFIER *pSignatureAlgorithm, const SYSTEMTIME *pStartTime,
3642 const SYSTEMTIME *pEndTime, const CERT_PUBLIC_KEY_INFO *pubKey,
3643 const CERT_EXTENSIONS *pExtensions)
3644{
3645 static CHAR oid[] = szOID_RSA_SHA1RSA;
3646
3647 assert(info);
3648 assert(pSerialNumber);
3649 assert(pSubjectIssuerBlob);
3650 assert(pubKey);
3651
3652 if (pExtensions && pExtensions->cExtension)
3653 info->dwVersion = CERT_V3;
3654 else
3655 info->dwVersion = CERT_V1;
3656 info->SerialNumber.cbData = pSerialNumber->cbData;
3657 info->SerialNumber.pbData = pSerialNumber->pbData;
3658 if (pSignatureAlgorithm)
3659 info->SignatureAlgorithm = *pSignatureAlgorithm;
3660 else
3661 {
3662 info->SignatureAlgorithm.pszObjId = oid;
3663 info->SignatureAlgorithm.Parameters.cbData = 0;
3664 info->SignatureAlgorithm.Parameters.pbData = NULL;
3665 }
3666 info->Issuer.cbData = pSubjectIssuerBlob->cbData;
3667 info->Issuer.pbData = pSubjectIssuerBlob->pbData;
3668 if (pStartTime)
3669 SystemTimeToFileTime(pStartTime, &info->NotBefore);
3670 else
3671 GetSystemTimeAsFileTime(&info->NotBefore);
3672 if (pEndTime)
3673 SystemTimeToFileTime(pEndTime, &info->NotAfter);
3674 else
3675 {
3676 SYSTEMTIME endTime;
3677
3678 if (FileTimeToSystemTime(&info->NotBefore, &endTime))
3679 {
3680 endTime.wYear++;
3681 SystemTimeToFileTime(&endTime, &info->NotAfter);
3682 }
3683 }
3684 info->Subject.cbData = pSubjectIssuerBlob->cbData;
3685 info->Subject.pbData = pSubjectIssuerBlob->pbData;
3686 info->SubjectPublicKeyInfo = *pubKey;
3687 if (pExtensions)
3688 {
3689 info->cExtension = pExtensions->cExtension;
3690 info->rgExtension = pExtensions->rgExtension;
3691 }
3692 else
3693 {
3694 info->cExtension = 0;
3695 info->rgExtension = NULL;
3696 }
3697}
3698
3700typedef RPC_STATUS (RPC_ENTRY *UuidToStringFunc)(UUID *, unsigned char **);
3701typedef RPC_STATUS (RPC_ENTRY *RpcStringFreeFunc)(unsigned char **);
3702
3704{
3705 HCRYPTPROV hProv = 0;
3706 HMODULE rpcrt = LoadLibraryW(L"rpcrt4");
3707
3708 if (rpcrt)
3709 {
3710 UuidCreateFunc uuidCreate = (UuidCreateFunc)GetProcAddress(rpcrt,
3711 "UuidCreate");
3712 UuidToStringFunc uuidToString = (UuidToStringFunc)GetProcAddress(rpcrt,
3713 "UuidToStringA");
3715 rpcrt, "RpcStringFreeA");
3716
3717 if (uuidCreate && uuidToString && rpcStringFree)
3718 {
3719 UUID uuid;
3720 RPC_STATUS status = uuidCreate(&uuid);
3721
3723 {
3724 unsigned char *uuidStr;
3725
3726 status = uuidToString(&uuid, &uuidStr);
3727 if (status == RPC_S_OK)
3728 {
3731
3732 if (ret)
3733 {
3734 HCRYPTKEY key;
3735
3737 if (ret)
3739 }
3740 rpcStringFree(&uuidStr);
3741 }
3742 }
3743 }
3744 FreeLibrary(rpcrt);
3745 }
3746 return hProv;
3747}
3748
3750 PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags,
3751 PCRYPT_KEY_PROV_INFO pKeyProvInfo,
3752 PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime,
3753 PSYSTEMTIME pEndTime, PCERT_EXTENSIONS pExtensions)
3754{
3756 BOOL ret, releaseContext = FALSE;
3758 DWORD pubKeySize = 0, dwKeySpec;
3759
3760 TRACE("(%08Ix, %p, %08lx, %p, %p, %p, %p, %p)\n", hProv,
3761 pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
3762 pExtensions, pExtensions);
3763
3764 if(!pSubjectIssuerBlob)
3765 {
3767 return NULL;
3768 }
3769
3770 dwKeySpec = pKeyProvInfo ? pKeyProvInfo->dwKeySpec : AT_SIGNATURE;
3771 if (!hProv)
3772 {
3773 if (!pKeyProvInfo)
3774 {
3776 releaseContext = TRUE;
3777 }
3778 else if (pKeyProvInfo->dwFlags & CERT_SET_KEY_PROV_HANDLE_PROP_ID)
3779 {
3781 return NULL;
3782 }
3783 else
3784 {
3785 HCRYPTKEY hKey = 0;
3786 /* acquire the context using the given information*/
3788 pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
3789 pKeyProvInfo->dwFlags);
3790 if (!ret)
3791 {
3793 return NULL;
3794 /* create the key set */
3796 pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
3797 pKeyProvInfo->dwFlags|CRYPT_NEWKEYSET);
3798 if (!ret)
3799 return NULL;
3800 }
3801 /* check if the key is here */
3802 ret = CryptGetUserKey(hProv,dwKeySpec,&hKey);
3803 if(!ret)
3804 {
3805 if (NTE_NO_KEY == GetLastError())
3806 { /* generate the key */
3807 ret = CryptGenKey(hProv,dwKeySpec,0,&hKey);
3808 }
3809 if (!ret)
3810 {
3813 return NULL;
3814 }
3815 }
3817 releaseContext = TRUE;
3818 }
3819 }
3820
3822 &pubKeySize);
3823 if (!ret)
3824 goto end;
3825 pubKey = CryptMemAlloc(pubKeySize);
3826 if (pubKey)
3827 {
3829 pubKey, &pubKeySize);
3830 if (ret)
3831 {
3832 CERT_INFO info = { 0 };
3833 CRYPT_DER_BLOB blob = { 0, NULL };
3834 BYTE serial[16];
3835 CRYPT_DATA_BLOB serialBlob = { sizeof(serial), serial };
3836
3837 CryptGenRandom(hProv, sizeof(serial), serial);
3838 CRYPT_MakeCertInfo(&info, &serialBlob, pSubjectIssuerBlob,
3839 pSignatureAlgorithm, pStartTime, pEndTime, pubKey, pExtensions);
3842 &blob.cbData);
3843 if (ret)
3844 {
3847 &info.SignatureAlgorithm);
3848 else
3850 blob.pbData, blob.cbData);
3853 LocalFree(blob.pbData);
3854 }
3855 }
3857 }
3858end:
3859 if (releaseContext)
3861 return context;
3862}
3863
3864BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType,
3865 void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags,
3866 PCTL_VERIFY_USAGE_PARA pVerifyUsagePara,
3867 PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus)
3868{
3869 FIXME("(0x%lx, %ld, %p, %p, 0x%lx, %p, %p): stub\n", dwEncodingType,
3870 dwSubjectType, pvSubject, pSubjectUsage, dwFlags, pVerifyUsagePara,
3871 pVerifyUsageStatus);
3873 return FALSE;
3874}
3875
3876const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType,
3877 const BYTE *pbEncoded, DWORD cbEncoded,
3879{
3880 TRACE("(0x%lx, 0x%lx, %p, %ld, 0x%08lx, %p)\n", dwContextType, dwEncodingType,
3881 pbEncoded, cbEncoded, dwFlags, pCreatePara);
3882
3883 if (dwFlags)
3884 {
3885 FIXME("dwFlags 0x%08lx not handled\n", dwFlags);
3886 return NULL;
3887 }
3888 if (pCreatePara)
3889 {
3890 FIXME("pCreatePara not handled\n");
3891 return NULL;
3892 }
3893
3894 switch (dwContextType)
3895 {
3897 return CertCreateCertificateContext(dwEncodingType, pbEncoded, cbEncoded);
3899 return CertCreateCRLContext(dwEncodingType, pbEncoded, cbEncoded);
3901 return CertCreateCTLContext(dwEncodingType, pbEncoded, cbEncoded);
3902 default:
3903 WARN("unknown context type: 0x%lx\n", dwContextType);
3904 return NULL;
3905 }
3906}
3907
3909 DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData)
3910{
3911 FIXME("(%p, 0x%lx, 0x%lx, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags,
3912 debugstr_w(pwszComputerName), pvReserved, pvData);
3913 return FALSE;
3914}
#define compare
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC
Definition: bcrypt.h:209
NTSTATUS WINAPI BCryptDestroyKey(BCRYPT_KEY_HANDLE)
static const WCHAR BCRYPT_HASH_LENGTH[]
Definition: bcrypt.h:132
#define BCRYPT_RSA_SIGN_ALG_HANDLE
Definition: bcrypt.h:495
#define BCRYPT_ECDSA_PUBLIC_P384_MAGIC
Definition: bcrypt.h:211
static const WCHAR BCRYPT_ECCPUBLIC_BLOB[]
Definition: bcrypt.h:147
NTSTATUS WINAPI BCryptVerifySignature(BCRYPT_KEY_HANDLE, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG)
#define BCRYPT_RSA_ALG_HANDLE
Definition: bcrypt.h:460
#define BCRYPT_ECDSA_P384_ALG_HANDLE
Definition: bcrypt.h:493
struct _BCRYPT_ECCKEY_BLOB BCRYPT_ECCKEY_BLOB
#define BCRYPT_RSAPUBLIC_MAGIC
Definition: bcrypt.h:286
NTSTATUS WINAPI BCryptImportKeyPair(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *, UCHAR *, ULONG, ULONG)
static const WCHAR BCRYPT_RSAPUBLIC_BLOB[]
Definition: bcrypt.h:149
#define BCRYPT_ECDSA_P256_ALG_HANDLE
Definition: bcrypt.h:492
NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1058
NTSTATUS WINAPI BCryptGetProperty(BCRYPT_HANDLE handle, LPCWSTR prop, UCHAR *buffer, ULONG count, ULONG *res, ULONG flags)
Definition: bcrypt_main.c:978
NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE handle)
Definition: bcrypt_main.c:1047
NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags)
Definition: bcrypt_main.c:336
NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE handle, DWORD flags)
Definition: bcrypt_main.c:380
NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE *handle, UCHAR *object, ULONG objectlen, UCHAR *secret, ULONG secretlen, ULONG flags)
Definition: bcrypt_main.c:1005
NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1077
Definition: _set.h:50
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
Definition: decode.c:6998
BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo)
Definition: decode.c:6990
static void * context_ptr(context_t *context)
DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id)
Definition: proplist.c:170
BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
Definition: encode.c:478
#define CERT_CTL_PROP_ID
#define CERT_CRL_PROP_ID
#define CERT_CERT_PROP_ID
#define WINE_CRYPTCERTSTORE_MAGIC
HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID)
Definition: main.c:215
static context_t * context_from_ptr(const void *ptr)
BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, PCRYPT_DATA_BLOB blob)
Definition: proplist.c:72
@ StoreTypeCollection
static cert_t * cert_from_ptr(const CERT_CONTEXT *ptr)
void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id)
Definition: proplist.c:149
WINECRYPT_CERTSTORE empty_store
Definition: store.c:1503
BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, const BYTE *pbData, size_t cbData)
Definition: proplist.c:95
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static TAGID TAGID find
Definition: db.cpp:156
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: crypt.c:715
BOOL WINAPI CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
Definition: crypt.c:684
BOOL WINAPI CryptSetProvParam(HCRYPTPROV hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
Definition: crypt.c:2153
BOOL WINAPI CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1584
BOOL WINAPI CryptDestroyKey(HCRYPTKEY hKey)
Definition: crypt.c:911
BOOL WINAPI CryptDestroyHash(HCRYPTHASH hHash)
Definition: crypt.c:875
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
Definition: crypt.c:641
BOOL WINAPI CryptHashData(HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
Definition: crypt.c:1745
BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:571
BOOL WINAPI CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1423
BOOL WINAPI CryptEnumProvidersW(DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
Definition: crypt.c:1119
BOOL WINAPI CryptVerifySignatureW(HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
Definition: crypt.c:2205
BOOL WINAPI CryptGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
Definition: crypt.c:1694
BOOL WINAPI CryptGetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1626
BOOL WINAPI CryptSignHashW(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
Definition: crypt.c:1882
BOOL WINAPI CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:362
BOOL WINAPI CryptGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1667
DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pPublicKey)
Definition: cert.c:1375
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1585
static BOOL CNG_ImportRSAPubKey(CERT_PUBLIC_KEY_INFO *info, BCRYPT_KEY_HANDLE *key)
Definition: cert.c:2701
static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
Definition: cert.c:2562
static PCCERT_CONTEXT find_cert_by_name_str_w(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1804
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
Definition: cert.c:284
static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
Definition: cert.c:2637
static HCRYPTPROV CRYPT_CreateKeyProv(void)
Definition: cert.c:3703
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:369
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:314
static const context_vtbl_t cert_vtbl
Definition: cert.c:116
RPC_STATUS(RPC_ENTRY * UuidCreateFunc)(UUID *)
Definition: cert.c:3699
static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
Definition: cert.c:2896
BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
Definition: cert.c:1250
static PCCERT_CONTEXT find_cert_by_name_str_a(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1778
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1830
static BOOL compare_cert_by_sha1_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1458
static BOOL cert_prov_info_matches_cert(PCCERT_CONTEXT pCert)
Definition: cert.c:1202
BOOL WINAPI CertRemoveEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, LPCSTR pszUsageIdentifier)
Definition: cert.c:3260
BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo, PCERT_INFO pIssuerInfo)
Definition: cert.c:2249
BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
Definition: cert.c:2005
static BOOL container_matches_cert(PCCERT_CONTEXT pCert, LPCSTR container, CRYPT_KEY_PROV_INFO *keyProvInfo)
Definition: cert.c:1064
#define BITS_PER_DWORD
Definition: cert.c:3323
static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, const CRYPT_KEY_PROV_INFO *pInfo, HCRYPTPROV hProv)
Definition: cert.c:3501
static void Cert_free(context_t *context)
Definition: cert.c:118
BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert, DWORD dwFlags, void *pvReserved)
Definition: cert.c:1223
static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1437
static BOOL CertContext_GetHashProp(cert_t *cert, DWORD dwPropId, ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData, DWORD *pcbData)
Definition: cert.c:393
PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, CRYPT_ATTRIBUTE rgAttr[])
Definition: cert.c:2077
PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, PCERT_INFO pCertId)
Definition: cert.c:1902
BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:97
static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties, const CRYPT_KEY_PROV_INFO *info)
Definition: cert.c:665
BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType, void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags, PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus)
Definition: cert.c:3864
static DWORD CRYPT_significantBytes(const CRYPT_INTEGER_BLOB *pInt)
Definition: cert.c:1275
BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage)
Definition: cert.c:3007
BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, PCERT_ENHKEY_USAGE pUsage)
Definition: cert.c:3149
static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNumber, const CERT_NAME_BLOB *pSubjectIssuerBlob, const CRYPT_ALGORITHM_IDENTIFIER *pSignatureAlgorithm, const SYSTEMTIME *pStartTime, const SYSTEMTIME *pEndTime, const CERT_PUBLIC_KEY_INFO *pubKey, const CERT_EXTENSIONS *pExtensions)
Definition: cert.c:3639
BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
Definition: cert.c:920
BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN)
Definition: cert.c:2202
BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:294
static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1640
BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
Definition: cert.c:2770
BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext, LPCSTR pszUsageIdentifier)
Definition: cert.c:3175
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject, DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
Definition: cert.c:2914
BOOL WINAPI CryptSetKeyIdentifierProperty(const CRYPT_HASH_BLOB *pKeyIdentifier, DWORD dwPropId, DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData)
Definition: cert.c:3908
static BOOL CNG_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
Definition: cert.c:2861
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2340
static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1646
BOOL(WINAPI * CertVerifyRevocationFunc)(DWORD, DWORD, DWORD, void **, DWORD, PCERT_REVOCATION_PARA, PCERT_REVOCATION_STATUS)
Definition: cert.c:2002
static PCCERT_CONTEXT cert_compare_certs_in_store(HCERTSTORE store, PCCERT_CONTEXT prev, CertCompareFunc compare, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1621
static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb, DWORD cb)
Definition: cert.c:408
BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, PCERT_INFO pCertId1, PCERT_INFO pCertId2)
Definition: cert.c:1236
static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *cert, DWORD add_disposition, BOOL use_link, PCCERT_CONTEXT *ret_context)
Definition: cert.c:169
static BOOL CNG_CalcHash(const WCHAR *algorithm, const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **hash_value, DWORD *hash_len)
Definition: cert.c:2598
static BOOL compare_cert_by_name(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1479
BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
Definition: cert.c:2488
BOOL(* CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1434
static BOOL find_key_prov_info_in_provider(PCCERT_CONTEXT pCert, CRYPT_KEY_PROV_INFO *keyProvInfo)
Definition: cert.c:1100
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob, HCRYPTPROV hProv, DWORD dwKeySpec, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
Definition: cert.c:3585
PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext, DWORD *pdwFlags)
Definition: cert.c:1958
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:56
RPC_STATUS(RPC_ENTRY * RpcStringFreeFunc)(unsigned char **)
Definition: cert.c:3701
BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2287
BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, PCERT_PUBLIC_KEY_INFO pPublicKey)
Definition: cert.c:2551
static BOOL CRYPT_IsBitInFieldSet(const struct BitField *field, DWORD bit)
Definition: cert.c:3346
static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:514
BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:78
PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME pEndTime, PCERT_EXTENSIONS pExtensions)
Definition: cert.c:3749
BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned, DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
Definition: cert.c:2429
static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1748
PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, CERT_EXTENSION rgExtensions[])
Definition: cert.c:2099
RPC_STATUS(RPC_ENTRY * UuidToStringFunc)(UUID *, unsigned char **)
Definition: cert.c:3700
static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1593
BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject, PCCERT_CONTEXT pIssuer, DWORD *pdwFlags)
Definition: cert.c:1916
BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: cert.c:838
static void fix_KeyProvInfoProperty(CRYPT_KEY_PROV_INFO *info)
Definition: cert.c:440
BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2384
static void copy_KeyProvInfoProperty(const CRYPT_KEY_PROV_INFO *from, CRYPT_KEY_PROV_INFO *to)
Definition: cert.c:472
static BOOL find_matching_provider(PCCERT_CONTEXT pCert, DWORD dwFlags)
Definition: cert.c:1133
BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len, BYTE **sig_value, DWORD *sig_len)
Definition: cert.c:2822
static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1535
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:615
static void CRYPT_SetBitInField(struct BitField *field, DWORD bit)
Definition: cert.c:3325
static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1510
static context_t * Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link)
Definition: cert.c:126
BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2)
Definition: cert.c:1314
static BOOL CNG_PrepareCertSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **sig_value, DWORD *sig_len)
Definition: cert.c:2833
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:358
static BOOL compare_cert_by_public_key(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1499
static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, DWORD dwFlags, PCRYPT_KEY_PROV_INFO info, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec)
Definition: cert.c:868
void CRYPT_ConvertKeyContext(const struct store_CERT_KEY_CONTEXT *src, CERT_KEY_CONTEXT *dst)
Definition: cert.c:429
const void *WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCERT_CREATE_CONTEXT_PARA pCreatePara)
Definition: cert.c:3876
DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, DWORD dwPropId)
Definition: cert.c:378
struct _OLD_CERT_REVOCATION_STATUS OLD_CERT_REVOCATION_STATUS
BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2258
BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs)
Definition: cert.c:3356
static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: cert.c:707
LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, PCERT_INFO pCertInfo)
Definition: cert.c:2229
static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len)
Definition: cert.c:2783
static BOOL find_matching_rdn_attr(DWORD dwFlags, const CERT_NAME_INFO *name, const CERT_RDN_ATTR *attr)
Definition: cert.c:2143
static BOOL CertContext_SetKeyContextProperty(CONTEXT_PROPERTY_LIST *properties, const CERT_KEY_CONTEXT *keyContext)
Definition: cert.c:694
BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1, PCRYPT_INTEGER_BLOB pInt2)
Definition: cert.c:1291
BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage)
Definition: cert.c:3044
static BOOL key_prov_info_matches_cert(PCCERT_CONTEXT pCert, const CRYPT_KEY_PROV_INFO *keyProvInfo)
Definition: cert.c:1025
PCCERT_CONTEXT(* CertFindFunc)(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1637
PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName)
Definition: cert.c:2122
DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
Definition: chain.c:264
void Context_AddRef(context_t *context)
Definition: context.c:78
void Context_Release(context_t *context)
Definition: context.c:106
context_t * Context_CreateLinkContext(unsigned int contextSize, context_t *linked, WINECRYPT_CERTSTORE *store)
Definition: context.c:54
context_t * Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
Definition: context.c:28
void Context_CopyProperties(const void *to, const void *from)
Definition: context.c:123
PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags)
Definition: crl.c:431
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded)
Definition: crl.c:179
BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, PCERT_INFO pCertId, DWORD cCrlInfo, PCRL_INFO rgpCrlInfo[])
Definition: crl.c:856
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
Definition: ctl.c:363
BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
Definition: encode.c:4909
BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded)
Definition: encode.c:4950
BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey)
Definition: encode.c:5284
BOOL WINAPI CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey)
Definition: encode.c:5210
BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo)
Definition: encode.c:5015
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:136
LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize)
Definition: main.c:141
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:146
static struct list oidInfo
Definition: oid.c:1194
HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
Definition: oid.c:103
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
Definition: oid.c:499
PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, DWORD dwGroupId)
Definition: oid.c:1714
BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList)
Definition: oid.c:182
BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags)
Definition: oid.c:456
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara)
Definition: store.c:809
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:922
HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubSystemProtocol)
Definition: store.c:898
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1121
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: store.c:1166
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:910
DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz)
Definition: str.c:463
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define RtlUlongByteSwap(_x)
Definition: compat.h:815
#define wcsnicmp
Definition: compat.h:14
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define FreeLibrary(x)
Definition: compat.h:748
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define LoadLibraryW(x)
Definition: compat.h:747
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:183
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:153
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:523
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3335
static wchar_t * wcslwr(wchar_t *str)
Definition: string.h:96
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t serial
Definition: fsck.fat.h:29
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
Definition: msctf.idl:532
char hdr[14]
Definition: iptest.cpp:33
#define d
Definition: ke_i.h:81
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define matches(FN)
Definition: match.h:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static LPSTR pName
Definition: security.c:86
static const BYTE crl[]
Definition: message.c:817
static BYTE pubKey[]
Definition: msg.c:1147
static BYTE cert[]
Definition: msg.c:1374
static LPCWSTR LPVOID pvReserved
Definition: asmcache.c:749
static const char szContainer[]
Definition: rsaenh.c:35
static HCRYPTPROV hProv
Definition: rsaenh.c:32
static const char * szProvider
Definition: rsaenh.c:36
int k
Definition: mpi.c:3369
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define LPVOID
Definition: nt_native.h:45
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
_In_ _Out_writes_opt_ pcchValueName _Inout_opt_ LPDWORD _Out_opt_ _Out_writes_bytes_to_opt_ pcbData _Inout_opt_ LPDWORD pcbData
Definition: shlwapi.h:757
const WCHAR * str
#define RPC_S_OK
Definition: rpcnterr.h:22
#define RPC_ENTRY
Definition: rpc.h:63
long RPC_STATUS
Definition: rpc.h:48
#define ASN_SEQUENCE
Definition: snmp.h:110
wcscpy
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
DWORD cIndexes
Definition: cert.c:3319
DWORD * indexes
Definition: cert.c:3320
const store_vtbl_t * vtbl
Definition: wincrypt.h:341
CERT_NAME_BLOB DirectoryName
Definition: wincrypt.h:347
DWORD dwCertEncodingType
Definition: wincrypt.h:488
HCERTSTORE hCertStore
Definition: wincrypt.h:492
PCERT_INFO pCertInfo
Definition: wincrypt.h:491
BYTE * pbCertEncoded
Definition: wincrypt.h:489
DWORD cbCertEncoded
Definition: wincrypt.h:490
CRYPT_UINT_BLOB s
Definition: wincrypt.h:309
CRYPT_UINT_BLOB r
Definition: wincrypt.h:308
DWORD cExtension
Definition: wincrypt.h:245
PCERT_EXTENSION rgExtension
Definition: wincrypt.h:246
CRYPT_HASH_BLOB KeyId
Definition: wincrypt.h:3833
DWORD dwIdChoice
Definition: wincrypt.h:3830
PCERT_EXTENSION rgExtension
Definition: wincrypt.h:261
CERT_NAME_BLOB Subject
Definition: wincrypt.h:256
CERT_NAME_BLOB Issuer
Definition: wincrypt.h:253
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo
Definition: wincrypt.h:257
CRYPT_INTEGER_BLOB SerialNumber
Definition: wincrypt.h:251
FILETIME NotBefore
Definition: wincrypt.h:254
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm
Definition: wincrypt.h:252
DWORD cExtension
Definition: wincrypt.h:260
FILETIME NotAfter
Definition: wincrypt.h:255
HCRYPTPROV hCryptProv
Definition: wincrypt.h:229
CRYPT_BIT_BLOB PublicKey
Definition: wincrypt.h:235
CRYPT_ALGORITHM_IDENTIFIER Algorithm
Definition: wincrypt.h:234
DWORD cRDNAttr
Definition: wincrypt.h:271
PCERT_RDN_ATTR rgRDNAttr
Definition: wincrypt.h:272
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm
Definition: wincrypt.h:631
CRYPT_BIT_BLOB Signature
Definition: wincrypt.h:632
CRYPT_DER_BLOB ToBeSigned
Definition: wincrypt.h:630
BOOL(* addContext)(struct WINE_CRYPTCERTSTORE *, context_t *, context_t *, context_t **, BOOL)
BYTE * pbData
Definition: wincrypt.h:112
CRYPT_OBJID_BLOB Parameters
Definition: wincrypt.h:136
DWORD cUnusedBits
Definition: wincrypt.h:207
BYTE * pbData
Definition: wincrypt.h:206
LPWSTR pwszContainerName
Definition: wincrypt.h:218
PCRYPT_KEY_PROV_PARAM rgProvParam
Definition: wincrypt.h:223
DWORD cUsageIdentifier
Definition: wincrypt.h:831
LPSTR * rgpszUsageIdentifier
Definition: wincrypt.h:832
DWORD pubexp
Definition: wincrypt.h:154
DWORD bitlen
Definition: wincrypt.h:153
Definition: cookie.c:202
Definition: image.c:134
Definition: cache.c:49
CERT_CONTEXT ctx
Definition: bug.cpp:8
Definition: http.c:7252
Definition: parser.c:44
Definition: _hash_fun.h:40
Definition: copy.c:22
Definition: match.c:28
Definition: name.c:39
Definition: ps.c:97
CONTEXT_FUNCS certs
#define max(a, b)
Definition: svc.c:63
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CERT_SET_KEY_PROV_HANDLE_PROP_ID
Definition: wincrypt.h:3754
#define szOID_RSA_DH
Definition: wincrypt.h:3180
ULONG_PTR HCRYPTPROV_OR_NCRYPT_KEY_HANDLE
Definition: wincrypt.h:56
#define X509_OBJECT_IDENTIFIER
Definition: wincrypt.h:3593
#define CERT_PVK_FILE_PROP_ID
Definition: wincrypt.h:2845
#define MS_DEF_PROV_A
Definition: wincrypt.h:2115
#define CERT_CROSS_CERT_DIST_POINTS_PROP_ID
Definition: wincrypt.h:2856
#define CERT_ENROLLMENT_PROP_ID
Definition: wincrypt.h:2859
#define X509_AUTHORITY_KEY_ID2
Definition: wincrypt.h:3550
#define szOID_AUTHORITY_KEY_IDENTIFIER
Definition: wincrypt.h:3331
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL
Definition: wincrypt.h:3634
#define CERT_ID_ISSUER_SERIAL_NUMBER
Definition: wincrypt.h:3838
#define CERT_MD5_HASH_PROP_ID
Definition: wincrypt.h:2836
#define CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID
Definition: wincrypt.h:2857
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2274
#define CERT_COMPARE_MD5_HASH
Definition: wincrypt.h:2992
#define CERT_ENCODING_TYPE_MASK
Definition: wincrypt.h:2494
#define CERT_ENHKEY_USAGE_PROP_ID
Definition: wincrypt.h:2841
#define CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID
Definition: wincrypt.h:2858
#define CRYPT_DECODE_NOCOPY_FLAG
Definition: wincrypt.h:3608
#define PROV_RSA_FULL
Definition: wincrypt.h:2243
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2273
#define CALG_SHA1
Definition: wincrypt.h:2060
#define CERT_KEY_CONTEXT_PROP_ID
Definition: wincrypt.h:2837
#define CERT_KEY_IDENTIFIER_PROP_ID
Definition: wincrypt.h:2853
#define CERT_COMPARE_NAME_STR_W
Definition: wincrypt.h:2996
#define CERT_COMPARE_ISSUER_OF
Definition: wincrypt.h:3001
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL
Definition: wincrypt.h:3628
#define X509_NAME
Definition: wincrypt.h:3524
#define X509_CERT_TO_BE_SIGNED
Definition: wincrypt.h:3518
#define GET_CERT_ENCODING_TYPE(x)
Definition: wincrypt.h:2496
#define X509_UNICODE_NAME
Definition: wincrypt.h:3537
#define CERT_COMPARE_PUBLIC_KEY
Definition: wincrypt.h:2994
#define CERT_COMPARE_SUBJECT_CERT
Definition: wincrypt.h:3000
#define CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID
Definition: wincrypt.h:2861
#define CERT_V3
Definition: wincrypt.h:2805
ULONG_PTR HCRYPTPROV_LEGACY
Definition: wincrypt.h:57
#define CERT_STORE_REVOCATION_FLAG
Definition: wincrypt.h:3618
#define CERT_STORE_ADD_REPLACE_EXISTING
Definition: wincrypt.h:2653
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_CHAIN
Definition: wincrypt.h:3633
#define CALG_RSA_SIGN
Definition: wincrypt.h:2069
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:55
#define CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
Definition: wincrypt.h:2657
#define CRYPT_USER_KEYSET
Definition: wincrypt.h:4320
#define CERT_FIND_SUBJECT_CERT
Definition: wincrypt.h:3048
#define CERT_ALT_NAME_DIRECTORY_NAME
Definition: wincrypt.h:358
#define X509_CERT
Definition: wincrypt.h:3517
#define CERT_KEY_PROV_INFO_PROP_ID
Definition: wincrypt.h:2833
#define CALG_MD5
Definition: wincrypt.h:2058
#define CERT_STORE_ADD_NEWER
Definition: wincrypt.h:2656
#define CERT_ID_KEY_IDENTIFIER
Definition: wincrypt.h:3839
#define CERT_FIRST_USER_PROP_ID
Definition: wincrypt.h:2895
#define CERT_DESCRIPTION_PROP_ID
Definition: wincrypt.h:2846
struct _CERT_REVOCATION_PARA * PCERT_REVOCATION_PARA
#define CERT_SET_KEY_CONTEXT_PROP_ID
Definition: wincrypt.h:3755
#define CERT_OCSP_RESPONSE_PROP_ID
Definition: wincrypt.h:2877
unsigned int ALG_ID
Definition: wincrypt.h:54
#define CERT_COMPARE_CERT_ID
Definition: wincrypt.h:3005
#define CRYPT_OID_VERIFY_REVOCATION_FUNC
Definition: wincrypt.h:2666
#define CRYPT_HASH_ALG_OID_GROUP_ID
Definition: wincrypt.h:1937
#define CERT_INFO_ISSUER_FLAG
Definition: wincrypt.h:2809
#define CERT_EXTENDED_ERROR_INFO_PROP_ID
Definition: wincrypt.h:2863
#define CERT_COMPARE_MASK
Definition: wincrypt.h:2985
#define CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
Definition: wincrypt.h:3063
#define CERT_NEXT_UPDATE_LOCATION_PROP_ID
Definition: wincrypt.h:2843
#define CRYPT_FIND_MACHINE_KEYSET_FLAG
Definition: wincrypt.h:3768
#define CERT_COMPARE_ANY
Definition: wincrypt.h:2987
#define CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG
Definition: wincrypt.h:2954
struct _CTL_USAGE CERT_ENHKEY_USAGE
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY
Definition: wincrypt.h:3631
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT
Definition: wincrypt.h:3632
#define CERT_V1
Definition: wincrypt.h:2803
#define szOID_KEY_USAGE
Definition: wincrypt.h:3341
#define CALG_OID_INFO_CNG_ONLY
Definition: wincrypt.h:1595
#define PP_ENUMCONTAINERS
Definition: wincrypt.h:2287
#define szOID_ECC_CURVE_P256
Definition: wincrypt.h:3217
#define szOID_ECC_PUBLIC_KEY
Definition: wincrypt.h:3216
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT
Definition: wincrypt.h:3627
#define X509_ASN_ENCODING
Definition: wincrypt.h:2501
#define CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG
Definition: wincrypt.h:3065
#define X509_ECC_SIGNATURE
Definition: wincrypt.h:3569
#define CERT_COMPARE_NAME_STR_A
Definition: wincrypt.h:2995
#define CRYPT_DECODE_ALLOC_FLAG
Definition: wincrypt.h:3612
#define CERT_PUBKEY_ALG_PARA_PROP_ID
Definition: wincrypt.h:2855
#define szOID_SUBJECT_KEY_IDENTIFIER
Definition: wincrypt.h:3340
#define X509_AUTHORITY_KEY_ID
Definition: wincrypt.h:3526
#define CERT_SIMPLE_NAME_STR
Definition: wincrypt.h:3642
#define CRYPT_ACQUIRE_SILENT_FLAG
Definition: wincrypt.h:3764
#define CERT_INFO_SUBJECT_FLAG
Definition: wincrypt.h:2812
#define CERT_AUTO_ENROLL_PROP_ID
Definition: wincrypt.h:2854
#define CERT_CREATE_SELFSIGN_NO_KEY_INFO
Definition: wincrypt.h:3758
#define CRYPT_FIRST
Definition: wincrypt.h:2264
#define CERT_FRIENDLY_NAME_PROP_ID
Definition: wincrypt.h:2844
#define szOID_ECC_CURVE_P384
Definition: wincrypt.h:3263
#define CERT_CTL_USAGE_PROP_ID
Definition: wincrypt.h:2842
#define CALG_RSA_KEYX
Definition: wincrypt.h:2080
#define CERT_STORE_NO_CRL_FLAG
Definition: wincrypt.h:3619
#define CERT_STORE_CERTIFICATE_CONTEXT
Definition: wincrypt.h:3121
#define CRYPT_SILENT
Definition: wincrypt.h:2277
#define CERT_ACCESS_STATE_PROP_ID
Definition: wincrypt.h:2847
#define CERT_COMPARE_NAME
Definition: wincrypt.h:2990
#define RSA_CSP_PUBLICKEYBLOB
Definition: wincrypt.h:3536
#define PP_NAME
Definition: wincrypt.h:2289
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:58
#define CERT_COMPARE_SHIFT
Definition: wincrypt.h:2986
ULONG_PTR HCRYPTHASH
Definition: wincrypt.h:59
const CERT_CONTEXT * PCCERT_CONTEXT
Definition: wincrypt.h:494
#define CERT_STORE_SIGNATURE_FLAG
Definition: wincrypt.h:3616
#define CERT_STORE_ADD_USE_EXISTING
Definition: wincrypt.h:2652
#define CERT_STORE_CTL_CONTEXT
Definition: wincrypt.h:3123
#define X509_BITS
Definition: wincrypt.h:3544
#define szOID_ENHANCED_KEY_USAGE
Definition: wincrypt.h:3358
#define CERT_STORE_ADD_NEW
Definition: wincrypt.h:2651
#define CERT_COMPARE_SHA1_HASH
Definition: wincrypt.h:2988
#define CERT_HASH_PROP_ID
Definition: wincrypt.h:2835
#define CERT_CREATE_SELFSIGN_NO_SIGN
Definition: wincrypt.h:3757
#define CRYPT_FIND_SILENT_KEYSET_FLAG
Definition: wincrypt.h:3769
#define CERT_RENEWAL_PROP_ID
Definition: wincrypt.h:2871
#define CERT_STORE_ADD_ALWAYS
Definition: wincrypt.h:2654
#define CERT_STORE_PROV_SYSTEM_W
Definition: wincrypt.h:2463
#define CERT_FIND_SUBJECT_NAME
Definition: wincrypt.h:3025
#define CERT_SHA1_HASH_PROP_ID
Definition: wincrypt.h:2834
#define CERT_FIND_SHA1_HASH
Definition: wincrypt.h:3012
#define CRYPT_ENCODE_ALLOC_FLAG
Definition: wincrypt.h:3599
#define PP_CONTAINER
Definition: wincrypt.h:2291
#define szOID_RSA_SHA1RSA
Definition: wincrypt.h:3175
#define CRYPT_FIND_USER_KEYSET_FLAG
Definition: wincrypt.h:3767
#define X509_PUBLIC_KEY_INFO
Definition: wincrypt.h:3525
#define CERT_SIGNATURE_HASH_PROP_ID
Definition: wincrypt.h:2848
#define CRYPT_OID_INFO_OID_KEY
Definition: wincrypt.h:1955
#define CERT_COMPARE_SIGNATURE_HASH
Definition: wincrypt.h:3003
#define PP_PROVTYPE
Definition: wincrypt.h:2300
#define CERT_UNICODE_IS_RDN_ATTRS_FLAG
Definition: wincrypt.h:2953
#define CERT_STORE_NO_CRYPT_RELEASE_FLAG
Definition: wincrypt.h:2621
#define CERT_SYSTEM_STORE_CURRENT_USER
Definition: wincrypt.h:2528
#define szOID_AUTHORITY_KEY_IDENTIFIER2
Definition: wincrypt.h:3356
#define CERT_COMPARE_KEY_IDENTIFIER
Definition: wincrypt.h:3004
#define szOID_RSA_RSA
Definition: wincrypt.h:3168
#define CERT_FIND_EXISTING
Definition: wincrypt.h:3052
#define CERT_ID_SHA1_HASH
Definition: wincrypt.h:3840
#define KP_KEYLEN
Definition: wincrypt.h:2340
#define AT_SIGNATURE
Definition: wincrypt.h:2240
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB
Definition: wincrypt.h:3626
#define CERT_LAST_USER_PROP_ID
Definition: wincrypt.h:2896
struct _CRYPT_KEY_PROV_INFO CRYPT_KEY_PROV_INFO
#define CERT_KEY_PROV_HANDLE_PROP_ID
Definition: wincrypt.h:2832
#define CERT_STORE_CRL_CONTEXT
Definition: wincrypt.h:3122
struct _CERT_REVOCATION_STATUS * PCERT_REVOCATION_STATUS
#define CRYPT_ACQUIRE_USE_PROV_INFO_FLAG
Definition: wincrypt.h:3762
#define CERT_STORE_TIME_VALIDITY_FLAG
Definition: wincrypt.h:3617
#define X509_ENHANCED_KEY_USAGE
Definition: wincrypt.h:3555
#define HP_HASHVAL
Definition: wincrypt.h:2387
#define CERT_FIND_ISSUER_OF
Definition: wincrypt.h:3050
#define CRYPT_SIGN_ALG_OID_GROUP_ID
Definition: wincrypt.h:1940
#define CRYPT_ACQUIRE_CACHE_FLAG
Definition: wincrypt.h:3761
struct _CRYPT_KEY_PROV_PARAM CRYPT_KEY_PROV_PARAM
#define CERT_SUBJECT_NAME_MD5_HASH_PROP_ID
Definition: wincrypt.h:2862
#define CRYPT_MACHINE_KEYSET
Definition: wincrypt.h:2276
#define CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
Definition: wincrypt.h:2655
#define CERT_DATE_STAMP_PROP_ID
Definition: wincrypt.h:2860
#define CERT_COMPARE_EXISTING
Definition: wincrypt.h:3002
#define CRYPT_NEXT
Definition: wincrypt.h:2265
#define WINAPI
Definition: msvc.h:6
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define CRYPT_E_NO_MATCH
Definition: winerror.h:4426
#define CRYPT_E_NOT_FOUND
Definition: winerror.h:4421
#define NTE_BAD_ALGID
Definition: winerror.h:4255
#define CRYPT_E_NO_REVOCATION_DLL
Definition: winerror.h:4434
#define NTE_NO_KEY
Definition: winerror.h:4260
#define CRYPT_E_SELF_SIGNED
Definition: winerror.h:4424
#define CRYPT_E_NO_KEY_PROPERTY
Definition: winerror.h:4428
#define NTE_BAD_KEYSET
Definition: winerror.h:4269
#define RPC_S_UUID_LOCAL_ONLY
Definition: winerror.h:1488
#define CRYPT_E_EXISTS
Definition: winerror.h:4422
#define NTE_BAD_FLAGS
Definition: winerror.h:4256
#define CRYPT_E_ASN1_BADTAG
Definition: winerror.h:4510
#define ERROR_INVALID_DATA
Definition: winerror.h:238
unsigned char BYTE
Definition: xxhash.c:193