ReactOS  0.4.13-dev-544-gede3fdd
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 #define NONAMELESSUNION
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wine/winternl.h"
29 #define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
30 #include "wincrypt.h"
31 #include "snmp.h"
32 #include "bcrypt.h"
33 #include "winnls.h"
34 #include "rpc.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
37 #include "crypt32_private.h"
38 
40 
41 /* Internal version of CertGetCertificateContextProperty that gets properties
42  * directly from the context (or the context it's linked to, depending on its
43  * type.) Doesn't handle special-case properties, since they are handled by
44  * CertGetCertificateContextProperty, and are particular to the store in which
45  * the property exists (which is separate from the context.)
46  */
48  void *pvData, DWORD *pcbData);
49 
50 /* Internal version of CertSetCertificateContextProperty that sets properties
51  * directly on the context (or the context it's linked to, depending on its
52  * type.) Doesn't handle special cases, since they're handled by
53  * CertSetCertificateContextProperty anyway.
54  */
56  DWORD dwFlags, const void *pvData);
57 
59  DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded,
61 {
63  pbCertEncoded, cbCertEncoded);
64  BOOL ret;
65 
66  TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType,
68 
69  if (cert)
70  {
74  }
75  else
76  ret = FALSE;
77  return ret;
78 }
79 
81  const BYTE *pbCertEncoded, DWORD cbCertEncoded)
82 {
83  HCERTSTORE store;
84  BOOL ret = FALSE;
85 
86  TRACE("(%s, %p, %d)\n", debugstr_a(pszCertStoreName), pbCertEncoded,
88 
89  store = CertOpenSystemStoreA(0, pszCertStoreName);
90  if (store)
91  {
94  CertCloseStore(store, 0);
95  }
96  return ret;
97 }
98 
100  const BYTE *pbCertEncoded, DWORD cbCertEncoded)
101 {
102  HCERTSTORE store;
103  BOOL ret = FALSE;
104 
105  TRACE("(%s, %p, %d)\n", debugstr_w(pszCertStoreName), pbCertEncoded,
106  cbCertEncoded);
107 
108  store = CertOpenSystemStoreW(0, pszCertStoreName);
109  if (store)
110  {
113  CertCloseStore(store, 0);
114  }
115  return ret;
116 }
117 
119 
121 {
122  cert_t *cert = (cert_t*)context;
123 
124  CryptMemFree(cert->ctx.pbCertEncoded);
125  LocalFree(cert->ctx.pCertInfo);
126 }
127 
129 {
130  cert_t *cert;
131 
132  if(use_link) {
134  if(!cert)
135  return NULL;
136  }else {
137  const cert_t *cloned = (const cert_t*)context;
138  DWORD size = 0;
139  BOOL res;
140 
142  if(!cert)
143  return NULL;
144 
145  Context_CopyProperties(&cert->ctx, &cloned->ctx);
146 
147  cert->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType;
148  cert->ctx.pbCertEncoded = CryptMemAlloc(cloned->ctx.cbCertEncoded);
149  memcpy(cert->ctx.pbCertEncoded, cloned->ctx.pbCertEncoded, cloned->ctx.cbCertEncoded);
150  cert->ctx.cbCertEncoded = cloned->ctx.cbCertEncoded;
151 
152  /* FIXME: We don't need to decode the object here, we could just clone cert info. */
153  res = CryptDecodeObjectEx(cert->ctx.dwCertEncodingType, X509_CERT_TO_BE_SIGNED,
154  cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
155  &cert->ctx.pCertInfo, &size);
156  if(!res) {
158  return NULL;
159  }
160  }
161 
162  cert->ctx.hCertStore = store;
163  return &cert->base;
164 }
165 
166 static const context_vtbl_t cert_vtbl = {
167  Cert_free,
168  Cert_clone
169 };
170 
172  DWORD add_disposition, BOOL use_link, PCCERT_CONTEXT *ret_context)
173 {
174  const CERT_CONTEXT *existing = NULL;
175  BOOL ret = TRUE, inherit_props = FALSE;
176  context_t *new_context = NULL;
177 
178  switch (add_disposition)
179  {
181  break;
182  case CERT_STORE_ADD_NEW:
188  {
189  BYTE hashToAdd[20];
190  DWORD size = sizeof(hashToAdd);
191 
193  hashToAdd, &size);
194  if (ret)
195  {
196  CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
197 
198  existing = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0,
200  }
201  break;
202  }
203  default:
204  FIXME("Unimplemented add disposition %d\n", add_disposition);
206  return FALSE;
207  }
208 
209  switch (add_disposition)
210  {
212  break;
213  case CERT_STORE_ADD_NEW:
214  if (existing)
215  {
216  TRACE("found matching certificate, not adding\n");
218  return FALSE;
219  }
220  break;
222  break;
224  if (use_link)
225  FIXME("CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: semi-stub for links\n");
226  if (existing)
227  inherit_props = TRUE;
228  break;
230  if(use_link)
231  FIXME("CERT_STORE_ADD_USE_EXISTING: semi-stub for links\n");
232  if (existing)
233  {
234  Context_CopyProperties(existing, cert);
235  if (ret_context)
236  *ret_context = CertDuplicateCertificateContext(existing);
237  return TRUE;
238  }
239  break;
241  if (existing && CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
242  {
243  TRACE("existing certificate is newer, not adding\n");
245  return FALSE;
246  }
247  break;
249  if (existing)
250  {
251  if (CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
252  {
253  TRACE("existing certificate is newer, not adding\n");
255  return FALSE;
256  }
257  inherit_props = TRUE;
258  }
259  break;
260  }
261 
262  /* FIXME: We have tests that this works, but what should we really do in this case? */
263  if(!store) {
264  if(ret_context)
265  *ret_context = CertDuplicateCertificateContext(cert);
266  return TRUE;
267  }
268 
269  ret = store->vtbl->certs.addContext(store, context_from_ptr(cert), existing ? context_from_ptr(existing) : NULL,
270  (ret_context || inherit_props) ? &new_context : NULL, use_link);
271  if(!ret)
272  return FALSE;
273 
274  if(inherit_props)
275  Context_CopyProperties(context_ptr(new_context), existing);
276 
277  if(ret_context)
278  *ret_context = context_ptr(new_context);
279  else if(new_context)
280  Context_Release(new_context);
281 
282  TRACE("returning %d\n", ret);
283  return ret;
284 }
285 
288 {
289  WINECRYPT_CERTSTORE *store = hCertStore;
290 
291  TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext);
292 
294 }
295 
299 {
300  static int calls;
301  WINECRYPT_CERTSTORE *store = (WINECRYPT_CERTSTORE*)hCertStore;
302 
303  if (!(calls++))
304  FIXME("(%p, %p, %08x, %p): semi-stub\n", hCertStore, pCertContext,
306  if (store->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
307  return FALSE;
308  if (store->type == StoreTypeCollection)
309  {
311  return FALSE;
312  }
314 }
315 
317  const BYTE *pbCertEncoded, DWORD cbCertEncoded)
318 {
319  cert_t *cert = NULL;
320  BYTE *data = NULL;
321  BOOL ret;
322  PCERT_INFO certInfo = NULL;
323  DWORD size = 0;
324 
325  TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCertEncoded,
326  cbCertEncoded);
327 
329  {
331  return NULL;
332  }
333 
335  pbCertEncoded, cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
336  &certInfo, &size);
337  if (!ret)
338  return NULL;
339 
341  if (!cert)
342  return NULL;
344  if (!data)
345  {
346  Context_Release(&cert->base);
347  return NULL;
348  }
349 
350  memcpy(data, pbCertEncoded, cbCertEncoded);
351  cert->ctx.dwCertEncodingType = dwCertEncodingType;
352  cert->ctx.pbCertEncoded = data;
353  cert->ctx.cbCertEncoded = cbCertEncoded;
354  cert->ctx.pCertInfo = certInfo;
355  cert->ctx.hCertStore = &empty_store;
356 
357  return &cert->ctx;
358 }
359 
361 {
362  TRACE("(%p)\n", pCertContext);
363 
364  if (!pCertContext)
365  return NULL;
366 
368  return pCertContext;
369 }
370 
372 {
373  TRACE("(%p)\n", pCertContext);
374 
375  if (pCertContext)
377  return TRUE;
378 }
379 
381  DWORD dwPropId)
382 {
384  DWORD ret;
385 
386  TRACE("(%p, %d)\n", pCertContext, dwPropId);
387 
388  if (cert->base.properties)
389  ret = ContextPropertyList_EnumPropIDs(cert->base.properties, dwPropId);
390  else
391  ret = 0;
392  return ret;
393 }
394 
396  ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
397  DWORD *pcbData)
398 {
399  BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
400  pcbData);
401  if (ret && pvData)
402  {
404 
406  }
407  return ret;
408 }
409 
410 static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb,
411  DWORD cb)
412 {
413  BOOL ret = TRUE;
414 
415  if (!pvData)
416  *pcbData = cb;
417  else if (*pcbData < cb)
418  {
420  *pcbData = cb;
421  ret = FALSE;
422  }
423  else
424  {
425  memcpy(pvData, pb, cb);
426  *pcbData = cb;
427  }
428  return ret;
429 }
430 
432  void *pvData, DWORD *pcbData)
433 {
434  BOOL ret;
436 
437  TRACE("(%p, %d, %p, %p)\n", cert, dwPropId, pvData, pcbData);
438 
439  if (cert->base.properties)
440  ret = ContextPropertyList_FindProperty(cert->base.properties, dwPropId, &blob);
441  else
442  ret = FALSE;
443  if (ret)
444  ret = CertContext_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
445  else
446  {
447  /* Implicit properties */
448  switch (dwPropId)
449  {
452  cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
453  pcbData);
454  break;
457  cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
458  pcbData);
459  break;
462  cert->ctx.pCertInfo->Subject.pbData,
463  cert->ctx.pCertInfo->Subject.cbData,
464  pvData, pcbData);
465  break;
468  cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
469  cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
470  pvData, pcbData);
471  break;
474  cert->ctx.pCertInfo->SerialNumber.pbData,
475  cert->ctx.pCertInfo->SerialNumber.cbData,
476  pvData, pcbData);
477  break;
479  ret = CryptHashToBeSigned(0, cert->ctx.dwCertEncodingType,
480  cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
481  pcbData);
482  if (ret && pvData)
483  {
485 
487  }
488  break;
490  {
492  szOID_SUBJECT_KEY_IDENTIFIER, cert->ctx.pCertInfo->cExtension,
493  cert->ctx.pCertInfo->rgExtension);
494 
495  if (ext)
496  {
498  DWORD size = sizeof(value);
499 
501  szOID_SUBJECT_KEY_IDENTIFIER, ext->Value.pbData,
502  ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &value,
503  &size);
504  if (ret)
505  {
507  value.cbData);
509  }
510  }
511  else
513  break;
514  }
515  default:
517  }
518  }
519  TRACE("returning %d\n", ret);
520  return ret;
521 }
522 
524 {
525  DWORD i, containerLen, provNameLen;
527 
528  info->pwszContainerName = (LPWSTR)data;
529  containerLen = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
530  data += containerLen;
531 
532  info->pwszProvName = (LPWSTR)data;
533  provNameLen = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
534  data += provNameLen;
535 
536  if (info->cProvParam)
537  {
538  info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data;
539  data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
540 
541  for (i = 0; i < info->cProvParam; i++)
542  {
543  info->rgProvParam[i].pbData = data;
544  data += info->rgProvParam[i].cbData;
545  }
546  }
547  else
548  info->rgProvParam = NULL;
549 }
550 
552  DWORD dwPropId, void *pvData, DWORD *pcbData)
553 {
555  BOOL ret;
556 
557  TRACE("(%p, %d, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData);
558 
559  switch (dwPropId)
560  {
561  case 0:
562  case CERT_CERT_PROP_ID:
563  case CERT_CRL_PROP_ID:
564  case CERT_CTL_PROP_ID:
566  ret = FALSE;
567  break;
569  ret = CertGetStoreProperty(cert->ctx.hCertStore, dwPropId, pvData, pcbData);
570  break;
572  {
573  CERT_KEY_CONTEXT keyContext;
574  DWORD size = sizeof(keyContext);
575 
577  CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
578  if (ret)
580  sizeof(keyContext.hCryptProv));
581  break;
582  }
585  pcbData);
586  if (ret && pvData)
588  break;
589  default:
591  pcbData);
592  }
593 
594  TRACE("returning %d\n", ret);
595  return ret;
596 }
597 
598 /* Copies key provider info from from into to, where to is assumed to be a
599  * contiguous buffer of memory large enough for from and all its associated
600  * data, but whose pointers are uninitialized.
601  * Upon return, to contains a contiguous copy of from, packed in the following
602  * order:
603  * - CRYPT_KEY_PROV_INFO
604  * - pwszContainerName
605  * - pwszProvName
606  * - rgProvParam[0]...
607  */
609  const CRYPT_KEY_PROV_INFO *from)
610 {
611  DWORD i;
612  LPBYTE nextData = (LPBYTE)to + sizeof(CRYPT_KEY_PROV_INFO);
613 
614  if (from->pwszContainerName)
615  {
616  to->pwszContainerName = (LPWSTR)nextData;
617  lstrcpyW(to->pwszContainerName, from->pwszContainerName);
618  nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
619  }
620  else
621  to->pwszContainerName = NULL;
622  if (from->pwszProvName)
623  {
624  to->pwszProvName = (LPWSTR)nextData;
625  lstrcpyW(to->pwszProvName, from->pwszProvName);
626  nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
627  }
628  else
629  to->pwszProvName = NULL;
630  to->dwProvType = from->dwProvType;
631  to->dwFlags = from->dwFlags;
632  to->cProvParam = from->cProvParam;
633  to->rgProvParam = (PCRYPT_KEY_PROV_PARAM)nextData;
634  nextData += to->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
635  to->dwKeySpec = from->dwKeySpec;
636  for (i = 0; i < to->cProvParam; i++)
637  {
638  memcpy(&to->rgProvParam[i], &from->rgProvParam[i],
639  sizeof(CRYPT_KEY_PROV_PARAM));
640  to->rgProvParam[i].pbData = nextData;
641  memcpy(to->rgProvParam[i].pbData, from->rgProvParam[i].pbData,
642  from->rgProvParam[i].cbData);
643  nextData += from->rgProvParam[i].cbData;
644  }
645 }
646 
648  const CRYPT_KEY_PROV_INFO *info)
649 {
650  BOOL ret;
651  LPBYTE buf = NULL;
652  DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i, containerSize, provNameSize;
653 
654  if (info->pwszContainerName)
655  containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
656  else
657  containerSize = 0;
658  if (info->pwszProvName)
659  provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
660  else
661  provNameSize = 0;
662  size += containerSize + provNameSize;
663  for (i = 0; i < info->cProvParam; i++)
664  size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
666  if (buf)
667  {
671  CryptMemFree(buf);
672  }
673  else
674  ret = FALSE;
675  return ret;
676 }
677 
679  DWORD dwFlags, const void *pvData)
680 {
681  BOOL ret;
682 
683  TRACE("(%p, %d, %08x, %p)\n", cert, dwPropId, dwFlags, pvData);
684 
685  if (!cert->base.properties)
686  ret = FALSE;
687  else
688  {
689  switch (dwPropId)
690  {
692  case CERT_CTL_USAGE_PROP_ID: /* same as CERT_ENHKEY_USAGE_PROP_ID */
695  case CERT_HASH_PROP_ID:
710  {
711  if (pvData)
712  {
713  const CRYPT_DATA_BLOB *blob = pvData;
714 
715  ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
716  blob->pbData, blob->cbData);
717  }
718  else
719  {
721  ret = TRUE;
722  }
723  break;
724  }
726  if (pvData)
727  ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
728  pvData, sizeof(FILETIME));
729  else
730  {
732  ret = TRUE;
733  }
734  break;
736  {
737  if (pvData)
738  {
739  const CERT_KEY_CONTEXT *keyContext = pvData;
740 
741  if (keyContext->cbSize != sizeof(CERT_KEY_CONTEXT))
742  {
744  ret = FALSE;
745  }
746  else
747  ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
748  (const BYTE *)keyContext, keyContext->cbSize);
749  }
750  else
751  {
753  ret = TRUE;
754  }
755  break;
756  }
758  if (pvData)
759  ret = CertContext_SetKeyProvInfoProperty(cert->base.properties, pvData);
760  else
761  {
763  ret = TRUE;
764  }
765  break;
767  {
768  CERT_KEY_CONTEXT keyContext;
769  DWORD size = sizeof(keyContext);
770 
772  &keyContext, &size);
773  if (ret)
774  {
776  CryptReleaseContext(keyContext.hCryptProv, 0);
777  }
778  keyContext.cbSize = sizeof(keyContext);
779  if (pvData)
780  keyContext.hCryptProv = *(const HCRYPTPROV *)pvData;
781  else
782  {
783  keyContext.hCryptProv = 0;
784  keyContext.dwKeySpec = AT_SIGNATURE;
785  }
787  0, &keyContext);
788  break;
789  }
790  default:
791  FIXME("%d: stub\n", dwPropId);
792  ret = FALSE;
793  }
794  }
795  TRACE("returning %d\n", ret);
796  return ret;
797 }
798 
800  DWORD dwPropId, DWORD dwFlags, const void *pvData)
801 {
802  BOOL ret;
803 
804  TRACE("(%p, %d, %08x, %p)\n", pCertContext, dwPropId, dwFlags, pvData);
805 
806  /* Handle special cases for "read-only"/invalid prop IDs. Windows just
807  * crashes on most of these, I'll be safer.
808  */
809  switch (dwPropId)
810  {
811  case 0:
813  case CERT_CERT_PROP_ID:
814  case CERT_CRL_PROP_ID:
815  case CERT_CTL_PROP_ID:
817  return FALSE;
818  }
820  pvData);
821  TRACE("returning %d\n", ret);
822  return ret;
823 }
824 
825 /* Acquires the private key using the key provider info, retrieving info from
826  * the certificate if info is NULL. The acquired provider is returned in
827  * *phCryptProv, and the key spec for the provider is returned in *pdwKeySpec.
828  */
830  PCRYPT_KEY_PROV_INFO info, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec)
831 {
832  DWORD size = 0;
833  BOOL allocated = FALSE, ret = TRUE;
834 
835  if (!info)
836  {
839  if (ret)
840  {
842  if (info)
843  {
846  allocated = TRUE;
847  }
848  else
849  {
851  ret = FALSE;
852  }
853  }
854  else
856  }
857  if (ret)
858  {
859  ret = CryptAcquireContextW(phCryptProv, info->pwszContainerName,
860  info->pwszProvName, info->dwProvType, 0);
861  if (ret)
862  {
863  DWORD i;
864 
865  for (i = 0; i < info->cProvParam; i++)
866  {
867  CryptSetProvParam(*phCryptProv,
868  info->rgProvParam[i].dwParam, info->rgProvParam[i].pbData,
869  info->rgProvParam[i].dwFlags);
870  }
871  *pdwKeySpec = info->dwKeySpec;
872  }
873  else
875  }
876  if (allocated)
878  return ret;
879 }
880 
883  DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
884 {
885  BOOL ret = FALSE, cache = FALSE;
887  CERT_KEY_CONTEXT keyContext;
888  DWORD size;
889 
890  TRACE("(%p, %08x, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved,
891  phCryptProv, pdwKeySpec, pfCallerFreeProv);
892 
894  {
895  DWORD size = 0;
896 
899  if (ret)
900  {
904  if (ret)
906  }
907  }
909  cache = TRUE;
910  *phCryptProv = 0;
911  if (cache)
912  {
913  size = sizeof(keyContext);
915  &keyContext, &size);
916  if (ret)
917  {
918  *phCryptProv = keyContext.hCryptProv;
919  if (pdwKeySpec)
920  *pdwKeySpec = keyContext.dwKeySpec;
921  if (pfCallerFreeProv)
922  *pfCallerFreeProv = !cache;
923  }
924  }
925  if (!*phCryptProv)
926  {
928  &keyContext.hCryptProv, &keyContext.dwKeySpec);
929  if (ret)
930  {
931  *phCryptProv = keyContext.hCryptProv;
932  if (pdwKeySpec)
933  *pdwKeySpec = keyContext.dwKeySpec;
934  if (cache)
935  {
936  keyContext.cbSize = sizeof(keyContext);
938  CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext))
939  {
940  if (pfCallerFreeProv)
941  *pfCallerFreeProv = FALSE;
942  }
943  }
944  else
945  {
946  if (pfCallerFreeProv)
947  *pfCallerFreeProv = TRUE;
948  }
949  }
950  }
952  return ret;
953 }
954 
956  const CRYPT_KEY_PROV_INFO *keyProvInfo)
957 {
958  HCRYPTPROV csp;
959  BOOL matches = FALSE;
960 
961  if (CryptAcquireContextW(&csp, keyProvInfo->pwszContainerName,
962  keyProvInfo->pwszProvName, keyProvInfo->dwProvType, keyProvInfo->dwFlags))
963  {
964  DWORD size;
965 
966  /* Need to sign something to verify the sig. What to sign? Why not
967  * the certificate itself?
968  */
971  &pCert->pCertInfo->SignatureAlgorithm, NULL, NULL, &size))
972  {
973  BYTE *certEncoded = CryptMemAlloc(size);
974 
975  if (certEncoded)
976  {
979  pCert->pCertInfo, &pCert->pCertInfo->SignatureAlgorithm,
980  NULL, certEncoded, &size))
981  {
982  if (size == pCert->cbCertEncoded &&
983  !memcmp(certEncoded, pCert->pbCertEncoded, size))
984  matches = TRUE;
985  }
986  CryptMemFree(certEncoded);
987  }
988  }
989  CryptReleaseContext(csp, 0);
990  }
991  return matches;
992 }
993 
995  CRYPT_KEY_PROV_INFO *keyProvInfo)
996 {
998  WCHAR containerW[MAX_PATH];
999  BOOL matches;
1000 
1001  MultiByteToWideChar(CP_ACP, 0, container, -1, containerW, ARRAY_SIZE(containerW));
1002  /* We make a copy of the CRYPT_KEY_PROV_INFO because the caller expects
1003  * keyProvInfo->pwszContainerName to be NULL or a heap-allocated container
1004  * name.
1005  */
1006  copy = *keyProvInfo;
1007  copy.pwszContainerName = containerW;
1009  if (matches)
1010  {
1011  keyProvInfo->pwszContainerName =
1012  CryptMemAlloc((strlenW(containerW) + 1) * sizeof(WCHAR));
1013  if (keyProvInfo->pwszContainerName)
1014  {
1015  strcpyW(keyProvInfo->pwszContainerName, containerW);
1016  keyProvInfo->dwKeySpec = AT_SIGNATURE;
1017  }
1018  else
1019  matches = FALSE;
1020  }
1021  return matches;
1022 }
1023 
1024 /* Searches the provider named keyProvInfo.pwszProvName for a container whose
1025  * private key matches pCert's public key. Upon success, updates keyProvInfo
1026  * with the matching container's info (free keyProvInfo.pwszContainerName upon
1027  * success.)
1028  * Returns TRUE if found, FALSE if not.
1029  */
1031  CRYPT_KEY_PROV_INFO *keyProvInfo)
1032 {
1033  HCRYPTPROV defProvider;
1034  BOOL ret, found = FALSE;
1035  char containerA[MAX_PATH];
1036 
1037  assert(keyProvInfo->pwszContainerName == NULL);
1038  if ((ret = CryptAcquireContextW(&defProvider, NULL,
1039  keyProvInfo->pwszProvName, keyProvInfo->dwProvType,
1040  keyProvInfo->dwFlags | CRYPT_VERIFYCONTEXT)))
1041  {
1042  DWORD enumFlags = keyProvInfo->dwFlags | CRYPT_FIRST;
1043 
1044  while (ret && !found)
1045  {
1046  DWORD size = sizeof(containerA);
1047 
1048  ret = CryptGetProvParam(defProvider, PP_ENUMCONTAINERS,
1049  (BYTE *)containerA, &size, enumFlags);
1050  if (ret)
1051  found = container_matches_cert(pCert, containerA, keyProvInfo);
1052  if (enumFlags & CRYPT_FIRST)
1053  {
1054  enumFlags &= ~CRYPT_FIRST;
1055  enumFlags |= CRYPT_NEXT;
1056  }
1057  }
1058  CryptReleaseContext(defProvider, 0);
1059  }
1060  return found;
1061 }
1062 
1064 {
1065  BOOL found = FALSE, ret = TRUE;
1066  DWORD index = 0, cbProvName = 0;
1067  CRYPT_KEY_PROV_INFO keyProvInfo;
1068 
1069  TRACE("(%p, %08x)\n", pCert, dwFlags);
1070 
1071  memset(&keyProvInfo, 0, sizeof(keyProvInfo));
1072  while (ret && !found)
1073  {
1074  DWORD size = 0;
1075 
1076  ret = CryptEnumProvidersW(index, NULL, 0, &keyProvInfo.dwProvType,
1077  NULL, &size);
1078  if (ret)
1079  {
1080  if (size <= cbProvName)
1082  &keyProvInfo.dwProvType, keyProvInfo.pwszProvName, &size);
1083  else
1084  {
1085  CryptMemFree(keyProvInfo.pwszProvName);
1086  keyProvInfo.pwszProvName = CryptMemAlloc(size);
1087  if (keyProvInfo.pwszProvName)
1088  {
1089  cbProvName = size;
1091  &keyProvInfo.dwProvType, keyProvInfo.pwszProvName, &size);
1092  if (ret)
1093  {
1095  keyProvInfo.dwFlags |= CRYPT_SILENT;
1099  {
1100  keyProvInfo.dwFlags |= CRYPT_USER_KEYSET;
1101  found = find_key_prov_info_in_provider(pCert,
1102  &keyProvInfo);
1103  }
1104  if (!found)
1105  {
1109  {
1110  keyProvInfo.dwFlags &= ~CRYPT_USER_KEYSET;
1111  keyProvInfo.dwFlags |= CRYPT_MACHINE_KEYSET;
1112  found = find_key_prov_info_in_provider(pCert,
1113  &keyProvInfo);
1114  }
1115  }
1116  }
1117  }
1118  else
1119  ret = FALSE;
1120  }
1121  index++;
1122  }
1123  }
1124  if (found)
1126  0, &keyProvInfo);
1127  CryptMemFree(keyProvInfo.pwszProvName);
1128  CryptMemFree(keyProvInfo.pwszContainerName);
1129  return found;
1130 }
1131 
1133 {
1134  BOOL matches = FALSE;
1135  DWORD size;
1136 
1138  NULL, &size))
1139  {
1140  CRYPT_KEY_PROV_INFO *keyProvInfo = CryptMemAlloc(size);
1141 
1142  if (keyProvInfo)
1143  {
1145  CERT_KEY_PROV_INFO_PROP_ID, keyProvInfo, &size))
1146  matches = key_prov_info_matches_cert(pCert, keyProvInfo);
1147  CryptMemFree(keyProvInfo);
1148  }
1149  }
1150  return matches;
1151 }
1152 
1154  DWORD dwFlags, void *pvReserved)
1155 {
1156  BOOL matches;
1157 
1158  TRACE("(%p, %08x, %p)\n", pCert, dwFlags, pvReserved);
1159 
1161  if (!matches)
1163  return matches;
1164 }
1165 
1167  PCERT_INFO pCertId1, PCERT_INFO pCertId2)
1168 {
1169  BOOL ret;
1170 
1171  TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2);
1172 
1174  &pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber,
1175  &pCertId2->SerialNumber);
1176  TRACE("returning %d\n", ret);
1177  return ret;
1178 }
1179 
1181  PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
1182 {
1183  BOOL ret;
1184 
1185  TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2);
1186 
1187  if (pCertName1->cbData == pCertName2->cbData)
1188  {
1189  if (pCertName1->cbData)
1190  ret = !memcmp(pCertName1->pbData, pCertName2->pbData,
1191  pCertName1->cbData);
1192  else
1193  ret = TRUE;
1194  }
1195  else
1196  ret = FALSE;
1197  TRACE("returning %d\n", ret);
1198  return ret;
1199 }
1200 
1201 /* Returns the number of significant bytes in pInt, where a byte is
1202  * insignificant if it's a leading 0 for positive numbers or a leading 0xff
1203  * for negative numbers. pInt is assumed to be little-endian.
1204  */
1206 {
1207  DWORD ret = pInt->cbData;
1208 
1209  while (ret > 1)
1210  {
1211  if (pInt->pbData[ret - 2] <= 0x7f && pInt->pbData[ret - 1] == 0)
1212  ret--;
1213  else if (pInt->pbData[ret - 2] >= 0x80 && pInt->pbData[ret - 1] == 0xff)
1214  ret--;
1215  else
1216  break;
1217  }
1218  return ret;
1219 }
1220 
1222  PCRYPT_INTEGER_BLOB pInt2)
1223 {
1224  BOOL ret;
1225  DWORD cb1, cb2;
1226 
1227  TRACE("(%p, %p)\n", pInt1, pInt2);
1228 
1229  cb1 = CRYPT_significantBytes(pInt1);
1230  cb2 = CRYPT_significantBytes(pInt2);
1231  if (cb1 == cb2)
1232  {
1233  if (cb1)
1234  ret = !memcmp(pInt1->pbData, pInt2->pbData, cb1);
1235  else
1236  ret = TRUE;
1237  }
1238  else
1239  ret = FALSE;
1240  TRACE("returning %d\n", ret);
1241  return ret;
1242 }
1243 
1245  PCERT_PUBLIC_KEY_INFO pPublicKey1, PCERT_PUBLIC_KEY_INFO pPublicKey2)
1246 {
1247  BOOL ret;
1248 
1249  TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
1250 
1251  /* RSA public key data should start with ASN_SEQUENCE,
1252  * otherwise it's not a RSA_CSP_PUBLICKEYBLOB.
1253  */
1254  if (!pPublicKey1->PublicKey.cbData || pPublicKey1->PublicKey.pbData[0] != ASN_SEQUENCE)
1255  dwCertEncodingType = 0;
1256 
1258  {
1259  case 0: /* Seems to mean "raw binary bits" */
1260  if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
1261  pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
1262  {
1263  if (pPublicKey2->PublicKey.cbData)
1264  ret = !memcmp(pPublicKey1->PublicKey.pbData,
1265  pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
1266  else
1267  ret = TRUE;
1268  }
1269  else
1270  ret = FALSE;
1271  break;
1272  default:
1273  WARN("Unknown encoding type %08x\n", dwCertEncodingType);
1274  /* FALLTHROUGH */
1275  case X509_ASN_ENCODING:
1276  {
1277  BLOBHEADER *pblob1, *pblob2;
1278  DWORD length;
1279  ret = FALSE;
1281  pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
1282  CRYPT_DECODE_ALLOC_FLAG, &pblob1, &length))
1283  {
1285  pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
1286  CRYPT_DECODE_ALLOC_FLAG, &pblob2, &length))
1287  {
1288  /* The RSAPUBKEY structure directly follows the BLOBHEADER */
1289  RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
1290  *pk2 = (LPVOID)(pblob2 + 1);
1291  ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
1292  && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
1293 
1294  LocalFree(pblob2);
1295  }
1296  LocalFree(pblob1);
1297  }
1298 
1299  break;
1300  }
1301  }
1302  return ret;
1303 }
1304 
1306  PCERT_PUBLIC_KEY_INFO pPublicKey)
1307 {
1308  DWORD len = 0;
1309 
1310  TRACE("(%08x, %p)\n", dwCertEncodingType, pPublicKey);
1311 
1313  {
1315  return 0;
1316  }
1317  if (pPublicKey->Algorithm.pszObjId &&
1318  !strcmp(pPublicKey->Algorithm.pszObjId, szOID_RSA_DH))
1319  {
1320  FIXME("unimplemented for DH public keys\n");
1322  }
1323  else
1324  {
1326  DWORD size;
1327  PBYTE buf;
1328  BOOL ret;
1329 
1331  if (info)
1332  {
1333  HCRYPTKEY key;
1334 
1335  TRACE("public key algid %#x (%s)\n", info->u.Algid, debugstr_a(pPublicKey->Algorithm.pszObjId));
1336 
1338  if (ret)
1339  {
1340  size = sizeof(len);
1341  ret = CryptGetKeyParam(key, KP_KEYLEN, (BYTE *)&len, &size, 0);
1343  return len;
1344  }
1345  /* fallback to RSA */
1346  }
1347 
1349  RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
1351  &size);
1352 
1353  if (ret)
1354  {
1355  RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
1356 
1357  len = rsaPubKey->bitlen;
1358  LocalFree(buf);
1359  }
1360  }
1361  return len;
1362 }
1363 
1365  DWORD dwFlags, const void *pvPara);
1366 
1368  DWORD dwFlags, const void *pvPara)
1369 {
1370  BOOL ret;
1371  BYTE hash[16];
1372  DWORD size = sizeof(hash);
1373 
1376  if (ret)
1377  {
1378  const CRYPT_HASH_BLOB *pHash = pvPara;
1379 
1380  if (size == pHash->cbData)
1381  ret = !memcmp(pHash->pbData, hash, size);
1382  else
1383  ret = FALSE;
1384  }
1385  return ret;
1386 }
1387 
1389  DWORD dwFlags, const void *pvPara)
1390 {
1391  BOOL ret;
1392  BYTE hash[20];
1393  DWORD size = sizeof(hash);
1394 
1397  if (ret)
1398  {
1399  const CRYPT_HASH_BLOB *pHash = pvPara;
1400 
1401  if (size == pHash->cbData)
1402  ret = !memcmp(pHash->pbData, hash, size);
1403  else
1404  ret = FALSE;
1405  }
1406  return ret;
1407 }
1408 
1410  DWORD dwFlags, const void *pvPara)
1411 {
1412  CERT_NAME_BLOB *blob = (CERT_NAME_BLOB *)pvPara, *toCompare;
1413  BOOL ret;
1414 
1415  if (dwType & CERT_INFO_SUBJECT_FLAG)
1416  toCompare = &pCertContext->pCertInfo->Subject;
1417  else
1418  toCompare = &pCertContext->pCertInfo->Issuer;
1420  toCompare, blob);
1421  return ret;
1422 }
1423 
1425  DWORD dwType, DWORD dwFlags, const void *pvPara)
1426 {
1428  BOOL ret;
1429 
1432  return ret;
1433 }
1434 
1436  DWORD dwType, DWORD dwFlags, const void *pvPara)
1437 {
1438  CERT_INFO *pCertInfo = (CERT_INFO *)pvPara;
1439  BOOL ret;
1440 
1441  /* Matching serial number and subject match.. */
1443  &pCertContext->pCertInfo->Subject, &pCertInfo->Issuer);
1444  if (ret)
1446  &pCertInfo->SerialNumber);
1447  else
1448  {
1449  /* failing that, if the serial number and issuer match, we match */
1451  &pCertInfo->SerialNumber);
1452  if (ret)
1454  &pCertContext->pCertInfo->Issuer, &pCertInfo->Issuer);
1455  }
1456  TRACE("returning %d\n", ret);
1457  return ret;
1458 }
1459 
1461  DWORD dwFlags, const void *pvPara)
1462 {
1463  CERT_ID *id = (CERT_ID *)pvPara;
1464  BOOL ret;
1465 
1466  switch (id->dwIdChoice)
1467  {
1470  &pCertContext->pCertInfo->Issuer, &id->u.IssuerSerialNumber.Issuer);
1471  if (ret)
1473  &id->u.IssuerSerialNumber.SerialNumber);
1474  break;
1475  case CERT_ID_SHA1_HASH:
1477  &id->u.HashId);
1478  break;
1480  {
1481  DWORD size = 0;
1482 
1485  if (ret && size == id->u.KeyId.cbData)
1486  {
1488 
1489  if (buf)
1490  {
1493  ret = !memcmp(buf, id->u.KeyId.pbData, size);
1494  CryptMemFree(buf);
1495  }
1496  else
1497  ret = FALSE;
1498  }
1499  else
1500  ret = FALSE;
1501  break;
1502  }
1503  default:
1504  ret = FALSE;
1505  break;
1506  }
1507  return ret;
1508 }
1509 
1511  DWORD dwFlags, const void *pvPara)
1512 {
1513  PCCERT_CONTEXT toCompare = pvPara;
1515  pCertContext->pCertInfo, toCompare->pCertInfo);
1516 }
1517 
1519  DWORD dwFlags, const void *pvPara)
1520 {
1521  const CRYPT_HASH_BLOB *hash = pvPara;
1522  DWORD size = 0;
1523  BOOL ret;
1524 
1527  if (ret && size == hash->cbData)
1528  {
1530 
1531  if (buf)
1532  {
1535  ret = !memcmp(buf, hash->pbData, size);
1536  CryptMemFree(buf);
1537  }
1538  else
1539  ret = FALSE;
1540  }
1541  else
1542  ret = FALSE;
1543  return ret;
1544 }
1545 
1548  const void *pvPara)
1549 {
1550  BOOL matches = FALSE;
1552 
1553  ret = prev;
1554  do {
1556  if (ret)
1557  matches = compare(ret, dwType, dwFlags, pvPara);
1558  } while (ret != NULL && !matches);
1559  return ret;
1560 }
1561 
1562 typedef PCCERT_CONTEXT (*CertFindFunc)(HCERTSTORE store, DWORD dwType,
1563  DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev);
1564 
1566  DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1567 {
1568  return CertEnumCertificatesInStore(store, prev);
1569 }
1570 
1572  DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1573 {
1574  BOOL ret;
1575  PCCERT_CONTEXT found = NULL, subject = pvPara;
1577  DWORD size;
1578 
1580  subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
1581  {
1583 
1584  ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
1585  X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
1587  &info, &size);
1588  if (ret)
1589  {
1590  CERT_ID id;
1591 
1592  if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
1593  {
1594  id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1595  memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer,
1596  sizeof(CERT_NAME_BLOB));
1597  memcpy(&id.u.IssuerSerialNumber.SerialNumber,
1598  &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
1599  }
1600  else if (info->KeyId.cbData)
1601  {
1602  id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1603  memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
1604  }
1605  else
1606  ret = FALSE;
1607  if (ret)
1608  found = cert_compare_certs_in_store(store, prev,
1609  compare_cert_by_cert_id, dwType, dwFlags, &id);
1610  LocalFree(info);
1611  }
1612  }
1614  subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
1615  {
1617 
1618  ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
1619  X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
1621  &info, &size);
1622  if (ret)
1623  {
1624  CERT_ID id;
1625 
1626  if (info->AuthorityCertIssuer.cAltEntry &&
1627  info->AuthorityCertSerialNumber.cbData)
1628  {
1629  PCERT_ALT_NAME_ENTRY directoryName = NULL;
1630  DWORD i;
1631 
1632  for (i = 0; !directoryName &&
1633  i < info->AuthorityCertIssuer.cAltEntry; i++)
1634  if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
1636  directoryName =
1637  &info->AuthorityCertIssuer.rgAltEntry[i];
1638  if (directoryName)
1639  {
1640  id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1641  memcpy(&id.u.IssuerSerialNumber.Issuer,
1642  &directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB));
1643  memcpy(&id.u.IssuerSerialNumber.SerialNumber,
1644  &info->AuthorityCertSerialNumber,
1645  sizeof(CRYPT_INTEGER_BLOB));
1646  }
1647  else
1648  {
1649  FIXME("no supported name type in authority key id2\n");
1650  ret = FALSE;
1651  }
1652  }
1653  else if (info->KeyId.cbData)
1654  {
1655  id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1656  memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
1657  }
1658  else
1659  ret = FALSE;
1660  if (ret)
1661  found = cert_compare_certs_in_store(store, prev,
1662  compare_cert_by_cert_id, dwType, dwFlags, &id);
1663  LocalFree(info);
1664  }
1665  }
1666  else
1667  found = cert_compare_certs_in_store(store, prev,
1669  dwFlags, &subject->pCertInfo->Issuer);
1670  return found;
1671 }
1672 
1674  DWORD dwType, DWORD dwFlags, const void *pvPara)
1675 {
1677  DWORD len;
1678  BOOL ret = FALSE;
1679 
1680  if (dwType & CERT_INFO_SUBJECT_FLAG)
1682  else
1686  if (len)
1687  {
1688  LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
1689 
1690  if (str)
1691  {
1692  LPWSTR ptr;
1693 
1696  for (ptr = str; *ptr; ptr++)
1697  *ptr = tolowerW(*ptr);
1698  if (strstrW(str, pvPara))
1699  ret = TRUE;
1700  CryptMemFree(str);
1701  }
1702  }
1703  return ret;
1704 }
1705 
1707  DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1708 {
1709  PCCERT_CONTEXT found = NULL;
1710 
1711  TRACE("%s\n", debugstr_a(pvPara));
1712 
1713  if (pvPara)
1714  {
1715  int len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
1716  LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
1717 
1718  if (str)
1719  {
1720  LPWSTR ptr;
1721 
1723  for (ptr = str; *ptr; ptr++)
1724  *ptr = tolowerW(*ptr);
1725  found = cert_compare_certs_in_store(store, prev,
1727  CryptMemFree(str);
1728  }
1729  }
1730  else
1731  found = find_cert_any(store, dwType, dwFlags, NULL, prev);
1732  return found;
1733 }
1734 
1736  DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
1737 {
1738  PCCERT_CONTEXT found = NULL;
1739 
1740  TRACE("%s\n", debugstr_w(pvPara));
1741 
1742  if (pvPara)
1743  {
1744  DWORD len = strlenW(pvPara);
1745  LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR));
1746 
1747  if (str)
1748  {
1749  LPCWSTR src;
1750  LPWSTR dst;
1751 
1752  for (src = pvPara, dst = str; *src; src++, dst++)
1753  *dst = tolowerW(*src);
1754  *dst = 0;
1755  found = cert_compare_certs_in_store(store, prev,
1757  CryptMemFree(str);
1758  }
1759  }
1760  else
1761  found = find_cert_any(store, dwType, dwFlags, NULL, prev);
1762  return found;
1763 }
1764 
1766  DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara,
1768 {
1772 
1773  TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType,
1774  dwFlags, dwType, pvPara, pPrevCertContext);
1775 
1776  switch (dwType >> CERT_COMPARE_SHIFT)
1777  {
1778  case CERT_COMPARE_ANY:
1779  find = find_cert_any;
1780  break;
1781  case CERT_COMPARE_MD5_HASH:
1783  break;
1786  break;
1787  case CERT_COMPARE_NAME:
1789  break;
1792  break;
1795  break;
1798  break;
1801  break;
1802  case CERT_COMPARE_CERT_ID:
1804  break;
1807  break;
1808  case CERT_COMPARE_EXISTING:
1810  break;
1813  break;
1814  default:
1815  FIXME("find type %08x unimplemented\n", dwType);
1816  }
1817 
1818  if (find)
1819  ret = find(hCertStore, dwType, dwFlags, pvPara, pPrevCertContext);
1820  else if (compare)
1822  compare, dwType, dwFlags, pvPara);
1823  else
1824  ret = NULL;
1825  if (!ret)
1827  TRACE("returning %p\n", ret);
1828  return ret;
1829 }
1830 
1833 {
1834  TRACE("(%p, %08x, %p)\n", hCertStore, dwCertEncodingType, pCertId);
1835 
1836  if (!pCertId)
1837  {
1839  return NULL;
1840  }
1841  return CertFindCertificateInStore(hCertStore, dwCertEncodingType, 0,
1842  CERT_FIND_SUBJECT_CERT, pCertId, NULL);
1843 }
1844 
1846  PCCERT_CONTEXT pIssuer, DWORD *pdwFlags)
1847 {
1848  static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
1850 
1851  if (*pdwFlags & ~supportedFlags)
1852  {
1854  return FALSE;
1855  }
1856  if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
1857  {
1858  DWORD flags = 0;
1859  PCCRL_CONTEXT crl = CertGetCRLFromStore(pSubject->hCertStore, pSubject,
1860  NULL, &flags);
1861 
1862  /* FIXME: what if the CRL has expired? */
1863  if (crl)
1864  {
1866  pSubject->pCertInfo, 1, (PCRL_INFO *)&crl->pCrlInfo))
1867  *pdwFlags &= CERT_STORE_REVOCATION_FLAG;
1868  }
1869  else
1870  *pdwFlags |= CERT_STORE_NO_CRL_FLAG;
1871  }
1872  if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
1873  {
1874  if (0 == CertVerifyTimeValidity(NULL, pSubject->pCertInfo))
1875  *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
1876  }
1877  if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
1878  {
1880  CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubject,
1882  *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
1883  }
1884  return TRUE;
1885 }
1886 
1888  PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
1889  DWORD *pdwFlags)
1890 {
1892 
1893  TRACE("(%p, %p, %p, %08x)\n", hCertStore, pSubjectContext,
1894  pPrevIssuerContext, *pdwFlags);
1895 
1896  if (!pSubjectContext)
1897  {
1899  return NULL;
1900  }
1901 
1902  ret = CertFindCertificateInStore(hCertStore,
1903  pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
1904  pSubjectContext, pPrevIssuerContext);
1905  if (ret)
1906  {
1907  if (!CertVerifySubjectCertificateContext(pSubjectContext, ret,
1908  pdwFlags))
1909  {
1911  ret = NULL;
1912  }
1913  if (CRYPT_IsCertificateSelfSigned(pSubjectContext))
1914  {
1916  ret = NULL;
1918  }
1919  }
1920  TRACE("returning %p\n", ret);
1921  return ret;
1922 }
1923 
1930 
1933 
1935  DWORD cContext, PVOID rgpvContext[], DWORD dwFlags,
1936  PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
1937 {
1938  BOOL ret;
1939 
1940  TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType,
1941  cContext, rgpvContext, dwFlags, pRevPara, pRevStatus);
1942 
1943  if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) &&
1944  pRevStatus->cbSize != sizeof(CERT_REVOCATION_STATUS))
1945  {
1947  return FALSE;
1948  }
1949  if (cContext)
1950  {
1951  static HCRYPTOIDFUNCSET set = NULL;
1952  DWORD size;
1953 
1954  if (!set)
1957  if (ret)
1958  {
1959  if (size == 1)
1960  {
1961  /* empty list */
1963  ret = FALSE;
1964  }
1965  else
1966  {
1967  LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR)), ptr;
1968 
1969  if (dllList)
1970  {
1972  dllList, &size);
1973  if (ret)
1974  {
1975  for (ptr = dllList; ret && *ptr;
1976  ptr += lstrlenW(ptr) + 1)
1977  {
1979  HCRYPTOIDFUNCADDR hFunc;
1980 
1982  dwEncodingType, ptr, 0, (void **)&func, &hFunc);
1983  if (ret)
1984  {
1985  ret = func(dwEncodingType, dwRevType, cContext,
1986  rgpvContext, dwFlags, pRevPara, pRevStatus);
1987  CryptFreeOIDFunctionAddress(hFunc, 0);
1988  }
1989  }
1990  }
1991  CryptMemFree(dllList);
1992  }
1993  else
1994  {
1996  ret = FALSE;
1997  }
1998  }
1999  }
2000  }
2001  else
2002  ret = TRUE;
2003  return ret;
2004 }
2005 
2007  CRYPT_ATTRIBUTE rgAttr[])
2008 {
2010  DWORD i;
2011 
2012  TRACE("%s %d %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
2013 
2014  if (!cAttr)
2015  return NULL;
2016  if (!pszObjId)
2017  {
2019  return NULL;
2020  }
2021 
2022  for (i = 0; !ret && i < cAttr; i++)
2023  if (rgAttr[i].pszObjId && !strcmp(pszObjId, rgAttr[i].pszObjId))
2024  ret = &rgAttr[i];
2025  return ret;
2026 }
2027 
2029  CERT_EXTENSION rgExtensions[])
2030 {
2032  DWORD i;
2033 
2034  TRACE("%s %d %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
2035 
2036  if (!cExtensions)
2037  return NULL;
2038  if (!pszObjId)
2039  {
2041  return NULL;
2042  }
2043 
2044  for (i = 0; !ret && i < cExtensions; i++)
2045  if (rgExtensions[i].pszObjId && !strcmp(pszObjId,
2046  rgExtensions[i].pszObjId))
2047  ret = &rgExtensions[i];
2048  return ret;
2049 }
2050 
2052 {
2054  DWORD i, j;
2055 
2056  TRACE("%s %p\n", debugstr_a(pszObjId), pName);
2057 
2058  if (!pszObjId)
2059  {
2061  return NULL;
2062  }
2063 
2064  for (i = 0; !ret && i < pName->cRDN; i++)
2065  for (j = 0; !ret && j < pName->rgRDN[i].cRDNAttr; j++)
2066  if (pName->rgRDN[i].rgRDNAttr[j].pszObjId && !strcmp(pszObjId,
2067  pName->rgRDN[i].rgRDNAttr[j].pszObjId))
2068  ret = &pName->rgRDN[i].rgRDNAttr[j];
2069  return ret;
2070 }
2071 
2073  const CERT_RDN_ATTR *attr)
2074 {
2075  DWORD i, j;
2076  BOOL match = FALSE;
2077 
2078  for (i = 0; !match && i < name->cRDN; i++)
2079  {
2080  for (j = 0; j < name->rgRDN[i].cRDNAttr; j++)
2081  {
2082  if (!strcmp(name->rgRDN[i].rgRDNAttr[j].pszObjId,
2083  attr->pszObjId) &&
2084  name->rgRDN[i].rgRDNAttr[j].dwValueType ==
2085  attr->dwValueType)
2086  {
2088  {
2089  LPCWSTR nameStr =
2090  (LPCWSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData;
2091  LPCWSTR attrStr = (LPCWSTR)attr->Value.pbData;
2092 
2093  if (attr->Value.cbData !=
2094  name->rgRDN[i].rgRDNAttr[j].Value.cbData)
2095  match = FALSE;
2097  match = !strncmpiW(nameStr, attrStr,
2098  attr->Value.cbData / sizeof(WCHAR));
2099  else
2100  match = !strncmpW(nameStr, attrStr,
2101  attr->Value.cbData / sizeof(WCHAR));
2102  TRACE("%s : %s => %d\n",
2103  debugstr_wn(nameStr, attr->Value.cbData / sizeof(WCHAR)),
2104  debugstr_wn(attrStr, attr->Value.cbData / sizeof(WCHAR)),
2105  match);
2106  }
2107  else
2108  {
2109  LPCSTR nameStr =
2110  (LPCSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData;
2111  LPCSTR attrStr = (LPCSTR)attr->Value.pbData;
2112 
2113  if (attr->Value.cbData !=
2114  name->rgRDN[i].rgRDNAttr[j].Value.cbData)
2115  match = FALSE;
2117  match = !strncasecmp(nameStr, attrStr,
2118  attr->Value.cbData);
2119  else
2120  match = !strncmp(nameStr, attrStr, attr->Value.cbData);
2121  TRACE("%s : %s => %d\n",
2122  debugstr_an(nameStr, attr->Value.cbData),
2123  debugstr_an(attrStr, attr->Value.cbData), match);
2124  }
2125  }
2126  }
2127  }
2128  return match;
2129 }
2130 
2132  DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN)
2133 {
2135  LPCSTR type;
2136  DWORD size;
2137  BOOL ret;
2138 
2139  TRACE("(%08x, %08x, %p, %p)\n", dwCertEncodingType, dwFlags, pCertName,
2140  pRDN);
2141 
2143  X509_NAME;
2145  pCertName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &name, &size)))
2146  {
2147  DWORD i;
2148 
2149  for (i = 0; ret && i < pRDN->cRDNAttr; i++)
2151  if (!ret)
2153  LocalFree(name);
2154  }
2155  return ret;
2156 }
2157 
2159  PCERT_INFO pCertInfo)
2160 {
2162  LONG ret;
2163 
2164  if (!pTimeToVerify)
2165  {
2167  pTimeToVerify = &fileTime;
2168  }
2169  if ((ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotBefore)) >= 0)
2170  {
2171  ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotAfter);
2172  if (ret < 0)
2173  ret = 0;
2174  }
2175  return ret;
2176 }
2177 
2179  PCERT_INFO pIssuerInfo)
2180 {
2181  TRACE("(%p, %p)\n", pSubjectInfo, pIssuerInfo);
2182 
2183  return CertVerifyTimeValidity(&pSubjectInfo->NotBefore, pIssuerInfo) == 0
2184  && CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0;
2185 }
2186 
2188  DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
2189  DWORD *pcbComputedHash)
2190 {
2191  BOOL ret = TRUE;
2192  HCRYPTHASH hHash = 0;
2193 
2194  TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags,
2195  pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
2196 
2197  if (!hCryptProv)
2198  hCryptProv = I_CryptGetDefaultCryptProv(0);
2199  if (!Algid)
2200  Algid = CALG_SHA1;
2201  if (ret)
2202  {
2203  ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
2204  if (ret)
2205  {
2206  ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0);
2207  if (ret)
2208  ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2209  pcbComputedHash, 0);
2211  }
2212  }
2213  return ret;
2214 }
2215 
2218  BYTE *pbComputedHash, DWORD *pcbComputedHash)
2219 {
2220  BOOL ret = TRUE;
2221  HCRYPTHASH hHash = 0;
2222 
2223  TRACE("(%08lx, %d, %08x, %d, %p, %p, %p)\n", hCryptProv, Algid, dwFlags,
2224  dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
2225 
2226  if (!hCryptProv)
2227  hCryptProv = I_CryptGetDefaultCryptProv(0);
2228  if (!Algid)
2229  Algid = CALG_MD5;
2231  {
2233  return FALSE;
2234  }
2235  if (ret)
2236  {
2237  BYTE *buf;
2238  DWORD size = 0;
2239 
2242  (LPBYTE)&buf, &size);
2243  if (ret)
2244  {
2245  ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
2246  if (ret)
2247  {
2248  ret = CryptHashData(hHash, buf, size, 0);
2249  if (ret)
2250  ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2251  pcbComputedHash, 0);
2253  }
2254  LocalFree(buf);
2255  }
2256  }
2257  return ret;
2258 }
2259 
2261  DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
2262  BYTE *pbComputedHash, DWORD *pcbComputedHash)
2263 {
2264  BOOL ret;
2266  DWORD size;
2267 
2268  TRACE("(%08lx, %08x, %p, %d, %p, %d)\n", hCryptProv, dwCertEncodingType,
2269  pbEncoded, cbEncoded, pbComputedHash, *pcbComputedHash);
2270 
2272  pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
2273  if (ret)
2274  {
2276  HCRYPTHASH hHash;
2277 
2278  if (!hCryptProv)
2279  hCryptProv = I_CryptGetDefaultCryptProv(0);
2281  info->SignatureAlgorithm.pszObjId, 0);
2282  if (!oidInfo)
2283  {
2285  ret = FALSE;
2286  }
2287  else
2288  {
2289  ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash);
2290  if (ret)
2291  {
2292  ret = CryptHashData(hHash, info->ToBeSigned.pbData,
2293  info->ToBeSigned.cbData, 0);
2294  if (ret)
2295  ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
2296  pcbComputedHash, 0);
2298  }
2299  }
2300  LocalFree(info);
2301  }
2302  return ret;
2303 }
2304 
2306  DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
2307  DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
2308  const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
2309 {
2310  BOOL ret;
2312  HCRYPTHASH hHash;
2313 
2314  TRACE("(%08lx, %d, %d, %p, %d, %p, %p, %p, %p)\n", hCryptProv,
2315  dwKeySpec, dwCertEncodingType, pbEncodedToBeSigned, cbEncodedToBeSigned,
2316  pSignatureAlgorithm, pvHashAuxInfo, pbSignature, pcbSignature);
2317 
2319  pSignatureAlgorithm->pszObjId, 0);
2320  if (!info)
2321  {
2323  return FALSE;
2324  }
2325  if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
2326  {
2327  if (!hCryptProv)
2328  hCryptProv = I_CryptGetDefaultCryptProv(0);
2329  ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
2330  if (ret)
2331  {
2332  ret = CryptHashData(hHash, pbEncodedToBeSigned,
2333  cbEncodedToBeSigned, 0);
2334  if (ret)
2335  ret = CryptGetHashParam(hHash, HP_HASHVAL, pbSignature,
2336  pcbSignature, 0);
2338  }
2339  }
2340  else
2341  {
2342  if (!hCryptProv)
2343  {
2345  ret = FALSE;
2346  }
2347  else
2348  {
2349  ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
2350  if (ret)
2351  {
2352  ret = CryptHashData(hHash, pbEncodedToBeSigned,
2353  cbEncodedToBeSigned, 0);
2354  if (ret)
2355  ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature,
2356  pcbSignature);
2358  }
2359  }
2360  }
2361  return ret;
2362 }
2363 
2365  DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType,
2366  const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
2367  const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
2368 {
2369  BOOL ret;
2370  DWORD encodedSize, hashSize;
2371 
2372  TRACE("(%08lx, %d, %d, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec,
2373  dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo,
2374  pSignatureAlgorithm, pvHashAuxInfo, pbEncoded, pcbEncoded);
2375 
2376  ret = CryptEncodeObject(dwCertEncodingType, lpszStructType, pvStructInfo,
2377  NULL, &encodedSize);
2378  if (ret)
2379  {
2380  PBYTE encoded = CryptMemAlloc(encodedSize);
2381 
2382  if (encoded)
2383  {
2384  ret = CryptEncodeObject(dwCertEncodingType, lpszStructType,
2385  pvStructInfo, encoded, &encodedSize);
2386  if (ret)
2387  {
2388  ret = CryptSignCertificate(hCryptProv, dwKeySpec,
2389  dwCertEncodingType, encoded, encodedSize, pSignatureAlgorithm,
2390  pvHashAuxInfo, NULL, &hashSize);
2391  if (ret)
2392  {
2393  PBYTE hash = CryptMemAlloc(hashSize);
2394 
2395  if (hash)
2396  {
2397  ret = CryptSignCertificate(hCryptProv, dwKeySpec,
2398  dwCertEncodingType, encoded, encodedSize,
2399  pSignatureAlgorithm, pvHashAuxInfo, hash, &hashSize);
2400  if (ret)
2401  {
2402  CERT_SIGNED_CONTENT_INFO info = { { 0 } };
2403 
2404  info.ToBeSigned.cbData = encodedSize;
2405  info.ToBeSigned.pbData = encoded;
2406  info.SignatureAlgorithm = *pSignatureAlgorithm;
2407  info.Signature.cbData = hashSize;
2408  info.Signature.pbData = hash;
2409  info.Signature.cUnusedBits = 0;
2412  }
2413  CryptMemFree(hash);
2414  }
2415  else
2416  ret = FALSE;
2417  }
2418  }
2419  CryptMemFree(encoded);
2420  }
2421  else
2422  ret = FALSE;
2423  }
2424  return ret;
2425 }
2426 
2428  DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
2429  PCERT_PUBLIC_KEY_INFO pPublicKey)
2430 {
2431  CRYPT_DATA_BLOB blob = { cbEncoded, (BYTE *)pbEncoded };
2432 
2435  CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pPublicKey, 0, NULL);
2436 }
2437 
2439  CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
2440 {
2441  BOOL ret;
2442  HCRYPTKEY key;
2443  ALG_ID pubKeyID, hashID;
2444 
2445  hashID = info->u.Algid;
2446  if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
2447  pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
2448  else
2449  pubKeyID = hashID;
2450  /* Load the default provider if necessary */
2451  if (!hCryptProv)
2452  hCryptProv = I_CryptGetDefaultCryptProv(0);
2454  pubKeyInfo, pubKeyID, 0, NULL, &key);
2455  if (ret)
2456  {
2457  HCRYPTHASH hash;
2458 
2459  ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash);
2460  if (ret)
2461  {
2462  ret = CryptHashData(hash, signedCert->ToBeSigned.pbData,
2463  signedCert->ToBeSigned.cbData, 0);
2464  if (ret)
2466  signedCert->Signature.cbData, key, NULL, 0);
2468  }
2470  }
2471  return ret;
2472 }
2473 
2474 static BOOL CNG_CalcHash(const WCHAR *algorithm, const CERT_SIGNED_CONTENT_INFO *signedCert,
2475  BYTE **hash_value, DWORD *hash_len)
2476 {
2478  BCRYPT_ALG_HANDLE alg = NULL;
2479  NTSTATUS status;
2480  DWORD size;
2481 
2482  if ((status = BCryptOpenAlgorithmProvider(&alg, algorithm, NULL, 0)))
2483  goto done;
2484 
2485  if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
2486  goto done;
2487 
2488  if ((status = BCryptHashData(hash, signedCert->ToBeSigned.pbData, signedCert->ToBeSigned.cbData, 0)))
2489  goto done;
2490 
2491  if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)hash_len, sizeof(*hash_len), &size, 0)))
2492  goto done;
2493 
2494  if (!(*hash_value = CryptMemAlloc(*hash_len)))
2495  {
2497  goto done;
2498  }
2499 
2500  if ((status = BCryptFinishHash(hash, *hash_value, *hash_len, 0)))
2501  {
2502  CryptMemFree(*hash_value);
2503  goto done;
2504  }
2505 
2506 done:
2507  if (hash) BCryptDestroyHash(hash);
2508  if (alg) BCryptCloseAlgorithmProvider(alg, 0);
2510  return status == 0;
2511 }
2512 
2514 {
2515  DWORD blob_magic, ecckey_len, size;
2516  BCRYPT_ALG_HANDLE alg = NULL;
2517  BCRYPT_ECCKEY_BLOB *ecckey;
2518  const WCHAR *sign_algo;
2519  char **ecc_curve;
2520  NTSTATUS status;
2521 
2522  if (!pubKeyInfo->PublicKey.cbData)
2523  {
2525  return FALSE;
2526  }
2527 
2528  if (pubKeyInfo->PublicKey.pbData[0] != 0x4)
2529  {
2530  FIXME("Compressed ECC curves (%02x) not yet supported\n", pubKeyInfo->PublicKey.pbData[0]);
2532  return FALSE;
2533  }
2534 
2536  pubKeyInfo->Algorithm.Parameters.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_curve, &size))
2537  return FALSE;
2538 
2539  if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256))
2540  {
2541  sign_algo = BCRYPT_ECDSA_P256_ALGORITHM;
2542  blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
2543  }
2544  else if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P384))
2545  {
2546  sign_algo = BCRYPT_ECDSA_P384_ALGORITHM;
2547  blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
2548  }
2549  else
2550  {
2551  FIXME("Unsupported ecc curve type: %s\n", *ecc_curve);
2552  sign_algo = NULL;
2553  blob_magic = 0;
2554  }
2555  LocalFree(ecc_curve);
2556 
2557  if (!sign_algo)
2558  {
2560  return FALSE;
2561  }
2562 
2563  if ((status = BCryptOpenAlgorithmProvider(&alg, sign_algo, NULL, 0)))
2564  goto done;
2565 
2566  ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1;
2567  if (!(ecckey = CryptMemAlloc(ecckey_len)))
2568  {
2570  goto done;
2571  }
2572 
2573  ecckey->dwMagic = blob_magic;
2574  ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2;
2575  memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1);
2576 
2577  status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0);
2578  CryptMemFree(ecckey);
2579 
2580 done:
2581  if (alg) BCryptCloseAlgorithmProvider(alg, 0);
2583  return !status;
2584 }
2585 
2587 {
2588  if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
2589  return CNG_ImportECCPubKey(pubKeyInfo, key);
2590 
2591  FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
2593  return FALSE;
2594 }
2595 
2596 static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len)
2597 {
2598  CERT_ECC_SIGNATURE *ecc_sig;
2599  DWORD size;
2600  int i;
2601 
2602  if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, encoded_sig, encoded_size,
2603  CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size))
2604  return FALSE;
2605 
2606  if (!ecc_sig->r.cbData || !ecc_sig->s.cbData)
2607  {
2608  LocalFree(ecc_sig);
2610  return FALSE;
2611  }
2612 
2613  *sig_len = ecc_sig->r.cbData + ecc_sig->s.cbData;
2614  if (!(*sig_value = CryptMemAlloc(*sig_len)))
2615  {
2616  LocalFree(ecc_sig);
2618  return FALSE;
2619  }
2620 
2621  for (i = 0; i < ecc_sig->r.cbData; i++)
2622  (*sig_value)[i] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1];
2623  for (i = 0; i < ecc_sig->s.cbData; i++)
2624  (*sig_value)[ecc_sig->r.cbData + i] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1];
2625 
2626  LocalFree(ecc_sig);
2627  return TRUE;
2628 }
2629 
2631  BYTE **sig_value, DWORD *sig_len)
2632 {
2633  BYTE *encoded_sig;
2634  BOOL ret = FALSE;
2635  int i;
2636 
2637  if (!signedCert->Signature.cbData)
2638  {
2640  return FALSE;
2641  }
2642 
2643  if (!(encoded_sig = CryptMemAlloc(signedCert->Signature.cbData)))
2644  {
2646  return FALSE;
2647  }
2648 
2649  for (i = 0; i < signedCert->Signature.cbData; i++)
2650  encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1];
2651 
2653  ret = CNG_PrepareSignatureECC(encoded_sig, signedCert->Signature.cbData, sig_value, sig_len);
2654  else
2655  {
2656  FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
2658  }
2659 
2660  CryptMemFree(encoded_sig);
2661  return ret;
2662 }
2663 
2665  CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
2666 {
2668  BYTE *hash_value = NULL, *sig_value;
2669  DWORD hash_len, sig_len;
2670  NTSTATUS status;
2671  BOOL ret;
2672 
2673  ret = CNG_ImportPubKey(pubKeyInfo, &key);
2674  if (ret)
2675  {
2676  ret = CNG_CalcHash(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len);
2677  if (ret)
2678  {
2679  ret = CNG_PrepareSignature(pubKeyInfo, signedCert, &sig_value, &sig_len);
2680  if (ret)
2681  {
2682  status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
2683  if (status)
2684  {
2685  FIXME("Failed to verify signature: %08x\n", status);
2687  ret = FALSE;
2688  }
2689  CryptMemFree(sig_value);
2690  }
2691  CryptMemFree(hash_value);
2692  }
2694  }
2695 
2696  return ret;
2697 }
2698 
2700  CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
2701 {
2703 
2705  if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
2706  {
2708  return FALSE;
2709  }
2710 
2711  if (info->u.Algid == CALG_OID_INFO_CNG_ONLY)
2712  return CNG_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
2713  else
2714  return CRYPT_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
2715 }
2716 
2718  DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
2719  DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
2720 {
2721  BOOL ret = TRUE;
2722  CRYPT_DATA_BLOB subjectBlob;
2723 
2724  TRACE("(%08lx, %d, %d, %p, %d, %p, %08x, %p)\n", hCryptProv,
2725  dwCertEncodingType, dwSubjectType, pvSubject, dwIssuerType, pvIssuer,
2726  dwFlags, pvReserved);
2727 
2728  switch (dwSubjectType)
2729  {
2731  {
2732  PCRYPT_DATA_BLOB blob = pvSubject;
2733 
2734  subjectBlob.pbData = blob->pbData;
2735  subjectBlob.cbData = blob->cbData;
2736  break;
2737  }
2739  {
2740  PCERT_CONTEXT context = pvSubject;
2741 
2742  subjectBlob.pbData = context->pbCertEncoded;
2743  subjectBlob.cbData = context->cbCertEncoded;
2744  break;
2745  }
2747  {
2748  PCRL_CONTEXT context = pvSubject;
2749 
2750  subjectBlob.pbData = context->pbCrlEncoded;
2751  subjectBlob.cbData = context->cbCrlEncoded;
2752  break;
2753  }
2754  default:
2756  ret = FALSE;
2757  }
2758 
2759  if (ret)
2760  {
2761  PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
2762  DWORD size = 0;
2763 
2765  subjectBlob.pbData, subjectBlob.cbData,
2767  &signedCert, &size);
2768  if (ret)
2769  {
2770  switch (dwIssuerType)
2771  {
2774  dwCertEncodingType, pvIssuer,
2775  signedCert);
2776  break;
2780  &((PCCERT_CONTEXT)pvIssuer)->pCertInfo->SubjectPublicKeyInfo,
2781  signedCert);
2782  break;
2784  FIXME("CRYPT_VERIFY_CERT_SIGN_ISSUER_CHAIN: stub\n");
2785  ret = FALSE;
2786  break;
2788  if (pvIssuer)
2789  {
2791  ret = FALSE;
2792  }
2793  else
2794  {
2795  FIXME("unimplemented for NULL signer\n");
2797  ret = FALSE;
2798  }
2799  break;
2800  default:
2802  ret = FALSE;
2803  }
2804  LocalFree(signedCert);
2805  }
2806  }
2807  return ret;
2808 }
2809 
2811  PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage)
2812 {
2814  BOOL ret = FALSE;
2815 
2816  TRACE("(%08x, %p, %p, %d)\n", dwCertEncodingType, pCertInfo, pbKeyUsage,
2817  cbKeyUsage);
2818 
2820  pCertInfo->rgExtension);
2821  if (ext)
2822  {
2824  DWORD size = sizeof(usage);
2825 
2827  ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL,
2828  &usage, &size);
2829  if (ret)
2830  {
2831  if (cbKeyUsage < usage.cbData)
2832  ret = FALSE;
2833  else
2834  {
2835  memcpy(pbKeyUsage, usage.pbData, usage.cbData);
2836  if (cbKeyUsage > usage.cbData)
2837  memset(pbKeyUsage + usage.cbData, 0,
2838  cbKeyUsage - usage.cbData);
2839  }
2840  }
2841  }
2842  else
2843  SetLastError(0);
2844  return ret;
2845 }
2846 
2848  PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage)
2849 {
2851  DWORD bytesNeeded;
2852  BOOL ret = TRUE;
2853 
2854  if (!pCertContext || !pcbUsage)
2855  {
2857  return FALSE;
2858  }
2859 
2860  TRACE("(%p, %08x, %p, %d)\n", pCertContext, dwFlags, pUsage, *pcbUsage);
2861 
2863  {
2864  DWORD propSize = 0;
2865 
2867  CERT_ENHKEY_USAGE_PROP_ID, NULL, &propSize))
2868  {
2869  LPBYTE buf = CryptMemAlloc(propSize);
2870 
2871  if (buf)
2872  {
2874  CERT_ENHKEY_USAGE_PROP_ID, buf, &propSize))
2875  {
2877  X509_ENHANCED_KEY_USAGE, buf, propSize,
2878  CRYPT_ENCODE_ALLOC_FLAG, NULL, &usage, &bytesNeeded);
2879  }
2880  CryptMemFree(buf);
2881  }
2882  }
2883  }
2885  {
2889 
2890  if (ext)
2891  {
2893  X509_ENHANCED_KEY_USAGE, ext->Value.pbData, ext->Value.cbData,
2894  CRYPT_ENCODE_ALLOC_FLAG, NULL, &usage, &bytesNeeded);
2895  }
2896  }
2897  if (!usage)
2898  {
2899  /* If a particular location is specified, this should fail. Otherwise
2900  * it should succeed with an empty usage. (This is true on Win2k and
2901  * later, which we emulate.)
2902  */
2903  if (dwFlags)
2904  {
2906  ret = FALSE;
2907  }
2908  else
2909  bytesNeeded = sizeof(CERT_ENHKEY_USAGE);
2910  }
2911 
2912  if (ret)
2913  {
2914  if (!pUsage)
2915  *pcbUsage = bytesNeeded;
2916  else if (*pcbUsage < bytesNeeded)
2917  {
2919  *pcbUsage = bytesNeeded;
2920  ret = FALSE;
2921  }
2922  else
2923  {
2924  *pcbUsage = bytesNeeded;
2925  if (usage)
2926  {
2927  DWORD i;
2928  LPSTR nextOID = (LPSTR)((LPBYTE)pUsage +
2929  sizeof(CERT_ENHKEY_USAGE) +
2930  usage->cUsageIdentifier * sizeof(LPSTR));
2931 
2932  pUsage->cUsageIdentifier = usage->cUsageIdentifier;
2933  pUsage->rgpszUsageIdentifier = (LPSTR *)((LPBYTE)pUsage +
2934  sizeof(CERT_ENHKEY_USAGE));
2935  for (i = 0; i < usage->cUsageIdentifier; i++)
2936  {
2937  pUsage->rgpszUsageIdentifier[i] = nextOID;
2938  strcpy(nextOID, usage->rgpszUsageIdentifier[i]);
2939  nextOID += strlen(nextOID) + 1;
2940  }
2941  }
2942  else
2943  pUsage->cUsageIdentifier = 0;
2944  }
2945  }
2946  if (usage)
2947  LocalFree(usage);
2948  TRACE("returning %d\n", ret);
2949  return ret;
2950 }
2951 
2953  PCERT_ENHKEY_USAGE pUsage)
2954 {
2955  BOOL ret;
2956 
2957  TRACE("(%p, %p)\n", pCertContext, pUsage);
2958 
2959  if (pUsage)
2960  {
2961  CRYPT_DATA_BLOB blob = { 0, NULL };
2962 
2964  pUsage, CRYPT_ENCODE_ALLOC_FLAG, NULL, &blob.pbData, &blob.cbData);
2965  if (ret)
2966  {
2969  LocalFree(blob.pbData);
2970  }
2971  }
2972  else
2975  return ret;
2976 }
2977 
2979  LPCSTR pszUsageIdentifier)
2980 {
2981  BOOL ret;
2982  DWORD size;
2983 
2984  TRACE("(%p, %s)\n", pCertContext, debugstr_a(pszUsageIdentifier));
2985 
2988  {
2990 
2991  if (usage)
2992  {
2995  if (ret)
2996  {
2997  DWORD i;
2998  BOOL exists = FALSE;
2999 
3000  /* Make sure usage doesn't already exist */
3001  for (i = 0; !exists && i < usage->cUsageIdentifier; i++)
3002  {
3003  if (!strcmp(usage->rgpszUsageIdentifier[i],
3004  pszUsageIdentifier))
3005  exists = TRUE;
3006  }
3007  if (!exists)
3008  {
3010  sizeof(LPSTR) + strlen(pszUsageIdentifier) + 1);
3011 
3012  if (newUsage)
3013  {
3014  LPSTR nextOID;
3015 
3016  newUsage->rgpszUsageIdentifier = (LPSTR *)
3017  ((LPBYTE)newUsage + sizeof(CERT_ENHKEY_USAGE));
3018  nextOID = (LPSTR)((LPBYTE)newUsage->rgpszUsageIdentifier
3019  + (usage->cUsageIdentifier + 1) * sizeof(LPSTR));
3020  for (i = 0; i < usage->cUsageIdentifier; i++)
3021  {
3022  newUsage->rgpszUsageIdentifier[i] = nextOID;
3023  strcpy(nextOID, usage->rgpszUsageIdentifier[i]);
3024  nextOID += strlen(nextOID) + 1;
3025  }
3026  newUsage->rgpszUsageIdentifier[i] = nextOID;
3027  strcpy(nextOID, pszUsageIdentifier);
3028  newUsage->cUsageIdentifier = i + 1;
3030  CryptMemFree(newUsage);
3031  }
3032  else
3033  ret = FALSE;
3034  }
3035  }
3037  }
3038  else
3039  ret = FALSE;
3040  }
3041  else
3042  {
3044  sizeof(LPSTR) + strlen(pszUsageIdentifier) + 1);
3045 
3046  if (usage)
3047  {
3048  usage->rgpszUsageIdentifier =
3049  (LPSTR *)((LPBYTE)usage + sizeof(CERT_ENHKEY_USAGE));
3050  usage->rgpszUsageIdentifier[0] = (LPSTR)((LPBYTE)usage +
3051  sizeof(CERT_ENHKEY_USAGE) + sizeof(LPSTR));
3052  strcpy(usage->rgpszUsageIdentifier[0], pszUsageIdentifier);
3053  usage->cUsageIdentifier = 1;
3056  }
3057  else
3058  ret = FALSE;
3059  }
3060  return ret;
3061 }
3062 
3064  LPCSTR pszUsageIdentifier)
3065 {
3066  BOOL ret;
3067  DWORD size;
3069 
3070  TRACE("(%p, %s)\n", pCertContext, debugstr_a(pszUsageIdentifier));
3071 
3072  size = sizeof(usage);
3075  if (!ret && GetLastError() == ERROR_MORE_DATA)
3076  {
3078 
3079  if (pUsage)
3080  {
3083  if (ret)
3084  {
3085  if (pUsage->cUsageIdentifier)
3086  {
3087  DWORD i;
3088  BOOL found = FALSE;
3089 
3090  for (i = 0; i < pUsage->cUsageIdentifier; i++)
3091  {
3092  if (!strcmp(pUsage->rgpszUsageIdentifier[i],
3093  pszUsageIdentifier))
3094  found = TRUE;
3095  if (found && i < pUsage->cUsageIdentifier - 1)
3096  pUsage->rgpszUsageIdentifier[i] =
3097  pUsage->rgpszUsageIdentifier[i + 1];
3098  }
3099  pUsage->cUsageIdentifier--;
3100  /* Remove the usage if it's empty */
3101  if (pUsage->cUsageIdentifier)
3103  else
3105  }
3106  }
3107  CryptMemFree(pUsage);
3108  }
3109  else
3110  ret = FALSE;
3111  }
3112  else
3113  {
3114  /* it fit in an empty usage, therefore there's nothing to remove */
3115  ret = TRUE;
3116  }
3117  return ret;
3118 }
3119 
3120 struct BitField
3121 {
3124 };
3125 
3126 #define BITS_PER_DWORD (sizeof(DWORD) * 8)
3127 
3128 static void CRYPT_SetBitInField(struct BitField *field, DWORD bit)
3129 {
3130  DWORD indexIndex = bit / BITS_PER_DWORD;
3131 
3132  if (indexIndex + 1 > field->cIndexes)
3133  {
3134  if (field->cIndexes)
3135  field->indexes = CryptMemRealloc(field->indexes,
3136  (indexIndex + 1) * sizeof(DWORD));
3137  else
3138  field->indexes = CryptMemAlloc(sizeof(DWORD));
3139  if (field->indexes)
3140  {
3141  field->indexes[indexIndex] = 0;
3142  field->cIndexes = indexIndex + 1;
3143  }
3144  }
3145  if (field->indexes)
3146  field->indexes[indexIndex] |= 1 << (bit % BITS_PER_DWORD);
3147 }
3148 
3149 static BOOL CRYPT_IsBitInFieldSet(const struct BitField *field, DWORD bit)
3150 {
3151  BOOL set;
3152  DWORD indexIndex = bit / BITS_PER_DWORD;
3153 
3154  assert(field->cIndexes);
3155  set = field->indexes[indexIndex] & (1 << (bit % BITS_PER_DWORD));
3156  return set;
3157 }
3158 
3160  int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs)
3161 {
3162  BOOL ret = TRUE;
3163  DWORD i, cbOIDs = 0;
3164  BOOL allUsagesValid = TRUE;
3165  CERT_ENHKEY_USAGE validUsages = { 0, NULL };
3166 
3167  TRACE("(%d, %p, %d, %p, %d)\n", cCerts, rghCerts, *cNumOIDs,
3168  rghOIDs, *pcbOIDs);
3169 
3170  for (i = 0; i < cCerts; i++)
3171  {
3173  DWORD size = sizeof(usage);
3174 
3175  ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, &usage, &size);
3176  /* Success is deliberately ignored: it implies all usages are valid */
3177  if (!ret && GetLastError() == ERROR_MORE_DATA)
3178  {
3180 
3181  allUsagesValid = FALSE;
3182  if (pUsage)
3183  {
3184  ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, pUsage, &size);
3185  if (ret)
3186  {
3187  if (!validUsages.cUsageIdentifier)
3188  {
3189  DWORD j;
3190 
3191  cbOIDs = pUsage->cUsageIdentifier * sizeof(LPSTR);
3192  validUsages.cUsageIdentifier = pUsage->cUsageIdentifier;
3193  for (j = 0; j < validUsages.cUsageIdentifier; j++)
3194  cbOIDs += lstrlenA(pUsage->rgpszUsageIdentifier[j])
3195  + 1;
3196  validUsages.rgpszUsageIdentifier =
3197  CryptMemAlloc(cbOIDs);
3198  if (validUsages.rgpszUsageIdentifier)
3199  {
3200  LPSTR nextOID = (LPSTR)
3201  ((LPBYTE)validUsages.rgpszUsageIdentifier +
3202  validUsages.cUsageIdentifier * sizeof(LPSTR));
3203 
3204  for (j = 0; j < validUsages.cUsageIdentifier; j++)
3205  {
3206  validUsages.rgpszUsageIdentifier[j] = nextOID;
3207  lstrcpyA(validUsages.rgpszUsageIdentifier[j],
3208  pUsage->rgpszUsageIdentifier[j]);
3209  nextOID += lstrlenA(nextOID) + 1;
3210  }
3211  }
3212  }
3213  else
3214  {
3215  struct BitField validIndexes = { 0, NULL };
3216  DWORD j, k, numRemoved = 0;
3217 
3218  /* Merge: build a bitmap of all the indexes of
3219  * validUsages.rgpszUsageIdentifier that are in pUsage.
3220  */
3221  for (j = 0; j < pUsage->cUsageIdentifier; j++)
3222  {
3223  for (k = 0; k < validUsages.cUsageIdentifier; k++)
3224  {
3225  if (!strcmp(pUsage->rgpszUsageIdentifier[j],
3226  validUsages.rgpszUsageIdentifier[k]))
3227  {
3228  CRYPT_SetBitInField(&validIndexes, k);
3229  break;
3230  }
3231  }
3232  }
3233  /* Merge by removing from validUsages those that are
3234  * not in the bitmap.
3235  */
3236  for (j = 0; j < validUsages.cUsageIdentifier; j++)
3237  {
3238  if (!CRYPT_IsBitInFieldSet(&validIndexes, j))
3239  {
3240  if (j < validUsages.cUsageIdentifier - 1)
3241  {
3242  memmove(&validUsages.rgpszUsageIdentifier[j],
3243  &validUsages.rgpszUsageIdentifier[j +
3244  numRemoved + 1],
3245  (validUsages.cUsageIdentifier - numRemoved
3246  - j - 1) * sizeof(LPSTR));
3247  cbOIDs -= lstrlenA(
3248  validUsages.rgpszUsageIdentifier[j]) + 1 +
3249  sizeof(LPSTR);
3250  validUsages.cUsageIdentifier--;
3251  numRemoved++;
3252  }
3253  else
3254  validUsages.cUsageIdentifier--;
3255  }
3256  }
3257  CryptMemFree(validIndexes.indexes);
3258  }
3259  }
3260  CryptMemFree(pUsage);
3261  }
3262  }
3263  }
3264  ret = TRUE;
3265  if (allUsagesValid)
3266  {
3267  *cNumOIDs = -1;
3268  *pcbOIDs = 0;
3269  }
3270  else
3271  {
3272  *cNumOIDs = validUsages.cUsageIdentifier;
3273  if (!rghOIDs)
3274  *pcbOIDs = cbOIDs;
3275  else if (*pcbOIDs < cbOIDs)
3276  {
3277  *pcbOIDs = cbOIDs;
3279  ret = FALSE;
3280  }
3281  else
3282  {
3283  LPSTR nextOID = (LPSTR)((LPBYTE)rghOIDs +
3284  validUsages.cUsageIdentifier * sizeof(LPSTR));
3285 
3286  *pcbOIDs = cbOIDs;
3287  for (i = 0; i < validUsages.cUsageIdentifier; i++)
3288  {
3289  rghOIDs[i] = nextOID;
3290  lstrcpyA(nextOID, validUsages.rgpszUsageIdentifier[i]);
3291  nextOID += lstrlenA(nextOID) + 1;
3292  }
3293  }
3294  }
3295  CryptMemFree(validUsages.rgpszUsageIdentifier);
3296  TRACE("cNumOIDs: %d\n", *cNumOIDs);
3297  TRACE("returning %d\n", ret);
3298  return ret;
3299 }
3300 
3301 /* Sets the CERT_KEY_PROV_INFO_PROP_ID property of context from pInfo, or, if
3302  * pInfo is NULL, from the attributes of hProv.
3303  */
3305  const CRYPT_KEY_PROV_INFO *pInfo, HCRYPTPROV hProv)
3306 {
3307  CRYPT_KEY_PROV_INFO info = { 0 };
3308  BOOL ret;
3309 
3310  if (!pInfo)
3311  {
3312  DWORD size;
3313  int len;
3314 
3316  if (ret)
3317  {
3319 
3320  if (szContainer)
3321  {
3323  (BYTE *)szContainer, &size, 0);
3324  if (ret)
3325  {
3327  NULL, 0);
3328  if (len)
3329  {
3330  info.pwszContainerName = CryptMemAlloc(len *
3331  sizeof(WCHAR));
3333  info.pwszContainerName, len);
3334  }
3335  }
3337  }
3338  }
3340  if (ret)
3341  {
3343 
3344  if (szProvider)
3345  {
3347  &size, 0);
3348  if (ret)
3349  {
3351  NULL, 0);
3352  if (len)
3353  {
3354  info.pwszProvName = CryptMemAlloc(len *
3355  sizeof(WCHAR));
3357  info.pwszProvName, len);
3358  }
3359  }
3361  }
3362  }
3363  /* in case no CRYPT_KEY_PROV_INFO given,
3364  * we always use AT_SIGNATURE key spec
3365  */
3366  info.dwKeySpec = AT_SIGNATURE;
3367  size = sizeof(info.dwProvType);
3368  ret = CryptGetProvParam(hProv, PP_PROVTYPE, (LPBYTE)&info.dwProvType,
3369  &size, 0);
3370  if (!ret)
3371  info.dwProvType = PROV_RSA_FULL;
3372  pInfo = &info;
3373  }
3374 
3376  0, pInfo);
3377 
3378  if (pInfo == &info)
3379  {
3380  CryptMemFree(info.pwszContainerName);
3381  CryptMemFree(info.pwszProvName);
3382  }
3383 }
3384 
3385 /* Creates a signed certificate context from the unsigned, encoded certificate
3386  * in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
3387  */
3389  HCRYPTPROV hProv, DWORD dwKeySpec, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
3390 {
3392  BOOL ret;
3393  DWORD sigSize = 0;
3394 
3396  blob->pbData, blob->cbData, sigAlgo, NULL, NULL, &sigSize);
3397  if (ret)
3398  {
3399  LPBYTE sig = CryptMemAlloc(sigSize);
3400 
3402  blob->pbData, blob->cbData, sigAlgo, NULL, sig, &sigSize);
3403  if (ret)
3404  {
3405  CERT_SIGNED_CONTENT_INFO signedInfo;
3406  BYTE *encodedSignedCert = NULL;
3407  DWORD encodedSignedCertSize = 0;
3408 
3409  signedInfo.ToBeSigned.cbData = blob->cbData;
3410  signedInfo.ToBeSigned.pbData = blob->pbData;
3411  signedInfo.SignatureAlgorithm = *sigAlgo;
3412  signedInfo.Signature.cbData = sigSize;
3413  signedInfo.Signature.pbData = sig;
3414  signedInfo.Signature.cUnusedBits = 0;
3416  &signedInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL,
3417  &encodedSignedCert, &encodedSignedCertSize);
3418  if (ret)
3419  {
3421  encodedSignedCert, encodedSignedCertSize);
3422  LocalFree(encodedSignedCert);
3423  }
3424  }
3425  CryptMemFree(sig);
3426  }
3427  return context;
3428 }
3429 
3430 /* Copies data from the parameters into info, where:
3431  * pSerialNumber: The serial number. Must not be NULL.
3432  * pSubjectIssuerBlob: Specifies both the subject and issuer for info.
3433  * Must not be NULL
3434  * pSignatureAlgorithm: Optional.
3435  * pStartTime: The starting time of the certificate. If NULL, the current
3436  * system time is used.
3437  * pEndTime: The ending time of the certificate. If NULL, one year past the
3438  * starting time is used.
3439  * pubKey: The public key of the certificate. Must not be NULL.
3440  * pExtensions: Extensions to be included with the certificate. Optional.
3441  */
3442 static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNumber,
3443  const CERT_NAME_BLOB *pSubjectIssuerBlob,
3444  const CRYPT_ALGORITHM_IDENTIFIER *pSignatureAlgorithm, const SYSTEMTIME *pStartTime,
3445  const SYSTEMTIME *pEndTime, const CERT_PUBLIC_KEY_INFO *pubKey,
3446  const CERT_EXTENSIONS *pExtensions)
3447 {
3448  static CHAR oid[] = szOID_RSA_SHA1RSA;
3449 
3450  assert(info);
3451  assert(pSerialNumber);
3452  assert(pSubjectIssuerBlob);
3453  assert(pubKey);
3454 
3455  if (pExtensions && pExtensions->cExtension)
3456  info->dwVersion = CERT_V3;
3457  else
3458  info->dwVersion = CERT_V1;
3459  info->SerialNumber.cbData = pSerialNumber->cbData;
3460  info->SerialNumber.pbData = pSerialNumber->pbData;
3461  if (pSignatureAlgorithm)
3462  info->SignatureAlgorithm = *pSignatureAlgorithm;
3463  else
3464  {
3465  info->SignatureAlgorithm.pszObjId = oid;
3466  info->SignatureAlgorithm.Parameters.cbData = 0;
3467  info->SignatureAlgorithm.Parameters.pbData = NULL;
3468  }
3469  info->Issuer.cbData = pSubjectIssuerBlob->cbData;
3470  info->Issuer.pbData = pSubjectIssuerBlob->pbData;
3471  if (pStartTime)
3472  SystemTimeToFileTime(pStartTime, &info->NotBefore);
3473  else
3474  GetSystemTimeAsFileTime(&info->NotBefore);
3475  if (pEndTime)
3476  SystemTimeToFileTime(pEndTime, &info->NotAfter);
3477  else
3478  {
3479  SYSTEMTIME endTime;
3480 
3481  if (FileTimeToSystemTime(&info->NotBefore, &endTime))
3482  {
3483  endTime.wYear++;
3484  SystemTimeToFileTime(&endTime, &info->NotAfter);
3485  }
3486  }
3487  info->Subject.cbData = pSubjectIssuerBlob->cbData;
3488  info->Subject.pbData = pSubjectIssuerBlob->pbData;
3489  info->SubjectPublicKeyInfo = *pubKey;
3490  if (pExtensions)
3491  {
3492  info->cExtension = pExtensions->cExtension;
3493  info->rgExtension = pExtensions->rgExtension;
3494  }
3495  else
3496  {
3497  info->cExtension = 0;
3498  info->rgExtension = NULL;
3499  }
3500 }
3501 
3503 typedef RPC_STATUS (RPC_ENTRY *UuidToStringFunc)(UUID *, unsigned char **);
3504 typedef RPC_STATUS (RPC_ENTRY *RpcStringFreeFunc)(unsigned char **);
3505 
3507 {
3508  HCRYPTPROV hProv = 0;
3509  HMODULE rpcrt = LoadLibraryA("rpcrt4");
3510 
3511  if (rpcrt)
3512  {
3513  UuidCreateFunc uuidCreate = (UuidCreateFunc)GetProcAddress(rpcrt,
3514  "UuidCreate");
3515  UuidToStringFunc uuidToString = (UuidToStringFunc)GetProcAddress(rpcrt,
3516  "UuidToStringA");
3518  rpcrt, "RpcStringFreeA");
3519 
3520  if (uuidCreate && uuidToString && rpcStringFree)
3521  {
3522  UUID uuid;
3523  RPC_STATUS status = uuidCreate(&uuid);
3524 
3526  {
3527  unsigned char *uuidStr;
3528 
3529  status = uuidToString(&uuid, &uuidStr);
3530  if (status == RPC_S_OK)
3531  {
3532  BOOL ret = CryptAcquireContextA(&hProv, (LPCSTR)uuidStr,
3534 
3535  if (ret)
3536  {
3537  HCRYPTKEY key;
3538 
3540  if (ret)
3542  }
3543  rpcStringFree(&uuidStr);
3544  }
3545  }
3546  }
3547  FreeLibrary(rpcrt);
3548  }
3549  return hProv;
3550 }
3551 
3553  PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags,
3554  PCRYPT_KEY_PROV_INFO pKeyProvInfo,
3555  PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime,
3556  PSYSTEMTIME pEndTime, PCERT_EXTENSIONS pExtensions)
3557 {
3559  BOOL ret, releaseContext = FALSE;
3561  DWORD pubKeySize = 0, dwKeySpec;
3562 
3563  TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
3564  pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
3565  pExtensions, pExtensions);
3566 
3567  if(!pSubjectIssuerBlob)
3568  {
3570  return NULL;
3571  }
3572 
3573  dwKeySpec = pKeyProvInfo ? pKeyProvInfo->dwKeySpec : AT_SIGNATURE;
3574  if (!hProv)
3575  {
3576  if (!pKeyProvInfo)
3577  {
3579  releaseContext = TRUE;
3580  }
3581  else if (pKeyProvInfo->dwFlags & CERT_SET_KEY_PROV_HANDLE_PROP_ID)
3582  {
3584  return NULL;
3585  }
3586  else
3587  {
3588  HCRYPTKEY hKey = 0;
3589  /* acquire the context using the given information*/
3591  pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
3592  pKeyProvInfo->dwFlags);
3593  if (!ret)
3594  {
3595  if(GetLastError() != NTE_BAD_KEYSET)
3596  return NULL;
3597  /* create the key set */
3599  pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
3600  pKeyProvInfo->dwFlags|CRYPT_NEWKEYSET);
3601  if (!ret)
3602  return NULL;
3603  }
3604  /* check if the key is here */
3605  ret = CryptGetUserKey(hProv,dwKeySpec,&hKey);
3606  if(!ret)
3607  {
3608  if (NTE_NO_KEY == GetLastError())
3609  { /* generate the key */
3610  ret = CryptGenKey(hProv,dwKeySpec,0,&hKey);
3611  }
3612  if (!ret)
3613  {
3616  return NULL;
3617  }
3618  }
3619  CryptDestroyKey(hKey);
3620  releaseContext = TRUE;
3621  }
3622  }
3623 
3625  &pubKeySize);
3626  if (!ret)
3627  goto end;
3628  pubKey = CryptMemAlloc(pubKeySize);
3629  if (pubKey)
3630  {
3632  pubKey, &pubKeySize);
3633  if (ret)
3634  {
3635  CERT_INFO info = { 0 };
3636  CRYPT_DER_BLOB blob = { 0, NULL };
3637  BYTE serial[16];
3638  CRYPT_DATA_BLOB serialBlob = { sizeof(serial), serial };
3639 
3640  CryptGenRandom(hProv, sizeof(serial), serial);
3641  CRYPT_MakeCertInfo(&info, &serialBlob, pSubjectIssuerBlob,
3642  pSignatureAlgorithm, pStartTime, pEndTime, pubKey, pExtensions);
3644  &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &blob.pbData,
3645  &blob.cbData);
3646  if (ret)
3647  {
3649  context = CRYPT_CreateSignedCert(&blob, hProv,dwKeySpec,
3650  &info.SignatureAlgorithm);
3651  else
3653  blob.pbData, blob.cbData);
3655  CertContext_SetKeyProvInfo(context, pKeyProvInfo, hProv);
3656  LocalFree(blob.pbData);
3657  }
3658  }
3660  }
3661 end:
3662  if (releaseContext)
3664  return context;
3665 }
3666 
3668  void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags,
3669  PCTL_VERIFY_USAGE_PARA pVerifyUsagePara,
3670  PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus)
3671 {
3672  FIXME("(0x%x, %d, %p, %p, 0x%x, %p, %p): stub\n", dwEncodingType,
3673  dwSubjectType, pvSubject, pSubjectUsage, dwFlags, pVerifyUsagePara,
3674  pVerifyUsageStatus);
3676  return FALSE;
3677 }
3678 
3679 const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType,
3680  const BYTE *pbEncoded, DWORD cbEncoded,
3682 {
3683  TRACE("(0x%x, 0x%x, %p, %d, 0x%08x, %p)\n", dwContextType, dwEncodingType,
3684  pbEncoded, cbEncoded, dwFlags, pCreatePara);
3685 
3686  if (dwFlags)
3687  {
3688  FIXME("dwFlags 0x%08x not handled\n", dwFlags);
3689  return NULL;
3690  }
3691  if (pCreatePara)
3692  {
3693  FIXME("pCreatePara not handled\n");
3694  return NULL;
3695  }
3696 
3697  switch (dwContextType)
3698  {
3702  return CertCreateCRLContext(dwEncodingType, pbEncoded, cbEncoded);
3704  return CertCreateCTLContext(dwEncodingType, pbEncoded, cbEncoded);
3705  default:
3706  WARN("unknown context type: 0x%x\n", dwContextType);
3707  return NULL;
3708  }
3709 }
3710 
3712  DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData)
3713 {
3714  FIXME("(%p, 0x%x, 0x%x, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags,
3715  debugstr_w(pwszComputerName), pvReserved, pvData);
3716  return FALSE;
3717 }
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 * u
Definition: glfuncs.h:240
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC
Definition: bcrypt.h:82
#define CERT_V3
Definition: wincrypt.h:2658
PCERT_RDN_ATTR rgRDNAttr
Definition: wincrypt.h:263
#define CRYPT_E_ASN1_BADTAG
Definition: winerror.h:3095
PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, PCERT_INFO pCertId)
Definition: cert.c:1831
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define CERT_SET_KEY_CONTEXT_PROP_ID
Definition: wincrypt.h:3595
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1765
Definition: cache.c:46
static const char * szProvider
Definition: rsaenh.c:36
GLenum func
Definition: glext.h:6028
void Context_CopyProperties(const void *to, const void *from)
Definition: context.c:123
Definition: bug.cpp:7
LPWSTR pwszContainerName
Definition: wincrypt.h:209
void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id) DECLSPEC_HIDDEN
Definition: proplist.c:149
#define CRYPT_ACQUIRE_USE_PROV_INFO_FLAG
Definition: wincrypt.h:3602
PCCERT_CONTEXT(* CertFindFunc)(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1562
HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
Definition: oid.c:114
#define CERT_COMPARE_NAME
Definition: wincrypt.h:2843
#define szOID_KEY_USAGE
Definition: wincrypt.h:3185
CERT_CONTEXT ctx
#define CERT_ENROLLMENT_PROP_ID
Definition: wincrypt.h:2712
static context_t * context_from_ptr(const void *ptr)
static BOOL cert_prov_info_matches_cert(PCCERT_CONTEXT pCert)
Definition: cert.c:1132
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
BOOL(* CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1364
#define CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID
Definition: wincrypt.h:2711
#define PP_PROVTYPE
Definition: wincrypt.h:2096
struct _CTL_USAGE CERT_ENHKEY_USAGE
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2070
struct list * prev
Definition: list.h:39
WINECRYPT_CERTSTORE empty_store
Definition: store.c:1509
#define TRUE
Definition: types.h:120
static HCRYPTPROV CRYPT_CreateKeyProv(void)
Definition: cert.c:3506
#define NTE_NO_KEY
Definition: winerror.h:2881
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: store.c:1172
#define PP_CONTAINER
Definition: wincrypt.h:2087
DWORD cIndexes
Definition: cert.c:3122
static const BYTE crl[]
Definition: message.c:864
#define matches(FN)
Definition: match.h:70
#define CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
Definition: wincrypt.h:2486
CERT_NAME_BLOB DirectoryName
Definition: wincrypt.h:338
static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: cert.c:678
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define CRYPT_HASH_ALG_OID_GROUP_ID
Definition: wincrypt.h:1684
#define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT
Definition: wincrypt.h:3469
#define X509_ENHANCED_KEY_USAGE
Definition: wincrypt.h:3403
#define CRYPT_E_NOT_FOUND
Definition: winerror.h:3007
unsigned int ALG_ID
Definition: wincrypt.h:45
static BOOL find_matching_provider(PCCERT_CONTEXT pCert, DWORD dwFlags)
Definition: cert.c:1063
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:6286
_In_ HCRYPTHASH hHash
Definition: wincrypt.h:4198
#define CERT_FIND_SHA1_HASH
Definition: wincrypt.h:2865
#define CERT_V1
Definition: wincrypt.h:2656
#define CERT_CERT_PROP_ID
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
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:2664
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1510
Definition: image.c:133
static BOOL container_matches_cert(PCCERT_CONTEXT pCert, LPCSTR container, CRYPT_KEY_PROV_INFO *keyProvInfo)
Definition: cert.c:994
BYTE * pbCertEncoded
Definition: wincrypt.h:480
static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
Definition: cert.c:2513
#define CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL
Definition: wincrypt.h:3476
Definition: http.c:6587
#define CERT_COMPARE_ISSUER_OF
Definition: wincrypt.h:2854
BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, PCERT_PUBLIC_KEY_INFO pPublicKey)
Definition: cert.c:2427
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define X509_ECC_SIGNATURE
Definition: wincrypt.h:3417
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo)
Definition: decode.c:6278
Definition: match.c:28
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob, HCRYPTPROV hProv, DWORD dwKeySpec, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
Definition: cert.c:3388
DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz)
Definition: str.c:702
#define CERT_ALT_NAME_DIRECTORY_NAME
Definition: wincrypt.h:349
static const context_vtbl_t cert_vtbl
Definition: cert.c:118
#define CRYPT_SILENT
Definition: wincrypt.h:2073
#define NTE_BAD_ALGID
Definition: winerror.h:2876
_In_ void _In_ PCCERT_CONTEXT pIssuer
Definition: wincrypt.h:6081
BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:99
static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:431
static DWORD CRYPT_significantBytes(const CRYPT_INTEGER_BLOB *pInt)
Definition: cert.c:1205
BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
Definition: cert.c:1934
#define CP_ACP
Definition: compat.h:99
#define CERT_COMPARE_SHIFT
Definition: wincrypt.h:2839
BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, const BYTE *pbData, size_t cbData) DECLSPEC_HIDDEN
Definition: proplist.c:95
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
Definition: cert.c:286
BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, PCRYPT_DATA_BLOB blob) DECLSPEC_HIDDEN
Definition: proplist.c:72
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
#define CERT_FIND_ISSUER_OF
Definition: wincrypt.h:2903
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
#define CERT_STORE_SIGNATURE_FLAG
Definition: wincrypt.h:3458
NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE handle, DWORD flags)
Definition: bcrypt_main.c:374
LONG NTSTATUS
Definition: precomp.h:26
#define CERT_COMPARE_CERT_ID
Definition: wincrypt.h:2858
DWORD dwCertEncodingType
Definition: wincrypt.h:479
BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN
Definition: encode.c:484
#define CERT_DATE_STAMP_PROP_ID
Definition: wincrypt.h:2713
#define CRYPT_FIRST
Definition: wincrypt.h:2060
BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded)
Definition: encode.c:4696
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:58
Definition: wincrypt.h:332
#define CRYPT_E_SELF_SIGNED
Definition: winerror.h:3010
PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags)
Definition: crl.c:337
#define PP_ENUMCONTAINERS
Definition: wincrypt.h:2083
#define CERT_STORE_REVOCATION_FLAG
Definition: wincrypt.h:3460
NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1052
static BOOL(WINAPI *pCertGetValidUsages)(DWORD
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo
Definition: wincrypt.h:248
const void *WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCERT_CREATE_CONTEXT_PARA pCreatePara)
Definition: cert.c:3679
HCERTSTORE hCertStore
Definition: wincrypt.h:483
static PCCERT_CONTEXT find_cert_by_name_str_a(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1706
_In_ PCCERT_CONTEXT _In_ DWORD dwAddDisposition
Definition: wincrypt.h:4987
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
CRYPT_INTEGER_BLOB SerialNumber
Definition: wincrypt.h:242
NTSTATUS WINAPI BCryptVerifySignature(BCRYPT_KEY_HANDLE, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG)
NTSTATUS WINAPI BCryptImportKeyPair(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *, UCHAR *, ULONG, ULONG)
PCERT_EXTENSION rgExtension
Definition: wincrypt.h:237
#define CERT_ENCODING_TYPE_MASK
Definition: wincrypt.h:2290
#define CRYPT_E_EXISTS
Definition: winerror.h:3008
void Context_AddRef(context_t *context)
Definition: context.c:78
static void CRYPT_SetBitInField(struct BitField *field, DWORD bit)
Definition: cert.c:3128
RPC_STATUS(RPC_ENTRY * RpcStringFreeFunc)(unsigned char **)
Definition: cert.c:3504
#define CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID
Definition: wincrypt.h:2710
GLuint GLuint end
Definition: gl.h:1545
static BOOL CRYPT_IsBitInFieldSet(const struct BitField *field, DWORD bit)
Definition: cert.c:3149
#define CERT_COMPARE_SHA1_HASH
Definition: wincrypt.h:2841
NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags)
Definition: bcrypt_main.c:1071
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:916
#define CRYPT_NEXT
Definition: wincrypt.h:2061
static BOOL CNG_CalcHash(const WCHAR *algorithm, const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **hash_value, DWORD *hash_len)
Definition: cert.c:2474
#define CERT_STORE_ADD_NEW
Definition: wincrypt.h:2482
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define X509_PUBLIC_KEY_INFO
Definition: wincrypt.h:3373
BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert, DWORD dwFlags, void *pvReserved)
Definition: cert.c:1153
char * LPSTR
Definition: xmlstorage.h:182
static BOOL CNG_PrepareSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **sig_value, DWORD *sig_len)
Definition: cert.c:2630
#define CERT_AUTO_ENROLL_PROP_ID
Definition: wincrypt.h:2707
static BOOL compare_cert_by_sha1_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1388
#define lstrlenW
Definition: compat.h:407
#define CERT_STORE_ADD_NEWER
Definition: wincrypt.h:2487
static void * context_ptr(context_t *context)
#define CERT_STORE_TIME_VALIDITY_FLAG
Definition: wincrypt.h:3459
BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:80
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:2216
DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
Definition: chain.c:268
#define CERT_CTL_PROP_ID
BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
Definition: cert.c:881
static BOOL find_key_prov_info_in_provider(PCCERT_CONTEXT pCert, CRYPT_KEY_PROV_INFO *keyProvInfo)
Definition: cert.c:1030
ULONG_PTR HCRYPTPROV_LEGACY
Definition: wincrypt.h:48
void Context_Release(context_t *context)
Definition: context.c:106
BOOL WINAPI CryptGetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1654
BOOL(* addContext)(struct WINE_CRYPTCERTSTORE *, context_t *, context_t *, context_t **, BOOL)
#define CRYPT_E_NO_REVOCATION_DLL
Definition: winerror.h:3020
WINE_UNICODE_INLINE int strncmpW(const WCHAR *str1, const WCHAR *str2, int n)
Definition: unicode.h:235
static HCRYPTPROV hProv
Definition: rsaenh.c:32
CRYPT_DER_BLOB ToBeSigned
Definition: wincrypt.h:613
_In_ PCCERT_CONTEXT _In_ DWORD _Outptr_opt_ PCCERT_CONTEXT * ppStoreContext
Definition: wincrypt.h:4987
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:2305
BOOL WINAPI CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
Definition: crypt.c:705
BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, PCERT_NAME_BLOB pCertName1, PCERT_NAME_BLOB pCertName2)
Definition: cert.c:1180
struct _test_info info[]
Definition: SetCursorPos.c:19
static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1571
_In_ PCCERT_STORE_PROV_FIND_INFO _In_ PCCERT_CONTEXT pPrevCertContext
Definition: wincrypt.h:1279
static const char szContainer[]
Definition: rsaenh.c:35
BOOL WINAPI CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:358
#define CERT_KEY_IDENTIFIER_PROP_ID
Definition: wincrypt.h:2706
static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType, DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
Definition: cert.c:1565
context_t * Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
Definition: context.c:28
#define X509_ASN_ENCODING
Definition: wincrypt.h:2297
#define CERT_ACCESS_STATE_PROP_ID
Definition: wincrypt.h:2700
static struct list oidInfo
Definition: oid.c:1206
#define CERT_ID_SHA1_HASH
Definition: wincrypt.h:3675
#define CRYPT_FIND_MACHINE_KEYSET_FLAG
Definition: wincrypt.h:3608
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
Definition: oid.c:511
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
Definition: ctl.c:363
#define CERT_COMPARE_SIGNATURE_HASH
Definition: wincrypt.h:2856
WORD wYear
Definition: winbase.h:870
long RPC_STATUS
Definition: rpc.h:52
static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
Definition: cert.c:2699
LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, PCERT_INFO pCertInfo)
Definition: cert.c:2158
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
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
static BOOL compare_cert_by_public_key(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara)
Definition: cert.c:1424
static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to, const CRYPT_KEY_PROV_INFO *from)
Definition: cert.c:608
SYSTEMTIME fileTime
Definition: main.cpp:57
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:551
CRYPT_OBJID_BLOB Parameters
Definition: wincrypt.h:127
unsigned char * LPBYTE
Definition: typedefs.h:52
NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags)
Definition: bcrypt_main.c:332
BOOL WINAPI CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1615
static BOOL find_matching_rdn_attr(DWORD dwFlags, const CERT_NAME_INFO *