2 * Copyright 2001 Rein Klazes
3 * Copyright 2007 Juan Lang
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
36 #include "wintrust_priv.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(wintrust
);
42 /***********************************************************************
43 * DllMain (WINTRUST.@)
45 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
49 case DLL_PROCESS_ATTACH
:
50 DisableThreadLibraryCalls( inst
);
56 /***********************************************************************
57 * TrustIsCertificateSelfSigned (WINTRUST.@)
59 BOOL WINAPI
TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert
)
64 ret
= CertCompareCertificateName(cert
->dwCertEncodingType
,
65 &cert
->pCertInfo
->Subject
, &cert
->pCertInfo
->Issuer
);
69 static LONG
WINTRUST_DefaultVerify(HWND hwnd
, GUID
*actionID
,
72 DWORD err
= ERROR_SUCCESS
;
73 CRYPT_PROVIDER_DATA
*provData
;
76 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
78 provData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA
));
81 provData
->cbStruct
= sizeof(CRYPT_PROVIDER_DATA
);
83 provData
->padwTrustStepErrors
=
84 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
85 if (!provData
->padwTrustStepErrors
)
87 provData
->cdwTrustStepErrors
= TRUSTERROR_MAX_STEPS
;
89 provData
->u
.pPDSip
= WINTRUST_Alloc(sizeof(PROVDATA_SIP
));
90 if (!provData
->u
.pPDSip
)
92 provData
->u
.pPDSip
->cbStruct
= sizeof(PROVDATA_SIP
);
94 provData
->psPfns
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS
));
95 if (!provData
->psPfns
)
97 provData
->psPfns
->cbStruct
= sizeof(CRYPT_PROVIDER_FUNCTIONS
);
98 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
101 err
= GetLastError();
105 data
->hWVTStateData
= (HANDLE
)provData
;
106 provData
->pWintrustData
= data
;
107 if (hwnd
== INVALID_HANDLE_VALUE
)
108 provData
->hWndParent
= GetDesktopWindow();
110 provData
->hWndParent
= hwnd
;
111 provData
->pgActionID
= actionID
;
112 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
114 if (provData
->psPfns
->pfnInitialize
)
116 err
= provData
->psPfns
->pfnInitialize(provData
);
120 if (provData
->psPfns
->pfnObjectTrust
)
122 err
= provData
->psPfns
->pfnObjectTrust(provData
);
126 if (provData
->psPfns
->pfnSignatureTrust
)
128 err
= provData
->psPfns
->pfnSignatureTrust(provData
);
132 if (provData
->psPfns
->pfnCertificateTrust
)
134 err
= provData
->psPfns
->pfnCertificateTrust(provData
);
138 if (provData
->psPfns
->pfnFinalPolicy
)
139 err
= provData
->psPfns
->pfnFinalPolicy(provData
);
143 err
= ERROR_OUTOFMEMORY
;
147 WINTRUST_Free(provData
->padwTrustStepErrors
);
148 WINTRUST_Free(provData
->u
.pPDSip
);
149 WINTRUST_Free(provData
->psPfns
);
150 WINTRUST_Free(provData
);
153 TRACE("returning %08x\n", err
);
157 static LONG
WINTRUST_DefaultClose(HWND hwnd
, GUID
*actionID
,
160 DWORD err
= ERROR_SUCCESS
;
161 CRYPT_PROVIDER_DATA
*provData
= (CRYPT_PROVIDER_DATA
*)data
->hWVTStateData
;
163 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
167 if (provData
->psPfns
->pfnCleanupPolicy
)
168 err
= provData
->psPfns
->pfnCleanupPolicy(provData
);
170 WINTRUST_Free(provData
->padwTrustStepErrors
);
171 WINTRUST_Free(provData
->u
.pPDSip
);
172 WINTRUST_Free(provData
->psPfns
);
173 WINTRUST_Free(provData
);
174 data
->hWVTStateData
= NULL
;
176 TRACE("returning %08x\n", err
);
180 static LONG
WINTRUST_DefaultVerifyAndClose(HWND hwnd
, GUID
*actionID
,
185 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
187 err
= WINTRUST_DefaultVerify(hwnd
, actionID
, data
);
188 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
189 TRACE("returning %08x\n", err
);
193 static LONG
WINTRUST_PublishedSoftware(HWND hwnd
, GUID
*actionID
,
196 WINTRUST_DATA wintrust_data
= { sizeof(wintrust_data
), 0 };
197 /* Undocumented: the published software action is passed a path,
198 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
200 LPCWSTR path
= (LPCWSTR
)data
->u
.pFile
;
201 LPWIN_TRUST_SUBJECT_FILE subjectFile
=
202 (LPWIN_TRUST_SUBJECT_FILE
)data
->pSIPClientData
;
203 WINTRUST_FILE_INFO fileInfo
= { sizeof(fileInfo
), 0 };
205 TRACE("subjectFile->hFile: %p\n", subjectFile
->hFile
);
206 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile
->lpPath
));
207 fileInfo
.pcwszFilePath
= path
;
208 fileInfo
.hFile
= subjectFile
->hFile
;
209 wintrust_data
.u
.pFile
= &fileInfo
;
210 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
211 wintrust_data
.dwUIChoice
= WTD_UI_NONE
;
213 return WINTRUST_DefaultVerifyAndClose(hwnd
, actionID
, &wintrust_data
);
216 static void dump_file_info(WINTRUST_FILE_INFO
*pFile
)
218 TRACE("%p\n", pFile
);
221 TRACE("cbStruct: %d\n", pFile
->cbStruct
);
222 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile
->pcwszFilePath
));
223 TRACE("hFile: %p\n", pFile
->hFile
);
224 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile
->pgKnownSubject
));
228 static void dump_catalog_info(WINTRUST_CATALOG_INFO
*catalog
)
230 TRACE("%p\n", catalog
);
233 TRACE("cbStruct: %d\n", catalog
->cbStruct
);
234 TRACE("dwCatalogVersion: %d\n", catalog
->dwCatalogVersion
);
235 TRACE("pcwszCatalogFilePath: %s\n",
236 debugstr_w(catalog
->pcwszCatalogFilePath
));
237 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog
->pcwszMemberTag
));
238 TRACE("pcwszMemberFilePath: %s\n",
239 debugstr_w(catalog
->pcwszMemberFilePath
));
240 TRACE("hMemberFile: %p\n", catalog
->hMemberFile
);
241 TRACE("pbCalculatedFileHash: %p\n", catalog
->pbCalculatedFileHash
);
242 TRACE("cbCalculatedFileHash: %d\n", catalog
->cbCalculatedFileHash
);
243 TRACE("pcCatalogContext: %p\n", catalog
->pcCatalogContext
);
247 static void dump_blob_info(WINTRUST_BLOB_INFO
*blob
)
252 TRACE("cbStruct: %d\n", blob
->cbStruct
);
253 TRACE("gSubject: %s\n", debugstr_guid(&blob
->gSubject
));
254 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob
->pcwszDisplayName
));
255 TRACE("cbMemObject: %d\n", blob
->cbMemObject
);
256 TRACE("pbMemObject: %p\n", blob
->pbMemObject
);
257 TRACE("cbMemSignedMsg: %d\n", blob
->cbMemSignedMsg
);
258 TRACE("pbMemSignedMsg: %p\n", blob
->pbMemSignedMsg
);
262 static void dump_sgnr_info(WINTRUST_SGNR_INFO
*sgnr
)
267 TRACE("cbStruct: %d\n", sgnr
->cbStruct
);
268 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr
->pcwszDisplayName
));
269 TRACE("psSignerInfo: %p\n", sgnr
->psSignerInfo
);
270 TRACE("chStores: %d\n", sgnr
->chStores
);
274 static void dump_cert_info(WINTRUST_CERT_INFO
*cert
)
279 TRACE("cbStruct: %d\n", cert
->cbStruct
);
280 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert
->pcwszDisplayName
));
281 TRACE("psCertContext: %p\n", cert
->psCertContext
);
282 TRACE("chStores: %d\n", cert
->chStores
);
283 TRACE("dwFlags: %08x\n", cert
->dwFlags
);
284 TRACE("psftVerifyAsOf: %p\n", cert
->psftVerifyAsOf
);
288 static void dump_wintrust_data(WINTRUST_DATA
*data
)
293 TRACE("cbStruct: %d\n", data
->cbStruct
);
294 TRACE("pPolicyCallbackData: %p\n", data
->pPolicyCallbackData
);
295 TRACE("pSIPClientData: %p\n", data
->pSIPClientData
);
296 TRACE("dwUIChoice: %d\n", data
->dwUIChoice
);
297 TRACE("fdwRevocationChecks: %08x\n", data
->fdwRevocationChecks
);
298 TRACE("dwUnionChoice: %d\n", data
->dwUnionChoice
);
299 switch (data
->dwUnionChoice
)
301 case WTD_CHOICE_FILE
:
302 dump_file_info(data
->u
.pFile
);
304 case WTD_CHOICE_CATALOG
:
305 dump_catalog_info(data
->u
.pCatalog
);
307 case WTD_CHOICE_BLOB
:
308 dump_blob_info(data
->u
.pBlob
);
310 case WTD_CHOICE_SIGNER
:
311 dump_sgnr_info(data
->u
.pSgnr
);
313 case WTD_CHOICE_CERT
:
314 dump_cert_info(data
->u
.pCert
);
317 TRACE("dwStateAction: %d\n", data
->dwStateAction
);
318 TRACE("hWVTStateData: %p\n", data
->hWVTStateData
);
319 TRACE("pwszURLReference: %s\n", debugstr_w(data
->pwszURLReference
));
320 TRACE("dwProvFlags: %08x\n", data
->dwProvFlags
);
321 TRACE("dwUIContext: %d\n", data
->dwUIContext
);
325 /***********************************************************************
326 * WinVerifyTrust (WINTRUST.@)
328 * Verifies an object by calling the specified trust provider.
331 * hwnd [I] Handle to a caller window.
332 * ActionID [I] Pointer to a GUID that identifies the action to perform.
333 * ActionData [I] Information used by the trust provider to verify the object.
337 * Failure: A TRUST_E_* error code.
340 * Trust providers can be found at:
341 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
343 LONG WINAPI
WinVerifyTrust( HWND hwnd
, GUID
*ActionID
, LPVOID ActionData
)
345 static const GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
346 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
347 static const GUID published_software
= WIN_SPUB_ACTION_PUBLISHED_SOFTWARE
;
348 static const GUID generic_verify_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
349 static const GUID generic_cert_verify
= WINTRUST_ACTION_GENERIC_CERT_VERIFY
;
350 static const GUID generic_chain_verify
= WINTRUST_ACTION_GENERIC_CHAIN_VERIFY
;
351 LONG err
= ERROR_SUCCESS
;
352 WINTRUST_DATA
*actionData
= (WINTRUST_DATA
*)ActionData
;
354 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(ActionID
), ActionData
);
355 dump_wintrust_data(ActionData
);
357 /* Support for known old-style callers: */
358 if (IsEqualGUID(ActionID
, &published_software
))
359 err
= WINTRUST_PublishedSoftware(hwnd
, ActionID
, ActionData
);
362 /* Check known actions to warn of possible problems */
363 if (!IsEqualGUID(ActionID
, &unknown
) &&
364 !IsEqualGUID(ActionID
, &generic_verify_v2
) &&
365 !IsEqualGUID(ActionID
, &generic_cert_verify
) &&
366 !IsEqualGUID(ActionID
, &generic_chain_verify
))
367 WARN("unknown action %s, default behavior may not be right\n",
368 debugstr_guid(ActionID
));
369 switch (actionData
->dwStateAction
)
371 case WTD_STATEACTION_IGNORE
:
372 err
= WINTRUST_DefaultVerifyAndClose(hwnd
, ActionID
, ActionData
);
374 case WTD_STATEACTION_VERIFY
:
375 err
= WINTRUST_DefaultVerify(hwnd
, ActionID
, ActionData
);
377 case WTD_STATEACTION_CLOSE
:
378 err
= WINTRUST_DefaultClose(hwnd
, ActionID
, ActionData
);
381 FIXME("unimplemented for %d\n", actionData
->dwStateAction
);
385 TRACE("returning %08x\n", err
);
389 /***********************************************************************
390 * WinVerifyTrustEx (WINTRUST.@)
392 HRESULT WINAPI
WinVerifyTrustEx( HWND hwnd
, GUID
*ActionID
,
393 WINTRUST_DATA
* ActionData
)
395 return WinVerifyTrust(hwnd
, ActionID
, ActionData
);
398 /***********************************************************************
399 * WTHelperGetProvSignerFromChain (WINTRUST.@)
401 CRYPT_PROVIDER_SGNR
* WINAPI
WTHelperGetProvSignerFromChain(
402 CRYPT_PROVIDER_DATA
*pProvData
, DWORD idxSigner
, BOOL fCounterSigner
,
403 DWORD idxCounterSigner
)
405 CRYPT_PROVIDER_SGNR
*sgnr
;
407 TRACE("(%p %d %d %d)\n", pProvData
, idxSigner
, fCounterSigner
,
410 if (idxSigner
>= pProvData
->csSigners
|| !pProvData
->pasSigners
)
412 sgnr
= &pProvData
->pasSigners
[idxSigner
];
415 if (idxCounterSigner
>= sgnr
->csCounterSigners
||
416 !sgnr
->pasCounterSigners
)
418 sgnr
= &sgnr
->pasCounterSigners
[idxCounterSigner
];
420 TRACE("returning %p\n", sgnr
);
424 /***********************************************************************
425 * WTHelperGetProvCertFromChain (WINTRUST.@)
427 CRYPT_PROVIDER_CERT
* WINAPI
WTHelperGetProvCertFromChain(
428 CRYPT_PROVIDER_SGNR
*pSgnr
, DWORD idxCert
)
430 CRYPT_PROVIDER_CERT
*cert
;
432 TRACE("(%p %d)\n", pSgnr
, idxCert
);
434 if (idxCert
>= pSgnr
->csCertChain
|| !pSgnr
->pasCertChain
)
436 cert
= &pSgnr
->pasCertChain
[idxCert
];
437 TRACE("returning %p\n", cert
);
441 CRYPT_PROVIDER_PRIVDATA
*WINAPI
WTHelperGetProvPrivateDataFromChain(
442 CRYPT_PROVIDER_DATA
* pProvData
,
445 CRYPT_PROVIDER_PRIVDATA
*privdata
= NULL
;
448 TRACE("(%p, %s)\n", pProvData
, debugstr_guid(pgProviderID
));
450 for (i
= 0; i
< pProvData
->csProvPrivData
; i
++)
451 if (IsEqualGUID(pgProviderID
, &pProvData
->pasProvPrivData
[i
].gProviderID
))
453 privdata
= &pProvData
->pasProvPrivData
[i
];
460 /***********************************************************************
461 * WTHelperProvDataFromStateData (WINTRUST.@)
463 CRYPT_PROVIDER_DATA
* WINAPI
WTHelperProvDataFromStateData(HANDLE hStateData
)
465 TRACE("%p\n", hStateData
);
466 return (CRYPT_PROVIDER_DATA
*)hStateData
;
469 /***********************************************************************
470 * WTHelperGetFileName(WINTRUST.@)
472 LPCWSTR WINAPI
WTHelperGetFileName(WINTRUST_DATA
*data
)
475 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
476 return data
->u
.pFile
->pcwszFilePath
;
481 /***********************************************************************
482 * WTHelperGetFileHandle(WINTRUST.@)
484 HANDLE WINAPI
WTHelperGetFileHandle(WINTRUST_DATA
*data
)
487 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
488 return data
->u
.pFile
->hFile
;
490 return INVALID_HANDLE_VALUE
;
493 static const WCHAR Software_Publishing
[] = {
494 'S','o','f','t','w','a','r','e','\\',
495 'M','i','c','r','o','s','o','f','t','\\',
496 'W','i','n','d','o','w','s','\\',
497 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
498 'W','i','n','t','r','u','s','t','\\',
499 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
500 'S','o','f','t','w','a','r','e',' ',
501 'P','u','b','l','i','s','h','i','n','g',0 };
502 static const WCHAR State
[] = { 'S','t','a','t','e',0 };
504 /***********************************************************************
505 * WintrustGetRegPolicyFlags (WINTRUST.@)
507 void WINAPI
WintrustGetRegPolicyFlags( DWORD
* pdwPolicyFlags
)
512 TRACE("%p\n", pdwPolicyFlags
);
515 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0, NULL
, 0,
516 KEY_READ
, NULL
, &key
, NULL
);
519 DWORD size
= sizeof(DWORD
);
521 r
= RegQueryValueExW(key
, State
, NULL
, NULL
, (LPBYTE
)pdwPolicyFlags
,
526 /* Failed to query, create and return default value */
527 *pdwPolicyFlags
= WTPF_IGNOREREVOCATIONONTS
|
528 WTPF_OFFLINEOKNBU_COM
|
529 WTPF_OFFLINEOKNBU_IND
|
532 WintrustSetRegPolicyFlags(*pdwPolicyFlags
);
537 /***********************************************************************
538 * WintrustSetRegPolicyFlags (WINTRUST.@)
540 BOOL WINAPI
WintrustSetRegPolicyFlags( DWORD dwPolicyFlags
)
545 TRACE("%x\n", dwPolicyFlags
);
547 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0,
548 NULL
, 0, KEY_WRITE
, NULL
, &key
, NULL
);
551 r
= RegSetValueExW(key
, State
, 0, REG_DWORD
, (LPBYTE
)&dwPolicyFlags
,
555 if (r
) SetLastError(r
);
556 return r
== ERROR_SUCCESS
;
559 /* Utility functions */
560 void * WINAPI
WINTRUST_Alloc(DWORD cb
)
562 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cb
);
565 void * WINAPI
WINTRUST_ReAlloc(void *ptr
, DWORD cb
)
567 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ptr
, cb
);
570 void WINAPI
WINTRUST_Free(void *p
)
572 HeapFree(GetProcessHeap(), 0, p
);
575 BOOL WINAPI
WINTRUST_AddStore(CRYPT_PROVIDER_DATA
*data
, HCERTSTORE store
)
580 data
->pahStores
= WINTRUST_ReAlloc(data
->pahStores
,
581 (data
->chStores
+ 1) * sizeof(HCERTSTORE
));
584 data
->pahStores
= WINTRUST_Alloc(sizeof(HCERTSTORE
));
589 data
->pahStores
[data
->chStores
++] = CertDuplicateStore(store
);
593 SetLastError(ERROR_OUTOFMEMORY
);
597 BOOL WINAPI
WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA
*data
,
598 BOOL fCounterSigner
, DWORD idxSigner
, CRYPT_PROVIDER_SGNR
*sgnr
)
602 if (sgnr
->cbStruct
> sizeof(CRYPT_PROVIDER_SGNR
))
604 SetLastError(ERROR_INVALID_PARAMETER
);
609 FIXME("unimplemented for counter signers\n");
610 SetLastError(ERROR_INVALID_PARAMETER
);
614 data
->pasSigners
= WINTRUST_ReAlloc(data
->pasSigners
,
615 (data
->csSigners
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
618 data
->pasSigners
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
621 if (data
->pasSigners
)
623 if (idxSigner
< data
->csSigners
)
624 memmove(&data
->pasSigners
[idxSigner
],
625 &data
->pasSigners
[idxSigner
+ 1],
626 (data
->csSigners
- idxSigner
) * sizeof(CRYPT_PROVIDER_SGNR
));
628 if (sgnr
->cbStruct
== sizeof(CRYPT_PROVIDER_SGNR
))
630 /* The PSDK says psSigner should be allocated using pfnAlloc, but
631 * it doesn't say anything about ownership. Since callers are
632 * internal, assume ownership is passed, and just store the
635 memcpy(&data
->pasSigners
[idxSigner
], sgnr
,
636 sizeof(CRYPT_PROVIDER_SGNR
));
639 memset(&data
->pasSigners
[idxSigner
], 0,
640 sizeof(CRYPT_PROVIDER_SGNR
));
644 SetLastError(ERROR_OUTOFMEMORY
);
648 BOOL WINAPI
WINTRUST_AddCert(CRYPT_PROVIDER_DATA
*data
, DWORD idxSigner
,
649 BOOL fCounterSigner
, DWORD idxCounterSigner
, PCCERT_CONTEXT pCert2Add
)
655 FIXME("unimplemented for counter signers\n");
656 SetLastError(ERROR_INVALID_PARAMETER
);
659 if (data
->pasSigners
[idxSigner
].csCertChain
)
660 data
->pasSigners
[idxSigner
].pasCertChain
=
661 WINTRUST_ReAlloc(data
->pasSigners
[idxSigner
].pasCertChain
,
662 (data
->pasSigners
[idxSigner
].csCertChain
+ 1) *
663 sizeof(CRYPT_PROVIDER_CERT
));
666 data
->pasSigners
[idxSigner
].pasCertChain
=
667 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT
));
668 data
->pasSigners
[idxSigner
].csCertChain
= 0;
670 if (data
->pasSigners
[idxSigner
].pasCertChain
)
672 CRYPT_PROVIDER_CERT
*cert
= &data
->pasSigners
[idxSigner
].pasCertChain
[
673 data
->pasSigners
[idxSigner
].csCertChain
];
675 cert
->cbStruct
= sizeof(CRYPT_PROVIDER_CERT
);
676 cert
->pCert
= CertDuplicateCertificateContext(pCert2Add
);
677 data
->pasSigners
[idxSigner
].csCertChain
++;
681 SetLastError(ERROR_OUTOFMEMORY
);
685 BOOL WINAPI
WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA
*data
,
686 CRYPT_PROVIDER_PRIVDATA
*pPrivData2Add
)
690 TRACE("(%p, %p)\n", data
, pPrivData2Add
);
692 if (pPrivData2Add
->cbStruct
> sizeof(CRYPT_PROVIDER_PRIVDATA
))
694 SetLastError(ERROR_INVALID_PARAMETER
);
695 WARN("invalid struct size\n");
698 if (data
->csProvPrivData
)
699 data
->pasProvPrivData
= WINTRUST_ReAlloc(data
->pasProvPrivData
,
700 (data
->csProvPrivData
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
703 data
->pasProvPrivData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
704 data
->csProvPrivData
= 0;
706 if (data
->pasProvPrivData
)
710 for (i
= 0; i
< data
->csProvPrivData
; i
++)
711 if (IsEqualGUID(&pPrivData2Add
->gProviderID
, &data
->pasProvPrivData
[i
]))
714 data
->pasProvPrivData
[i
] = *pPrivData2Add
;
715 if (i
== data
->csProvPrivData
)
716 data
->csProvPrivData
++;
719 SetLastError(ERROR_OUTOFMEMORY
);