2 * Copyright 2005-2008 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
18 * This file implements ASN.1 DER encoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
47 #include "wine/debug.h"
48 #include "wine/exception.h"
49 #include "wine/unicode.h"
50 #include "crypt32_private.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
53 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
55 typedef BOOL (WINAPI
*CryptEncodeObjectFunc
)(DWORD
, LPCSTR
, const void *,
58 /* Prototypes for built-in encoders. They follow the Ex style prototypes.
59 * The dwCertEncodingType and lpszStructType are ignored by the built-in
60 * functions, but the parameters are retained to simplify CryptEncodeObjectEx,
61 * since it must call functions in external DLLs that follow these signatures.
63 BOOL WINAPI
CRYPT_AsnEncodeOid(DWORD dwCertEncodingType
,
64 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
65 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
66 static BOOL WINAPI
CRYPT_AsnEncodeExtensions(DWORD dwCertEncodingType
,
67 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
68 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
69 static BOOL WINAPI
CRYPT_AsnEncodeSequenceOfAny(DWORD dwCertEncodingType
,
70 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
71 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
72 static BOOL WINAPI
CRYPT_AsnEncodeBool(DWORD dwCertEncodingType
,
73 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
74 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
75 static BOOL WINAPI
CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType
,
76 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
77 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
78 static BOOL WINAPI
CRYPT_AsnEncodeBits(DWORD dwCertEncodingType
,
79 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
80 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
81 static BOOL WINAPI
CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType
,
82 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
83 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
84 static BOOL WINAPI
CRYPT_AsnEncodeInt(DWORD dwCertEncodingType
,
85 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
86 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
87 static BOOL WINAPI
CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType
,
88 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
89 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
90 static BOOL WINAPI
CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType
,
91 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
92 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
93 static BOOL WINAPI
CRYPT_AsnEncodeChoiceOfTime(DWORD dwCertEncodingType
,
94 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
95 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
96 static BOOL WINAPI
CRYPT_AsnEncodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
97 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
98 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
99 static BOOL WINAPI
CRYPT_AsnEncodePKCSAttributes(DWORD dwCertEncodingType
,
100 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
101 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
103 BOOL
CRYPT_EncodeEnsureSpace(DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
,
104 BYTE
*pbEncoded
, DWORD
*pcbEncoded
, DWORD bytesNeeded
)
108 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
110 if (pEncodePara
&& pEncodePara
->pfnAlloc
)
111 *(BYTE
**)pbEncoded
= pEncodePara
->pfnAlloc(bytesNeeded
);
113 *(BYTE
**)pbEncoded
= LocalAlloc(0, bytesNeeded
);
114 if (!*(BYTE
**)pbEncoded
)
117 *pcbEncoded
= bytesNeeded
;
119 else if (bytesNeeded
> *pcbEncoded
)
121 *pcbEncoded
= bytesNeeded
;
122 SetLastError(ERROR_MORE_DATA
);
126 *pcbEncoded
= bytesNeeded
;
130 BOOL
CRYPT_EncodeLen(DWORD len
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
132 DWORD bytesNeeded
, significantBytes
= 0;
140 for (temp
= len
, significantBytes
= sizeof(temp
); !(temp
& 0xff000000);
141 temp
<<= 8, significantBytes
--)
143 bytesNeeded
= significantBytes
+ 1;
147 *pcbEncoded
= bytesNeeded
;
150 if (*pcbEncoded
< bytesNeeded
)
152 SetLastError(ERROR_MORE_DATA
);
156 *pbEncoded
= (BYTE
)len
;
161 *pbEncoded
++ = significantBytes
| 0x80;
162 for (i
= 0; i
< significantBytes
; i
++)
164 *(pbEncoded
+ significantBytes
- i
- 1) = (BYTE
)(len
& 0xff);
168 *pcbEncoded
= bytesNeeded
;
172 BOOL WINAPI
CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType
,
173 struct AsnEncodeSequenceItem items
[], DWORD cItem
, DWORD dwFlags
,
174 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
177 DWORD i
, dataLen
= 0;
179 TRACE("%p, %d, %08x, %p, %p, %d\n", items
, cItem
, dwFlags
, pEncodePara
,
180 pbEncoded
, *pcbEncoded
);
181 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
183 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
184 items
[i
].pvStructInfo
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
,
185 NULL
, &items
[i
].size
);
186 /* Some functions propagate their errors through the size */
188 *pcbEncoded
= items
[i
].size
;
189 dataLen
+= items
[i
].size
;
193 DWORD lenBytes
, bytesNeeded
;
195 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
196 bytesNeeded
= 1 + lenBytes
+ dataLen
;
198 *pcbEncoded
= bytesNeeded
;
201 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
202 pcbEncoded
, bytesNeeded
)))
204 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
205 pbEncoded
= *(BYTE
**)pbEncoded
;
206 *pbEncoded
++ = ASN_SEQUENCE
;
207 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
208 pbEncoded
+= lenBytes
;
209 for (i
= 0; ret
&& i
< cItem
; i
++)
211 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
212 items
[i
].pvStructInfo
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
,
213 NULL
, pbEncoded
, &items
[i
].size
);
214 /* Some functions propagate their errors through the size */
216 *pcbEncoded
= items
[i
].size
;
217 pbEncoded
+= items
[i
].size
;
222 TRACE("returning %d (%08x)\n", ret
, GetLastError());
226 BOOL WINAPI
CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType
,
227 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
228 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
231 const struct AsnConstructedItem
*item
= pvStructInfo
;
234 if ((ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
235 item
->pvStructInfo
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &len
)))
237 DWORD dataLen
, bytesNeeded
;
239 CRYPT_EncodeLen(len
, NULL
, &dataLen
);
240 bytesNeeded
= 1 + dataLen
+ len
;
242 *pcbEncoded
= bytesNeeded
;
243 else if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
244 pbEncoded
, pcbEncoded
, bytesNeeded
)))
246 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
247 pbEncoded
= *(BYTE
**)pbEncoded
;
248 *pbEncoded
++ = ASN_CONTEXT
| ASN_CONSTRUCTOR
| item
->tag
;
249 CRYPT_EncodeLen(len
, pbEncoded
, &dataLen
);
250 pbEncoded
+= dataLen
;
251 ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
252 item
->pvStructInfo
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
,
256 /* Some functions propagate their errors through the size */
263 /* Some functions propagate their errors through the size */
269 struct AsnEncodeTagSwappedItem
272 const void *pvStructInfo
;
273 CryptEncodeObjectExFunc encodeFunc
;
276 /* Sort of a wacky hack, it encodes something using the struct
277 * AsnEncodeTagSwappedItem's encodeFunc, then replaces the tag byte with the tag
278 * given in the struct AsnEncodeTagSwappedItem.
280 static BOOL WINAPI
CRYPT_AsnEncodeSwapTag(DWORD dwCertEncodingType
,
281 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
282 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
285 const struct AsnEncodeTagSwappedItem
*item
= pvStructInfo
;
287 ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
288 item
->pvStructInfo
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
289 if (ret
&& pbEncoded
)
290 *pbEncoded
= item
->tag
;
294 static BOOL WINAPI
CRYPT_AsnEncodeCertVersion(DWORD dwCertEncodingType
,
295 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
296 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
298 const DWORD
*ver
= pvStructInfo
;
301 /* CERT_V1 is not encoded */
309 struct AsnConstructedItem item
= { 0, ver
, CRYPT_AsnEncodeInt
};
311 ret
= CRYPT_AsnEncodeConstructed(dwCertEncodingType
, X509_INTEGER
,
312 &item
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
317 static BOOL WINAPI
CRYPT_CopyEncodedBlob(DWORD dwCertEncodingType
,
318 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
319 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
321 const CRYPT_DER_BLOB
*blob
= pvStructInfo
;
326 *pcbEncoded
= blob
->cbData
;
331 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
332 pcbEncoded
, blob
->cbData
)))
334 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
335 pbEncoded
= *(BYTE
**)pbEncoded
;
337 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
338 *pcbEncoded
= blob
->cbData
;
345 static BOOL WINAPI
CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType
,
346 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
347 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
350 /* This has two filetimes in a row, a NotBefore and a NotAfter */
351 const FILETIME
*timePtr
= pvStructInfo
;
352 struct AsnEncodeSequenceItem items
[] = {
353 { timePtr
, CRYPT_AsnEncodeChoiceOfTime
, 0 },
354 { timePtr
+ 1, CRYPT_AsnEncodeChoiceOfTime
, 0 },
357 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
358 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
363 /* Like CRYPT_AsnEncodeAlgorithmId, but encodes parameters as an asn.1 NULL
366 static BOOL WINAPI
CRYPT_AsnEncodeAlgorithmIdWithNullParams(
367 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
368 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
371 const CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
372 static const BYTE asn1Null
[] = { ASN_NULL
, 0 };
373 static const CRYPT_DATA_BLOB nullBlob
= { sizeof(asn1Null
),
376 struct AsnEncodeSequenceItem items
[2] = {
377 { algo
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
378 { NULL
, CRYPT_CopyEncodedBlob
, 0 },
381 if (algo
->Parameters
.cbData
)
382 items
[1].pvStructInfo
= &algo
->Parameters
;
384 items
[1].pvStructInfo
= &nullBlob
;
385 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
386 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
391 static BOOL WINAPI
CRYPT_AsnEncodeAlgorithmId(DWORD dwCertEncodingType
,
392 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
393 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
395 const CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
397 struct AsnEncodeSequenceItem items
[] = {
398 { algo
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
399 { &algo
->Parameters
, CRYPT_CopyEncodedBlob
, 0 },
402 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
403 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
408 static BOOL WINAPI
CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType
,
409 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
410 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
416 const CERT_PUBLIC_KEY_INFO
*info
= pvStructInfo
;
417 struct AsnEncodeSequenceItem items
[] = {
418 { &info
->Algorithm
, CRYPT_AsnEncodeAlgorithmIdWithNullParams
, 0 },
419 { &info
->PublicKey
, CRYPT_AsnEncodeBits
, 0 },
422 TRACE("Encoding public key with OID %s\n",
423 debugstr_a(info
->Algorithm
.pszObjId
));
424 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
425 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
430 SetLastError(STATUS_ACCESS_VIOLATION
);
437 static BOOL WINAPI
CRYPT_AsnEncodeCert(DWORD dwCertEncodingType
,
438 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
439 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
445 const CERT_SIGNED_CONTENT_INFO
*info
= pvStructInfo
;
446 struct AsnEncodeSequenceItem items
[] = {
447 { &info
->ToBeSigned
, CRYPT_CopyEncodedBlob
, 0 },
448 { &info
->SignatureAlgorithm
, CRYPT_AsnEncodeAlgorithmId
, 0 },
449 { &info
->Signature
, CRYPT_AsnEncodeBitsSwapBytes
, 0 },
452 if (dwFlags
& CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
453 items
[2].encodeFunc
= CRYPT_AsnEncodeBits
;
454 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
455 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
460 SetLastError(STATUS_ACCESS_VIOLATION
);
467 BOOL WINAPI
CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType
,
468 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
469 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
472 const CERT_PUBLIC_KEY_INFO
*info
= pvStructInfo
;
473 struct AsnEncodeSequenceItem items
[] = {
474 { &info
->Algorithm
, CRYPT_AsnEncodeAlgorithmId
, 0 },
475 { &info
->PublicKey
, CRYPT_AsnEncodeBits
, 0 },
478 TRACE("Encoding public key with OID %s\n",
479 debugstr_a(info
->Algorithm
.pszObjId
));
480 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
481 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
486 /* Like in Windows, this blithely ignores the validity of the passed-in
487 * CERT_INFO, and just encodes it as-is. The resulting encoded data may not
488 * decode properly, see CRYPT_AsnDecodeCertInfo.
490 static BOOL WINAPI
CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType
,
491 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
492 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
498 const CERT_INFO
*info
= pvStructInfo
;
499 struct AsnEncodeSequenceItem items
[10] = {
500 { &info
->dwVersion
, CRYPT_AsnEncodeCertVersion
, 0 },
501 { &info
->SerialNumber
, CRYPT_AsnEncodeInteger
, 0 },
502 { &info
->SignatureAlgorithm
, CRYPT_AsnEncodeAlgorithmId
, 0 },
503 { &info
->Issuer
, CRYPT_CopyEncodedBlob
, 0 },
504 { &info
->NotBefore
, CRYPT_AsnEncodeValidity
, 0 },
505 { &info
->Subject
, CRYPT_CopyEncodedBlob
, 0 },
506 { &info
->SubjectPublicKeyInfo
, CRYPT_AsnEncodePubKeyInfoNoNull
, 0 },
509 struct AsnConstructedItem constructed
= { 0 };
510 struct AsnEncodeTagSwappedItem swapped
[2] = { { 0 } };
511 DWORD cItem
= 7, cSwapped
= 0;
513 if (info
->IssuerUniqueId
.cbData
)
515 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 1;
516 swapped
[cSwapped
].pvStructInfo
= &info
->IssuerUniqueId
;
517 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBits
;
518 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
519 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
523 if (info
->SubjectUniqueId
.cbData
)
525 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 2;
526 swapped
[cSwapped
].pvStructInfo
= &info
->SubjectUniqueId
;
527 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBits
;
528 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
529 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
533 if (info
->cExtension
)
536 constructed
.pvStructInfo
= &info
->cExtension
;
537 constructed
.encodeFunc
= CRYPT_AsnEncodeExtensions
;
538 items
[cItem
].pvStructInfo
= &constructed
;
539 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
543 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
544 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
548 SetLastError(STATUS_ACCESS_VIOLATION
);
555 static BOOL
CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY
*entry
,
556 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
558 struct AsnEncodeSequenceItem items
[3] = {
559 { &entry
->SerialNumber
, CRYPT_AsnEncodeInteger
, 0 },
560 { &entry
->RevocationDate
, CRYPT_AsnEncodeChoiceOfTime
, 0 },
566 TRACE("%p, %p, %p\n", entry
, pbEncoded
, pcbEncoded
);
568 if (entry
->cExtension
)
570 items
[cItem
].pvStructInfo
= &entry
->cExtension
;
571 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeExtensions
;
575 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
, cItem
, 0, NULL
,
576 pbEncoded
, pcbEncoded
);
578 TRACE("returning %d (%08x)\n", ret
, GetLastError());
582 static BOOL WINAPI
CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType
,
583 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
584 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
586 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
587 const CRL_INFO
*info
= pvStructInfo
;
588 const CRL_ENTRY
*rgCRLEntry
= info
->rgCRLEntry
;
591 for (i
= 0, dataLen
= 0; ret
&& i
< info
->cCRLEntry
; i
++)
595 ret
= CRYPT_AsnEncodeCRLEntry(&rgCRLEntry
[i
], NULL
, &size
);
601 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
602 bytesNeeded
= 1 + lenBytes
+ dataLen
;
604 *pcbEncoded
= bytesNeeded
;
607 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
608 pcbEncoded
, bytesNeeded
)))
610 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
611 pbEncoded
= *(BYTE
**)pbEncoded
;
612 *pbEncoded
++ = ASN_SEQUENCEOF
;
613 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
614 pbEncoded
+= lenBytes
;
615 for (i
= 0; i
< info
->cCRLEntry
; i
++)
617 DWORD size
= dataLen
;
619 ret
= CRYPT_AsnEncodeCRLEntry(&rgCRLEntry
[i
], pbEncoded
,
630 static BOOL WINAPI
CRYPT_AsnEncodeCRLVersion(DWORD dwCertEncodingType
,
631 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
632 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
634 const DWORD
*ver
= pvStructInfo
;
637 /* CRL_V1 is not encoded */
644 ret
= CRYPT_AsnEncodeInt(dwCertEncodingType
, X509_INTEGER
, ver
,
645 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
649 /* Like in Windows, this blithely ignores the validity of the passed-in
650 * CRL_INFO, and just encodes it as-is. The resulting encoded data may not
651 * decode properly, see CRYPT_AsnDecodeCRLInfo.
653 static BOOL WINAPI
CRYPT_AsnEncodeCRLInfo(DWORD dwCertEncodingType
,
654 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
655 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
661 const CRL_INFO
*info
= pvStructInfo
;
662 struct AsnEncodeSequenceItem items
[7] = {
663 { &info
->dwVersion
, CRYPT_AsnEncodeCRLVersion
, 0 },
664 { &info
->SignatureAlgorithm
, CRYPT_AsnEncodeAlgorithmId
, 0 },
665 { &info
->Issuer
, CRYPT_CopyEncodedBlob
, 0 },
666 { &info
->ThisUpdate
, CRYPT_AsnEncodeChoiceOfTime
, 0 },
669 struct AsnConstructedItem constructed
[1] = { { 0 } };
670 DWORD cItem
= 4, cConstructed
= 0;
672 if (info
->NextUpdate
.dwLowDateTime
|| info
->NextUpdate
.dwHighDateTime
)
674 items
[cItem
].pvStructInfo
= &info
->NextUpdate
;
675 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeChoiceOfTime
;
680 items
[cItem
].pvStructInfo
= info
;
681 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeCRLEntries
;
684 if (info
->cExtension
)
686 constructed
[cConstructed
].tag
= 0;
687 constructed
[cConstructed
].pvStructInfo
= &info
->cExtension
;
688 constructed
[cConstructed
].encodeFunc
= CRYPT_AsnEncodeExtensions
;
689 items
[cItem
].pvStructInfo
= &constructed
[cConstructed
];
690 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
695 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
696 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
700 SetLastError(STATUS_ACCESS_VIOLATION
);
707 static BOOL
CRYPT_AsnEncodeExtension(CERT_EXTENSION
*ext
, BYTE
*pbEncoded
,
711 struct AsnEncodeSequenceItem items
[3] = {
712 { ext
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
718 TRACE("%p, %p, %d\n", ext
, pbEncoded
, *pcbEncoded
);
722 items
[cItem
].pvStructInfo
= &ext
->fCritical
;
723 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeBool
;
726 items
[cItem
].pvStructInfo
= &ext
->Value
;
727 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeOctets
;
730 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
, cItem
, 0, NULL
,
731 pbEncoded
, pcbEncoded
);
732 TRACE("returning %d (%08x)\n", ret
, GetLastError());
736 static BOOL WINAPI
CRYPT_AsnEncodeExtensions(DWORD dwCertEncodingType
,
737 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
738 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
744 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
745 const CERT_EXTENSIONS
*exts
= pvStructInfo
;
748 for (i
= 0, dataLen
= 0; ret
&& i
< exts
->cExtension
; i
++)
752 ret
= CRYPT_AsnEncodeExtension(&exts
->rgExtension
[i
], NULL
, &size
);
758 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
759 bytesNeeded
= 1 + lenBytes
+ dataLen
;
761 *pcbEncoded
= bytesNeeded
;
764 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
765 pbEncoded
, pcbEncoded
, bytesNeeded
)))
767 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
768 pbEncoded
= *(BYTE
**)pbEncoded
;
769 *pbEncoded
++ = ASN_SEQUENCEOF
;
770 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
771 pbEncoded
+= lenBytes
;
772 for (i
= 0; i
< exts
->cExtension
; i
++)
774 DWORD size
= dataLen
;
776 ret
= CRYPT_AsnEncodeExtension(&exts
->rgExtension
[i
],
787 SetLastError(STATUS_ACCESS_VIOLATION
);
794 BOOL WINAPI
CRYPT_AsnEncodeOid(DWORD dwCertEncodingType
,
795 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
796 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
798 LPCSTR pszObjId
= pvStructInfo
;
799 DWORD bytesNeeded
= 0, lenBytes
;
804 TRACE("%s\n", debugstr_a(pszObjId
));
811 if (sscanf(pszObjId
, "%d.%d%n", &val1
, &val2
, &firstPos
) != 2)
813 SetLastError(CRYPT_E_ASN1_ERROR
);
817 firstByte
= val1
* 40 + val2
;
818 ptr
= pszObjId
+ firstPos
;
828 /* note I assume each component is at most 32-bits long in base 2 */
829 if (sscanf(ptr
, "%d%n", &val1
, &pos
) == 1)
831 if (val1
>= 0x10000000)
833 else if (val1
>= 0x200000)
835 else if (val1
>= 0x4000)
837 else if (val1
>= 0x80)
847 SetLastError(CRYPT_E_ASN1_ERROR
);
851 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
855 bytesNeeded
+= 1 + lenBytes
;
858 if (*pcbEncoded
< bytesNeeded
)
860 SetLastError(ERROR_MORE_DATA
);
865 *pbEncoded
++ = ASN_OBJECTIDENTIFIER
;
866 CRYPT_EncodeLen(bytesNeeded
- 1 - lenBytes
, pbEncoded
, &lenBytes
);
867 pbEncoded
+= lenBytes
;
873 *pbEncoded
++ = firstByte
;
874 ptr
= pszObjId
+ firstPos
;
877 sscanf(ptr
, "%d%n", &val
, &pos
);
879 unsigned char outBytes
[5];
882 if (val
>= 0x10000000)
884 else if (val
>= 0x200000)
886 else if (val
>= 0x4000)
888 else if (val
>= 0x80)
892 for (i
= numBytes
; i
> 0; i
--)
894 outBytes
[i
- 1] = val
& 0x7f;
897 for (i
= 0; i
< numBytes
- 1; i
++)
898 *pbEncoded
++ = outBytes
[i
] | 0x80;
899 *pbEncoded
++ = outBytes
[i
];
908 *pcbEncoded
= bytesNeeded
;
912 static BOOL
CRYPT_AsnEncodeStringCoerce(const CERT_NAME_VALUE
*value
,
913 BYTE tag
, DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
917 LPCSTR str
= (LPCSTR
)value
->Value
.pbData
;
918 DWORD bytesNeeded
, lenBytes
, encodedLen
;
920 encodedLen
= value
->Value
.cbData
? value
->Value
.cbData
: strlen(str
);
921 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
922 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
924 *pcbEncoded
= bytesNeeded
;
927 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
928 pbEncoded
, pcbEncoded
, bytesNeeded
)))
930 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
931 pbEncoded
= *(BYTE
**)pbEncoded
;
933 CRYPT_EncodeLen(encodedLen
, pbEncoded
, &lenBytes
);
934 pbEncoded
+= lenBytes
;
935 memcpy(pbEncoded
, str
, encodedLen
);
941 static BOOL
CRYPT_AsnEncodeBMPString(const CERT_NAME_VALUE
*value
,
942 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
946 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
947 DWORD bytesNeeded
, lenBytes
, strLen
;
949 if (value
->Value
.cbData
)
950 strLen
= value
->Value
.cbData
/ sizeof(WCHAR
);
951 else if (value
->Value
.pbData
)
952 strLen
= lstrlenW(str
);
955 CRYPT_EncodeLen(strLen
* 2, NULL
, &lenBytes
);
956 bytesNeeded
= 1 + lenBytes
+ strLen
* 2;
958 *pcbEncoded
= bytesNeeded
;
961 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
962 pbEncoded
, pcbEncoded
, bytesNeeded
)))
966 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
967 pbEncoded
= *(BYTE
**)pbEncoded
;
968 *pbEncoded
++ = ASN_BMPSTRING
;
969 CRYPT_EncodeLen(strLen
* 2, pbEncoded
, &lenBytes
);
970 pbEncoded
+= lenBytes
;
971 for (i
= 0; i
< strLen
; i
++)
973 *pbEncoded
++ = (str
[i
] & 0xff00) >> 8;
974 *pbEncoded
++ = str
[i
] & 0x00ff;
981 static BOOL
CRYPT_AsnEncodeUTF8String(const CERT_NAME_VALUE
*value
,
982 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
986 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
987 DWORD bytesNeeded
, lenBytes
, encodedLen
, strLen
;
989 strLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
991 encodedLen
= WideCharToMultiByte(CP_UTF8
, 0, str
, strLen
, NULL
, 0, NULL
,
993 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
994 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
996 *pcbEncoded
= bytesNeeded
;
999 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1000 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1002 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1003 pbEncoded
= *(BYTE
**)pbEncoded
;
1004 *pbEncoded
++ = ASN_UTF8STRING
;
1005 CRYPT_EncodeLen(encodedLen
, pbEncoded
, &lenBytes
);
1006 pbEncoded
+= lenBytes
;
1007 WideCharToMultiByte(CP_UTF8
, 0, str
, strLen
, (LPSTR
)pbEncoded
,
1008 bytesNeeded
- lenBytes
- 1, NULL
, NULL
);
1014 static BOOL WINAPI
CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType
,
1015 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1016 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1022 const CERT_NAME_VALUE
*value
= pvStructInfo
;
1024 switch (value
->dwValueType
)
1026 case CERT_RDN_ANY_TYPE
:
1027 /* explicitly disallowed */
1028 SetLastError(E_INVALIDARG
);
1031 case CERT_RDN_ENCODED_BLOB
:
1032 ret
= CRYPT_CopyEncodedBlob(dwCertEncodingType
, NULL
,
1033 &value
->Value
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1035 case CERT_RDN_OCTET_STRING
:
1036 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_OCTETSTRING
,
1037 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1039 case CERT_RDN_NUMERIC_STRING
:
1040 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_NUMERICSTRING
,
1041 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1043 case CERT_RDN_PRINTABLE_STRING
:
1044 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_PRINTABLESTRING
,
1045 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1047 case CERT_RDN_TELETEX_STRING
:
1048 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_T61STRING
,
1049 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1051 case CERT_RDN_VIDEOTEX_STRING
:
1052 ret
= CRYPT_AsnEncodeStringCoerce(value
,
1053 ASN_VIDEOTEXSTRING
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1055 case CERT_RDN_IA5_STRING
:
1056 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_IA5STRING
,
1057 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1059 case CERT_RDN_GRAPHIC_STRING
:
1060 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_GRAPHICSTRING
,
1061 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1063 case CERT_RDN_VISIBLE_STRING
:
1064 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_VISIBLESTRING
,
1065 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1067 case CERT_RDN_GENERAL_STRING
:
1068 ret
= CRYPT_AsnEncodeStringCoerce(value
, ASN_GENERALSTRING
,
1069 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1071 case CERT_RDN_UNIVERSAL_STRING
:
1072 FIXME("CERT_RDN_UNIVERSAL_STRING: unimplemented\n");
1073 SetLastError(CRYPT_E_ASN1_CHOICE
);
1076 case CERT_RDN_BMP_STRING
:
1077 ret
= CRYPT_AsnEncodeBMPString(value
, dwFlags
, pEncodePara
,
1078 pbEncoded
, pcbEncoded
);
1080 case CERT_RDN_UTF8_STRING
:
1081 ret
= CRYPT_AsnEncodeUTF8String(value
, dwFlags
, pEncodePara
,
1082 pbEncoded
, pcbEncoded
);
1085 SetLastError(CRYPT_E_ASN1_CHOICE
);
1091 SetLastError(STATUS_ACCESS_VIOLATION
);
1098 static BOOL
CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType
,
1099 const CERT_RDN_ATTR
*attr
, CryptEncodeObjectExFunc nameValueEncodeFunc
,
1100 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1102 DWORD bytesNeeded
= 0, lenBytes
, size
;
1105 ret
= CRYPT_AsnEncodeOid(dwCertEncodingType
, NULL
, attr
->pszObjId
,
1106 0, NULL
, NULL
, &size
);
1109 bytesNeeded
+= size
;
1110 /* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning
1111 * with dwValueType, so "cast" it to get its encoded size
1113 ret
= nameValueEncodeFunc(dwCertEncodingType
, NULL
, &attr
->dwValueType
,
1114 0, NULL
, NULL
, &size
);
1117 bytesNeeded
+= size
;
1118 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
1119 bytesNeeded
+= 1 + lenBytes
;
1122 if (*pcbEncoded
< bytesNeeded
)
1124 SetLastError(ERROR_MORE_DATA
);
1129 *pbEncoded
++ = ASN_SEQUENCE
;
1130 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
1132 pbEncoded
+= lenBytes
;
1133 size
= bytesNeeded
- 1 - lenBytes
;
1134 ret
= CRYPT_AsnEncodeOid(dwCertEncodingType
, NULL
,
1135 attr
->pszObjId
, 0, NULL
, pbEncoded
, &size
);
1139 size
= bytesNeeded
- 1 - lenBytes
- size
;
1140 ret
= nameValueEncodeFunc(dwCertEncodingType
, NULL
,
1141 &attr
->dwValueType
, 0, NULL
, pbEncoded
, &size
);
1148 *pcbEncoded
= bytesNeeded
;
1152 /* Have to propagate index of failing character */
1159 static int BLOBComp(const void *l
, const void *r
)
1161 const CRYPT_DER_BLOB
*a
= l
, *b
= r
;
1164 if (!(ret
= memcmp(a
->pbData
, b
->pbData
, min(a
->cbData
, b
->cbData
))))
1165 ret
= a
->cbData
- b
->cbData
;
1169 /* This encodes a SET OF, which in DER must be lexicographically sorted.
1171 static BOOL WINAPI
CRYPT_DEREncodeSet(DWORD dwCertEncodingType
,
1172 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1173 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1175 const CRYPT_BLOB_ARRAY
*set
= pvStructInfo
;
1176 DWORD bytesNeeded
= 0, lenBytes
, i
;
1179 for (i
= 0; i
< set
->cBlob
; i
++)
1180 bytesNeeded
+= set
->rgBlob
[i
].cbData
;
1181 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
1182 bytesNeeded
+= 1 + lenBytes
;
1185 *pcbEncoded
= bytesNeeded
;
1188 else if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1189 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1191 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1192 pbEncoded
= *(BYTE
**)pbEncoded
;
1193 qsort(set
->rgBlob
, set
->cBlob
, sizeof(CRYPT_DER_BLOB
), BLOBComp
);
1194 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_SETOF
;
1195 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
, &lenBytes
);
1196 pbEncoded
+= lenBytes
;
1197 for (i
= 0; ret
&& i
< set
->cBlob
; i
++)
1199 memcpy(pbEncoded
, set
->rgBlob
[i
].pbData
, set
->rgBlob
[i
].cbData
);
1200 pbEncoded
+= set
->rgBlob
[i
].cbData
;
1206 struct DERSetDescriptor
1212 CryptEncodeObjectExFunc encode
;
1215 static BOOL WINAPI
CRYPT_DEREncodeItemsAsSet(DWORD dwCertEncodingType
,
1216 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1217 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1219 const struct DERSetDescriptor
*desc
= pvStructInfo
;
1220 CRYPT_BLOB_ARRAY setOf
= { 0, NULL
};
1226 setOf
.rgBlob
= CryptMemAlloc(desc
->cItems
* sizeof(CRYPT_DER_BLOB
));
1231 setOf
.cBlob
= desc
->cItems
;
1232 memset(setOf
.rgBlob
, 0, setOf
.cBlob
* sizeof(CRYPT_DER_BLOB
));
1235 for (i
= 0; ret
&& i
< setOf
.cBlob
; i
++)
1237 ret
= desc
->encode(dwCertEncodingType
, lpszStructType
,
1238 (const BYTE
*)desc
->items
+ i
* desc
->itemSize
+ desc
->itemOffset
,
1239 0, NULL
, NULL
, &setOf
.rgBlob
[i
].cbData
);
1242 setOf
.rgBlob
[i
].pbData
= CryptMemAlloc(setOf
.rgBlob
[i
].cbData
);
1243 if (!setOf
.rgBlob
[i
].pbData
)
1246 ret
= desc
->encode(dwCertEncodingType
, lpszStructType
,
1247 (const BYTE
*)desc
->items
+ i
* desc
->itemSize
+
1248 desc
->itemOffset
, 0, NULL
, setOf
.rgBlob
[i
].pbData
,
1249 &setOf
.rgBlob
[i
].cbData
);
1251 /* Some functions propagate their errors through the size */
1253 *pcbEncoded
= setOf
.rgBlob
[i
].cbData
;
1257 DWORD bytesNeeded
= 0, lenBytes
;
1259 for (i
= 0; i
< setOf
.cBlob
; i
++)
1260 bytesNeeded
+= setOf
.rgBlob
[i
].cbData
;
1261 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
1262 bytesNeeded
+= 1 + lenBytes
;
1264 *pcbEncoded
= bytesNeeded
;
1265 else if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1266 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1268 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1269 pbEncoded
= *(BYTE
**)pbEncoded
;
1270 qsort(setOf
.rgBlob
, setOf
.cBlob
, sizeof(CRYPT_DER_BLOB
),
1272 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_SETOF
;
1273 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
, &lenBytes
);
1274 pbEncoded
+= lenBytes
;
1275 for (i
= 0; i
< setOf
.cBlob
; i
++)
1277 memcpy(pbEncoded
, setOf
.rgBlob
[i
].pbData
,
1278 setOf
.rgBlob
[i
].cbData
);
1279 pbEncoded
+= setOf
.rgBlob
[i
].cbData
;
1283 for (i
= 0; i
< setOf
.cBlob
; i
++)
1284 CryptMemFree(setOf
.rgBlob
[i
].pbData
);
1285 CryptMemFree(setOf
.rgBlob
);
1289 static BOOL
CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType
, const CERT_RDN
*rdn
,
1290 CryptEncodeObjectExFunc nameValueEncodeFunc
, BYTE
*pbEncoded
,
1294 CRYPT_BLOB_ARRAY setOf
= { 0, NULL
};
1303 setOf
.cBlob
= rdn
->cRDNAttr
;
1304 setOf
.rgBlob
= CryptMemAlloc(rdn
->cRDNAttr
*
1305 sizeof(CRYPT_DER_BLOB
));
1309 memset(setOf
.rgBlob
, 0, setOf
.cBlob
* sizeof(CRYPT_DER_BLOB
));
1311 for (i
= 0; ret
&& i
< rdn
->cRDNAttr
; i
++)
1313 setOf
.rgBlob
[i
].cbData
= 0;
1314 ret
= CRYPT_AsnEncodeRdnAttr(dwCertEncodingType
, &rdn
->rgRDNAttr
[i
],
1315 nameValueEncodeFunc
, NULL
, &setOf
.rgBlob
[i
].cbData
);
1318 setOf
.rgBlob
[i
].pbData
= CryptMemAlloc(setOf
.rgBlob
[i
].cbData
);
1319 if (!setOf
.rgBlob
[i
].pbData
)
1322 ret
= CRYPT_AsnEncodeRdnAttr(dwCertEncodingType
,
1323 &rdn
->rgRDNAttr
[i
], nameValueEncodeFunc
,
1324 setOf
.rgBlob
[i
].pbData
, &setOf
.rgBlob
[i
].cbData
);
1328 /* Have to propagate index of failing character */
1329 *pcbEncoded
= setOf
.rgBlob
[i
].cbData
;
1333 ret
= CRYPT_DEREncodeSet(X509_ASN_ENCODING
, NULL
, &setOf
, 0, NULL
,
1334 pbEncoded
, pcbEncoded
);
1335 for (i
= 0; i
< setOf
.cBlob
; i
++)
1336 CryptMemFree(setOf
.rgBlob
[i
].pbData
);
1340 SetLastError(STATUS_ACCESS_VIOLATION
);
1344 CryptMemFree(setOf
.rgBlob
);
1348 static BOOL WINAPI
CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType
,
1349 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1350 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
);
1352 static BOOL WINAPI
CRYPT_AsnEncodeOrCopyUnicodeNameValue(
1353 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
1354 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1357 const CERT_NAME_VALUE
*value
= pvStructInfo
;
1360 if (value
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
1361 ret
= CRYPT_CopyEncodedBlob(dwCertEncodingType
, NULL
, &value
->Value
,
1362 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1364 ret
= CRYPT_AsnEncodeUnicodeNameValue(dwCertEncodingType
, NULL
, value
,
1365 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1369 static BOOL WINAPI
CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType
,
1370 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1371 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1377 const CERT_NAME_INFO
*info
= pvStructInfo
;
1378 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
1380 TRACE("encoding name with %d RDNs\n", info
->cRDN
);
1382 for (i
= 0; ret
&& i
< info
->cRDN
; i
++)
1384 ret
= CRYPT_AsnEncodeRdn(dwCertEncodingType
, &info
->rgRDN
[i
],
1385 CRYPT_AsnEncodeOrCopyUnicodeNameValue
, NULL
, &size
);
1387 bytesNeeded
+= size
;
1391 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
1392 bytesNeeded
+= 1 + lenBytes
;
1396 *pcbEncoded
= bytesNeeded
;
1399 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1400 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1402 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1403 pbEncoded
= *(BYTE
**)pbEncoded
;
1404 *pbEncoded
++ = ASN_SEQUENCEOF
;
1405 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
1407 pbEncoded
+= lenBytes
;
1408 for (i
= 0; ret
&& i
< info
->cRDN
; i
++)
1411 ret
= CRYPT_AsnEncodeRdn(dwCertEncodingType
,
1412 &info
->rgRDN
[i
], CRYPT_AsnEncodeOrCopyUnicodeNameValue
,
1417 bytesNeeded
-= size
;
1428 SetLastError(STATUS_ACCESS_VIOLATION
);
1435 static BOOL WINAPI
CRYPT_AsnEncodeCTLVersion(DWORD dwCertEncodingType
,
1436 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1437 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1439 const DWORD
*ver
= pvStructInfo
;
1442 /* CTL_V1 is not encoded */
1449 ret
= CRYPT_AsnEncodeInt(dwCertEncodingType
, X509_INTEGER
, ver
,
1450 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1454 /* Like CRYPT_AsnEncodeAlgorithmId, but encodes parameters as an asn.1 NULL
1455 * if they are empty and the OID is not empty (otherwise omits them.)
1457 static BOOL WINAPI
CRYPT_AsnEncodeCTLSubjectAlgorithm(
1458 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
1459 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1462 const CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
1464 struct AsnEncodeSequenceItem items
[2] = {
1465 { algo
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
1471 static const BYTE asn1Null
[] = { ASN_NULL
, 0 };
1472 static const CRYPT_DATA_BLOB nullBlob
= { sizeof(asn1Null
),
1475 if (algo
->Parameters
.cbData
)
1476 items
[cItem
].pvStructInfo
= &algo
->Parameters
;
1478 items
[cItem
].pvStructInfo
= &nullBlob
;
1479 items
[cItem
].encodeFunc
= CRYPT_CopyEncodedBlob
;
1482 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
1483 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1487 static BOOL
CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY
*entry
,
1488 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1490 struct AsnEncodeSequenceItem items
[2] = {
1491 { &entry
->SubjectIdentifier
, CRYPT_AsnEncodeOctets
, 0 },
1492 { &entry
->cAttribute
, CRYPT_AsnEncodePKCSAttributes
, 0 },
1496 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
,
1497 sizeof(items
) / sizeof(items
[0]), 0, NULL
, pbEncoded
, pcbEncoded
);
1507 static BOOL WINAPI
CRYPT_AsnEncodeCTLEntries(DWORD dwCertEncodingType
,
1508 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1509 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1512 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
1513 const struct CTLEntries
*entries
= pvStructInfo
;
1516 for (i
= 0, dataLen
= 0; ret
&& i
< entries
->cEntry
; i
++)
1520 ret
= CRYPT_AsnEncodeCTLEntry(&entries
->rgEntry
[i
], NULL
, &size
);
1526 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
1527 bytesNeeded
= 1 + lenBytes
+ dataLen
;
1529 *pcbEncoded
= bytesNeeded
;
1532 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1533 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1535 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1536 pbEncoded
= *(BYTE
**)pbEncoded
;
1537 *pbEncoded
++ = ASN_SEQUENCEOF
;
1538 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
1539 pbEncoded
+= lenBytes
;
1540 for (i
= 0; ret
&& i
< entries
->cEntry
; i
++)
1542 DWORD size
= dataLen
;
1544 ret
= CRYPT_AsnEncodeCTLEntry(&entries
->rgEntry
[i
],
1555 static BOOL WINAPI
CRYPT_AsnEncodeCTL(DWORD dwCertEncodingType
,
1556 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1557 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1563 const CTL_INFO
*info
= pvStructInfo
;
1564 struct AsnEncodeSequenceItem items
[9] = {
1565 { &info
->dwVersion
, CRYPT_AsnEncodeCTLVersion
, 0 },
1566 { &info
->SubjectUsage
, CRYPT_AsnEncodeEnhancedKeyUsage
, 0 },
1568 struct AsnConstructedItem constructed
= { 0 };
1571 if (info
->ListIdentifier
.cbData
)
1573 items
[cItem
].pvStructInfo
= &info
->ListIdentifier
;
1574 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeOctets
;
1577 if (info
->SequenceNumber
.cbData
)
1579 items
[cItem
].pvStructInfo
= &info
->SequenceNumber
;
1580 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeInteger
;
1583 items
[cItem
].pvStructInfo
= &info
->ThisUpdate
;
1584 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeChoiceOfTime
;
1586 if (info
->NextUpdate
.dwLowDateTime
|| info
->NextUpdate
.dwHighDateTime
)
1588 items
[cItem
].pvStructInfo
= &info
->NextUpdate
;
1589 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeChoiceOfTime
;
1592 items
[cItem
].pvStructInfo
= &info
->SubjectAlgorithm
;
1593 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeCTLSubjectAlgorithm
;
1595 if (info
->cCTLEntry
)
1597 items
[cItem
].pvStructInfo
= &info
->cCTLEntry
;
1598 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeCTLEntries
;
1601 if (info
->cExtension
)
1603 constructed
.tag
= 0;
1604 constructed
.pvStructInfo
= &info
->cExtension
;
1605 constructed
.encodeFunc
= CRYPT_AsnEncodeExtensions
;
1606 items
[cItem
].pvStructInfo
= &constructed
;
1607 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
1610 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
1611 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1615 SetLastError(STATUS_ACCESS_VIOLATION
);
1621 static BOOL
CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType
,
1622 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1623 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1629 const CRYPT_SMIME_CAPABILITY
*capability
= pvStructInfo
;
1631 if (!capability
->pszObjId
)
1632 SetLastError(E_INVALIDARG
);
1635 struct AsnEncodeSequenceItem items
[] = {
1636 { capability
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
1637 { &capability
->Parameters
, CRYPT_CopyEncodedBlob
, 0 },
1640 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
1641 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
1647 SetLastError(STATUS_ACCESS_VIOLATION
);
1653 static BOOL WINAPI
CRYPT_AsnEncodeSMIMECapabilities(DWORD dwCertEncodingType
,
1654 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1655 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1661 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
1662 const CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
1665 for (i
= 0, dataLen
= 0; ret
&& i
< capabilities
->cCapability
; i
++)
1669 ret
= CRYPT_AsnEncodeSMIMECapability(dwCertEncodingType
, NULL
,
1670 &capabilities
->rgCapability
[i
], 0, NULL
, NULL
, &size
);
1676 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
1677 bytesNeeded
= 1 + lenBytes
+ dataLen
;
1679 *pcbEncoded
= bytesNeeded
;
1682 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1683 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1685 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1686 pbEncoded
= *(BYTE
**)pbEncoded
;
1687 *pbEncoded
++ = ASN_SEQUENCEOF
;
1688 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
1689 pbEncoded
+= lenBytes
;
1690 for (i
= 0; i
< capabilities
->cCapability
; i
++)
1692 DWORD size
= dataLen
;
1694 ret
= CRYPT_AsnEncodeSMIMECapability(dwCertEncodingType
,
1695 NULL
, &capabilities
->rgCapability
[i
], 0, NULL
,
1706 SetLastError(STATUS_ACCESS_VIOLATION
);
1712 static BOOL WINAPI
CRYPT_AsnEncodeNoticeNumbers(DWORD dwCertEncodingType
,
1713 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1714 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1716 const CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*noticeRef
= pvStructInfo
;
1717 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
1720 for (i
= 0, dataLen
= 0; ret
&& i
< noticeRef
->cNoticeNumbers
; i
++)
1724 ret
= CRYPT_AsnEncodeInt(dwCertEncodingType
, X509_INTEGER
,
1725 ¬iceRef
->rgNoticeNumbers
[i
], 0, NULL
, NULL
, &size
);
1731 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
1732 bytesNeeded
= 1 + lenBytes
+ dataLen
;
1734 *pcbEncoded
= bytesNeeded
;
1737 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
1738 pcbEncoded
, bytesNeeded
)))
1740 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1741 pbEncoded
= *(BYTE
**)pbEncoded
;
1742 *pbEncoded
++ = ASN_SEQUENCE
;
1743 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
1744 pbEncoded
+= lenBytes
;
1745 for (i
= 0; i
< noticeRef
->cNoticeNumbers
; i
++)
1747 DWORD size
= dataLen
;
1749 ret
= CRYPT_AsnEncodeInt(dwCertEncodingType
, X509_INTEGER
,
1750 ¬iceRef
->rgNoticeNumbers
[i
], 0, NULL
, pbEncoded
, &size
);
1760 static BOOL WINAPI
CRYPT_AsnEncodeNoticeReference(DWORD dwCertEncodingType
,
1761 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1762 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1764 const CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*noticeRef
= pvStructInfo
;
1766 CERT_NAME_VALUE orgValue
= { CERT_RDN_IA5_STRING
,
1767 { 0, (LPBYTE
)noticeRef
->pszOrganization
} };
1768 struct AsnEncodeSequenceItem items
[] = {
1769 { &orgValue
, CRYPT_AsnEncodeNameValue
, 0 },
1770 { noticeRef
, CRYPT_AsnEncodeNoticeNumbers
, 0 },
1773 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
1774 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
1779 static BOOL WINAPI
CRYPT_AsnEncodePolicyQualifierUserNotice(
1780 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
1781 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1788 const CERT_POLICY_QUALIFIER_USER_NOTICE
*notice
= pvStructInfo
;
1789 struct AsnEncodeSequenceItem items
[2];
1790 CERT_NAME_VALUE displayTextValue
;
1794 if (notice
->pNoticeReference
)
1796 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeNoticeReference
;
1797 items
[cItem
].pvStructInfo
= notice
->pNoticeReference
;
1800 if (notice
->pszDisplayText
)
1802 displayTextValue
.dwValueType
= CERT_RDN_BMP_STRING
;
1803 displayTextValue
.Value
.cbData
= 0;
1804 displayTextValue
.Value
.pbData
= (LPBYTE
)notice
->pszDisplayText
;
1805 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeNameValue
;
1806 items
[cItem
].pvStructInfo
= &displayTextValue
;
1809 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
1810 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1814 SetLastError(STATUS_ACCESS_VIOLATION
);
1820 static BOOL WINAPI
CRYPT_AsnEncodePKCSAttribute(DWORD dwCertEncodingType
,
1821 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1822 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1828 const CRYPT_ATTRIBUTE
*attr
= pvStructInfo
;
1830 if (!attr
->pszObjId
)
1831 SetLastError(E_INVALIDARG
);
1834 struct AsnEncodeSequenceItem items
[2] = {
1835 { attr
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
1836 { &attr
->cValue
, CRYPT_DEREncodeSet
, 0 },
1839 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
1840 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
1846 SetLastError(STATUS_ACCESS_VIOLATION
);
1852 static BOOL WINAPI
CRYPT_AsnEncodePKCSAttributes(DWORD dwCertEncodingType
,
1853 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1854 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1860 const CRYPT_ATTRIBUTES
*attributes
= pvStructInfo
;
1861 struct DERSetDescriptor desc
= { attributes
->cAttr
, attributes
->rgAttr
,
1862 sizeof(CRYPT_ATTRIBUTE
), 0, CRYPT_AsnEncodePKCSAttribute
};
1864 ret
= CRYPT_DEREncodeItemsAsSet(X509_ASN_ENCODING
, lpszStructType
,
1865 &desc
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1869 SetLastError(STATUS_ACCESS_VIOLATION
);
1875 /* Like CRYPT_AsnEncodePKCSContentInfo, but allows the OID to be NULL */
1876 static BOOL WINAPI
CRYPT_AsnEncodePKCSContentInfoInternal(
1877 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
1878 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1881 const CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
1882 struct AsnEncodeSequenceItem items
[2] = {
1883 { info
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
1886 struct AsnConstructedItem constructed
= { 0 };
1889 if (info
->Content
.cbData
)
1891 constructed
.tag
= 0;
1892 constructed
.pvStructInfo
= &info
->Content
;
1893 constructed
.encodeFunc
= CRYPT_CopyEncodedBlob
;
1894 items
[cItem
].pvStructInfo
= &constructed
;
1895 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
1898 return CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
1899 cItem
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
1902 BOOL
CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA
*digestedData
,
1903 void *pvData
, DWORD
*pcbData
)
1905 struct AsnEncodeSequenceItem items
[] = {
1906 { &digestedData
->version
, CRYPT_AsnEncodeInt
, 0 },
1907 { &digestedData
->DigestAlgorithm
, CRYPT_AsnEncodeAlgorithmIdWithNullParams
,
1909 { &digestedData
->ContentInfo
, CRYPT_AsnEncodePKCSContentInfoInternal
, 0 },
1910 { &digestedData
->hash
, CRYPT_AsnEncodeOctets
, 0 },
1913 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
,
1914 sizeof(items
) / sizeof(items
[0]), 0, NULL
, pvData
, pcbData
);
1917 static BOOL WINAPI
CRYPT_AsnEncodePKCSContentInfo(DWORD dwCertEncodingType
,
1918 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
1919 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
1925 const CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
1927 if (!info
->pszObjId
)
1928 SetLastError(E_INVALIDARG
);
1930 ret
= CRYPT_AsnEncodePKCSContentInfoInternal(dwCertEncodingType
,
1931 lpszStructType
, pvStructInfo
, dwFlags
, pEncodePara
, pbEncoded
,
1936 SetLastError(STATUS_ACCESS_VIOLATION
);
1942 static BOOL
CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE
*value
,
1943 BYTE tag
, DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1947 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
1948 DWORD bytesNeeded
, lenBytes
, encodedLen
;
1950 encodedLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
1952 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
1953 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
1955 *pcbEncoded
= bytesNeeded
;
1958 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
1959 pbEncoded
, pcbEncoded
, bytesNeeded
)))
1963 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
1964 pbEncoded
= *(BYTE
**)pbEncoded
;
1966 CRYPT_EncodeLen(encodedLen
, pbEncoded
, &lenBytes
);
1967 pbEncoded
+= lenBytes
;
1968 for (i
= 0; i
< encodedLen
; i
++)
1969 *pbEncoded
++ = (BYTE
)str
[i
];
1975 static void CRYPT_FreeSpace(PCRYPT_ENCODE_PARA pEncodePara
, LPVOID pv
)
1977 if (pEncodePara
&& pEncodePara
->pfnFree
)
1978 pEncodePara
->pfnFree(pv
);
1983 static BOOL
CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE
*value
,
1984 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
1988 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
1989 DWORD bytesNeeded
, lenBytes
, encodedLen
;
1991 encodedLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
1993 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
1994 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
1996 *pcbEncoded
= bytesNeeded
;
1999 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2000 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2005 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2006 ptr
= *(BYTE
**)pbEncoded
;
2009 *ptr
++ = ASN_NUMERICSTRING
;
2010 CRYPT_EncodeLen(encodedLen
, ptr
, &lenBytes
);
2012 for (i
= 0; ret
&& i
< encodedLen
; i
++)
2014 if (isdigitW(str
[i
]))
2015 *ptr
++ = (BYTE
)str
[i
];
2019 SetLastError(CRYPT_E_INVALID_NUMERIC_STRING
);
2023 if (!ret
&& (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
))
2024 CRYPT_FreeSpace(pEncodePara
, *(BYTE
**)pbEncoded
);
2030 static inline int isprintableW(WCHAR wc
)
2032 return isalnumW(wc
) || isspaceW(wc
) || wc
== '\'' || wc
== '(' ||
2033 wc
== ')' || wc
== '+' || wc
== ',' || wc
== '-' || wc
== '.' ||
2034 wc
== '/' || wc
== ':' || wc
== '=' || wc
== '?';
2037 static BOOL
CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE
*value
,
2038 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
2042 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
2043 DWORD bytesNeeded
, lenBytes
, encodedLen
;
2045 encodedLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
2047 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
2048 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
2050 *pcbEncoded
= bytesNeeded
;
2053 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2054 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2059 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2060 ptr
= *(BYTE
**)pbEncoded
;
2063 *ptr
++ = ASN_PRINTABLESTRING
;
2064 CRYPT_EncodeLen(encodedLen
, ptr
, &lenBytes
);
2066 for (i
= 0; ret
&& i
< encodedLen
; i
++)
2068 if (isprintableW(str
[i
]))
2069 *ptr
++ = (BYTE
)str
[i
];
2073 SetLastError(CRYPT_E_INVALID_PRINTABLE_STRING
);
2077 if (!ret
&& (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
))
2078 CRYPT_FreeSpace(pEncodePara
, *(BYTE
**)pbEncoded
);
2084 static BOOL
CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE
*value
,
2085 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
2089 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
2090 DWORD bytesNeeded
, lenBytes
, encodedLen
;
2092 encodedLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
2094 CRYPT_EncodeLen(encodedLen
, NULL
, &lenBytes
);
2095 bytesNeeded
= 1 + lenBytes
+ encodedLen
;
2097 *pcbEncoded
= bytesNeeded
;
2100 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2101 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2106 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2107 ptr
= *(BYTE
**)pbEncoded
;
2110 *ptr
++ = ASN_IA5STRING
;
2111 CRYPT_EncodeLen(encodedLen
, ptr
, &lenBytes
);
2113 for (i
= 0; ret
&& i
< encodedLen
; i
++)
2116 *ptr
++ = (BYTE
)str
[i
];
2120 SetLastError(CRYPT_E_INVALID_IA5_STRING
);
2124 if (!ret
&& (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
))
2125 CRYPT_FreeSpace(pEncodePara
, *(BYTE
**)pbEncoded
);
2131 static BOOL
CRYPT_AsnEncodeUniversalString(const CERT_NAME_VALUE
*value
,
2132 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
2136 LPCWSTR str
= (LPCWSTR
)value
->Value
.pbData
;
2137 DWORD bytesNeeded
, lenBytes
, strLen
;
2139 /* FIXME: doesn't handle composite characters */
2140 strLen
= value
->Value
.cbData
? value
->Value
.cbData
/ sizeof(WCHAR
) :
2142 CRYPT_EncodeLen(strLen
* 4, NULL
, &lenBytes
);
2143 bytesNeeded
= 1 + lenBytes
+ strLen
* 4;
2145 *pcbEncoded
= bytesNeeded
;
2148 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2149 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2153 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2154 pbEncoded
= *(BYTE
**)pbEncoded
;
2155 *pbEncoded
++ = ASN_UNIVERSALSTRING
;
2156 CRYPT_EncodeLen(strLen
* 4, pbEncoded
, &lenBytes
);
2157 pbEncoded
+= lenBytes
;
2158 for (i
= 0; i
< strLen
; i
++)
2162 *pbEncoded
++ = (BYTE
)((str
[i
] & 0xff00) >> 8);
2163 *pbEncoded
++ = (BYTE
)(str
[i
] & 0x00ff);
2170 static BOOL WINAPI
CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType
,
2171 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2172 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2178 const CERT_NAME_VALUE
*value
= pvStructInfo
;
2180 switch (value
->dwValueType
)
2182 case CERT_RDN_ANY_TYPE
:
2183 case CERT_RDN_ENCODED_BLOB
:
2184 case CERT_RDN_OCTET_STRING
:
2185 SetLastError(CRYPT_E_NOT_CHAR_STRING
);
2187 case CERT_RDN_NUMERIC_STRING
:
2188 ret
= CRYPT_AsnEncodeNumericString(value
, dwFlags
, pEncodePara
,
2189 pbEncoded
, pcbEncoded
);
2191 case CERT_RDN_PRINTABLE_STRING
:
2192 ret
= CRYPT_AsnEncodePrintableString(value
, dwFlags
, pEncodePara
,
2193 pbEncoded
, pcbEncoded
);
2195 case CERT_RDN_TELETEX_STRING
:
2196 ret
= CRYPT_AsnEncodeUnicodeStringCoerce(value
, ASN_T61STRING
,
2197 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2199 case CERT_RDN_VIDEOTEX_STRING
:
2200 ret
= CRYPT_AsnEncodeUnicodeStringCoerce(value
,
2201 ASN_VIDEOTEXSTRING
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2203 case CERT_RDN_IA5_STRING
:
2204 ret
= CRYPT_AsnEncodeIA5String(value
, dwFlags
, pEncodePara
,
2205 pbEncoded
, pcbEncoded
);
2207 case CERT_RDN_GRAPHIC_STRING
:
2208 ret
= CRYPT_AsnEncodeUnicodeStringCoerce(value
, ASN_GRAPHICSTRING
,
2209 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2211 case CERT_RDN_VISIBLE_STRING
:
2212 ret
= CRYPT_AsnEncodeUnicodeStringCoerce(value
, ASN_VISIBLESTRING
,
2213 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2215 case CERT_RDN_GENERAL_STRING
:
2216 ret
= CRYPT_AsnEncodeUnicodeStringCoerce(value
, ASN_GENERALSTRING
,
2217 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2219 case CERT_RDN_UNIVERSAL_STRING
:
2220 ret
= CRYPT_AsnEncodeUniversalString(value
, dwFlags
, pEncodePara
,
2221 pbEncoded
, pcbEncoded
);
2223 case CERT_RDN_BMP_STRING
:
2224 ret
= CRYPT_AsnEncodeBMPString(value
, dwFlags
, pEncodePara
,
2225 pbEncoded
, pcbEncoded
);
2227 case CERT_RDN_UTF8_STRING
:
2228 ret
= CRYPT_AsnEncodeUTF8String(value
, dwFlags
, pEncodePara
,
2229 pbEncoded
, pcbEncoded
);
2232 SetLastError(CRYPT_E_ASN1_CHOICE
);
2237 SetLastError(STATUS_ACCESS_VIOLATION
);
2243 static BOOL WINAPI
CRYPT_AsnEncodeName(DWORD dwCertEncodingType
,
2244 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2245 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2251 const CERT_NAME_INFO
*info
= pvStructInfo
;
2252 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
2254 TRACE("encoding name with %d RDNs\n", info
->cRDN
);
2256 for (i
= 0; ret
&& i
< info
->cRDN
; i
++)
2258 ret
= CRYPT_AsnEncodeRdn(dwCertEncodingType
, &info
->rgRDN
[i
],
2259 CRYPT_AsnEncodeNameValue
, NULL
, &size
);
2261 bytesNeeded
+= size
;
2263 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
2264 bytesNeeded
+= 1 + lenBytes
;
2268 *pcbEncoded
= bytesNeeded
;
2271 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2272 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2274 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2275 pbEncoded
= *(BYTE
**)pbEncoded
;
2276 *pbEncoded
++ = ASN_SEQUENCEOF
;
2277 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
2279 pbEncoded
+= lenBytes
;
2280 for (i
= 0; ret
&& i
< info
->cRDN
; i
++)
2283 ret
= CRYPT_AsnEncodeRdn(dwCertEncodingType
,
2284 &info
->rgRDN
[i
], CRYPT_AsnEncodeNameValue
, pbEncoded
,
2289 bytesNeeded
-= size
;
2298 SetLastError(STATUS_ACCESS_VIOLATION
);
2305 static BOOL WINAPI
CRYPT_AsnEncodeBool(DWORD dwCertEncodingType
,
2306 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2307 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2309 BOOL val
= *(const BOOL
*)pvStructInfo
, ret
;
2318 else if (*pcbEncoded
< 3)
2321 SetLastError(ERROR_MORE_DATA
);
2327 *pbEncoded
++ = ASN_BOOL
;
2329 *pbEncoded
++ = val
? 0xff : 0;
2332 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2336 static BOOL WINAPI
CRYPT_AsnEncodeAltNameEntry(DWORD dwCertEncodingType
,
2337 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2338 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2340 const CERT_ALT_NAME_ENTRY
*entry
= pvStructInfo
;
2346 switch (entry
->dwAltNameChoice
)
2348 case CERT_ALT_NAME_RFC822_NAME
:
2349 case CERT_ALT_NAME_DNS_NAME
:
2350 case CERT_ALT_NAME_URL
:
2351 tag
= ASN_CONTEXT
| (entry
->dwAltNameChoice
- 1);
2352 if (entry
->u
.pwszURL
)
2356 /* Not + 1: don't encode the NULL-terminator */
2357 dataLen
= lstrlenW(entry
->u
.pwszURL
);
2358 for (i
= 0; ret
&& i
< dataLen
; i
++)
2360 if (entry
->u
.pwszURL
[i
] > 0x7f)
2362 SetLastError(CRYPT_E_INVALID_IA5_STRING
);
2371 case CERT_ALT_NAME_DIRECTORY_NAME
:
2372 tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| (entry
->dwAltNameChoice
- 1);
2373 dataLen
= entry
->u
.DirectoryName
.cbData
;
2375 case CERT_ALT_NAME_IP_ADDRESS
:
2376 tag
= ASN_CONTEXT
| (entry
->dwAltNameChoice
- 1);
2377 dataLen
= entry
->u
.IPAddress
.cbData
;
2379 case CERT_ALT_NAME_REGISTERED_ID
:
2381 struct AsnEncodeTagSwappedItem swapped
=
2382 { ASN_CONTEXT
| (entry
->dwAltNameChoice
- 1), entry
->u
.pszRegisteredID
,
2383 CRYPT_AsnEncodeOid
};
2385 return CRYPT_AsnEncodeSwapTag(0, NULL
, &swapped
, 0, NULL
, pbEncoded
,
2388 case CERT_ALT_NAME_OTHER_NAME
:
2389 FIXME("name type %d unimplemented\n", entry
->dwAltNameChoice
);
2392 SetLastError(E_INVALIDARG
);
2397 DWORD bytesNeeded
, lenBytes
;
2399 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
2400 bytesNeeded
= 1 + dataLen
+ lenBytes
;
2402 *pcbEncoded
= bytesNeeded
;
2403 else if (*pcbEncoded
< bytesNeeded
)
2405 SetLastError(ERROR_MORE_DATA
);
2406 *pcbEncoded
= bytesNeeded
;
2412 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
2413 pbEncoded
+= lenBytes
;
2414 switch (entry
->dwAltNameChoice
)
2416 case CERT_ALT_NAME_RFC822_NAME
:
2417 case CERT_ALT_NAME_DNS_NAME
:
2418 case CERT_ALT_NAME_URL
:
2422 for (i
= 0; i
< dataLen
; i
++)
2423 *pbEncoded
++ = (BYTE
)entry
->u
.pwszURL
[i
];
2426 case CERT_ALT_NAME_DIRECTORY_NAME
:
2427 memcpy(pbEncoded
, entry
->u
.DirectoryName
.pbData
, dataLen
);
2429 case CERT_ALT_NAME_IP_ADDRESS
:
2430 memcpy(pbEncoded
, entry
->u
.IPAddress
.pbData
, dataLen
);
2434 *pcbEncoded
= bytesNeeded
;
2437 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2441 static BOOL WINAPI
CRYPT_AsnEncodeIntegerSwapBytes(DWORD dwCertEncodingType
,
2442 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2443 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2449 const CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
2450 CRYPT_DATA_BLOB newBlob
= { blob
->cbData
, NULL
};
2455 newBlob
.pbData
= CryptMemAlloc(newBlob
.cbData
);
2460 for (i
= 0; i
< newBlob
.cbData
; i
++)
2461 newBlob
.pbData
[newBlob
.cbData
- i
- 1] = blob
->pbData
[i
];
2467 ret
= CRYPT_AsnEncodeInteger(dwCertEncodingType
, lpszStructType
,
2468 &newBlob
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2469 CryptMemFree(newBlob
.pbData
);
2473 SetLastError(STATUS_ACCESS_VIOLATION
);
2480 static BOOL WINAPI
CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType
,
2481 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2482 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2488 const CERT_AUTHORITY_KEY_ID_INFO
*info
= pvStructInfo
;
2489 struct AsnEncodeSequenceItem items
[3] = { { 0 } };
2490 struct AsnEncodeTagSwappedItem swapped
[3] = { { 0 } };
2491 struct AsnConstructedItem constructed
= { 0 };
2492 DWORD cItem
= 0, cSwapped
= 0;
2494 if (info
->KeyId
.cbData
)
2496 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 0;
2497 swapped
[cSwapped
].pvStructInfo
= &info
->KeyId
;
2498 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeIntegerSwapBytes
;
2499 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
2500 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
2504 if (info
->CertIssuer
.cbData
)
2506 constructed
.tag
= 1;
2507 constructed
.pvStructInfo
= &info
->CertIssuer
;
2508 constructed
.encodeFunc
= CRYPT_CopyEncodedBlob
;
2509 items
[cItem
].pvStructInfo
= &constructed
;
2510 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
2513 if (info
->CertSerialNumber
.cbData
)
2515 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 2;
2516 swapped
[cSwapped
].pvStructInfo
= &info
->CertSerialNumber
;
2517 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInteger
;
2518 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
2519 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
2523 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
, cItem
, dwFlags
,
2524 pEncodePara
, pbEncoded
, pcbEncoded
);
2528 SetLastError(STATUS_ACCESS_VIOLATION
);
2535 static BOOL WINAPI
CRYPT_AsnEncodeAltName(DWORD dwCertEncodingType
,
2536 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2537 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2543 const CERT_ALT_NAME_INFO
*info
= pvStructInfo
;
2544 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
2547 /* FIXME: should check that cAltEntry is not bigger than 0xff, since we
2548 * can't encode an erroneous entry index if it's bigger than this.
2550 for (i
= 0, dataLen
= 0; ret
&& i
< info
->cAltEntry
; i
++)
2554 ret
= CRYPT_AsnEncodeAltNameEntry(dwCertEncodingType
, NULL
,
2555 &info
->rgAltEntry
[i
], 0, NULL
, NULL
, &len
);
2558 else if (GetLastError() == CRYPT_E_INVALID_IA5_STRING
)
2560 /* CRYPT_AsnEncodeAltNameEntry encoded the index of
2561 * the bad character, now set the index of the bad
2564 *pcbEncoded
= (BYTE
)i
<<
2565 CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT
| len
;
2570 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
2571 bytesNeeded
= 1 + lenBytes
+ dataLen
;
2574 *pcbEncoded
= bytesNeeded
;
2579 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2580 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2582 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2583 pbEncoded
= *(BYTE
**)pbEncoded
;
2584 *pbEncoded
++ = ASN_SEQUENCEOF
;
2585 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
2586 pbEncoded
+= lenBytes
;
2587 for (i
= 0; ret
&& i
< info
->cAltEntry
; i
++)
2589 DWORD len
= dataLen
;
2591 ret
= CRYPT_AsnEncodeAltNameEntry(dwCertEncodingType
,
2592 NULL
, &info
->rgAltEntry
[i
], 0, NULL
, pbEncoded
, &len
);
2605 SetLastError(STATUS_ACCESS_VIOLATION
);
2612 static BOOL WINAPI
CRYPT_AsnEncodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2613 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2614 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2620 const CERT_AUTHORITY_KEY_ID2_INFO
*info
= pvStructInfo
;
2621 struct AsnEncodeSequenceItem items
[3] = { { 0 } };
2622 struct AsnEncodeTagSwappedItem swapped
[3] = { { 0 } };
2623 DWORD cItem
= 0, cSwapped
= 0;
2625 if (info
->KeyId
.cbData
)
2627 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 0;
2628 swapped
[cSwapped
].pvStructInfo
= &info
->KeyId
;
2629 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeIntegerSwapBytes
;
2630 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
2631 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
2635 if (info
->AuthorityCertIssuer
.cAltEntry
)
2637 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1;
2638 swapped
[cSwapped
].pvStructInfo
= &info
->AuthorityCertIssuer
;
2639 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeAltName
;
2640 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
2641 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
2645 if (info
->AuthorityCertSerialNumber
.cbData
)
2647 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 2;
2648 swapped
[cSwapped
].pvStructInfo
= &info
->AuthorityCertSerialNumber
;
2649 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInteger
;
2650 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
2651 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
2655 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
, cItem
, dwFlags
,
2656 pEncodePara
, pbEncoded
, pcbEncoded
);
2660 SetLastError(STATUS_ACCESS_VIOLATION
);
2667 static BOOL
CRYPT_AsnEncodeAccessDescription(
2668 const CERT_ACCESS_DESCRIPTION
*descr
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2670 struct AsnEncodeSequenceItem items
[] = {
2671 { descr
->pszAccessMethod
, CRYPT_AsnEncodeOid
, 0 },
2672 { &descr
->AccessLocation
, CRYPT_AsnEncodeAltNameEntry
, 0 },
2675 if (!descr
->pszAccessMethod
)
2677 SetLastError(E_INVALIDARG
);
2680 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
,
2681 sizeof(items
) / sizeof(items
[0]), 0, NULL
, pbEncoded
, pcbEncoded
);
2684 static BOOL WINAPI
CRYPT_AsnEncodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
2685 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2686 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2692 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
2693 const CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
2696 for (i
= 0, dataLen
= 0; ret
&& i
< info
->cAccDescr
; i
++)
2700 ret
= CRYPT_AsnEncodeAccessDescription(&info
->rgAccDescr
[i
], NULL
,
2707 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
2708 bytesNeeded
= 1 + lenBytes
+ dataLen
;
2710 *pcbEncoded
= bytesNeeded
;
2713 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2714 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2716 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2717 pbEncoded
= *(BYTE
**)pbEncoded
;
2718 *pbEncoded
++ = ASN_SEQUENCEOF
;
2719 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
2720 pbEncoded
+= lenBytes
;
2721 for (i
= 0; i
< info
->cAccDescr
; i
++)
2723 DWORD size
= dataLen
;
2725 ret
= CRYPT_AsnEncodeAccessDescription(
2726 &info
->rgAccDescr
[i
], pbEncoded
, &size
);
2736 SetLastError(STATUS_ACCESS_VIOLATION
);
2743 static BOOL WINAPI
CRYPT_AsnEncodeBasicConstraints(DWORD dwCertEncodingType
,
2744 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2745 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2751 const CERT_BASIC_CONSTRAINTS_INFO
*info
= pvStructInfo
;
2752 struct AsnEncodeSequenceItem items
[3] = {
2753 { &info
->SubjectType
, CRYPT_AsnEncodeBits
, 0 },
2758 if (info
->fPathLenConstraint
)
2760 items
[cItem
].pvStructInfo
= &info
->dwPathLenConstraint
;
2761 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeInt
;
2764 if (info
->cSubtreesConstraint
)
2766 items
[cItem
].pvStructInfo
= &info
->cSubtreesConstraint
;
2767 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSequenceOfAny
;
2770 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
2771 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2775 SetLastError(STATUS_ACCESS_VIOLATION
);
2782 static BOOL WINAPI
CRYPT_AsnEncodeBasicConstraints2(DWORD dwCertEncodingType
,
2783 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2784 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2790 const CERT_BASIC_CONSTRAINTS2_INFO
*info
= pvStructInfo
;
2791 struct AsnEncodeSequenceItem items
[2] = { { 0 } };
2796 items
[cItem
].pvStructInfo
= &info
->fCA
;
2797 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeBool
;
2800 if (info
->fPathLenConstraint
)
2802 items
[cItem
].pvStructInfo
= &info
->dwPathLenConstraint
;
2803 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeInt
;
2806 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
2807 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
2811 SetLastError(STATUS_ACCESS_VIOLATION
);
2818 static BOOL WINAPI
CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType
,
2819 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2820 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2822 const CERT_POLICY_INFO
*info
= pvStructInfo
;
2825 if (!info
->cPolicyQualifier
)
2832 struct AsnEncodeSequenceItem items
[2] = {
2833 { NULL
, CRYPT_AsnEncodeOid
, 0 },
2834 { NULL
, CRYPT_CopyEncodedBlob
, 0 },
2836 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
2839 for (i
= 0; ret
&& i
< info
->cPolicyQualifier
; i
++)
2841 items
[0].pvStructInfo
=
2842 info
->rgPolicyQualifier
[i
].pszPolicyQualifierId
;
2843 items
[1].pvStructInfo
= &info
->rgPolicyQualifier
[i
].Qualifier
;
2844 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
2845 sizeof(items
) / sizeof(items
[0]),
2846 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &size
);
2848 bytesNeeded
+= size
;
2850 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
2851 bytesNeeded
+= 1 + lenBytes
;
2855 *pcbEncoded
= bytesNeeded
;
2858 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2859 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2861 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2862 pbEncoded
= *(BYTE
**)pbEncoded
;
2863 *pbEncoded
++ = ASN_SEQUENCEOF
;
2864 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
2866 pbEncoded
+= lenBytes
;
2867 for (i
= 0; ret
&& i
< info
->cPolicyQualifier
; i
++)
2869 items
[0].pvStructInfo
=
2870 info
->rgPolicyQualifier
[i
].pszPolicyQualifierId
;
2871 items
[1].pvStructInfo
=
2872 &info
->rgPolicyQualifier
[i
].Qualifier
;
2874 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
2875 sizeof(items
) / sizeof(items
[0]),
2876 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pbEncoded
,
2881 bytesNeeded
-= size
;
2891 static BOOL
CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType
,
2892 const CERT_POLICY_INFO
*info
, DWORD dwFlags
, BYTE
*pbEncoded
,
2895 struct AsnEncodeSequenceItem items
[2] = {
2896 { info
->pszPolicyIdentifier
, CRYPT_AsnEncodeOid
, 0 },
2897 { info
, CRYPT_AsnEncodeCertPolicyQualifiers
, 0 },
2901 if (!info
->pszPolicyIdentifier
)
2903 SetLastError(E_INVALIDARG
);
2906 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
2907 sizeof(items
) / sizeof(items
[0]), dwFlags
, NULL
, pbEncoded
, pcbEncoded
);
2911 static BOOL WINAPI
CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType
,
2912 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2913 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2919 const CERT_POLICIES_INFO
*info
= pvStructInfo
;
2920 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
2923 for (i
= 0; ret
&& i
< info
->cPolicyInfo
; i
++)
2925 ret
= CRYPT_AsnEncodeCertPolicy(dwCertEncodingType
,
2926 &info
->rgPolicyInfo
[i
], dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
,
2929 bytesNeeded
+= size
;
2931 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
2932 bytesNeeded
+= 1 + lenBytes
;
2936 *pcbEncoded
= bytesNeeded
;
2939 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
2940 pbEncoded
, pcbEncoded
, bytesNeeded
)))
2942 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
2943 pbEncoded
= *(BYTE
**)pbEncoded
;
2944 *pbEncoded
++ = ASN_SEQUENCEOF
;
2945 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
2947 pbEncoded
+= lenBytes
;
2948 for (i
= 0; ret
&& i
< info
->cPolicyInfo
; i
++)
2951 ret
= CRYPT_AsnEncodeCertPolicy(dwCertEncodingType
,
2952 &info
->rgPolicyInfo
[i
],
2953 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pbEncoded
, &size
);
2957 bytesNeeded
-= size
;
2966 SetLastError(STATUS_ACCESS_VIOLATION
);
2972 static BOOL
CRYPT_AsnEncodeCertPolicyMapping(DWORD dwCertEncodingType
,
2973 const CERT_POLICY_MAPPING
*mapping
, DWORD dwFlags
, BYTE
*pbEncoded
,
2976 struct AsnEncodeSequenceItem items
[] = {
2977 { mapping
->pszIssuerDomainPolicy
, CRYPT_AsnEncodeOid
, 0 },
2978 { mapping
->pszSubjectDomainPolicy
, CRYPT_AsnEncodeOid
, 0 },
2981 if (!mapping
->pszIssuerDomainPolicy
|| !mapping
->pszSubjectDomainPolicy
)
2983 SetLastError(E_INVALIDARG
);
2986 return CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
2987 sizeof(items
) / sizeof(items
[0]), dwFlags
, NULL
, pbEncoded
, pcbEncoded
);
2990 static BOOL WINAPI
CRYPT_AsnEncodeCertPolicyMappings(DWORD dwCertEncodingType
,
2991 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
2992 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
2998 const CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
2999 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
3002 for (i
= 0; ret
&& i
< info
->cPolicyMapping
; i
++)
3004 ret
= CRYPT_AsnEncodeCertPolicyMapping(dwCertEncodingType
,
3005 &info
->rgPolicyMapping
[i
], dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
,
3008 bytesNeeded
+= size
;
3010 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
3011 bytesNeeded
+= 1 + lenBytes
;
3015 *pcbEncoded
= bytesNeeded
;
3018 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
3019 pbEncoded
, pcbEncoded
, bytesNeeded
)))
3021 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3022 pbEncoded
= *(BYTE
**)pbEncoded
;
3023 *pbEncoded
++ = ASN_SEQUENCEOF
;
3024 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
3026 pbEncoded
+= lenBytes
;
3027 for (i
= 0; ret
&& i
< info
->cPolicyMapping
; i
++)
3030 ret
= CRYPT_AsnEncodeCertPolicyMapping(
3031 dwCertEncodingType
, &info
->rgPolicyMapping
[i
],
3032 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pbEncoded
, &size
);
3036 bytesNeeded
-= size
;
3045 SetLastError(STATUS_ACCESS_VIOLATION
);
3051 static BOOL WINAPI
CRYPT_AsnEncodeCertPolicyConstraints(
3052 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
3053 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
3060 const CERT_POLICY_CONSTRAINTS_INFO
*info
= pvStructInfo
;
3061 struct AsnEncodeSequenceItem items
[2];
3062 struct AsnEncodeTagSwappedItem swapped
[2];
3063 DWORD cItem
= 0, cSwapped
= 0;
3065 if (info
->fRequireExplicitPolicy
)
3067 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 0;
3068 swapped
[cSwapped
].pvStructInfo
=
3069 &info
->dwRequireExplicitPolicySkipCerts
;
3070 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInt
;
3071 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3072 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3076 if (info
->fInhibitPolicyMapping
)
3078 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 1;
3079 swapped
[cSwapped
].pvStructInfo
=
3080 &info
->dwInhibitPolicyMappingSkipCerts
;
3081 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInt
;
3082 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3083 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3087 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
3088 dwFlags
, NULL
, pbEncoded
, pcbEncoded
);
3092 SetLastError(STATUS_ACCESS_VIOLATION
);
3098 static BOOL WINAPI
CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType
,
3099 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3100 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3106 const BLOBHEADER
*hdr
= pvStructInfo
;
3108 if (hdr
->bType
!= PUBLICKEYBLOB
)
3110 SetLastError(E_INVALIDARG
);
3115 const RSAPUBKEY
*rsaPubKey
= (const RSAPUBKEY
*)
3116 ((const BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
));
3117 CRYPT_INTEGER_BLOB blob
= { rsaPubKey
->bitlen
/ 8,
3118 (BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) };
3119 struct AsnEncodeSequenceItem items
[] = {
3120 { &blob
, CRYPT_AsnEncodeUnsignedInteger
, 0 },
3121 { &rsaPubKey
->pubexp
, CRYPT_AsnEncodeInt
, 0 },
3124 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
3125 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
3131 SetLastError(STATUS_ACCESS_VIOLATION
);
3138 BOOL WINAPI
CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType
,
3139 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3140 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3146 const CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
3147 DWORD bytesNeeded
, lenBytes
;
3149 TRACE("(%d, %p), %08x, %p, %p, %d\n", blob
->cbData
, blob
->pbData
,
3150 dwFlags
, pEncodePara
, pbEncoded
, *pcbEncoded
);
3152 CRYPT_EncodeLen(blob
->cbData
, NULL
, &lenBytes
);
3153 bytesNeeded
= 1 + lenBytes
+ blob
->cbData
;
3156 *pcbEncoded
= bytesNeeded
;
3161 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3162 pcbEncoded
, bytesNeeded
)))
3164 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3165 pbEncoded
= *(BYTE
**)pbEncoded
;
3166 *pbEncoded
++ = ASN_OCTETSTRING
;
3167 CRYPT_EncodeLen(blob
->cbData
, pbEncoded
, &lenBytes
);
3168 pbEncoded
+= lenBytes
;
3170 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
3176 SetLastError(STATUS_ACCESS_VIOLATION
);
3180 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3184 static BOOL WINAPI
CRYPT_AsnEncodeBits(DWORD dwCertEncodingType
,
3185 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3186 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3192 const CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
3193 DWORD bytesNeeded
, lenBytes
, dataBytes
;
3196 /* yep, MS allows cUnusedBits to be >= 8 */
3197 if (!blob
->cUnusedBits
)
3199 dataBytes
= blob
->cbData
;
3202 else if (blob
->cbData
* 8 > blob
->cUnusedBits
)
3204 dataBytes
= (blob
->cbData
* 8 - blob
->cUnusedBits
) / 8 + 1;
3205 unusedBits
= blob
->cUnusedBits
>= 8 ? blob
->cUnusedBits
/ 8 :
3213 CRYPT_EncodeLen(dataBytes
+ 1, NULL
, &lenBytes
);
3214 bytesNeeded
= 1 + lenBytes
+ dataBytes
+ 1;
3217 *pcbEncoded
= bytesNeeded
;
3222 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3223 pcbEncoded
, bytesNeeded
)))
3225 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3226 pbEncoded
= *(BYTE
**)pbEncoded
;
3227 *pbEncoded
++ = ASN_BITSTRING
;
3228 CRYPT_EncodeLen(dataBytes
+ 1, pbEncoded
, &lenBytes
);
3229 pbEncoded
+= lenBytes
;
3230 *pbEncoded
++ = unusedBits
;
3233 BYTE mask
= 0xff << unusedBits
;
3237 memcpy(pbEncoded
, blob
->pbData
, dataBytes
- 1);
3238 pbEncoded
+= dataBytes
- 1;
3240 *pbEncoded
= *(blob
->pbData
+ dataBytes
- 1) & mask
;
3247 SetLastError(STATUS_ACCESS_VIOLATION
);
3254 static BOOL WINAPI
CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType
,
3255 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3256 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3262 const CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
3263 CRYPT_BIT_BLOB newBlob
= { blob
->cbData
, NULL
, blob
->cUnusedBits
};
3268 newBlob
.pbData
= CryptMemAlloc(newBlob
.cbData
);
3273 for (i
= 0; i
< newBlob
.cbData
; i
++)
3274 newBlob
.pbData
[newBlob
.cbData
- i
- 1] = blob
->pbData
[i
];
3280 ret
= CRYPT_AsnEncodeBits(dwCertEncodingType
, lpszStructType
,
3281 &newBlob
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
3282 CryptMemFree(newBlob
.pbData
);
3286 SetLastError(STATUS_ACCESS_VIOLATION
);
3293 static BOOL WINAPI
CRYPT_AsnEncodeInt(DWORD dwCertEncodingType
,
3294 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3295 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3297 CRYPT_INTEGER_BLOB blob
= { sizeof(INT
), (BYTE
*)pvStructInfo
};
3299 return CRYPT_AsnEncodeInteger(dwCertEncodingType
, X509_MULTI_BYTE_INTEGER
,
3300 &blob
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
3303 static BOOL WINAPI
CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType
,
3304 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3305 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3311 DWORD significantBytes
, lenBytes
, bytesNeeded
;
3314 const CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
3316 significantBytes
= blob
->cbData
;
3317 if (significantBytes
)
3319 if (blob
->pbData
[significantBytes
- 1] & 0x80)
3321 /* negative, lop off leading (little-endian) 0xffs */
3322 for (; significantBytes
> 0 &&
3323 blob
->pbData
[significantBytes
- 1] == 0xff; significantBytes
--)
3325 if (blob
->pbData
[significantBytes
- 1] < 0x80)
3333 /* positive, lop off leading (little-endian) zeroes */
3334 for (; significantBytes
> 0 &&
3335 !blob
->pbData
[significantBytes
- 1]; significantBytes
--)
3337 if (significantBytes
== 0)
3338 significantBytes
= 1;
3339 if (blob
->pbData
[significantBytes
- 1] > 0x7f)
3347 CRYPT_EncodeLen(significantBytes
+ 1, NULL
, &lenBytes
);
3349 CRYPT_EncodeLen(significantBytes
, NULL
, &lenBytes
);
3350 bytesNeeded
= 1 + lenBytes
+ significantBytes
;
3355 *pcbEncoded
= bytesNeeded
;
3360 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3361 pcbEncoded
, bytesNeeded
)))
3363 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3364 pbEncoded
= *(BYTE
**)pbEncoded
;
3365 *pbEncoded
++ = ASN_INTEGER
;
3368 CRYPT_EncodeLen(significantBytes
+ 1, pbEncoded
, &lenBytes
);
3369 pbEncoded
+= lenBytes
;
3370 *pbEncoded
++ = padByte
;
3374 CRYPT_EncodeLen(significantBytes
, pbEncoded
, &lenBytes
);
3375 pbEncoded
+= lenBytes
;
3377 for (; significantBytes
> 0; significantBytes
--)
3378 *(pbEncoded
++) = blob
->pbData
[significantBytes
- 1];
3384 SetLastError(STATUS_ACCESS_VIOLATION
);
3391 static BOOL WINAPI
CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType
,
3392 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3393 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3399 DWORD significantBytes
, lenBytes
, bytesNeeded
;
3401 const CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
3403 significantBytes
= blob
->cbData
;
3404 if (significantBytes
)
3406 /* positive, lop off leading (little-endian) zeroes */
3407 for (; significantBytes
> 0 && !blob
->pbData
[significantBytes
- 1];
3410 if (significantBytes
== 0)
3411 significantBytes
= 1;
3412 if (blob
->pbData
[significantBytes
- 1] > 0x7f)
3416 CRYPT_EncodeLen(significantBytes
+ 1, NULL
, &lenBytes
);
3418 CRYPT_EncodeLen(significantBytes
, NULL
, &lenBytes
);
3419 bytesNeeded
= 1 + lenBytes
+ significantBytes
;
3424 *pcbEncoded
= bytesNeeded
;
3429 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3430 pcbEncoded
, bytesNeeded
)))
3432 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3433 pbEncoded
= *(BYTE
**)pbEncoded
;
3434 *pbEncoded
++ = ASN_INTEGER
;
3437 CRYPT_EncodeLen(significantBytes
+ 1, pbEncoded
, &lenBytes
);
3438 pbEncoded
+= lenBytes
;
3443 CRYPT_EncodeLen(significantBytes
, pbEncoded
, &lenBytes
);
3444 pbEncoded
+= lenBytes
;
3446 for (; significantBytes
> 0; significantBytes
--)
3447 *(pbEncoded
++) = blob
->pbData
[significantBytes
- 1];
3453 SetLastError(STATUS_ACCESS_VIOLATION
);
3460 static BOOL WINAPI
CRYPT_AsnEncodeEnumerated(DWORD dwCertEncodingType
,
3461 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3462 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3464 CRYPT_INTEGER_BLOB blob
;
3467 /* Encode as an unsigned integer, then change the tag to enumerated */
3468 blob
.cbData
= sizeof(DWORD
);
3469 blob
.pbData
= (BYTE
*)pvStructInfo
;
3470 ret
= CRYPT_AsnEncodeUnsignedInteger(dwCertEncodingType
,
3471 X509_MULTI_BYTE_UINT
, &blob
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
3472 if (ret
&& pbEncoded
)
3474 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3475 pbEncoded
= *(BYTE
**)pbEncoded
;
3476 pbEncoded
[0] = ASN_ENUMERATED
;
3481 static BOOL WINAPI
CRYPT_AsnEncodeUtcTime(DWORD dwCertEncodingType
,
3482 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3483 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3490 /* sorry, magic number: enough for tag, len, YYMMDDHHMMSSZ\0. I use a
3491 * temporary buffer because the output buffer is not NULL-terminated.
3494 static const DWORD bytesNeeded
= sizeof(buf
) - 1;
3498 *pcbEncoded
= bytesNeeded
;
3503 /* Sanity check the year, this is a two-digit year format */
3504 ret
= FileTimeToSystemTime(pvStructInfo
, &sysTime
);
3505 if (ret
&& (sysTime
.wYear
< 1950 || sysTime
.wYear
> 2050))
3507 SetLastError(CRYPT_E_BAD_ENCODE
);
3512 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
3513 pbEncoded
, pcbEncoded
, bytesNeeded
)))
3515 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3516 pbEncoded
= *(BYTE
**)pbEncoded
;
3517 buf
[0] = ASN_UTCTIME
;
3518 buf
[1] = bytesNeeded
- 2;
3519 snprintf(buf
+ 2, sizeof(buf
) - 2,
3520 "%02d%02d%02d%02d%02d%02dZ", sysTime
.wYear
>= 2000 ?
3521 sysTime
.wYear
- 2000 : sysTime
.wYear
- 1900,
3522 sysTime
.wMonth
, sysTime
.wDay
, sysTime
.wHour
,
3523 sysTime
.wMinute
, sysTime
.wSecond
);
3524 memcpy(pbEncoded
, buf
, bytesNeeded
);
3531 SetLastError(STATUS_ACCESS_VIOLATION
);
3538 static BOOL
CRYPT_AsnEncodeGeneralizedTime(DWORD dwCertEncodingType
,
3539 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3540 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3547 /* sorry, magic number: enough for tag, len, YYYYMMDDHHMMSSZ\0. I use a
3548 * temporary buffer because the output buffer is not NULL-terminated.
3551 static const DWORD bytesNeeded
= sizeof(buf
) - 1;
3555 *pcbEncoded
= bytesNeeded
;
3560 ret
= FileTimeToSystemTime(pvStructInfo
, &sysTime
);
3562 ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3563 pcbEncoded
, bytesNeeded
);
3566 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3567 pbEncoded
= *(BYTE
**)pbEncoded
;
3568 buf
[0] = ASN_GENERALTIME
;
3569 buf
[1] = bytesNeeded
- 2;
3570 snprintf(buf
+ 2, sizeof(buf
) - 2, "%04d%02d%02d%02d%02d%02dZ",
3571 sysTime
.wYear
, sysTime
.wMonth
, sysTime
.wDay
, sysTime
.wHour
,
3572 sysTime
.wMinute
, sysTime
.wSecond
);
3573 memcpy(pbEncoded
, buf
, bytesNeeded
);
3579 SetLastError(STATUS_ACCESS_VIOLATION
);
3586 static BOOL WINAPI
CRYPT_AsnEncodeChoiceOfTime(DWORD dwCertEncodingType
,
3587 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3588 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3596 /* Check the year, if it's in the UTCTime range call that encode func */
3597 if (!FileTimeToSystemTime(pvStructInfo
, &sysTime
))
3599 if (sysTime
.wYear
>= 1950 && sysTime
.wYear
<= 2050)
3600 ret
= CRYPT_AsnEncodeUtcTime(dwCertEncodingType
, lpszStructType
,
3601 pvStructInfo
, dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
3603 ret
= CRYPT_AsnEncodeGeneralizedTime(dwCertEncodingType
,
3604 lpszStructType
, pvStructInfo
, dwFlags
, pEncodePara
, pbEncoded
,
3609 SetLastError(STATUS_ACCESS_VIOLATION
);
3616 static BOOL WINAPI
CRYPT_AsnEncodeSequenceOfAny(DWORD dwCertEncodingType
,
3617 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3618 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3624 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
3625 const CRYPT_SEQUENCE_OF_ANY
*seq
= pvStructInfo
;
3627 for (i
= 0, dataLen
= 0; i
< seq
->cValue
; i
++)
3628 dataLen
+= seq
->rgValue
[i
].cbData
;
3629 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
3630 bytesNeeded
= 1 + lenBytes
+ dataLen
;
3633 *pcbEncoded
= bytesNeeded
;
3638 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
, pbEncoded
,
3639 pcbEncoded
, bytesNeeded
)))
3641 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3642 pbEncoded
= *(BYTE
**)pbEncoded
;
3643 *pbEncoded
++ = ASN_SEQUENCEOF
;
3644 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
3645 pbEncoded
+= lenBytes
;
3646 for (i
= 0; i
< seq
->cValue
; i
++)
3648 memcpy(pbEncoded
, seq
->rgValue
[i
].pbData
,
3649 seq
->rgValue
[i
].cbData
);
3650 pbEncoded
+= seq
->rgValue
[i
].cbData
;
3657 SetLastError(STATUS_ACCESS_VIOLATION
);
3664 static BOOL
CRYPT_AsnEncodeDistPoint(const CRL_DIST_POINT
*distPoint
,
3665 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3668 struct AsnEncodeSequenceItem items
[3] = { { 0 } };
3669 struct AsnConstructedItem constructed
= { 0 };
3670 struct AsnEncodeTagSwappedItem swapped
[3] = { { 0 } };
3671 DWORD cItem
= 0, cSwapped
= 0;
3673 switch (distPoint
->DistPointName
.dwDistPointNameChoice
)
3675 case CRL_DIST_POINT_NO_NAME
:
3678 case CRL_DIST_POINT_FULL_NAME
:
3679 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0;
3680 swapped
[cSwapped
].pvStructInfo
= &distPoint
->DistPointName
.u
.FullName
;
3681 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeAltName
;
3682 constructed
.tag
= 0;
3683 constructed
.pvStructInfo
= &swapped
[cSwapped
];
3684 constructed
.encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3685 items
[cItem
].pvStructInfo
= &constructed
;
3686 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
3690 case CRL_DIST_POINT_ISSUER_RDN_NAME
:
3691 FIXME("unimplemented for CRL_DIST_POINT_ISSUER_RDN_NAME\n");
3697 if (ret
&& distPoint
->ReasonFlags
.cbData
)
3699 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 1;
3700 swapped
[cSwapped
].pvStructInfo
= &distPoint
->ReasonFlags
;
3701 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBits
;
3702 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3703 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3707 if (ret
&& distPoint
->CRLIssuer
.cAltEntry
)
3709 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2;
3710 swapped
[cSwapped
].pvStructInfo
= &distPoint
->CRLIssuer
;
3711 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeAltName
;
3712 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3713 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3718 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
, items
, cItem
, 0, NULL
,
3719 pbEncoded
, pcbEncoded
);
3723 static BOOL WINAPI
CRYPT_AsnEncodeCRLDistPoints(DWORD dwCertEncodingType
,
3724 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3725 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3731 const CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
3733 if (!info
->cDistPoint
)
3735 SetLastError(E_INVALIDARG
);
3740 DWORD bytesNeeded
, dataLen
, lenBytes
, i
;
3743 for (i
= 0, dataLen
= 0; ret
&& i
< info
->cDistPoint
; i
++)
3747 ret
= CRYPT_AsnEncodeDistPoint(&info
->rgDistPoint
[i
], NULL
,
3751 else if (GetLastError() == CRYPT_E_INVALID_IA5_STRING
)
3753 /* Have to propagate index of failing character */
3759 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
3760 bytesNeeded
= 1 + lenBytes
+ dataLen
;
3763 *pcbEncoded
= bytesNeeded
;
3768 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
3769 pbEncoded
, pcbEncoded
, bytesNeeded
)))
3771 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3772 pbEncoded
= *(BYTE
**)pbEncoded
;
3773 *pbEncoded
++ = ASN_SEQUENCEOF
;
3774 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
3775 pbEncoded
+= lenBytes
;
3776 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
3778 DWORD len
= dataLen
;
3780 ret
= CRYPT_AsnEncodeDistPoint(
3781 &info
->rgDistPoint
[i
], pbEncoded
, &len
);
3795 SetLastError(STATUS_ACCESS_VIOLATION
);
3802 static BOOL WINAPI
CRYPT_AsnEncodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3803 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3804 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3810 const CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
3811 DWORD bytesNeeded
= 0, lenBytes
, size
, i
;
3814 for (i
= 0; ret
&& i
< usage
->cUsageIdentifier
; i
++)
3816 ret
= CRYPT_AsnEncodeOid(dwCertEncodingType
, NULL
,
3817 usage
->rgpszUsageIdentifier
[i
],
3818 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &size
);
3820 bytesNeeded
+= size
;
3822 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
3823 bytesNeeded
+= 1 + lenBytes
;
3827 *pcbEncoded
= bytesNeeded
;
3830 if ((ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
3831 pbEncoded
, pcbEncoded
, bytesNeeded
)))
3833 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
3834 pbEncoded
= *(BYTE
**)pbEncoded
;
3835 *pbEncoded
++ = ASN_SEQUENCEOF
;
3836 CRYPT_EncodeLen(bytesNeeded
- lenBytes
- 1, pbEncoded
,
3838 pbEncoded
+= lenBytes
;
3839 for (i
= 0; ret
&& i
< usage
->cUsageIdentifier
; i
++)
3842 ret
= CRYPT_AsnEncodeOid(dwCertEncodingType
, NULL
,
3843 usage
->rgpszUsageIdentifier
[i
],
3844 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pbEncoded
,
3849 bytesNeeded
-= size
;
3858 SetLastError(STATUS_ACCESS_VIOLATION
);
3865 static BOOL WINAPI
CRYPT_AsnEncodeIssuingDistPoint(DWORD dwCertEncodingType
,
3866 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3867 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3873 const CRL_ISSUING_DIST_POINT
*point
= pvStructInfo
;
3874 struct AsnEncodeSequenceItem items
[6] = { { 0 } };
3875 struct AsnConstructedItem constructed
= { 0 };
3876 struct AsnEncodeTagSwappedItem swapped
[5] = { { 0 } };
3877 DWORD cItem
= 0, cSwapped
= 0;
3880 switch (point
->DistPointName
.dwDistPointNameChoice
)
3882 case CRL_DIST_POINT_NO_NAME
:
3885 case CRL_DIST_POINT_FULL_NAME
:
3886 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0;
3887 swapped
[cSwapped
].pvStructInfo
= &point
->DistPointName
.u
.FullName
;
3888 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeAltName
;
3889 constructed
.tag
= 0;
3890 constructed
.pvStructInfo
= &swapped
[cSwapped
];
3891 constructed
.encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3892 items
[cItem
].pvStructInfo
= &constructed
;
3893 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
3898 SetLastError(E_INVALIDARG
);
3901 if (ret
&& point
->fOnlyContainsUserCerts
)
3903 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 1;
3904 swapped
[cSwapped
].pvStructInfo
= &point
->fOnlyContainsUserCerts
;
3905 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBool
;
3906 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3907 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3911 if (ret
&& point
->fOnlyContainsCACerts
)
3913 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 2;
3914 swapped
[cSwapped
].pvStructInfo
= &point
->fOnlyContainsCACerts
;
3915 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBool
;
3916 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3917 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3921 if (ret
&& point
->OnlySomeReasonFlags
.cbData
)
3923 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 3;
3924 swapped
[cSwapped
].pvStructInfo
= &point
->OnlySomeReasonFlags
;
3925 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBits
;
3926 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3927 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3931 if (ret
&& point
->fIndirectCRL
)
3933 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 4;
3934 swapped
[cSwapped
].pvStructInfo
= &point
->fIndirectCRL
;
3935 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeBool
;
3936 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3937 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3942 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
3943 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
3947 SetLastError(STATUS_ACCESS_VIOLATION
);
3954 static BOOL
CRYPT_AsnEncodeGeneralSubtree(DWORD dwCertEncodingType
,
3955 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3956 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3959 const CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
3960 struct AsnEncodeSequenceItem items
[3] = {
3961 { &subtree
->Base
, CRYPT_AsnEncodeAltNameEntry
, 0 },
3964 struct AsnEncodeTagSwappedItem swapped
[2] = { { 0 } };
3965 DWORD cItem
= 1, cSwapped
= 0;
3967 if (subtree
->dwMinimum
)
3969 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 0;
3970 swapped
[cSwapped
].pvStructInfo
= &subtree
->dwMinimum
;
3971 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInt
;
3972 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3973 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3977 if (subtree
->fMaximum
)
3979 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 1;
3980 swapped
[cSwapped
].pvStructInfo
= &subtree
->dwMaximum
;
3981 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeInt
;
3982 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
3983 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
3987 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
, dwFlags
,
3988 pEncodePara
, pbEncoded
, pcbEncoded
);
3992 static BOOL WINAPI
CRYPT_AsnEncodeNameConstraints(DWORD dwCertEncodingType
,
3993 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
3994 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
3997 CRYPT_BLOB_ARRAY permitted
= { 0, NULL
}, excluded
= { 0, NULL
};
3999 TRACE("%p\n", pvStructInfo
);
4003 const CERT_NAME_CONSTRAINTS_INFO
*constraints
= pvStructInfo
;
4004 struct AsnEncodeSequenceItem items
[2] = { { 0 } };
4005 struct AsnEncodeTagSwappedItem swapped
[2] = { { 0 } };
4006 DWORD i
, cItem
= 0, cSwapped
= 0;
4009 if (constraints
->cPermittedSubtree
)
4011 permitted
.rgBlob
= CryptMemAlloc(
4012 constraints
->cPermittedSubtree
* sizeof(CRYPT_DER_BLOB
));
4013 if (permitted
.rgBlob
)
4015 permitted
.cBlob
= constraints
->cPermittedSubtree
;
4016 memset(permitted
.rgBlob
, 0,
4017 permitted
.cBlob
* sizeof(CRYPT_DER_BLOB
));
4018 for (i
= 0; ret
&& i
< permitted
.cBlob
; i
++)
4019 ret
= CRYPT_AsnEncodeGeneralSubtree(dwCertEncodingType
,
4020 NULL
, &constraints
->rgPermittedSubtree
[i
],
4021 CRYPT_ENCODE_ALLOC_FLAG
, NULL
,
4022 (BYTE
*)&permitted
.rgBlob
[i
].pbData
,
4023 &permitted
.rgBlob
[i
].cbData
);
4026 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0;
4027 swapped
[cSwapped
].pvStructInfo
= &permitted
;
4028 swapped
[cSwapped
].encodeFunc
= CRYPT_DEREncodeSet
;
4029 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4030 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4038 if (constraints
->cExcludedSubtree
)
4040 excluded
.rgBlob
= CryptMemAlloc(
4041 constraints
->cExcludedSubtree
* sizeof(CRYPT_DER_BLOB
));
4042 if (excluded
.rgBlob
)
4044 excluded
.cBlob
= constraints
->cExcludedSubtree
;
4045 memset(excluded
.rgBlob
, 0,
4046 excluded
.cBlob
* sizeof(CRYPT_DER_BLOB
));
4047 for (i
= 0; ret
&& i
< excluded
.cBlob
; i
++)
4048 ret
= CRYPT_AsnEncodeGeneralSubtree(dwCertEncodingType
,
4049 NULL
, &constraints
->rgExcludedSubtree
[i
],
4050 CRYPT_ENCODE_ALLOC_FLAG
, NULL
,
4051 (BYTE
*)&excluded
.rgBlob
[i
].pbData
,
4052 &excluded
.rgBlob
[i
].cbData
);
4055 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1;
4056 swapped
[cSwapped
].pvStructInfo
= &excluded
;
4057 swapped
[cSwapped
].encodeFunc
= CRYPT_DEREncodeSet
;
4058 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4059 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4068 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
4069 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
4070 for (i
= 0; i
< permitted
.cBlob
; i
++)
4071 LocalFree(permitted
.rgBlob
[i
].pbData
);
4072 for (i
= 0; i
< excluded
.cBlob
; i
++)
4073 LocalFree(excluded
.rgBlob
[i
].pbData
);
4077 SetLastError(STATUS_ACCESS_VIOLATION
);
4080 CryptMemFree(permitted
.rgBlob
);
4081 CryptMemFree(excluded
.rgBlob
);
4082 TRACE("returning %d\n", ret
);
4086 static BOOL WINAPI
CRYPT_AsnEncodeIssuerSerialNumber(
4087 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
4088 DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
,
4092 const CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
4093 struct AsnEncodeSequenceItem items
[] = {
4094 { &issuerSerial
->Issuer
, CRYPT_CopyEncodedBlob
, 0 },
4095 { &issuerSerial
->SerialNumber
, CRYPT_AsnEncodeInteger
, 0 },
4098 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
4099 sizeof(items
) / sizeof(items
[0]), dwFlags
, pEncodePara
, pbEncoded
,
4104 static BOOL WINAPI
CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType
,
4105 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
4106 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
4110 if (!(dwCertEncodingType
& PKCS_7_ASN_ENCODING
))
4112 SetLastError(E_INVALIDARG
);
4118 const CMSG_SIGNER_INFO
*info
= pvStructInfo
;
4120 if (!info
->Issuer
.cbData
)
4121 SetLastError(E_INVALIDARG
);
4124 struct AsnEncodeSequenceItem items
[7] = {
4125 { &info
->dwVersion
, CRYPT_AsnEncodeInt
, 0 },
4126 { &info
->Issuer
, CRYPT_AsnEncodeIssuerSerialNumber
, 0 },
4127 { &info
->HashAlgorithm
, CRYPT_AsnEncodeAlgorithmIdWithNullParams
,
4130 struct AsnEncodeTagSwappedItem swapped
[2] = { { 0 } };
4131 DWORD cItem
= 3, cSwapped
= 0;
4133 if (info
->AuthAttrs
.cAttr
)
4135 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0;
4136 swapped
[cSwapped
].pvStructInfo
= &info
->AuthAttrs
;
4137 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodePKCSAttributes
;
4138 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4139 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4143 items
[cItem
].pvStructInfo
= &info
->HashEncryptionAlgorithm
;
4144 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeAlgorithmIdWithNullParams
;
4146 items
[cItem
].pvStructInfo
= &info
->EncryptedHash
;
4147 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeOctets
;
4149 if (info
->UnauthAttrs
.cAttr
)
4151 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1;
4152 swapped
[cSwapped
].pvStructInfo
= &info
->UnauthAttrs
;
4153 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodePKCSAttributes
;
4154 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4155 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4159 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
4160 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
4165 SetLastError(STATUS_ACCESS_VIOLATION
);
4171 static BOOL WINAPI
CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType
,
4172 LPCSTR lpszStructType
, const void *pvStructInfo
, DWORD dwFlags
,
4173 PCRYPT_ENCODE_PARA pEncodePara
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
4177 if (!(dwCertEncodingType
& PKCS_7_ASN_ENCODING
))
4179 SetLastError(E_INVALIDARG
);
4185 const CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
4187 if (info
->SignerId
.dwIdChoice
!= CERT_ID_ISSUER_SERIAL_NUMBER
&&
4188 info
->SignerId
.dwIdChoice
!= CERT_ID_KEY_IDENTIFIER
)
4189 SetLastError(E_INVALIDARG
);
4190 else if (info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
&&
4191 !info
->SignerId
.u
.IssuerSerialNumber
.Issuer
.cbData
)
4192 SetLastError(E_INVALIDARG
);
4195 struct AsnEncodeSequenceItem items
[7] = {
4196 { &info
->dwVersion
, CRYPT_AsnEncodeInt
, 0 },
4198 struct AsnEncodeTagSwappedItem swapped
[3] = { { 0 } };
4199 DWORD cItem
= 1, cSwapped
= 0;
4201 if (info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
)
4203 items
[cItem
].pvStructInfo
=
4204 &info
->SignerId
.u
.IssuerSerialNumber
.Issuer
;
4205 items
[cItem
].encodeFunc
=
4206 CRYPT_AsnEncodeIssuerSerialNumber
;
4211 swapped
[cSwapped
].tag
= ASN_CONTEXT
| 0;
4212 swapped
[cSwapped
].pvStructInfo
= &info
->SignerId
.u
.KeyId
;
4213 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodeOctets
;
4214 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4215 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4219 items
[cItem
].pvStructInfo
= &info
->HashAlgorithm
;
4220 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeAlgorithmIdWithNullParams
;
4222 if (info
->AuthAttrs
.cAttr
)
4224 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0;
4225 swapped
[cSwapped
].pvStructInfo
= &info
->AuthAttrs
;
4226 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodePKCSAttributes
;
4227 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4228 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4232 items
[cItem
].pvStructInfo
= &info
->HashEncryptionAlgorithm
;
4233 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeAlgorithmIdWithNullParams
;
4235 items
[cItem
].pvStructInfo
= &info
->EncryptedHash
;
4236 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeOctets
;
4238 if (info
->UnauthAttrs
.cAttr
)
4240 swapped
[cSwapped
].tag
= ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1;
4241 swapped
[cSwapped
].pvStructInfo
= &info
->UnauthAttrs
;
4242 swapped
[cSwapped
].encodeFunc
= CRYPT_AsnEncodePKCSAttributes
;
4243 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4244 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4248 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
4249 dwFlags
, pEncodePara
, pbEncoded
, pcbEncoded
);
4254 SetLastError(STATUS_ACCESS_VIOLATION
);
4260 BOOL
CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO
*signedInfo
, void *pvData
,
4263 struct AsnEncodeSequenceItem items
[7] = {
4264 { &signedInfo
->version
, CRYPT_AsnEncodeInt
, 0 },
4266 struct DERSetDescriptor digestAlgorithmsSet
= { 0 }, certSet
= { 0 };
4267 struct DERSetDescriptor crlSet
= { 0 }, signerSet
= { 0 };
4268 struct AsnEncodeTagSwappedItem swapped
[2] = { { 0 } };
4269 DWORD cItem
= 1, cSwapped
= 0;
4272 if (signedInfo
->cSignerInfo
)
4274 digestAlgorithmsSet
.cItems
= signedInfo
->cSignerInfo
;
4275 digestAlgorithmsSet
.items
= signedInfo
->rgSignerInfo
;
4276 digestAlgorithmsSet
.itemSize
= sizeof(CMSG_CMS_SIGNER_INFO
);
4277 digestAlgorithmsSet
.itemOffset
=
4278 offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
);
4279 digestAlgorithmsSet
.encode
= CRYPT_AsnEncodeAlgorithmIdWithNullParams
;
4280 items
[cItem
].pvStructInfo
= &digestAlgorithmsSet
;
4281 items
[cItem
].encodeFunc
= CRYPT_DEREncodeItemsAsSet
;
4284 items
[cItem
].pvStructInfo
= &signedInfo
->content
;
4285 items
[cItem
].encodeFunc
= CRYPT_AsnEncodePKCSContentInfoInternal
;
4287 if (signedInfo
->cCertEncoded
)
4289 certSet
.cItems
= signedInfo
->cCertEncoded
;
4290 certSet
.items
= signedInfo
->rgCertEncoded
;
4291 certSet
.itemSize
= sizeof(CERT_BLOB
);
4292 certSet
.itemOffset
= 0;
4293 certSet
.encode
= CRYPT_CopyEncodedBlob
;
4294 swapped
[cSwapped
].tag
= ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0;
4295 swapped
[cSwapped
].pvStructInfo
= &certSet
;
4296 swapped
[cSwapped
].encodeFunc
= CRYPT_DEREncodeItemsAsSet
;
4297 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4298 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4302 if (signedInfo
->cCrlEncoded
)
4304 crlSet
.cItems
= signedInfo
->cCrlEncoded
;
4305 crlSet
.items
= signedInfo
->rgCrlEncoded
;
4306 crlSet
.itemSize
= sizeof(CRL_BLOB
);
4307 crlSet
.itemOffset
= 0;
4308 crlSet
.encode
= CRYPT_CopyEncodedBlob
;
4309 swapped
[cSwapped
].tag
= ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1;
4310 swapped
[cSwapped
].pvStructInfo
= &crlSet
;
4311 swapped
[cSwapped
].encodeFunc
= CRYPT_DEREncodeItemsAsSet
;
4312 items
[cItem
].pvStructInfo
= &swapped
[cSwapped
];
4313 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeSwapTag
;
4317 if (ret
&& signedInfo
->cSignerInfo
)
4319 signerSet
.cItems
= signedInfo
->cSignerInfo
;
4320 signerSet
.items
= signedInfo
->rgSignerInfo
;
4321 signerSet
.itemSize
= sizeof(CMSG_CMS_SIGNER_INFO
);
4322 signerSet
.itemOffset
= 0;
4323 signerSet
.encode
= CRYPT_AsnEncodeCMSSignerInfo
;
4324 items
[cItem
].pvStructInfo
= &signerSet
;
4325 items
[cItem
].encodeFunc
= CRYPT_DEREncodeItemsAsSet
;
4329 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
,
4330 items
, cItem
, 0, NULL
, pvData
, pcbData
);
4335 static CryptEncodeObjectExFunc
CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType
,
4336 LPCSTR lpszStructType
)
4338 CryptEncodeObjectExFunc encodeFunc
= NULL
;
4340 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4341 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4343 SetLastError(ERROR_FILE_NOT_FOUND
);
4347 if (!HIWORD(lpszStructType
))
4349 switch (LOWORD(lpszStructType
))
4351 case LOWORD(X509_CERT
):
4352 encodeFunc
= CRYPT_AsnEncodeCert
;
4354 case LOWORD(X509_CERT_TO_BE_SIGNED
):
4355 encodeFunc
= CRYPT_AsnEncodeCertInfo
;
4357 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
4358 encodeFunc
= CRYPT_AsnEncodeCRLInfo
;
4360 case LOWORD(X509_EXTENSIONS
):
4361 encodeFunc
= CRYPT_AsnEncodeExtensions
;
4363 case LOWORD(X509_NAME_VALUE
):
4364 encodeFunc
= CRYPT_AsnEncodeNameValue
;
4366 case LOWORD(X509_NAME
):
4367 encodeFunc
= CRYPT_AsnEncodeName
;
4369 case LOWORD(X509_PUBLIC_KEY_INFO
):
4370 encodeFunc
= CRYPT_AsnEncodePubKeyInfo
;
4372 case LOWORD(X509_AUTHORITY_KEY_ID
):
4373 encodeFunc
= CRYPT_AsnEncodeAuthorityKeyId
;
4375 case LOWORD(X509_ALTERNATE_NAME
):
4376 encodeFunc
= CRYPT_AsnEncodeAltName
;
4378 case LOWORD(X509_BASIC_CONSTRAINTS
):
4379 encodeFunc
= CRYPT_AsnEncodeBasicConstraints
;
4381 case LOWORD(X509_BASIC_CONSTRAINTS2
):
4382 encodeFunc
= CRYPT_AsnEncodeBasicConstraints2
;
4384 case LOWORD(X509_CERT_POLICIES
):
4385 encodeFunc
= CRYPT_AsnEncodeCertPolicies
;
4387 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
4388 encodeFunc
= CRYPT_AsnEncodeRsaPubKey
;
4390 case LOWORD(X509_UNICODE_NAME
):
4391 encodeFunc
= CRYPT_AsnEncodeUnicodeName
;
4393 case LOWORD(PKCS_CONTENT_INFO
):
4394 encodeFunc
= CRYPT_AsnEncodePKCSContentInfo
;
4396 case LOWORD(PKCS_ATTRIBUTE
):
4397 encodeFunc
= CRYPT_AsnEncodePKCSAttribute
;
4399 case LOWORD(X509_UNICODE_NAME_VALUE
):
4400 encodeFunc
= CRYPT_AsnEncodeUnicodeNameValue
;
4402 case LOWORD(X509_OCTET_STRING
):
4403 encodeFunc
= CRYPT_AsnEncodeOctets
;
4405 case LOWORD(X509_BITS
):
4406 case LOWORD(X509_KEY_USAGE
):
4407 encodeFunc
= CRYPT_AsnEncodeBits
;
4409 case LOWORD(X509_INTEGER
):
4410 encodeFunc
= CRYPT_AsnEncodeInt
;
4412 case LOWORD(X509_MULTI_BYTE_INTEGER
):
4413 encodeFunc
= CRYPT_AsnEncodeInteger
;
4415 case LOWORD(X509_MULTI_BYTE_UINT
):
4416 encodeFunc
= CRYPT_AsnEncodeUnsignedInteger
;
4418 case LOWORD(X509_ENUMERATED
):
4419 encodeFunc
= CRYPT_AsnEncodeEnumerated
;
4421 case LOWORD(X509_CHOICE_OF_TIME
):
4422 encodeFunc
= CRYPT_AsnEncodeChoiceOfTime
;
4424 case LOWORD(X509_AUTHORITY_KEY_ID2
):
4425 encodeFunc
= CRYPT_AsnEncodeAuthorityKeyId2
;
4427 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
4428 encodeFunc
= CRYPT_AsnEncodeAuthorityInfoAccess
;
4430 case LOWORD(X509_SEQUENCE_OF_ANY
):
4431 encodeFunc
= CRYPT_AsnEncodeSequenceOfAny
;
4433 case LOWORD(PKCS_UTC_TIME
):
4434 encodeFunc
= CRYPT_AsnEncodeUtcTime
;
4436 case LOWORD(X509_CRL_DIST_POINTS
):
4437 encodeFunc
= CRYPT_AsnEncodeCRLDistPoints
;
4439 case LOWORD(X509_ENHANCED_KEY_USAGE
):
4440 encodeFunc
= CRYPT_AsnEncodeEnhancedKeyUsage
;
4442 case LOWORD(PKCS_CTL
):
4443 encodeFunc
= CRYPT_AsnEncodeCTL
;
4445 case LOWORD(PKCS_SMIME_CAPABILITIES
):
4446 encodeFunc
= CRYPT_AsnEncodeSMIMECapabilities
;
4448 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
4449 encodeFunc
= CRYPT_AsnEncodePolicyQualifierUserNotice
;
4451 case LOWORD(PKCS_ATTRIBUTES
):
4452 encodeFunc
= CRYPT_AsnEncodePKCSAttributes
;
4454 case LOWORD(X509_ISSUING_DIST_POINT
):
4455 encodeFunc
= CRYPT_AsnEncodeIssuingDistPoint
;
4457 case LOWORD(X509_NAME_CONSTRAINTS
):
4458 encodeFunc
= CRYPT_AsnEncodeNameConstraints
;
4460 case LOWORD(X509_POLICY_MAPPINGS
):
4461 encodeFunc
= CRYPT_AsnEncodeCertPolicyMappings
;
4463 case LOWORD(X509_POLICY_CONSTRAINTS
):
4464 encodeFunc
= CRYPT_AsnEncodeCertPolicyConstraints
;
4466 case LOWORD(PKCS7_SIGNER_INFO
):
4467 encodeFunc
= CRYPT_AsnEncodePKCSSignerInfo
;
4469 case LOWORD(CMS_SIGNER_INFO
):
4470 encodeFunc
= CRYPT_AsnEncodeCMSSignerInfo
;
4474 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4475 encodeFunc
= CRYPT_AsnEncodeExtensions
;
4476 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4477 encodeFunc
= CRYPT_AsnEncodeUtcTime
;
4478 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
4479 encodeFunc
= CRYPT_AsnEncodeUtcTime
;
4480 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4481 encodeFunc
= CRYPT_AsnEncodeAuthorityKeyId
;
4482 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
4483 encodeFunc
= CRYPT_AsnEncodeCertPolicyMappings
;
4484 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4485 encodeFunc
= CRYPT_AsnEncodeAuthorityKeyId2
;
4486 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4487 encodeFunc
= CRYPT_AsnEncodeEnumerated
;
4488 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4489 encodeFunc
= CRYPT_AsnEncodeBits
;
4490 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4491 encodeFunc
= CRYPT_AsnEncodeOctets
;
4492 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4493 encodeFunc
= CRYPT_AsnEncodeBasicConstraints
;
4494 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4495 encodeFunc
= CRYPT_AsnEncodeBasicConstraints2
;
4496 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4497 encodeFunc
= CRYPT_AsnEncodeAltName
;
4498 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4499 encodeFunc
= CRYPT_AsnEncodeAltName
;
4500 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4501 encodeFunc
= CRYPT_AsnEncodeAltName
;
4502 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4503 encodeFunc
= CRYPT_AsnEncodeAltName
;
4504 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4505 encodeFunc
= CRYPT_AsnEncodeAltName
;
4506 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4507 encodeFunc
= CRYPT_AsnEncodeCRLDistPoints
;
4508 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
4509 encodeFunc
= CRYPT_AsnEncodeCertPolicies
;
4510 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
4511 encodeFunc
= CRYPT_AsnEncodeCertPolicyMappings
;
4512 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
4513 encodeFunc
= CRYPT_AsnEncodeCertPolicyConstraints
;
4514 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4515 encodeFunc
= CRYPT_AsnEncodeEnhancedKeyUsage
;
4516 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4517 encodeFunc
= CRYPT_AsnEncodeIssuingDistPoint
;
4518 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
4519 encodeFunc
= CRYPT_AsnEncodeNameConstraints
;
4520 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
4521 encodeFunc
= CRYPT_AsnEncodeAuthorityInfoAccess
;
4522 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
4523 encodeFunc
= CRYPT_AsnEncodePolicyQualifierUserNotice
;
4524 else if (!strcmp(lpszStructType
, szOID_CTL
))
4525 encodeFunc
= CRYPT_AsnEncodeCTL
;
4529 static CryptEncodeObjectFunc
CRYPT_LoadEncoderFunc(DWORD dwCertEncodingType
,
4530 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4532 static HCRYPTOIDFUNCSET set
= NULL
;
4533 CryptEncodeObjectFunc encodeFunc
= NULL
;
4536 set
= CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_FUNC
, 0);
4537 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4538 (void **)&encodeFunc
, hFunc
);
4542 static CryptEncodeObjectExFunc
CRYPT_LoadEncoderExFunc(DWORD dwCertEncodingType
,
4543 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4545 static HCRYPTOIDFUNCSET set
= NULL
;
4546 CryptEncodeObjectExFunc encodeFunc
= NULL
;
4549 set
= CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_EX_FUNC
, 0);
4550 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4551 (void **)&encodeFunc
, hFunc
);
4555 BOOL WINAPI
CryptEncodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4556 const void *pvStructInfo
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
4559 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4560 CryptEncodeObjectFunc pCryptEncodeObject
= NULL
;
4561 CryptEncodeObjectExFunc pCryptEncodeObjectEx
= NULL
;
4563 TRACE_(crypt
)("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
4564 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
,
4567 if (!pbEncoded
&& !pcbEncoded
)
4569 SetLastError(ERROR_INVALID_PARAMETER
);
4573 if (!(pCryptEncodeObjectEx
= CRYPT_GetBuiltinEncoder(dwCertEncodingType
,
4576 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4577 debugstr_a(lpszStructType
));
4578 pCryptEncodeObject
= CRYPT_LoadEncoderFunc(dwCertEncodingType
,
4579 lpszStructType
, &hFunc
);
4580 if (!pCryptEncodeObject
)
4581 pCryptEncodeObjectEx
= CRYPT_LoadEncoderExFunc(dwCertEncodingType
,
4582 lpszStructType
, &hFunc
);
4584 if (pCryptEncodeObject
)
4585 ret
= pCryptEncodeObject(dwCertEncodingType
, lpszStructType
,
4586 pvStructInfo
, pbEncoded
, pcbEncoded
);
4587 else if (pCryptEncodeObjectEx
)
4588 ret
= pCryptEncodeObjectEx(dwCertEncodingType
, lpszStructType
,
4589 pvStructInfo
, 0, NULL
, pbEncoded
, pcbEncoded
);
4591 CryptFreeOIDFunctionAddress(hFunc
, 0);
4592 TRACE_(crypt
)("returning %d\n", ret
);
4596 BOOL WINAPI
CryptEncodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4597 const void *pvStructInfo
, DWORD dwFlags
, PCRYPT_ENCODE_PARA pEncodePara
,
4598 void *pvEncoded
, DWORD
*pcbEncoded
)
4601 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4602 CryptEncodeObjectExFunc encodeFunc
= NULL
;
4604 TRACE_(crypt
)("(0x%08x, %s, %p, 0x%08x, %p, %p, %p)\n", dwCertEncodingType
,
4605 debugstr_a(lpszStructType
), pvStructInfo
, dwFlags
, pEncodePara
,
4606 pvEncoded
, pcbEncoded
);
4608 if (!pvEncoded
&& !pcbEncoded
)
4610 SetLastError(ERROR_INVALID_PARAMETER
);
4614 SetLastError(NOERROR
);
4615 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
&& pvEncoded
)
4616 *(BYTE
**)pvEncoded
= NULL
;
4617 encodeFunc
= CRYPT_GetBuiltinEncoder(dwCertEncodingType
, lpszStructType
);
4620 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4621 debugstr_a(lpszStructType
));
4622 encodeFunc
= CRYPT_LoadEncoderExFunc(dwCertEncodingType
, lpszStructType
,
4626 ret
= encodeFunc(dwCertEncodingType
, lpszStructType
, pvStructInfo
,
4627 dwFlags
, pEncodePara
, pvEncoded
, pcbEncoded
);
4630 CryptEncodeObjectFunc pCryptEncodeObject
=
4631 CRYPT_LoadEncoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
4633 if (pCryptEncodeObject
)
4635 if (dwFlags
& CRYPT_ENCODE_ALLOC_FLAG
)
4637 ret
= pCryptEncodeObject(dwCertEncodingType
, lpszStructType
,
4638 pvStructInfo
, NULL
, pcbEncoded
);
4639 if (ret
&& (ret
= CRYPT_EncodeEnsureSpace(dwFlags
, pEncodePara
,
4640 pvEncoded
, pcbEncoded
, *pcbEncoded
)))
4641 ret
= pCryptEncodeObject(dwCertEncodingType
,
4642 lpszStructType
, pvStructInfo
, *(BYTE
**)pvEncoded
,
4646 ret
= pCryptEncodeObject(dwCertEncodingType
, lpszStructType
,
4647 pvStructInfo
, pvEncoded
, pcbEncoded
);
4651 CryptFreeOIDFunctionAddress(hFunc
, 0);
4652 TRACE_(crypt
)("returning %d\n", ret
);
4656 BOOL WINAPI
PFXExportCertStore(HCERTSTORE hStore
, CRYPT_DATA_BLOB
*pPFX
,
4657 LPCWSTR szPassword
, DWORD dwFlags
)
4659 return PFXExportCertStoreEx(hStore
, pPFX
, szPassword
, NULL
, dwFlags
);
4662 BOOL WINAPI
PFXExportCertStoreEx(HCERTSTORE hStore
, CRYPT_DATA_BLOB
*pPFX
,
4663 LPCWSTR szPassword
, void *pvReserved
, DWORD dwFlags
)
4665 FIXME_(crypt
)("(%p, %p, %p, %p, %08x): stub\n", hStore
, pPFX
, szPassword
,
4666 pvReserved
, dwFlags
);
4670 BOOL WINAPI
CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv
, DWORD dwKeySpec
,
4671 DWORD dwCertEncodingType
, PCERT_PUBLIC_KEY_INFO pInfo
, DWORD
*pcbInfo
)
4673 return CryptExportPublicKeyInfoEx(hCryptProv
, dwKeySpec
, dwCertEncodingType
,
4674 NULL
, 0, NULL
, pInfo
, pcbInfo
);
4677 static BOOL WINAPI
CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv
,
4678 DWORD dwKeySpec
, DWORD dwCertEncodingType
, LPSTR pszPublicKeyObjId
,
4679 DWORD dwFlags
, void *pvAuxInfo
, PCERT_PUBLIC_KEY_INFO pInfo
, DWORD
*pcbInfo
)
4683 static CHAR oid
[] = szOID_RSA_RSA
;
4685 TRACE_(crypt
)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv
,
4686 dwKeySpec
, dwCertEncodingType
, debugstr_a(pszPublicKeyObjId
), dwFlags
,
4687 pvAuxInfo
, pInfo
, pInfo
? *pcbInfo
: 0);
4689 if (!pszPublicKeyObjId
)
4690 pszPublicKeyObjId
= oid
;
4691 if ((ret
= CryptGetUserKey(hCryptProv
, dwKeySpec
, &key
)))
4695 ret
= CryptExportKey(key
, 0, PUBLICKEYBLOB
, 0, NULL
, &keySize
);
4698 LPBYTE pubKey
= CryptMemAlloc(keySize
);
4702 ret
= CryptExportKey(key
, 0, PUBLICKEYBLOB
, 0, pubKey
,
4706 DWORD encodedLen
= 0;
4708 ret
= CryptEncodeObject(dwCertEncodingType
,
4709 RSA_CSP_PUBLICKEYBLOB
, pubKey
, NULL
, &encodedLen
);
4712 DWORD sizeNeeded
= sizeof(CERT_PUBLIC_KEY_INFO
) +
4713 strlen(pszPublicKeyObjId
) + 1 + encodedLen
;
4716 *pcbInfo
= sizeNeeded
;
4717 else if (*pcbInfo
< sizeNeeded
)
4719 SetLastError(ERROR_MORE_DATA
);
4720 *pcbInfo
= sizeNeeded
;
4725 *pcbInfo
= sizeNeeded
;
4726 pInfo
->Algorithm
.pszObjId
= (char *)pInfo
+
4727 sizeof(CERT_PUBLIC_KEY_INFO
);
4728 lstrcpyA(pInfo
->Algorithm
.pszObjId
,
4730 pInfo
->Algorithm
.Parameters
.cbData
= 0;
4731 pInfo
->Algorithm
.Parameters
.pbData
= NULL
;
4732 pInfo
->PublicKey
.pbData
=
4733 (BYTE
*)pInfo
->Algorithm
.pszObjId
4734 + lstrlenA(pInfo
->Algorithm
.pszObjId
) + 1;
4735 pInfo
->PublicKey
.cbData
= encodedLen
;
4736 pInfo
->PublicKey
.cUnusedBits
= 0;
4737 ret
= CryptEncodeObject(dwCertEncodingType
,
4738 RSA_CSP_PUBLICKEYBLOB
, pubKey
,
4739 pInfo
->PublicKey
.pbData
, &pInfo
->PublicKey
.cbData
);
4743 CryptMemFree(pubKey
);
4748 CryptDestroyKey(key
);
4753 typedef BOOL (WINAPI
*ExportPublicKeyInfoExFunc
)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv
,
4754 DWORD dwKeySpec
, DWORD dwCertEncodingType
, LPSTR pszPublicKeyObjId
,
4755 DWORD dwFlags
, void *pvAuxInfo
, PCERT_PUBLIC_KEY_INFO pInfo
, DWORD
*pcbInfo
);
4757 BOOL WINAPI
CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv
, DWORD dwKeySpec
,
4758 DWORD dwCertEncodingType
, LPSTR pszPublicKeyObjId
, DWORD dwFlags
,
4759 void *pvAuxInfo
, PCERT_PUBLIC_KEY_INFO pInfo
, DWORD
*pcbInfo
)
4761 static HCRYPTOIDFUNCSET set
= NULL
;
4763 ExportPublicKeyInfoExFunc exportFunc
= NULL
;
4764 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4766 TRACE_(crypt
)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv
,
4767 dwKeySpec
, dwCertEncodingType
, debugstr_a(pszPublicKeyObjId
), dwFlags
,
4768 pvAuxInfo
, pInfo
, pInfo
? *pcbInfo
: 0);
4772 SetLastError(ERROR_INVALID_PARAMETER
);
4776 if (pszPublicKeyObjId
)
4779 set
= CryptInitOIDFunctionSet(CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC
,
4781 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, pszPublicKeyObjId
,
4782 0, (void **)&exportFunc
, &hFunc
);
4785 exportFunc
= CRYPT_ExportRsaPublicKeyInfoEx
;
4786 ret
= exportFunc(hCryptProv
, dwKeySpec
, dwCertEncodingType
,
4787 pszPublicKeyObjId
, dwFlags
, pvAuxInfo
, pInfo
, pcbInfo
);
4789 CryptFreeOIDFunctionAddress(hFunc
, 0);
4793 BOOL WINAPI
CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv
,
4794 DWORD dwCertEncodingType
, PCERT_PUBLIC_KEY_INFO pInfo
, HCRYPTKEY
*phKey
)
4796 return CryptImportPublicKeyInfoEx(hCryptProv
, dwCertEncodingType
, pInfo
,
4800 static BOOL WINAPI
CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv
,
4801 DWORD dwCertEncodingType
, PCERT_PUBLIC_KEY_INFO pInfo
, ALG_ID aiKeyAlg
,
4802 DWORD dwFlags
, void *pvAuxInfo
, HCRYPTKEY
*phKey
)
4805 DWORD pubKeySize
= 0;
4807 TRACE_(crypt
)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv
,
4808 dwCertEncodingType
, pInfo
, aiKeyAlg
, dwFlags
, pvAuxInfo
, phKey
);
4810 ret
= CryptDecodeObject(dwCertEncodingType
, RSA_CSP_PUBLICKEYBLOB
,
4811 pInfo
->PublicKey
.pbData
, pInfo
->PublicKey
.cbData
, 0, NULL
, &pubKeySize
);
4814 LPBYTE pubKey
= CryptMemAlloc(pubKeySize
);
4818 ret
= CryptDecodeObject(dwCertEncodingType
, RSA_CSP_PUBLICKEYBLOB
,
4819 pInfo
->PublicKey
.pbData
, pInfo
->PublicKey
.cbData
, 0, pubKey
,
4824 ((BLOBHEADER
*)pubKey
)->aiKeyAlg
= aiKeyAlg
;
4825 ret
= CryptImportKey(hCryptProv
, pubKey
, pubKeySize
, 0, 0,
4828 CryptMemFree(pubKey
);
4836 typedef BOOL (WINAPI
*ImportPublicKeyInfoExFunc
)(HCRYPTPROV hCryptProv
,
4837 DWORD dwCertEncodingType
, PCERT_PUBLIC_KEY_INFO pInfo
, ALG_ID aiKeyAlg
,
4838 DWORD dwFlags
, void *pvAuxInfo
, HCRYPTKEY
*phKey
);
4840 BOOL WINAPI
CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv
,
4841 DWORD dwCertEncodingType
, PCERT_PUBLIC_KEY_INFO pInfo
, ALG_ID aiKeyAlg
,
4842 DWORD dwFlags
, void *pvAuxInfo
, HCRYPTKEY
*phKey
)
4844 static HCRYPTOIDFUNCSET set
= NULL
;
4846 ImportPublicKeyInfoExFunc importFunc
= NULL
;
4847 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4849 TRACE_(crypt
)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv
,
4850 dwCertEncodingType
, pInfo
, aiKeyAlg
, dwFlags
, pvAuxInfo
, phKey
);
4853 set
= CryptInitOIDFunctionSet(CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC
, 0);
4854 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
,
4855 pInfo
->Algorithm
.pszObjId
, 0, (void **)&importFunc
, &hFunc
);
4857 importFunc
= CRYPT_ImportRsaPublicKeyInfoEx
;
4858 ret
= importFunc(hCryptProv
, dwCertEncodingType
, pInfo
, aiKeyAlg
, dwFlags
,
4861 CryptFreeOIDFunctionAddress(hFunc
, 0);