2 * Copyright 2006 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
28 /* This represents a subset of a certificate chain engine: it doesn't include
29 * the "hOther" store described by MSDN, because I'm not sure how that's used.
30 * It also doesn't include the "hTrust" store, because I don't yet implement
31 * CTLs or complex certificate chains.
33 typedef struct _CertificateChainEngine
39 DWORD dwUrlRetrievalTimeout
;
40 DWORD MaximumCachedCertificates
;
41 DWORD CycleDetectionModulus
;
42 } CertificateChainEngine
, *PCertificateChainEngine
;
44 static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection
,
45 DWORD cStores
, HCERTSTORE
*stores
)
49 for (i
= 0; i
< cStores
; i
++)
50 CertAddStoreToCollection(collection
, stores
[i
], 0, 0);
53 static inline void CRYPT_CloseStores(DWORD cStores
, HCERTSTORE
*stores
)
57 for (i
= 0; i
< cStores
; i
++)
58 CertCloseStore(stores
[i
], 0);
61 static const WCHAR rootW
[] = { 'R','o','o','t',0 };
63 static BOOL
CRYPT_CheckRestrictedRoot(HCERTSTORE store
)
69 HCERTSTORE rootStore
= CertOpenSystemStoreW(0, rootW
);
70 PCCERT_CONTEXT cert
= NULL
, check
;
75 cert
= CertEnumCertificatesInStore(store
, cert
);
80 ret
= CertGetCertificateContextProperty(cert
, CERT_HASH_PROP_ID
,
84 CRYPT_HASH_BLOB blob
= { sizeof(hash
), hash
};
86 check
= CertFindCertificateInStore(rootStore
,
87 cert
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
92 CertFreeCertificateContext(check
);
95 } while (ret
&& cert
);
97 CertFreeCertificateContext(cert
);
98 CertCloseStore(rootStore
, 0);
103 BOOL WINAPI
CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig
,
104 HCERTCHAINENGINE
*phChainEngine
)
106 static const WCHAR caW
[] = { 'C','A',0 };
107 static const WCHAR myW
[] = { 'M','y',0 };
108 static const WCHAR trustW
[] = { 'T','r','u','s','t',0 };
111 TRACE("(%p, %p)\n", pConfig
, phChainEngine
);
113 if (pConfig
->cbSize
!= sizeof(*pConfig
))
115 SetLastError(E_INVALIDARG
);
118 *phChainEngine
= NULL
;
119 ret
= CRYPT_CheckRestrictedRoot(pConfig
->hRestrictedRoot
);
122 PCertificateChainEngine engine
=
123 CryptMemAlloc(sizeof(CertificateChainEngine
));
127 HCERTSTORE worldStores
[4];
130 if (pConfig
->hRestrictedRoot
)
131 engine
->hRoot
= CertDuplicateStore(pConfig
->hRestrictedRoot
);
133 engine
->hRoot
= CertOpenSystemStoreW(0, rootW
);
134 engine
->hWorld
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
135 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
136 worldStores
[0] = CertDuplicateStore(engine
->hRoot
);
137 worldStores
[1] = CertOpenSystemStoreW(0, caW
);
138 worldStores
[2] = CertOpenSystemStoreW(0, myW
);
139 worldStores
[3] = CertOpenSystemStoreW(0, trustW
);
140 CRYPT_AddStoresToCollection(engine
->hWorld
,
141 sizeof(worldStores
) / sizeof(worldStores
[0]), worldStores
);
142 CRYPT_AddStoresToCollection(engine
->hWorld
,
143 pConfig
->cAdditionalStore
, pConfig
->rghAdditionalStore
);
144 CRYPT_CloseStores(sizeof(worldStores
) / sizeof(worldStores
[0]),
146 engine
->dwFlags
= pConfig
->dwFlags
;
147 engine
->dwUrlRetrievalTimeout
= pConfig
->dwUrlRetrievalTimeout
;
148 engine
->MaximumCachedCertificates
=
149 pConfig
->MaximumCachedCertificates
;
150 engine
->CycleDetectionModulus
= pConfig
->CycleDetectionModulus
;
151 *phChainEngine
= (HCERTCHAINENGINE
)engine
;
160 void WINAPI
CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine
)
162 PCertificateChainEngine engine
= (PCertificateChainEngine
)hChainEngine
;
164 TRACE("(%p)\n", hChainEngine
);
166 if (engine
&& InterlockedDecrement(&engine
->ref
) == 0)
168 CertCloseStore(engine
->hWorld
, 0);
169 CertCloseStore(engine
->hRoot
, 0);
170 CryptMemFree(engine
);