1 /**
2  * Windows API header module
3  *
4  * Translated from MinGW Windows headers
5  *
6  * Authors: Stewart Gordon
7  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source: $(DRUNTIMESRC core/sys/windows/_wincrypt.d)
9  */
10 module core.sys.windows.wincrypt;
11 version (Windows):
12 pragma(lib, "advapi32");
13 
14 version (ANSI) {} else version = Unicode;
15 
16 import core.sys.windows.w32api, core.sys.windows.winbase, core.sys.windows.windef;
17 
18 /* FIXME:
19  *  Types of some constants
20  *  Types of macros
21  *  Inits of various "size" and "version" members
22  *  Why are some #ifdefs commented out?
23  */
24 
25 const TCHAR[]
26     MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0",
27     MS_ENHANCED_PROV = "Microsoft Enhanced Cryptographic Provider v1.0",
28     MS_STRONG_PROV = "Microsoft Strong Cryptographic Provider",
29     MS_DEF_RSA_SIG_PROV = "Microsoft RSA Signature Cryptographic Provider",
30     MS_DEF_RSA_SCHANNEL_PROV = "Microsoft RSA SChannel Cryptographic Provider",
31     MS_DEF_DSS_PROV = "Microsoft Base DSS Cryptographic Provider",
32     MS_DEF_DSS_DH_PROV
33       = "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider",
34     MS_ENH_DSS_DH_PROV
35       = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider",
36     MS_DEF_DH_SCHANNEL_PROV = "Microsoft DH SChannel Cryptographic Provider",
37     MS_SCARD_PROV = "Microsoft Base Smart Card Crypto Provider";
38 
39 static if (_WIN32_WINNT > 0x501) {
40 const TCHAR[] MS_ENH_RSA_AES_PROV
41       = "Microsoft Enhanced RSA and AES Cryptographic Provider";
42 } else static if (_WIN32_WINNT == 0x501) {
43 const TCHAR[] MS_ENH_RSA_AES_PROV
44       = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)";
45 }
46 
47 ALG_ID GET_ALG_CLASS(ALG_ID x) { return x & 0xE000; }
48 ALG_ID GET_ALG_TYPE (ALG_ID x) { return x & 0x1E00; }
49 ALG_ID GET_ALG_SID  (ALG_ID x) { return x & 0x01FF; }
50 
51 enum : ALG_ID {
52     ALG_CLASS_ANY           = 0,
53     ALG_CLASS_SIGNATURE     = 0x2000,
54     ALG_CLASS_MSG_ENCRYPT   = 0x4000,
55     ALG_CLASS_DATA_ENCRYPT  = 0x6000,
56     ALG_CLASS_HASH          = 0x8000,
57     ALG_CLASS_KEY_EXCHANGE  = 0xA000,
58     ALG_CLASS_ALL           = 0xE000
59 }
60 
61 enum : ALG_ID {
62     ALG_TYPE_ANY           = 0,
63     ALG_TYPE_DSS           = 0x0200,
64     ALG_TYPE_RSA           = 0x0400,
65     ALG_TYPE_BLOCK         = 0x0600,
66     ALG_TYPE_STREAM        = 0x0800,
67     ALG_TYPE_DH            = 0x0A00,
68     ALG_TYPE_SECURECHANNEL = 0x0C00
69 }
70 
71 enum : ALG_ID {
72     ALG_SID_ANY          =  0,
73     ALG_SID_RSA_ANY      =  0,
74     ALG_SID_RSA_PKCS,
75     ALG_SID_RSA_MSATWORK,
76     ALG_SID_RSA_ENTRUST,
77     ALG_SID_RSA_PGP,  // =  4
78     ALG_SID_DSS_ANY      =  0,
79     ALG_SID_DSS_PKCS,
80     ALG_SID_DSS_DMS,  // =  2
81     ALG_SID_DES          =  1,
82     ALG_SID_3DES         =  3,
83     ALG_SID_DESX,
84     ALG_SID_IDEA,
85     ALG_SID_CAST,
86     ALG_SID_SAFERSK64,
87     ALG_SID_SAFERSK128,
88     ALG_SID_3DES_112,
89     ALG_SID_SKIPJACK,
90     ALG_SID_TEK,
91     ALG_SID_CYLINK_MEK,
92     ALG_SID_RC5,      // = 13
93     ALG_SID_RC2          =  2,
94     ALG_SID_RC4          =  1,
95     ALG_SID_SEAL         =  2,
96     ALG_SID_MD2          =  1,
97     ALG_SID_MD4,
98     ALG_SID_MD5,
99     ALG_SID_SHA,
100     ALG_SID_MAC,
101     ALG_SID_RIPEMD,
102     ALG_SID_RIPEMD160,
103     ALG_SID_SSL3SHAMD5,
104     ALG_SID_HMAC,
105     ALG_SID_TLS1PRF,  // = 10
106     ALG_SID_AES_128      = 14,
107     ALG_SID_AES_192,
108     ALG_SID_AES_256,
109     ALG_SID_AES,      // = 17
110     ALG_SID_EXAMPLE      = 80
111 }
112 
113 enum : ALG_ID {
114     CALG_MD2        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2,
115     CALG_MD4        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4,
116     CALG_MD5        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5,
117     CALG_SHA        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA,
118     CALG_SHA1       = CALG_SHA,
119     CALG_MAC        = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC,
120     CALG_3DES       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 3,
121     CALG_CYLINK_MEK = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 12,
122     CALG_SKIPJACK   = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 10,
123     CALG_KEA_KEYX   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS | 4,
124     CALG_RSA_SIGN   = ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY,
125     CALG_DSS_SIGN   = ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY,
126     CALG_RSA_KEYX   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY,
127     CALG_DES        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES,
128     CALG_RC2        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2,
129     CALG_RC4        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4,
130     CALG_SEAL       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL,
131     CALG_DH_EPHEM   = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS
132                       | ALG_SID_DSS_DMS,
133     CALG_DESX       = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX,
134 // is undefined ALG_CLASS_DHASH in MinGW - presuming typo
135     CALG_TLS1PRF    = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF,
136     CALG_AES_128    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128,
137     CALG_AES_192    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192,
138     CALG_AES_256    = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256,
139     CALG_AES        = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES,
140 }
141 
142 enum {
143     CRYPT_VERIFYCONTEXT = 0xF0000000,
144 }
145 
146 enum {
147     CRYPT_NEWKEYSET = 8,
148     CRYPT_DELETEKEYSET = 16,
149     CRYPT_MACHINE_KEYSET = 32,
150     CRYPT_SILENT = 64,
151 }
152 
153 enum {
154     CRYPT_EXPORTABLE = 1,
155     CRYPT_USER_PROTECTED = 2,
156     CRYPT_CREATE_SALT = 4,
157     CRYPT_UPDATE_KEY = 8,
158 }
159 
160 enum {
161     SIMPLEBLOB = 1,
162     PUBLICKEYBLOB = 6,
163     PRIVATEKEYBLOB = 7,
164     PLAINTEXTKEYBLOB = 8,
165     OPAQUEKEYBLOB = 9,
166     PUBLICKEYBLOBEX = 10,
167     SYMMETRICWRAPKEYBLOB = 11,
168 }
169 
170 enum {
171     AT_KEYEXCHANGE = 1,
172     AT_SIGNATURE = 2,
173 }
174 
175 enum {
176     CRYPT_USERDATA = 1,
177 }
178 
179 enum {
180     PKCS5_PADDING = 1,
181 }
182 
183 enum {
184     CRYPT_MODE_CBC = 1,
185     CRYPT_MODE_ECB = 2,
186     CRYPT_MODE_OFB = 3,
187     CRYPT_MODE_CFB = 4,
188     CRYPT_MODE_CTS = 5,
189     CRYPT_MODE_CBCI = 6,
190     CRYPT_MODE_CFBP = 7,
191     CRYPT_MODE_OFBP = 8,
192     CRYPT_MODE_CBCOFM = 9,
193     CRYPT_MODE_CBCOFMI = 10,
194 }
195 
196 enum {
197     CRYPT_ENCRYPT = 1,
198     CRYPT_DECRYPT = 2,
199     CRYPT_EXPORT = 4,
200     CRYPT_READ = 8,
201     CRYPT_WRITE = 16,
202     CRYPT_MAC = 32,
203 }
204 
205 enum {
206     HP_ALGID = 1,
207     HP_HASHVAL = 2,
208     HP_HASHSIZE = 4,
209     HP_HMAC_INFO = 5,
210 }
211 
212 enum {
213     CRYPT_FAILED = FALSE,
214     CRYPT_SUCCEED = TRUE,
215 }
216 
217 bool RCRYPT_SUCCEEDED(BOOL r) { return r==CRYPT_SUCCEED; }
218 bool RCRYPT_FAILED(BOOL r) { return r==CRYPT_FAILED; }
219 
220 enum {
221     PP_ENUMALGS = 1,
222     PP_ENUMCONTAINERS = 2,
223     PP_IMPTYPE = 3,
224     PP_NAME = 4,
225     PP_VERSION = 5,
226     PP_CONTAINER = 6,
227     PP_CHANGE_PASSWORD  = 7,
228     PP_KEYSET_SEC_DESCR = 8,
229     PP_CERTCHAIN    = 9,
230     PP_KEY_TYPE_SUBTYPE = 10,
231     PP_PROVTYPE = 16,
232     PP_KEYSTORAGE   = 17,
233     PP_APPLI_CERT   = 18,
234     PP_SYM_KEYSIZE  = 19,
235     PP_SESSION_KEYSIZE  = 20,
236     PP_UI_PROMPT    = 21,
237     PP_ENUMALGS_EX  = 22,
238     PP_ENUMMANDROOTS = 25,
239     PP_ENUMELECTROOTS = 26,
240     PP_KEYSET_TYPE = 27,
241     PP_ADMIN_PIN = 31,
242     PP_KEYEXCHANGE_PIN = 32,
243     PP_SIGNATURE_PIN = 33,
244     PP_SIG_KEYSIZE_INC = 34,
245     PP_KEYX_KEYSIZE_INC = 35,
246     PP_UNIQUE_CONTAINER = 36,
247     PP_SGC_INFO = 37,
248     PP_USE_HARDWARE_RNG = 38,
249     PP_KEYSPEC = 39,
250     PP_ENUMEX_SIGNING_PROT = 40,
251 }
252 
253 enum {
254     CRYPT_FIRST = 1,
255     CRYPT_NEXT = 2,
256 }
257 
258 enum {
259     CRYPT_IMPL_HARDWARE = 1,
260     CRYPT_IMPL_SOFTWARE = 2,
261     CRYPT_IMPL_MIXED = 3,
262     CRYPT_IMPL_UNKNOWN = 4,
263 }
264 
265 enum {
266     PROV_RSA_FULL = 1,
267     PROV_RSA_SIG = 2,
268     PROV_DSS = 3,
269     PROV_FORTEZZA = 4,
270     PROV_MS_MAIL = 5,
271     PROV_SSL = 6,
272     PROV_STT_MER = 7,
273     PROV_STT_ACQ = 8,
274     PROV_STT_BRND = 9,
275     PROV_STT_ROOT = 10,
276     PROV_STT_ISS = 11,
277     PROV_RSA_SCHANNEL = 12,
278     PROV_DSS_DH = 13,
279     PROV_EC_ECDSA_SIG = 14,
280     PROV_EC_ECNRA_SIG = 15,
281     PROV_EC_ECDSA_FULL = 16,
282     PROV_EC_ECNRA_FULL = 17,
283     PROV_DH_SCHANNEL = 18,
284     PROV_SPYRUS_LYNKS = 20,
285     PROV_RNG = 21,
286     PROV_INTEL_SEC = 22,
287     PROV_RSA_AES = 24,
288     MAXUIDLEN = 64,
289 }
290 
291 enum {
292     CUR_BLOB_VERSION = 2,
293 }
294 
295 enum {
296     X509_ASN_ENCODING = 1,
297     PKCS_7_ASN_ENCODING  = 65536,
298 }
299 
300 enum {
301     CERT_V1 = 0,
302     CERT_V2 = 1,
303     CERT_V3 = 2,
304 }
305 
306 enum {
307     CERT_E_CHAINING = (-2146762486),
308     CERT_E_CN_NO_MATCH = (-2146762481),
309     CERT_E_EXPIRED = (-2146762495),
310     CERT_E_PURPOSE = (-2146762490),
311     CERT_E_REVOCATION_FAILURE = (-2146762482),
312     CERT_E_REVOKED = (-2146762484),
313     CERT_E_ROLE = (-2146762493),
314     CERT_E_UNTRUSTEDROOT = (-2146762487),
315     CERT_E_UNTRUSTEDTESTROOT = (-2146762483),
316     CERT_E_VALIDITYPERIODNESTING = (-2146762494),
317     CERT_E_WRONG_USAGE = (-2146762480),
318     CERT_E_PATHLENCONST = (-2146762492),
319     CERT_E_CRITICAL = (-2146762491),
320     CERT_E_ISSUERCHAINING = (-2146762489),
321     CERT_E_MALFORMED = (-2146762488),
322     CRYPT_E_REVOCATION_OFFLINE = (-2146885613),
323     CRYPT_E_REVOKED = (-2146885616),
324     TRUST_E_BASIC_CONSTRAINTS = (-2146869223),
325     TRUST_E_CERT_SIGNATURE = (-2146869244),
326     TRUST_E_FAIL = (-2146762485),
327 }
328 
329 enum {
330     CERT_TRUST_NO_ERROR = 0,
331     CERT_TRUST_IS_NOT_TIME_VALID = 1,
332     CERT_TRUST_IS_NOT_TIME_NESTED = 2,
333     CERT_TRUST_IS_REVOKED = 4,
334     CERT_TRUST_IS_NOT_SIGNATURE_VALID = 8,
335     CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 16,
336     CERT_TRUST_IS_UNTRUSTED_ROOT = 32,
337     CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 64,
338     CERT_TRUST_IS_CYCLIC = 128,
339     CERT_TRUST_IS_PARTIAL_CHAIN = 65536,
340     CERT_TRUST_CTL_IS_NOT_TIME_VALID = 131072,
341     CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 262144,
342     CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 524288,
343 }
344 
345 enum {
346     CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 1,
347     CERT_TRUST_HAS_KEY_MATCH_ISSUER = 2,
348     CERT_TRUST_HAS_NAME_MATCH_ISSUER = 4,
349     CERT_TRUST_IS_SELF_SIGNED = 8,
350     CERT_TRUST_IS_COMPLEX_CHAIN = 65536,
351 }
352 
353 enum {
354     CERT_CHAIN_POLICY_BASE              = cast(LPCSTR) 1,
355     CERT_CHAIN_POLICY_AUTHENTICODE      = cast(LPCSTR) 2,
356     CERT_CHAIN_POLICY_AUTHENTICODE_TS   = cast(LPCSTR) 3,
357     CERT_CHAIN_POLICY_SSL               = cast(LPCSTR) 4,
358     CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = cast(LPCSTR) 5,
359     CERT_CHAIN_POLICY_NT_AUTH           = cast(LPCSTR) 6,
360 }
361 
362 enum {
363     USAGE_MATCH_TYPE_AND = 0,
364     USAGE_MATCH_TYPE_OR = 1,
365 }
366 
367 enum {
368     CERT_SIMPLE_NAME_STR = 1,
369     CERT_OID_NAME_STR = 2,
370     CERT_X500_NAME_STR = 3,
371 }
372 enum {
373     CERT_NAME_STR_SEMICOLON_FLAG = 1073741824,
374     CERT_NAME_STR_CRLF_FLAG = 134217728,
375     CERT_NAME_STR_NO_PLUS_FLAG = 536870912,
376     CERT_NAME_STR_NO_QUOTING_FLAG = 268435456,
377     CERT_NAME_STR_REVERSE_FLAG = 33554432,
378     CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 131072,
379 }
380 
381 enum {
382     CERT_FIND_ANY = 0,
383     CERT_FIND_CERT_ID = 1048576,
384     CERT_FIND_CTL_USAGE = 655360,
385     CERT_FIND_ENHKEY_USAGE = 655360,
386     CERT_FIND_EXISTING = 851968,
387     CERT_FIND_HASH = 65536,
388     CERT_FIND_ISSUER_ATTR = 196612,
389     CERT_FIND_ISSUER_NAME = 131076,
390     CERT_FIND_ISSUER_OF = 786432,
391     CERT_FIND_KEY_IDENTIFIER = 983040,
392     CERT_FIND_KEY_SPEC = 589824,
393     CERT_FIND_MD5_HASH = 262144,
394     CERT_FIND_PROPERTY = 327680,
395     CERT_FIND_PUBLIC_KEY = 393216,
396     CERT_FIND_SHA1_HASH = 65536,
397     CERT_FIND_SIGNATURE_HASH = 917504,
398     CERT_FIND_SUBJECT_ATTR = 196615,
399     CERT_FIND_SUBJECT_CERT = 720896,
400     CERT_FIND_SUBJECT_NAME = 131079,
401     CERT_FIND_SUBJECT_STR_A = 458759,
402     CERT_FIND_SUBJECT_STR_W = 524295,
403     CERT_FIND_ISSUER_STR_A = 458756,
404     CERT_FIND_ISSUER_STR_W = 524292,
405 }
406 
407 enum {
408     CERT_FIND_OR_ENHKEY_USAGE_FLAG = 16,
409     CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG  = 1,
410     CERT_FIND_NO_ENHKEY_USAGE_FLAG  = 8,
411     CERT_FIND_VALID_ENHKEY_USAGE_FLAG  = 32,
412     CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG  = 2,
413 }
414 
415 enum {
416     CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG  = 2,
417     CERT_UNICODE_IS_RDN_ATTRS_FLAG = 1,
418     CERT_CHAIN_FIND_BY_ISSUER = 1,
419 }
420 
421 enum {
422     CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG = 1,
423     CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG = 2,
424     CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG = 4,
425     CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG = 8,
426     CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG = 16384,
427     CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG = 32768,
428 }
429 
430 enum {
431     CERT_STORE_PROV_SYSTEM = 10,
432     CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072,
433 }
434 
435 enum {
436     szOID_PKIX_KP_SERVER_AUTH = "4235600",
437     szOID_SERVER_GATED_CRYPTO = "4235658",
438     szOID_SGC_NETSCAPE = "2.16.840.1.113730.4.1",
439     szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2",
440 }
441 
442 enum {
443     CRYPT_NOHASHOID = 0x00000001,
444     CRYPT_NO_SALT = 0x10,
445     CRYPT_PREGEN = 0x40,
446 }
447 
448 enum {
449     CRYPT_RECIPIENT = 0x10,
450     CRYPT_INITIATOR = 0x40,
451     CRYPT_ONLINE = 0x80,
452     CRYPT_SF = 0x100,
453     CRYPT_CREATE_IV = 0x200,
454     CRYPT_KEK = 0x400,
455     CRYPT_DATA_KEY = 0x800,
456     CRYPT_VOLATILE = 0x1000,
457     CRYPT_SGCKEY = 0x2000,
458 }
459 
460 enum {
461     KP_IV               = 0x00000001,
462     KP_SALT             = 0x00000002,
463     KP_PADDING          = 0x00000003,
464     KP_MODE             = 0x00000004,
465     KP_MODE_BITS        = 0x00000005,
466     KP_PERMISSIONS      = 0x00000006,
467     KP_ALGID            = 0x00000007,
468     KP_BLOCKLEN         = 0x00000008,
469     KP_KEYLEN           = 0x00000009,
470     KP_SALT_EX          = 0x0000000a,
471     KP_P                = 0x0000000b,
472     KP_G                = 0x0000000c,
473     KP_Q                = 0x0000000d,
474     KP_X                = 0x0000000e,
475     KP_Y                = 0x0000000f,
476     KP_RA               = 0x00000010,
477     KP_RB               = 0x00000011,
478     KP_INFO             = 0x00000012,
479     KP_EFFECTIVE_KEYLEN = 0x00000013,
480     KP_SCHANNEL_ALG     = 0x00000014,
481     KP_PUB_PARAMS       = 0x00000027,
482 }
483 
484 enum {
485     CRYPT_FLAG_PCT1    = 0x0001,
486     CRYPT_FLAG_SSL2    = 0x0002,
487     CRYPT_FLAG_SSL3    = 0x0004,
488     CRYPT_FLAG_TLS1    = 0x0008,
489     CRYPT_FLAG_IPSEC   = 0x0010,
490     CRYPT_FLAG_SIGNING = 0x0020,
491 }
492 
493 enum {
494     SCHANNEL_MAC_KEY    = 0x00000000,
495     SCHANNEL_ENC_KEY    = 0x00000001,
496 }
497 
498 enum {
499     INTERNATIONAL_USAGE = 0x00000001,
500 }
501 
502 
503 alias UINT ALG_ID;
504 alias ULONG_PTR HCRYPTPROV, HCRYPTKEY, HCRYPTHASH;
505 alias PVOID HCERTSTORE, HCRYPTMSG, HCERTCHAINENGINE;
506 
507 struct VTableProvStruc {
508     FARPROC FuncVerifyImage;
509 }
510 alias VTableProvStruc* PVTableProvStruc;
511 
512 struct _CRYPTOAPI_BLOB {
513     DWORD cbData;
514     BYTE* pbData;
515 }
516 alias _CRYPTOAPI_BLOB CRYPT_INTEGER_BLOB, CRYPT_UINT_BLOB,
517   CRYPT_OBJID_BLOB, CERT_NAME_BLOB, CERT_RDN_VALUE_BLOB, CERT_BLOB,
518   CRL_BLOB, DATA_BLOB, CRYPT_DATA_BLOB, CRYPT_HASH_BLOB,
519   CRYPT_DIGEST_BLOB, CRYPT_DER_BLOB, CRYPT_ATTR_BLOB;
520 alias _CRYPTOAPI_BLOB* PCRYPT_INTEGER_BLOB, PCRYPT_UINT_BLOB,
521   PCRYPT_OBJID_BLOB, PCERT_NAME_BLOB, PCERT_RDN_VALUE_BLOB, PCERT_BLOB,
522   PCRL_BLOB, PDATA_BLOB, PCRYPT_DATA_BLOB, PCRYPT_HASH_BLOB,
523   PCRYPT_DIGEST_BLOB, PCRYPT_DER_BLOB, PCRYPT_ATTR_BLOB;
524 
525 // not described in SDK; has the same layout as HTTPSPolicyCallbackData
526 struct SSL_EXTRA_CERT_CHAIN_POLICY_PARA {
527     DWORD  cbStruct;
528     DWORD  dwAuthType;
529     DWORD  fdwChecks;
530     LPWSTR pwszServerName;
531 }
532 alias SSL_EXTRA_CERT_CHAIN_POLICY_PARA HTTPSPolicyCallbackData;
533 alias SSL_EXTRA_CERT_CHAIN_POLICY_PARA* PSSL_EXTRA_CERT_CHAIN_POLICY_PARA,
534   PHTTPSPolicyCallbackData;
535 
536 /* #if (_WIN32_WINNT>=0x500) */
537 struct CERT_CHAIN_POLICY_PARA {
538     DWORD cbSize = CERT_CHAIN_POLICY_PARA.sizeof;
539     DWORD dwFlags;
540     void* pvExtraPolicyPara;
541 }
542 alias CERT_CHAIN_POLICY_PARA* PCERT_CHAIN_POLICY_PARA;
543 
544 struct CERT_CHAIN_POLICY_STATUS {
545     DWORD cbSize = CERT_CHAIN_POLICY_STATUS.sizeof;
546     DWORD dwError;
547     LONG  lChainIndex;
548     LONG  lElementIndex;
549     void* pvExtraPolicyStatus;
550 }
551 alias CERT_CHAIN_POLICY_STATUS* PCERT_CHAIN_POLICY_STATUS;
552 /* #endif */
553 
554 struct CRYPT_ALGORITHM_IDENTIFIER {
555     LPSTR pszObjId;
556     CRYPT_OBJID_BLOB Parameters;
557 }
558 alias CRYPT_ALGORITHM_IDENTIFIER* PCRYPT_ALGORITHM_IDENTIFIER;
559 
560 struct CRYPT_BIT_BLOB {
561     DWORD cbData;
562     BYTE* pbData;
563     DWORD cUnusedBits;
564 }
565 alias CRYPT_BIT_BLOB* PCRYPT_BIT_BLOB;
566 
567 struct CERT_PUBLIC_KEY_INFO {
568     CRYPT_ALGORITHM_IDENTIFIER Algorithm;
569     CRYPT_BIT_BLOB             PublicKey;
570 }
571 alias CERT_PUBLIC_KEY_INFO* PCERT_PUBLIC_KEY_INFO;
572 
573 struct CERT_EXTENSION {
574     LPSTR            pszObjId;
575     BOOL             fCritical;
576     CRYPT_OBJID_BLOB Value;
577 }
578 alias CERT_EXTENSION* PCERT_EXTENSION;
579 
580 struct CERT_INFO {
581     DWORD dwVersion;
582     CRYPT_INTEGER_BLOB SerialNumber;
583     CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
584     CERT_NAME_BLOB Issuer;
585     FILETIME NotBefore;
586     FILETIME NotAfter;
587     CERT_NAME_BLOB Subject;
588     CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
589     CRYPT_BIT_BLOB IssuerUniqueId;
590     CRYPT_BIT_BLOB SubjectUniqueId;
591     DWORD cExtension;
592     PCERT_EXTENSION rgExtension;
593 }
594 alias CERT_INFO* PCERT_INFO;
595 
596 struct CERT_CONTEXT {
597     DWORD      dwCertEncodingType;
598     BYTE*      pbCertEncoded;
599     DWORD      cbCertEncoded;
600     PCERT_INFO pCertInfo;
601     HCERTSTORE hCertStore;
602 }
603 alias CERT_CONTEXT*        PCERT_CONTEXT;
604 alias const(CERT_CONTEXT)* PCCERT_CONTEXT;
605 
606 struct CTL_USAGE {
607     DWORD  cUsageIdentifier;
608     LPSTR* rgpszUsageIdentifier;
609 }
610 alias CTL_USAGE CERT_ENHKEY_USAGE;
611 alias CTL_USAGE* PCTRL_USAGE, PCERT_ENHKEY_USAGE;
612 
613 struct CERT_USAGE_MATCH {
614     DWORD             dwType;
615     CERT_ENHKEY_USAGE Usage;
616 }
617 alias CERT_USAGE_MATCH* PCERT_USAGE_MATCH;
618 /* #if (_WIN32_WINNT>=0x500) */
619 
620 struct CERT_CHAIN_PARA {
621     DWORD            cbSize = CERT_CHAIN_PARA.sizeof;
622     CERT_USAGE_MATCH RequestedUsage;
623 //#if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS
624     CERT_USAGE_MATCH RequestedIssuancePolicy;
625     DWORD            dwUrlRetrievalTimeout;
626     BOOL             fCheckRevocationFreshnessTime;
627     DWORD            dwRevocationFreshnessTime;
628 //#endif
629 }
630 alias CERT_CHAIN_PARA* PCERT_CHAIN_PARA;
631 
632 extern (Windows) alias BOOL function(PCCERT_CONTEXT, void*)
633   PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK;
634 
635 struct CERT_CHAIN_FIND_BY_ISSUER_PARA {
636     DWORD  cbSize = CERT_CHAIN_FIND_BY_ISSUER_PARA.sizeof;
637     LPCSTR pszUsageIdentifier;
638     DWORD  dwKeySpec;
639     DWORD  dwAcquirePrivateKeyFlags;
640     DWORD  cIssuer;
641     CERT_NAME_BLOB* rgIssuer;
642     PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK pfnFIndCallback;
643     void*  pvFindArg;
644     DWORD* pdwIssuerChainIndex;
645     DWORD* pdwIssuerElementIndex;
646 }
647 alias CERT_CHAIN_FIND_BY_ISSUER_PARA* PCERT_CHAIN_FIND_BY_ISSUER_PARA;
648 /* #endif */
649 
650 struct CERT_TRUST_STATUS {
651     DWORD dwErrorStatus;
652     DWORD dwInfoStatus;
653 }
654 alias CERT_TRUST_STATUS* PCERT_TRUST_STATUS;
655 
656 struct CRL_ENTRY {
657     CRYPT_INTEGER_BLOB SerialNumber;
658     FILETIME           RevocationDate;
659     DWORD              cExtension;
660     PCERT_EXTENSION    rgExtension;
661 }
662 alias CRL_ENTRY* PCRL_ENTRY;
663 
664 struct CRL_INFO {
665     DWORD           dwVersion;
666     CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
667     CERT_NAME_BLOB  Issuer;
668     FILETIME        ThisUpdate;
669     FILETIME        NextUpdate;
670     DWORD           cCRLEntry;
671     PCRL_ENTRY      rgCRLEntry;
672     DWORD           cExtension;
673     PCERT_EXTENSION rgExtension;
674 }
675 alias CRL_INFO* PCRL_INFO;
676 
677 struct CRL_CONTEXT {
678     DWORD      dwCertEncodingType;
679     BYTE*      pbCrlEncoded;
680     DWORD      cbCrlEncoded;
681     PCRL_INFO  pCrlInfo;
682     HCERTSTORE hCertStore;
683 }
684 alias CRL_CONTEXT*        PCRL_CONTEXT;
685 alias const(CRL_CONTEXT)* PCCRL_CONTEXT;
686 
687 struct CERT_REVOCATION_CRL_INFO {
688     DWORD         cbSize = CERT_REVOCATION_CRL_INFO.sizeof;
689     PCCRL_CONTEXT pBaseCRLContext;
690     PCCRL_CONTEXT pDeltaCRLContext;
691     PCRL_ENTRY    pCrlEntry;
692     BOOL          fDeltaCrlEntry;
693 }
694 alias CERT_REVOCATION_CRL_INFO* PCERT_REVOCATION_CRL_INFO;
695 
696 struct CERT_REVOCATION_INFO {
697     DWORD  cbSize = CERT_REVOCATION_INFO.sizeof;
698     DWORD  dwRevocationResult;
699     LPCSTR pszRevocationOid;
700     LPVOID pvOidSpecificInfo;
701     BOOL   fHasFreshnessTime;
702     DWORD  dwFreshnessTime;
703     PCERT_REVOCATION_CRL_INFO pCrlInfo;
704 }
705 alias CERT_REVOCATION_INFO* PCERT_REVOCATION_INFO;
706 
707 /* #if (_WIN32_WINNT>=0x500) */
708 struct CERT_CHAIN_ELEMENT {
709     DWORD                 cbSize = CERT_CHAIN_ELEMENT.sizeof;
710     PCCERT_CONTEXT        pCertContext;
711     CERT_TRUST_STATUS     TrustStatus;
712     PCERT_REVOCATION_INFO pRevocationInfo;
713     PCERT_ENHKEY_USAGE    pIssuanceUsage;
714     PCERT_ENHKEY_USAGE    pApplicationUsage;
715 }
716 alias CERT_CHAIN_ELEMENT* PCERT_CHAIN_ELEMENT;
717 /* #endif */
718 
719 struct CRYPT_ATTRIBUTE {
720     LPSTR            pszObjId;
721     DWORD            cValue;
722     PCRYPT_ATTR_BLOB rgValue;
723 }
724 alias CRYPT_ATTRIBUTE* PCRYPT_ATTRIBUTE;
725 
726 struct CTL_ENTRY {
727     CRYPT_DATA_BLOB  SubjectIdentifier;
728     DWORD            cAttribute;
729     PCRYPT_ATTRIBUTE rgAttribute;
730 }
731 alias CTL_ENTRY* PCTL_ENTRY;
732 
733 struct CTL_INFO {
734     DWORD              dwVersion;
735     CTL_USAGE          SubjectUsage;
736     CRYPT_DATA_BLOB    ListIdentifier;
737     CRYPT_INTEGER_BLOB SequenceNumber;
738     FILETIME           ThisUpdate;
739     FILETIME           NextUpdate;
740     CRYPT_ALGORITHM_IDENTIFIER SubjectAlgorithm;
741     DWORD              cCTLEntry;
742     PCTL_ENTRY         rgCTLEntry;
743     DWORD              cExtension;
744     PCERT_EXTENSION    rgExtension;
745 }
746 alias CTL_INFO* PCTL_INFO;
747 
748 struct CTL_CONTEXT {
749     DWORD      dwMsgAndCertEncodingType;
750     BYTE*      pbCtlEncoded;
751     DWORD      cbCtlEncoded;
752     PCTL_INFO  pCtlInfo;
753     HCERTSTORE hCertStore;
754     HCRYPTMSG  hCryptMsg;
755     BYTE*      pbCtlContent;
756     DWORD      cbCtlContent;
757 }
758 alias CTL_CONTEXT*        PCTL_CONTEXT;
759 alias const(CTL_CONTEXT)* PCCTL_CONTEXT;
760 
761 struct CERT_TRUST_LIST_INFO {
762     DWORD         cbSize = CERT_TRUST_LIST_INFO.sizeof;
763     PCTL_ENTRY    pCtlEntry;
764     PCCTL_CONTEXT pCtlContext;
765 }
766 alias CERT_TRUST_LIST_INFO* PCERT_TRUST_LIST_INFO;
767 
768 struct CERT_SIMPLE_CHAIN {
769     DWORD                 cbSize = CERT_SIMPLE_CHAIN.sizeof;
770     CERT_TRUST_STATUS     TrustStatus;
771     DWORD                 cElement;
772     PCERT_CHAIN_ELEMENT*  rgpElement;
773     PCERT_TRUST_LIST_INFO pTrustListInfo;
774     BOOL                  fHasRevocationFreshnessTime;
775     DWORD                 dwRevocationFreshnessTime;
776 }
777 alias CERT_SIMPLE_CHAIN* PCERT_SIMPLE_CHAIN;
778 
779 /* #if (_WIN32_WINNT>=0x500) */
780 alias const(CERT_CHAIN_CONTEXT)* PCCERT_CHAIN_CONTEXT;
781 struct CERT_CHAIN_CONTEXT {
782     DWORD                 cbSize = CERT_CHAIN_CONTEXT.sizeof;
783     CERT_TRUST_STATUS     TrustStatus;
784     DWORD                 cChain;
785     PCERT_SIMPLE_CHAIN*   rgpChain;
786     DWORD                 cLowerQualityChainContext;
787     PCCERT_CHAIN_CONTEXT* rgpLowerQualityChainContext;
788     BOOL                  fHasRevocationFreshnessTime;
789     DWORD                 dwRevocationFreshnessTime;
790 }
791 alias CERT_CHAIN_CONTEXT* PCERT_CHAIN_CONTEXT;
792 /* #endif */
793 
794 struct PROV_ENUMALGS {
795     ALG_ID   aiAlgid;
796     DWORD    dwBitLen;
797     DWORD    dwNameLen;
798     CHAR[20] szName = 0;
799 }
800 
801 struct PUBLICKEYSTRUC {
802     BYTE   bType;
803     BYTE   bVersion;
804     WORD   reserved;
805     ALG_ID aiKeyAlg;
806 }
807 alias PUBLICKEYSTRUC BLOBHEADER;
808 
809 struct RSAPUBKEY {
810     DWORD magic;
811     DWORD bitlen;
812     DWORD pubexp;
813 }
814 
815 struct HMAC_INFO {
816     ALG_ID HashAlgid;
817     BYTE*  pbInnerString;
818     DWORD  cbInnerString;
819     BYTE*  pbOuterString;
820     DWORD  cbOuterString;
821 }
822 alias HMAC_INFO* PHMAC_INFO;
823 
824 extern (Windows) @nogc nothrow {
825     BOOL CertCloseStore(HCERTSTORE, DWORD);
826     BOOL CertGetCertificateChain(HCERTCHAINENGINE, PCCERT_CONTEXT, LPFILETIME,
827       HCERTSTORE, PCERT_CHAIN_PARA, DWORD, LPVOID, PCCERT_CHAIN_CONTEXT*);
828     BOOL CertVerifyCertificateChainPolicy(LPCSTR, PCCERT_CHAIN_CONTEXT,
829       PCERT_CHAIN_POLICY_PARA, PCERT_CHAIN_POLICY_STATUS);
830     void CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT);
831     DWORD CertNameToStrA(DWORD, PCERT_NAME_BLOB, DWORD, LPSTR, DWORD);
832     DWORD CertNameToStrW(DWORD, PCERT_NAME_BLOB, DWORD, LPWSTR, DWORD);
833     HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV, LPCSTR);
834     HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV, LPCWSTR);
835     HCERTSTORE CertOpenStore(LPCSTR, DWORD, HCRYPTPROV, DWORD, const(void)*);
836     PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE, DWORD, DWORD, DWORD,
837 const(void)*, PCCERT_CONTEXT);
838     BOOL CertFreeCertificateContext(PCCERT_CONTEXT);
839     PCCERT_CONTEXT CertGetIssuerCertificateFromStore(HCERTSTORE,
840       PCCERT_CONTEXT, PCCERT_CONTEXT, DWORD*);
841     PCCERT_CHAIN_CONTEXT CertFindChainInStore(HCERTSTORE, DWORD, DWORD, DWORD,
842 const(void)*, PCCERT_CHAIN_CONTEXT);
843 
844     BOOL CryptAcquireContextA(HCRYPTPROV*, LPCSTR, LPCSTR, DWORD, DWORD);
845     BOOL CryptAcquireContextW(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD);
846      BOOL CryptContextAddRef(HCRYPTPROV, DWORD*, DWORD);
847     BOOL CryptReleaseContext(HCRYPTPROV, ULONG_PTR);
848     BOOL CryptGenKey(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*);
849     BOOL CryptDeriveKey(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*);
850     BOOL CryptDestroyKey(HCRYPTKEY);
851     static if (_WIN32_WINNT >= 0x500) {
852         BOOL CryptDuplicateHash(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
853         BOOL CryptDuplicateKey(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*);
854     }
855     BOOL CryptSetKeyParam(HCRYPTKEY, DWORD, PBYTE, DWORD);
856     BOOL CryptGetKeyParam(HCRYPTKEY, DWORD, PBYTE, PDWORD, DWORD);
857     BOOL CryptSetHashParam(HCRYPTHASH, DWORD, PBYTE, DWORD);
858     BOOL CryptGetHashParam(HCRYPTHASH, DWORD, PBYTE, PDWORD, DWORD);
859     BOOL CryptSetProvParam(HCRYPTPROV, DWORD, PBYTE, DWORD);
860     BOOL CryptGetProvParam(HCRYPTPROV, DWORD, PBYTE, PDWORD, DWORD);
861     BOOL CryptGenRandom(HCRYPTPROV, DWORD, PBYTE);
862     BOOL CryptGetUserKey(HCRYPTPROV, DWORD, HCRYPTKEY*);
863     BOOL CryptExportKey(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, PBYTE, PDWORD);
864     BOOL CryptImportKey(HCRYPTPROV, PBYTE, DWORD, HCRYPTKEY, DWORD,
865       HCRYPTKEY*);
866     BOOL CryptEncrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD,
867       DWORD);
868     BOOL CryptDecrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD);
869     BOOL CryptCreateHash(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);
870     BOOL CryptHashData(HCRYPTHASH, PBYTE, DWORD, DWORD);
871     BOOL CryptHashSessionKey(HCRYPTHASH, HCRYPTKEY, DWORD);
872     BOOL CryptGetHashValue(HCRYPTHASH, DWORD, PBYTE, PDWORD);
873     BOOL CryptDestroyHash(HCRYPTHASH);
874     BOOL CryptSignHashA(HCRYPTHASH, DWORD, LPCSTR, DWORD, PBYTE, PDWORD);
875     BOOL CryptSignHashW(HCRYPTHASH, DWORD, LPCWSTR, DWORD, PBYTE, PDWORD);
876     BOOL CryptVerifySignatureA(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCSTR,
877       DWORD);
878     BOOL CryptVerifySignatureW(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCWSTR,
879       DWORD);
880     BOOL CryptSetProviderA(LPCSTR, DWORD);
881     BOOL CryptSetProviderW(LPCWSTR, DWORD);
882 }
883 
884 version (Unicode) {
885     alias CertNameToStrW CertNameToStr;
886     alias CryptAcquireContextW CryptAcquireContext;
887     alias CryptSignHashW CryptSignHash;
888     alias CryptVerifySignatureW CryptVerifySignature;
889     alias CryptSetProviderW CryptSetProvider;
890     alias CertOpenSystemStoreW CertOpenSystemStore;
891     /+alias CERT_FIND_SUBJECT_STR_W CERT_FIND_SUBJECT_STR;
892     alias CERT_FIND_ISSUER_STR_W CERT_FIND_ISSUER_STR;+/
893 } else {
894     alias CertNameToStrA CertNameToStr;
895     alias CryptAcquireContextA CryptAcquireContext;
896     alias CryptSignHashA CryptSignHash;
897     alias CryptVerifySignatureA CryptVerifySignature;
898     alias CryptSetProviderA CryptSetProvider;
899     alias CertOpenSystemStoreA CertOpenSystemStore;
900     /+alias CERT_FIND_SUBJECT_STR_A CERT_FIND_SUBJECT_STR;
901     alias CERT_FIND_ISSUER_STR_A CERT_FIND_ISSUER_STR;+/
902 }