2 * crypt32 Crypt*Object functions
4 * Copyright 2007 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define NONAMELESSUNION
28 #include "crypt32_private.h"
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
35 static BOOL
CRYPT_ReadBlobFromFile(LPCWSTR fileName
, PCERT_BLOB blob
)
40 TRACE("%s\n", debugstr_w(fileName
));
42 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
43 OPEN_EXISTING
, 0, NULL
);
44 if (file
!= INVALID_HANDLE_VALUE
)
47 blob
->cbData
= GetFileSize(file
, NULL
);
50 blob
->pbData
= CryptMemAlloc(blob
->cbData
);
55 ret
= ReadFile(file
, blob
->pbData
, blob
->cbData
, &read
, NULL
) && read
== blob
->cbData
;
56 if (!ret
) CryptMemFree(blob
->pbData
);
63 TRACE("returning %d\n", ret
);
67 static BOOL
CRYPT_QueryContextBlob(const CERT_BLOB
*blob
,
68 DWORD dwExpectedContentTypeFlags
, HCERTSTORE store
,
69 DWORD
*contentType
, const void **ppvContext
)
73 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
)
75 ret
= pCertInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
76 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
77 if (ret
&& contentType
)
78 *contentType
= CERT_QUERY_CONTENT_CERT
;
80 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
))
82 ret
= pCRLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
83 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
84 if (ret
&& contentType
)
85 *contentType
= CERT_QUERY_CONTENT_CRL
;
87 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
89 ret
= pCTLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
90 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
91 if (ret
&& contentType
)
92 *contentType
= CERT_QUERY_CONTENT_CTL
;
97 static BOOL
CRYPT_QueryContextObject(DWORD dwObjectType
, const void *pvObject
,
98 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
99 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
100 HCERTSTORE
*phCertStore
, const void **ppvContext
)
103 const CERT_BLOB
*blob
;
106 DWORD formatType
= 0;
108 switch (dwObjectType
)
110 case CERT_QUERY_OBJECT_FILE
:
111 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
112 * just read the file directly
114 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
117 case CERT_QUERY_OBJECT_BLOB
:
122 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
129 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
130 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
131 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
133 ret
= CRYPT_QueryContextBlob(blob
, dwExpectedContentTypeFlags
, store
,
134 pdwContentType
, ppvContext
);
136 formatType
= CERT_QUERY_FORMAT_BINARY
;
139 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
141 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
142 CRYPT_DATA_BLOB decoded
;
144 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
146 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
147 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
150 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
153 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
154 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
155 &decoded
.cbData
, NULL
, NULL
);
158 ret
= CRYPT_QueryContextBlob(&decoded
,
159 dwExpectedContentTypeFlags
, store
, pdwContentType
,
162 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
164 CryptMemFree(decoded
.pbData
);
172 if (pdwMsgAndCertEncodingType
)
173 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
175 *pdwFormatType
= formatType
;
177 *phCertStore
= CertDuplicateStore(store
);
179 CertCloseStore(store
, 0);
180 if (blob
== &fileBlob
)
181 CryptMemFree(blob
->pbData
);
182 TRACE("returning %d\n", ret
);
186 static BOOL
CRYPT_QuerySerializedContextObject(DWORD dwObjectType
,
187 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
188 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
189 HCERTSTORE
*phCertStore
, const void **ppvContext
)
192 const CERT_BLOB
*blob
;
193 const WINE_CONTEXT_INTERFACE
*contextInterface
= NULL
;
198 switch (dwObjectType
)
200 case CERT_QUERY_OBJECT_FILE
:
201 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
202 * just read the file directly
204 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
207 case CERT_QUERY_OBJECT_BLOB
:
212 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
219 context
= CRYPT_ReadSerializedElement(blob
->pbData
, blob
->cbData
,
220 CERT_STORE_ALL_CONTEXT_FLAG
, &contextType
);
223 DWORD contentType
, certStoreOffset
;
228 case CERT_STORE_CERTIFICATE_CONTEXT
:
229 contextInterface
= pCertInterface
;
230 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CERT
;
231 certStoreOffset
= offsetof(CERT_CONTEXT
, hCertStore
);
232 if (!(dwExpectedContentTypeFlags
&
233 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
))
235 SetLastError(ERROR_INVALID_DATA
);
240 case CERT_STORE_CRL_CONTEXT
:
241 contextInterface
= pCRLInterface
;
242 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CRL
;
243 certStoreOffset
= offsetof(CRL_CONTEXT
, hCertStore
);
244 if (!(dwExpectedContentTypeFlags
&
245 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
))
247 SetLastError(ERROR_INVALID_DATA
);
252 case CERT_STORE_CTL_CONTEXT
:
253 contextInterface
= pCTLInterface
;
254 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CTL
;
255 certStoreOffset
= offsetof(CTL_CONTEXT
, hCertStore
);
256 if (!(dwExpectedContentTypeFlags
&
257 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
))
259 SetLastError(ERROR_INVALID_DATA
);
265 SetLastError(ERROR_INVALID_DATA
);
269 if (pdwMsgAndCertEncodingType
)
270 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
272 *pdwContentType
= contentType
;
274 *phCertStore
= CertDuplicateStore(
275 *(HCERTSTORE
*)((const BYTE
*)context
+ certStoreOffset
));
278 *ppvContext
= context
;
279 Context_AddRef(context_from_ptr(context
));
284 if (contextInterface
&& context
)
285 Context_Release(context_from_ptr(context
));
286 if (blob
== &fileBlob
)
287 CryptMemFree(blob
->pbData
);
288 TRACE("returning %d\n", ret
);
292 static BOOL
CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName
,
293 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
294 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
299 TRACE("%s\n", debugstr_w(fileName
));
300 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
301 OPEN_EXISTING
, 0, NULL
);
302 if (file
!= INVALID_HANDLE_VALUE
)
304 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
305 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
307 ret
= CRYPT_ReadSerializedStoreFromFile(file
, store
);
310 if (pdwMsgAndCertEncodingType
)
311 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
313 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
315 *phCertStore
= CertDuplicateStore(store
);
317 CertCloseStore(store
, 0);
320 TRACE("returning %d\n", ret
);
324 static BOOL
CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB
*blob
,
325 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
326 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
328 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
329 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
332 TRACE("(%d, %p)\n", blob
->cbData
, blob
->pbData
);
334 ret
= CRYPT_ReadSerializedStoreFromBlob(blob
, store
);
337 if (pdwMsgAndCertEncodingType
)
338 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
340 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
342 *phCertStore
= CertDuplicateStore(store
);
344 CertCloseStore(store
, 0);
345 TRACE("returning %d\n", ret
);
349 static BOOL
CRYPT_QuerySerializedStoreObject(DWORD dwObjectType
,
350 const void *pvObject
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
351 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
353 switch (dwObjectType
)
355 case CERT_QUERY_OBJECT_FILE
:
356 return CRYPT_QuerySerializedStoreFromFile(pvObject
,
357 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
358 case CERT_QUERY_OBJECT_BLOB
:
359 return CRYPT_QuerySerializedStoreFromBlob(pvObject
,
360 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
362 FIXME("unimplemented for type %d\n", dwObjectType
);
363 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
368 static BOOL
CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB
*blob
,
369 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
371 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
375 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
377 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
380 DWORD type
, len
= sizeof(type
);
382 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
385 if (type
!= CMSG_SIGNED
)
387 SetLastError(ERROR_INVALID_DATA
);
395 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_SIGNED
, 0, NULL
,
399 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
410 if (pdwMsgAndCertEncodingType
)
411 *pdwMsgAndCertEncodingType
= encodingType
;
413 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
420 static BOOL
CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB
*blob
,
421 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
423 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
427 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
429 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
432 DWORD type
, len
= sizeof(type
);
434 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
437 if (type
!= CMSG_DATA
)
439 SetLastError(ERROR_INVALID_DATA
);
447 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_DATA
, 0,
451 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
462 if (pdwMsgAndCertEncodingType
)
463 *pdwMsgAndCertEncodingType
= encodingType
;
465 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
472 /* Used to decode non-embedded messages */
473 static BOOL
CRYPT_QueryMessageObject(DWORD dwObjectType
, const void *pvObject
,
474 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
475 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
476 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
479 const CERT_BLOB
*blob
;
481 HCRYPTMSG msg
= NULL
;
482 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
483 DWORD formatType
= 0;
485 TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
486 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
487 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
490 switch (dwObjectType
)
492 case CERT_QUERY_OBJECT_FILE
:
493 /* This isn't an embedded PKCS7 message, so just read the file
496 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
499 case CERT_QUERY_OBJECT_BLOB
:
504 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
511 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
513 /* Try it first as a signed message */
514 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
515 ret
= CRYPT_QuerySignedMessage(blob
, pdwMsgAndCertEncodingType
,
516 pdwContentType
, &msg
);
517 /* Failing that, try as an unsigned message */
519 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
520 ret
= CRYPT_QueryUnsignedMessage(blob
, pdwMsgAndCertEncodingType
,
521 pdwContentType
, &msg
);
523 formatType
= CERT_QUERY_FORMAT_BINARY
;
526 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
528 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
529 CRYPT_DATA_BLOB decoded
;
531 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
533 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
534 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
537 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
540 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
541 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
542 &decoded
.cbData
, NULL
, NULL
);
545 /* Try it first as a signed message */
546 if (dwExpectedContentTypeFlags
&
547 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
548 ret
= CRYPT_QuerySignedMessage(&decoded
,
549 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
550 /* Failing that, try as an unsigned message */
551 if (!ret
&& (dwExpectedContentTypeFlags
&
552 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
553 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
554 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
556 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
558 CryptMemFree(decoded
.pbData
);
563 if (!ret
&& !(blob
->cbData
% sizeof(WCHAR
)))
565 CRYPT_DATA_BLOB decoded
;
566 LPWSTR str
= (LPWSTR
)blob
->pbData
;
567 DWORD strLen
= blob
->cbData
/ sizeof(WCHAR
);
569 /* Try again, assuming the input string is UTF-16 base64 */
570 while (strLen
&& !str
[strLen
- 1])
572 ret
= CryptStringToBinaryW(str
, strLen
, CRYPT_STRING_BASE64_ANY
,
573 NULL
, &decoded
.cbData
, NULL
, NULL
);
576 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
579 ret
= CryptStringToBinaryW(str
, strLen
,
580 CRYPT_STRING_BASE64_ANY
, decoded
.pbData
, &decoded
.cbData
,
584 /* Try it first as a signed message */
585 if (dwExpectedContentTypeFlags
&
586 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
587 ret
= CRYPT_QuerySignedMessage(&decoded
,
588 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
589 /* Failing that, try as an unsigned message */
590 if (!ret
&& (dwExpectedContentTypeFlags
&
591 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
592 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
593 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
595 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
597 CryptMemFree(decoded
.pbData
);
607 *pdwFormatType
= formatType
;
609 *phCertStore
= CertOpenStore(CERT_STORE_PROV_MSG
, encodingType
, 0,
616 if (blob
== &fileBlob
)
617 CryptMemFree(blob
->pbData
);
618 TRACE("returning %d\n", ret
);
622 static BOOL
CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType
,
623 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
624 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
625 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
631 TRACE("%s\n", debugstr_w(pvObject
));
633 if (dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
635 WARN("don't know what to do for type %d embedded signed messages\n",
637 SetLastError(E_INVALIDARG
);
640 file
= CreateFileW(pvObject
, GENERIC_READ
, FILE_SHARE_READ
,
641 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
642 if (file
!= INVALID_HANDLE_VALUE
)
644 ret
= CryptSIPRetrieveSubjectGuid(pvObject
, file
, &subject
);
647 SIP_DISPATCH_INFO sip
;
649 memset(&sip
, 0, sizeof(sip
));
650 sip
.cbSize
= sizeof(sip
);
651 ret
= CryptSIPLoad(&subject
, 0, &sip
);
654 SIP_SUBJECTINFO subjectInfo
;
658 memset(&subjectInfo
, 0, sizeof(subjectInfo
));
659 subjectInfo
.cbSize
= sizeof(subjectInfo
);
660 subjectInfo
.pgSubjectType
= &subject
;
661 subjectInfo
.hFile
= file
;
662 subjectInfo
.pwsFileName
= pvObject
;
663 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0, &blob
.cbData
,
667 blob
.pbData
= CryptMemAlloc(blob
.cbData
);
670 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0,
671 &blob
.cbData
, blob
.pbData
);
674 ret
= CRYPT_QueryMessageObject(
675 CERT_QUERY_OBJECT_BLOB
, &blob
,
676 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
,
677 CERT_QUERY_FORMAT_FLAG_BINARY
,
678 pdwMsgAndCertEncodingType
, NULL
, NULL
,
680 if (ret
&& pdwContentType
)
681 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
;
683 CryptMemFree(blob
.pbData
);
687 SetLastError(ERROR_OUTOFMEMORY
);
695 TRACE("returning %d\n", ret
);
699 static BOOL
CRYPT_QueryPFXObject(DWORD dwObjectType
, const void *pvObject
,
700 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
701 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
702 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
704 CRYPT_DATA_BLOB blob
= {0}, *ptr
;
707 TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
708 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
709 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
712 switch (dwObjectType
)
714 case CERT_QUERY_OBJECT_FILE
:
715 if (!CRYPT_ReadBlobFromFile(pvObject
, &blob
)) return FALSE
;
719 case CERT_QUERY_OBJECT_BLOB
:
720 ptr
= (CRYPT_DATA_BLOB
*)pvObject
;
727 ret
= PFXIsPFXBlob(ptr
);
730 if (pdwMsgAndCertEncodingType
) *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
731 if (pdwContentType
) *pdwContentType
= CERT_QUERY_CONTENT_PFX
;
732 if (pdwFormatType
) *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
733 if (phCertStore
) *phCertStore
= NULL
;
734 if (phMsg
) *phMsg
= NULL
;
737 CryptMemFree(blob
.pbData
);
741 BOOL WINAPI
CryptQueryObject(DWORD dwObjectType
, const void *pvObject
,
742 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
743 DWORD dwFlags
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
744 DWORD
*pdwFormatType
, HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
,
745 const void **ppvContext
)
747 static const DWORD unimplementedTypes
=
748 CERT_QUERY_CONTENT_FLAG_PKCS10
| CERT_QUERY_CONTENT_FLAG_CERT_PAIR
;
751 TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
752 dwObjectType
, pvObject
, dwExpectedContentTypeFlags
,
753 dwExpectedFormatTypeFlags
, dwFlags
, pdwMsgAndCertEncodingType
,
754 pdwContentType
, pdwFormatType
, phCertStore
, phMsg
, ppvContext
);
756 if (dwObjectType
!= CERT_QUERY_OBJECT_BLOB
&&
757 dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
759 WARN("unsupported type %d\n", dwObjectType
);
760 SetLastError(E_INVALIDARG
);
765 WARN("missing required argument\n");
766 SetLastError(E_INVALIDARG
);
769 if (dwExpectedContentTypeFlags
& unimplementedTypes
)
770 WARN("unimplemented for types %08x\n",
771 dwExpectedContentTypeFlags
& unimplementedTypes
);
774 *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
783 if ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
) ||
784 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
) ||
785 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
787 ret
= CRYPT_QueryContextObject(dwObjectType
, pvObject
,
788 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
789 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
793 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE
))
795 ret
= CRYPT_QuerySerializedStoreObject(dwObjectType
, pvObject
,
796 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
799 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
) ||
800 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
) ||
801 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
)))
803 ret
= CRYPT_QuerySerializedContextObject(dwObjectType
, pvObject
,
804 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
805 phCertStore
, ppvContext
);
808 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
) ||
809 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
)))
811 ret
= CRYPT_QueryMessageObject(dwObjectType
, pvObject
,
812 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
813 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
817 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED
))
819 ret
= CRYPT_QueryEmbeddedMessageObject(dwObjectType
, pvObject
,
820 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
824 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PFX
))
826 ret
= CRYPT_QueryPFXObject(dwObjectType
, pvObject
,
827 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
828 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
832 SetLastError(CRYPT_E_NO_MATCH
);
833 TRACE("returning %d\n", ret
);
837 static BOOL WINAPI
CRYPT_FormatHexString(DWORD dwCertEncodingType
,
838 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
839 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
846 bytesNeeded
= (cbEncoded
* 3) * sizeof(WCHAR
);
848 bytesNeeded
= sizeof(WCHAR
);
851 *pcbFormat
= bytesNeeded
;
854 else if (*pcbFormat
< bytesNeeded
)
856 *pcbFormat
= bytesNeeded
;
857 SetLastError(ERROR_MORE_DATA
);
862 static const WCHAR fmt
[] = { '%','0','2','x',' ',0 };
863 static const WCHAR endFmt
[] = { '%','0','2','x',0 };
865 LPWSTR ptr
= pbFormat
;
867 *pcbFormat
= bytesNeeded
;
870 for (i
= 0; i
< cbEncoded
; i
++)
872 if (i
< cbEncoded
- 1)
873 ptr
+= sprintfW(ptr
, fmt
, pbEncoded
[i
]);
875 ptr
+= sprintfW(ptr
, endFmt
, pbEncoded
[i
]);
885 #define MAX_STRING_RESOURCE_LEN 128
887 static const WCHAR commaSpace
[] = { ',',' ',0 };
893 WCHAR str
[MAX_STRING_RESOURCE_LEN
];
896 static BOOL
CRYPT_FormatBits(BYTE bits
, const struct BitToString
*map
,
897 DWORD mapEntries
, void *pbFormat
, DWORD
*pcbFormat
, BOOL
*first
)
899 DWORD bytesNeeded
= sizeof(WCHAR
);
901 BOOL ret
= TRUE
, localFirst
= *first
;
903 for (i
= 0; i
< mapEntries
; i
++)
904 if (bits
& map
[i
].bit
)
907 bytesNeeded
+= strlenW(commaSpace
) * sizeof(WCHAR
);
909 bytesNeeded
+= strlenW(map
[i
].str
) * sizeof(WCHAR
);
914 *pcbFormat
= bytesNeeded
;
916 else if (*pcbFormat
< bytesNeeded
)
919 *pcbFormat
= bytesNeeded
;
920 SetLastError(ERROR_MORE_DATA
);
925 LPWSTR str
= pbFormat
;
928 *pcbFormat
= bytesNeeded
;
929 for (i
= 0; i
< mapEntries
; i
++)
930 if (bits
& map
[i
].bit
)
934 strcpyW(str
, commaSpace
);
935 str
+= strlenW(commaSpace
);
938 strcpyW(str
, map
[i
].str
);
939 str
+= strlenW(map
[i
].str
);
946 static struct BitToString keyUsageByte0Map
[] = {
947 { CERT_DIGITAL_SIGNATURE_KEY_USAGE
, IDS_DIGITAL_SIGNATURE
, { 0 } },
948 { CERT_NON_REPUDIATION_KEY_USAGE
, IDS_NON_REPUDIATION
, { 0 } },
949 { CERT_KEY_ENCIPHERMENT_KEY_USAGE
, IDS_KEY_ENCIPHERMENT
, { 0 } },
950 { CERT_DATA_ENCIPHERMENT_KEY_USAGE
, IDS_DATA_ENCIPHERMENT
, { 0 } },
951 { CERT_KEY_AGREEMENT_KEY_USAGE
, IDS_KEY_AGREEMENT
, { 0 } },
952 { CERT_KEY_CERT_SIGN_KEY_USAGE
, IDS_CERT_SIGN
, { 0 } },
953 { CERT_OFFLINE_CRL_SIGN_KEY_USAGE
, IDS_OFFLINE_CRL_SIGN
, { 0 } },
954 { CERT_CRL_SIGN_KEY_USAGE
, IDS_CRL_SIGN
, { 0 } },
955 { CERT_ENCIPHER_ONLY_KEY_USAGE
, IDS_ENCIPHER_ONLY
, { 0 } },
957 static struct BitToString keyUsageByte1Map
[] = {
958 { CERT_DECIPHER_ONLY_KEY_USAGE
, IDS_DECIPHER_ONLY
, { 0 } },
961 static BOOL WINAPI
CRYPT_FormatKeyUsage(DWORD dwCertEncodingType
,
962 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
963 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
967 CRYPT_BIT_BLOB
*bits
;
972 SetLastError(E_INVALIDARG
);
975 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_KEY_USAGE
,
976 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
978 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
979 DWORD bytesNeeded
= sizeof(WCHAR
);
981 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
982 if (!bits
->cbData
|| bits
->cbData
> 2)
984 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
986 *pcbFormat
= bytesNeeded
;
987 else if (*pcbFormat
< bytesNeeded
)
989 *pcbFormat
= bytesNeeded
;
990 SetLastError(ERROR_MORE_DATA
);
995 LPWSTR str
= pbFormat
;
997 *pcbFormat
= bytesNeeded
;
998 strcpyW(str
, infoNotAvailable
);
1003 static BOOL stringsLoaded
= FALSE
;
1010 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte0Map
); i
++)
1011 LoadStringW(hInstance
, keyUsageByte0Map
[i
].id
, keyUsageByte0Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1012 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte1Map
); i
++)
1013 LoadStringW(hInstance
, keyUsageByte1Map
[i
].id
, keyUsageByte1Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1014 stringsLoaded
= TRUE
;
1016 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1017 NULL
, &bitStringLen
, &first
);
1018 bytesNeeded
+= bitStringLen
;
1019 if (bits
->cbData
== 2)
1021 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1022 NULL
, &bitStringLen
, &first
);
1023 bytesNeeded
+= bitStringLen
;
1025 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
1026 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1027 bits
->cbData
, NULL
, &size
);
1028 bytesNeeded
+= size
;
1030 *pcbFormat
= bytesNeeded
;
1031 else if (*pcbFormat
< bytesNeeded
)
1033 *pcbFormat
= bytesNeeded
;
1034 SetLastError(ERROR_MORE_DATA
);
1039 LPWSTR str
= pbFormat
;
1041 bitStringLen
= bytesNeeded
;
1043 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1044 str
, &bitStringLen
, &first
);
1045 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1046 if (bits
->cbData
== 2)
1048 bitStringLen
= bytesNeeded
;
1049 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1050 str
, &bitStringLen
, &first
);
1051 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1055 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1056 bits
->cbData
, str
, &size
);
1057 str
+= size
/ sizeof(WCHAR
) - 1;
1067 static const WCHAR crlf
[] = { '\r','\n',0 };
1069 static WCHAR subjectTypeHeader
[MAX_STRING_RESOURCE_LEN
];
1070 static WCHAR subjectTypeCA
[MAX_STRING_RESOURCE_LEN
];
1071 static WCHAR subjectTypeEndCert
[MAX_STRING_RESOURCE_LEN
];
1072 static WCHAR pathLengthHeader
[MAX_STRING_RESOURCE_LEN
];
1074 static BOOL WINAPI
CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType
,
1075 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1076 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1080 CERT_BASIC_CONSTRAINTS2_INFO
*info
;
1085 SetLastError(E_INVALIDARG
);
1088 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BASIC_CONSTRAINTS2
,
1089 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1091 static const WCHAR pathFmt
[] = { '%','d',0 };
1092 static BOOL stringsLoaded
= FALSE
;
1093 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1094 WCHAR pathLength
[MAX_STRING_RESOURCE_LEN
];
1095 LPCWSTR sep
, subjectType
;
1098 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1101 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1106 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1111 LoadStringW(hInstance
, IDS_SUBJECT_TYPE
, subjectTypeHeader
, ARRAY_SIZE(subjectTypeHeader
));
1112 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_CA
, subjectTypeCA
, ARRAY_SIZE(subjectTypeCA
));
1113 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_END_CERT
, subjectTypeEndCert
, ARRAY_SIZE(subjectTypeEndCert
));
1114 LoadStringW(hInstance
, IDS_PATH_LENGTH
, pathLengthHeader
, ARRAY_SIZE(pathLengthHeader
));
1115 stringsLoaded
= TRUE
;
1117 bytesNeeded
+= strlenW(subjectTypeHeader
) * sizeof(WCHAR
);
1119 subjectType
= subjectTypeCA
;
1121 subjectType
= subjectTypeEndCert
;
1122 bytesNeeded
+= strlenW(subjectType
) * sizeof(WCHAR
);
1123 bytesNeeded
+= sepLen
;
1124 bytesNeeded
+= strlenW(pathLengthHeader
) * sizeof(WCHAR
);
1125 if (info
->fPathLenConstraint
)
1126 sprintfW(pathLength
, pathFmt
, info
->dwPathLenConstraint
);
1128 LoadStringW(hInstance
, IDS_PATH_LENGTH_NONE
, pathLength
, ARRAY_SIZE(pathLength
));
1129 bytesNeeded
+= strlenW(pathLength
) * sizeof(WCHAR
);
1131 *pcbFormat
= bytesNeeded
;
1132 else if (*pcbFormat
< bytesNeeded
)
1134 *pcbFormat
= bytesNeeded
;
1135 SetLastError(ERROR_MORE_DATA
);
1140 LPWSTR str
= pbFormat
;
1142 *pcbFormat
= bytesNeeded
;
1143 strcpyW(str
, subjectTypeHeader
);
1144 str
+= strlenW(subjectTypeHeader
);
1145 strcpyW(str
, subjectType
);
1146 str
+= strlenW(subjectType
);
1148 str
+= sepLen
/ sizeof(WCHAR
);
1149 strcpyW(str
, pathLengthHeader
);
1150 str
+= strlenW(pathLengthHeader
);
1151 strcpyW(str
, pathLength
);
1158 static BOOL
CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB
*blob
, int id
,
1159 LPWSTR str
, DWORD
*pcbStr
)
1161 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1165 LoadStringW(hInstance
, id
, buf
, ARRAY_SIZE(buf
));
1166 CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1167 blob
->pbData
, blob
->cbData
, NULL
, &bytesNeeded
);
1168 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1171 *pcbStr
= bytesNeeded
;
1174 else if (*pcbStr
< bytesNeeded
)
1176 *pcbStr
= bytesNeeded
;
1177 SetLastError(ERROR_MORE_DATA
);
1182 *pcbStr
= bytesNeeded
;
1184 str
+= strlenW(str
);
1185 bytesNeeded
-= strlenW(str
) * sizeof(WCHAR
);
1186 ret
= CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1187 blob
->pbData
, blob
->cbData
, str
, &bytesNeeded
);
1192 static BOOL
CRYPT_FormatKeyId(const CRYPT_DATA_BLOB
*keyId
, LPWSTR str
,
1195 return CRYPT_FormatHexStringWithPrefix(keyId
, IDS_KEY_ID
, str
, pcbStr
);
1198 static BOOL
CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB
*serialNum
, LPWSTR str
,
1201 return CRYPT_FormatHexStringWithPrefix(serialNum
, IDS_CERT_SERIAL_NUMBER
,
1205 static const WCHAR indent
[] = { ' ',' ',' ',' ',' ',0 };
1206 static const WCHAR colonCrlf
[] = { ':','\r','\n',0 };
1208 static BOOL
CRYPT_FormatAltNameEntry(DWORD dwFormatStrType
, DWORD indentLevel
,
1209 const CERT_ALT_NAME_ENTRY
*entry
, LPWSTR str
, DWORD
*pcbStr
)
1212 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1213 WCHAR mask
[MAX_STRING_RESOURCE_LEN
];
1214 WCHAR ipAddrBuf
[32];
1216 DWORD bytesNeeded
= sizeof(WCHAR
);
1217 DWORD strType
= CERT_X500_NAME_STR
| CERT_NAME_STR_REVERSE_FLAG
;
1219 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1220 bytesNeeded
+= indentLevel
* strlenW(indent
) * sizeof(WCHAR
);
1221 switch (entry
->dwAltNameChoice
)
1223 case CERT_ALT_NAME_RFC822_NAME
:
1224 LoadStringW(hInstance
, IDS_ALT_NAME_RFC822_NAME
, buf
, ARRAY_SIZE(buf
));
1225 bytesNeeded
+= strlenW(entry
->u
.pwszRfc822Name
) * sizeof(WCHAR
);
1228 case CERT_ALT_NAME_DNS_NAME
:
1229 LoadStringW(hInstance
, IDS_ALT_NAME_DNS_NAME
, buf
, ARRAY_SIZE(buf
));
1230 bytesNeeded
+= strlenW(entry
->u
.pwszDNSName
) * sizeof(WCHAR
);
1233 case CERT_ALT_NAME_DIRECTORY_NAME
:
1235 DWORD directoryNameLen
;
1237 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1238 strType
|= CERT_NAME_STR_CRLF_FLAG
;
1239 directoryNameLen
= cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1240 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, NULL
, 0);
1241 LoadStringW(hInstance
, IDS_ALT_NAME_DIRECTORY_NAME
, buf
, ARRAY_SIZE(buf
));
1242 bytesNeeded
+= (directoryNameLen
- 1) * sizeof(WCHAR
);
1243 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1244 bytesNeeded
+= strlenW(colonCrlf
) * sizeof(WCHAR
);
1246 bytesNeeded
+= sizeof(WCHAR
); /* '=' */
1250 case CERT_ALT_NAME_URL
:
1251 LoadStringW(hInstance
, IDS_ALT_NAME_URL
, buf
, ARRAY_SIZE(buf
));
1252 bytesNeeded
+= strlenW(entry
->u
.pwszURL
) * sizeof(WCHAR
);
1255 case CERT_ALT_NAME_IP_ADDRESS
:
1257 static const WCHAR ipAddrWithMaskFmt
[] = { '%','d','.','%','d','.',
1258 '%','d','.','%','d','/','%','d','.','%','d','.','%','d','.','%','d',0
1260 static const WCHAR ipAddrFmt
[] = { '%','d','.','%','d','.','%','d',
1263 LoadStringW(hInstance
, IDS_ALT_NAME_IP_ADDRESS
, buf
, ARRAY_SIZE(buf
));
1264 if (entry
->u
.IPAddress
.cbData
== 8)
1266 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1268 LoadStringW(hInstance
, IDS_ALT_NAME_MASK
, mask
, ARRAY_SIZE(mask
));
1269 bytesNeeded
+= strlenW(mask
) * sizeof(WCHAR
);
1270 sprintfW(ipAddrBuf
, ipAddrFmt
,
1271 entry
->u
.IPAddress
.pbData
[0],
1272 entry
->u
.IPAddress
.pbData
[1],
1273 entry
->u
.IPAddress
.pbData
[2],
1274 entry
->u
.IPAddress
.pbData
[3]);
1275 bytesNeeded
+= strlenW(ipAddrBuf
) * sizeof(WCHAR
);
1276 /* indent again, for the mask line */
1277 bytesNeeded
+= indentLevel
* strlenW(indent
) * sizeof(WCHAR
);
1278 sprintfW(maskBuf
, ipAddrFmt
,
1279 entry
->u
.IPAddress
.pbData
[4],
1280 entry
->u
.IPAddress
.pbData
[5],
1281 entry
->u
.IPAddress
.pbData
[6],
1282 entry
->u
.IPAddress
.pbData
[7]);
1283 bytesNeeded
+= strlenW(maskBuf
) * sizeof(WCHAR
);
1284 bytesNeeded
+= strlenW(crlf
) * sizeof(WCHAR
);
1288 sprintfW(ipAddrBuf
, ipAddrWithMaskFmt
,
1289 entry
->u
.IPAddress
.pbData
[0],
1290 entry
->u
.IPAddress
.pbData
[1],
1291 entry
->u
.IPAddress
.pbData
[2],
1292 entry
->u
.IPAddress
.pbData
[3],
1293 entry
->u
.IPAddress
.pbData
[4],
1294 entry
->u
.IPAddress
.pbData
[5],
1295 entry
->u
.IPAddress
.pbData
[6],
1296 entry
->u
.IPAddress
.pbData
[7]);
1297 bytesNeeded
+= (strlenW(ipAddrBuf
) + 1) * sizeof(WCHAR
);
1303 FIXME("unknown IP address format (%d bytes)\n",
1304 entry
->u
.IPAddress
.cbData
);
1310 FIXME("unimplemented for %d\n", entry
->dwAltNameChoice
);
1315 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1317 *pcbStr
= bytesNeeded
;
1318 else if (*pcbStr
< bytesNeeded
)
1320 *pcbStr
= bytesNeeded
;
1321 SetLastError(ERROR_MORE_DATA
);
1328 *pcbStr
= bytesNeeded
;
1329 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1331 for (i
= 0; i
< indentLevel
; i
++)
1333 strcpyW(str
, indent
);
1334 str
+= strlenW(indent
);
1338 str
+= strlenW(str
);
1339 switch (entry
->dwAltNameChoice
)
1341 case CERT_ALT_NAME_RFC822_NAME
:
1342 case CERT_ALT_NAME_DNS_NAME
:
1343 case CERT_ALT_NAME_URL
:
1344 strcpyW(str
, entry
->u
.pwszURL
);
1346 case CERT_ALT_NAME_DIRECTORY_NAME
:
1347 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1349 strcpyW(str
, colonCrlf
);
1350 str
+= strlenW(colonCrlf
);
1354 cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1355 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, str
,
1356 bytesNeeded
/ sizeof(WCHAR
));
1358 case CERT_ALT_NAME_IP_ADDRESS
:
1359 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1361 strcpyW(str
, ipAddrBuf
);
1362 str
+= strlenW(ipAddrBuf
);
1364 str
+= strlenW(crlf
);
1365 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1367 for (i
= 0; i
< indentLevel
; i
++)
1369 strcpyW(str
, indent
);
1370 str
+= strlenW(indent
);
1374 str
+= strlenW(mask
);
1375 strcpyW(str
, maskBuf
);
1378 strcpyW(str
, ipAddrBuf
);
1386 static BOOL
CRYPT_FormatAltNameInfo(DWORD dwFormatStrType
, DWORD indentLevel
,
1387 const CERT_ALT_NAME_INFO
*name
, LPWSTR str
, DWORD
*pcbStr
)
1389 DWORD i
, size
, bytesNeeded
= 0;
1394 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1397 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1402 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1405 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1407 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1408 &name
->rgAltEntry
[i
], NULL
, &size
);
1411 bytesNeeded
+= size
- sizeof(WCHAR
);
1412 if (i
< name
->cAltEntry
- 1)
1413 bytesNeeded
+= sepLen
;
1418 bytesNeeded
+= sizeof(WCHAR
);
1420 *pcbStr
= bytesNeeded
;
1421 else if (*pcbStr
< bytesNeeded
)
1423 *pcbStr
= bytesNeeded
;
1424 SetLastError(ERROR_MORE_DATA
);
1429 *pcbStr
= bytesNeeded
;
1430 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1432 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1433 &name
->rgAltEntry
[i
], str
, &size
);
1436 str
+= size
/ sizeof(WCHAR
) - 1;
1437 if (i
< name
->cAltEntry
- 1)
1440 str
+= sepLen
/ sizeof(WCHAR
);
1449 static const WCHAR colonSep
[] = { ':',' ',0 };
1451 static BOOL WINAPI
CRYPT_FormatAltName(DWORD dwCertEncodingType
,
1452 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1453 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1457 CERT_ALT_NAME_INFO
*info
;
1460 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ALTERNATE_NAME
,
1461 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1463 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 0, info
, pbFormat
, pcbFormat
);
1469 static BOOL
CRYPT_FormatCertIssuer(DWORD dwFormatStrType
,
1470 const CERT_ALT_NAME_INFO
*issuer
, LPWSTR str
, DWORD
*pcbStr
)
1472 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1473 DWORD bytesNeeded
, sepLen
;
1477 LoadStringW(hInstance
, IDS_CERT_ISSUER
, buf
, ARRAY_SIZE(buf
));
1478 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, NULL
,
1480 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1481 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1484 sepLen
= strlenW(colonCrlf
) * sizeof(WCHAR
);
1489 sepLen
= strlenW(colonSep
) * sizeof(WCHAR
);
1491 bytesNeeded
+= sepLen
;
1495 *pcbStr
= bytesNeeded
;
1496 else if (*pcbStr
< bytesNeeded
)
1498 *pcbStr
= bytesNeeded
;
1499 SetLastError(ERROR_MORE_DATA
);
1504 *pcbStr
= bytesNeeded
;
1506 bytesNeeded
-= strlenW(str
) * sizeof(WCHAR
);
1507 str
+= strlenW(str
);
1509 str
+= sepLen
/ sizeof(WCHAR
);
1510 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, str
,
1517 static BOOL WINAPI
CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType
,
1518 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1519 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1522 CERT_AUTHORITY_KEY_ID2_INFO
*info
;
1528 SetLastError(E_INVALIDARG
);
1531 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_AUTHORITY_KEY_ID2
,
1532 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1534 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1537 BOOL needSeparator
= FALSE
;
1539 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1542 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1547 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1550 if (info
->KeyId
.cbData
)
1552 needSeparator
= TRUE
;
1553 ret
= CRYPT_FormatKeyId(&info
->KeyId
, NULL
, &size
);
1556 /* don't include NULL-terminator more than once */
1557 bytesNeeded
+= size
- sizeof(WCHAR
);
1560 if (info
->AuthorityCertIssuer
.cAltEntry
)
1563 bytesNeeded
+= sepLen
;
1564 needSeparator
= TRUE
;
1565 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1566 &info
->AuthorityCertIssuer
, NULL
, &size
);
1569 /* don't include NULL-terminator more than once */
1570 bytesNeeded
+= size
- sizeof(WCHAR
);
1573 if (info
->AuthorityCertSerialNumber
.cbData
)
1576 bytesNeeded
+= sepLen
;
1577 ret
= CRYPT_FormatCertSerialNumber(
1578 &info
->AuthorityCertSerialNumber
, NULL
, &size
);
1581 /* don't include NULL-terminator more than once */
1582 bytesNeeded
+= size
- sizeof(WCHAR
);
1588 *pcbFormat
= bytesNeeded
;
1589 else if (*pcbFormat
< bytesNeeded
)
1591 *pcbFormat
= bytesNeeded
;
1592 SetLastError(ERROR_MORE_DATA
);
1597 LPWSTR str
= pbFormat
;
1599 *pcbFormat
= bytesNeeded
;
1600 needSeparator
= FALSE
;
1601 if (info
->KeyId
.cbData
)
1603 needSeparator
= TRUE
;
1604 /* Overestimate size available, it's already been checked
1608 ret
= CRYPT_FormatKeyId(&info
->KeyId
, str
, &size
);
1610 str
+= size
/ sizeof(WCHAR
) - 1;
1612 if (info
->AuthorityCertIssuer
.cAltEntry
)
1617 str
+= sepLen
/ sizeof(WCHAR
);
1619 needSeparator
= TRUE
;
1620 /* Overestimate size available, it's already been checked
1624 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1625 &info
->AuthorityCertIssuer
, str
, &size
);
1627 str
+= size
/ sizeof(WCHAR
) - 1;
1629 if (info
->AuthorityCertSerialNumber
.cbData
)
1634 str
+= sepLen
/ sizeof(WCHAR
);
1636 /* Overestimate size available, it's already been checked
1640 ret
= CRYPT_FormatCertSerialNumber(
1641 &info
->AuthorityCertSerialNumber
, str
, &size
);
1650 static WCHAR aia
[MAX_STRING_RESOURCE_LEN
];
1651 static WCHAR accessMethod
[MAX_STRING_RESOURCE_LEN
];
1652 static WCHAR ocsp
[MAX_STRING_RESOURCE_LEN
];
1653 static WCHAR caIssuers
[MAX_STRING_RESOURCE_LEN
];
1654 static WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
1655 static WCHAR accessLocation
[MAX_STRING_RESOURCE_LEN
];
1657 static BOOL WINAPI
CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType
,
1658 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1659 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1662 CERT_AUTHORITY_INFO_ACCESS
*info
;
1668 SetLastError(E_INVALIDARG
);
1671 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
1672 X509_AUTHORITY_INFO_ACCESS
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
,
1673 NULL
, &info
, &size
)))
1675 DWORD bytesNeeded
= sizeof(WCHAR
);
1677 if (!info
->cAccDescr
)
1679 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
1681 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
1682 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
1684 *pcbFormat
= bytesNeeded
;
1685 else if (*pcbFormat
< bytesNeeded
)
1687 *pcbFormat
= bytesNeeded
;
1688 SetLastError(ERROR_MORE_DATA
);
1693 *pcbFormat
= bytesNeeded
;
1694 strcpyW(pbFormat
, infoNotAvailable
);
1699 static const WCHAR numFmt
[] = { '%','d',0 };
1700 static const WCHAR equal
[] = { '=',0 };
1701 static BOOL stringsLoaded
= FALSE
;
1703 LPCWSTR headingSep
, accessMethodSep
, locationSep
;
1704 WCHAR accessDescrNum
[11];
1708 LoadStringW(hInstance
, IDS_AIA
, aia
, ARRAY_SIZE(aia
));
1709 LoadStringW(hInstance
, IDS_ACCESS_METHOD
, accessMethod
, ARRAY_SIZE(accessMethod
));
1710 LoadStringW(hInstance
, IDS_ACCESS_METHOD_OCSP
, ocsp
, ARRAY_SIZE(ocsp
));
1711 LoadStringW(hInstance
, IDS_ACCESS_METHOD_CA_ISSUERS
, caIssuers
, ARRAY_SIZE(caIssuers
));
1712 LoadStringW(hInstance
, IDS_ACCESS_METHOD_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
1713 LoadStringW(hInstance
, IDS_ACCESS_LOCATION
, accessLocation
, ARRAY_SIZE(accessLocation
));
1714 stringsLoaded
= TRUE
;
1716 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1719 accessMethodSep
= crlf
;
1720 locationSep
= colonCrlf
;
1724 headingSep
= colonSep
;
1725 accessMethodSep
= commaSpace
;
1726 locationSep
= equal
;
1729 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1732 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
1733 sprintfW(accessDescrNum
, numFmt
, i
+ 1);
1734 bytesNeeded
+= strlenW(accessDescrNum
) * sizeof(WCHAR
);
1735 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
1736 bytesNeeded
+= strlenW(aia
) * sizeof(WCHAR
);
1737 bytesNeeded
+= strlenW(headingSep
) * sizeof(WCHAR
);
1739 bytesNeeded
+= strlenW(accessMethod
) * sizeof(WCHAR
);
1740 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1741 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
1742 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1744 bytesNeeded
+= strlenW(ocsp
) * sizeof(WCHAR
);
1745 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1746 szOID_PKIX_CA_ISSUERS
))
1747 bytesNeeded
+= strlenW(caIssuers
) * sizeof(caIssuers
);
1749 bytesNeeded
+= strlenW(unknown
) * sizeof(WCHAR
);
1750 bytesNeeded
+= sizeof(WCHAR
); /* space */
1751 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
1752 bytesNeeded
+= strlen(info
->rgAccDescr
[i
].pszAccessMethod
)
1754 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
1755 /* Delimiter between access method and location */
1756 bytesNeeded
+= strlenW(accessMethodSep
) * sizeof(WCHAR
);
1757 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1758 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
1759 bytesNeeded
+= strlenW(accessLocation
) * sizeof(WCHAR
);
1760 bytesNeeded
+= strlenW(locationSep
) * sizeof(WCHAR
);
1761 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1762 &info
->rgAccDescr
[i
].AccessLocation
, NULL
, &size
);
1764 bytesNeeded
+= size
- sizeof(WCHAR
);
1765 /* Need extra delimiter between access method entries */
1766 if (i
< info
->cAccDescr
- 1)
1767 bytesNeeded
+= strlenW(accessMethodSep
) * sizeof(WCHAR
);
1772 *pcbFormat
= bytesNeeded
;
1773 else if (*pcbFormat
< bytesNeeded
)
1775 *pcbFormat
= bytesNeeded
;
1776 SetLastError(ERROR_MORE_DATA
);
1781 LPWSTR str
= pbFormat
;
1782 DWORD altNameEntrySize
;
1784 *pcbFormat
= bytesNeeded
;
1785 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1790 sprintfW(accessDescrNum
, numFmt
, i
+ 1);
1791 strcpyW(str
, accessDescrNum
);
1792 str
+= strlenW(accessDescrNum
);
1795 str
+= strlenW(aia
);
1796 strcpyW(str
, headingSep
);
1797 str
+= strlenW(headingSep
);
1798 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1800 strcpyW(str
, indent
);
1801 str
+= strlenW(indent
);
1803 strcpyW(str
, accessMethod
);
1804 str
+= strlenW(accessMethod
);
1805 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1809 str
+= strlenW(ocsp
);
1811 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1812 szOID_PKIX_CA_ISSUERS
))
1814 strcpyW(str
, caIssuers
);
1815 str
+= strlenW(caIssuers
);
1819 strcpyW(str
, unknown
);
1820 str
+= strlenW(unknown
);
1824 for (oidPtr
= info
->rgAccDescr
[i
].pszAccessMethod
;
1825 *oidPtr
; oidPtr
++, str
++)
1828 strcpyW(str
, accessMethodSep
);
1829 str
+= strlenW(accessMethodSep
);
1830 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1832 strcpyW(str
, indent
);
1833 str
+= strlenW(indent
);
1835 strcpyW(str
, accessLocation
);
1836 str
+= strlenW(accessLocation
);
1837 strcpyW(str
, locationSep
);
1838 str
+= strlenW(locationSep
);
1839 /* This overestimates the size available, but that
1840 * won't matter since we checked earlier whether enough
1841 * space for the entire string was available.
1843 altNameEntrySize
= bytesNeeded
;
1844 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1845 &info
->rgAccDescr
[i
].AccessLocation
, str
,
1848 str
+= altNameEntrySize
/ sizeof(WCHAR
) - 1;
1849 if (i
< info
->cAccDescr
- 1)
1851 strcpyW(str
, accessMethodSep
);
1852 str
+= strlenW(accessMethodSep
);
1863 static WCHAR keyCompromise
[MAX_STRING_RESOURCE_LEN
];
1864 static WCHAR caCompromise
[MAX_STRING_RESOURCE_LEN
];
1865 static WCHAR affiliationChanged
[MAX_STRING_RESOURCE_LEN
];
1866 static WCHAR superseded
[MAX_STRING_RESOURCE_LEN
];
1867 static WCHAR operationCeased
[MAX_STRING_RESOURCE_LEN
];
1868 static WCHAR certificateHold
[MAX_STRING_RESOURCE_LEN
];
1870 struct reason_map_entry
1876 static struct reason_map_entry reason_map
[] = {
1877 { CRL_REASON_KEY_COMPROMISE_FLAG
, keyCompromise
, IDS_REASON_KEY_COMPROMISE
},
1878 { CRL_REASON_CA_COMPROMISE_FLAG
, caCompromise
, IDS_REASON_CA_COMPROMISE
},
1879 { CRL_REASON_AFFILIATION_CHANGED_FLAG
, affiliationChanged
,
1880 IDS_REASON_AFFILIATION_CHANGED
},
1881 { CRL_REASON_SUPERSEDED_FLAG
, superseded
, IDS_REASON_SUPERSEDED
},
1882 { CRL_REASON_CESSATION_OF_OPERATION_FLAG
, operationCeased
,
1883 IDS_REASON_CESSATION_OF_OPERATION
},
1884 { CRL_REASON_CERTIFICATE_HOLD_FLAG
, certificateHold
,
1885 IDS_REASON_CERTIFICATE_HOLD
},
1888 static BOOL
CRYPT_FormatReason(DWORD dwFormatStrType
,
1889 const CRYPT_BIT_BLOB
*reasonFlags
, LPWSTR str
, DWORD
*pcbStr
)
1891 static const WCHAR sep
[] = { ',',' ',0 };
1892 static const WCHAR bitsFmt
[] = { ' ','(','%','0','2','x',')',0 };
1893 static BOOL stringsLoaded
= FALSE
;
1894 unsigned int i
, numReasons
= 0;
1896 DWORD bytesNeeded
= sizeof(WCHAR
);
1901 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1902 LoadStringW(hInstance
, reason_map
[i
].id
, reason_map
[i
].reason
,
1903 MAX_STRING_RESOURCE_LEN
);
1904 stringsLoaded
= TRUE
;
1906 /* No need to check reasonFlags->cbData, we already know it's positive.
1907 * Ignore any other bytes, as they're for undefined bits.
1909 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1911 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1913 bytesNeeded
+= strlenW(reason_map
[i
].reason
) * sizeof(WCHAR
);
1915 bytesNeeded
+= strlenW(sep
) * sizeof(WCHAR
);
1918 sprintfW(bits
, bitsFmt
, reasonFlags
->pbData
[0]);
1919 bytesNeeded
+= strlenW(bits
);
1921 *pcbStr
= bytesNeeded
;
1922 else if (*pcbStr
< bytesNeeded
)
1924 *pcbStr
= bytesNeeded
;
1925 SetLastError(ERROR_MORE_DATA
);
1930 *pcbStr
= bytesNeeded
;
1931 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1933 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1935 strcpyW(str
, reason_map
[i
].reason
);
1936 str
+= strlenW(reason_map
[i
].reason
);
1937 if (i
< ARRAY_SIZE(reason_map
) - 1 && numReasons
)
1940 str
+= strlenW(sep
);
1949 static WCHAR crlDistPoint
[MAX_STRING_RESOURCE_LEN
];
1950 static WCHAR distPointName
[MAX_STRING_RESOURCE_LEN
];
1951 static WCHAR fullName
[MAX_STRING_RESOURCE_LEN
];
1952 static WCHAR rdnName
[MAX_STRING_RESOURCE_LEN
];
1953 static WCHAR reason
[MAX_STRING_RESOURCE_LEN
];
1954 static WCHAR issuer
[MAX_STRING_RESOURCE_LEN
];
1956 static BOOL WINAPI
CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType
,
1957 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1958 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1961 CRL_DIST_POINTS_INFO
*info
;
1967 SetLastError(E_INVALIDARG
);
1970 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_CRL_DIST_POINTS
,
1971 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1973 static const WCHAR numFmt
[] = { '%','d',0 };
1974 static const WCHAR colon
[] = { ':',0 };
1975 static BOOL stringsLoaded
= FALSE
;
1976 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for NULL terminator */
1977 BOOL haveAnEntry
= FALSE
;
1978 LPCWSTR headingSep
, nameSep
;
1979 WCHAR distPointNum
[11];
1984 LoadStringW(hInstance
, IDS_CRL_DIST_POINT
, crlDistPoint
, ARRAY_SIZE(crlDistPoint
));
1985 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_NAME
, distPointName
, ARRAY_SIZE(distPointName
));
1986 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_FULL_NAME
, fullName
, ARRAY_SIZE(fullName
));
1987 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_RDN_NAME
, rdnName
, ARRAY_SIZE(rdnName
));
1988 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_REASON
, reason
, ARRAY_SIZE(reason
));
1989 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_ISSUER
, issuer
, ARRAY_SIZE(issuer
));
1990 stringsLoaded
= TRUE
;
1992 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1995 nameSep
= colonCrlf
;
1999 headingSep
= colonSep
;
2003 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2005 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2007 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2008 CRL_DIST_POINT_NO_NAME
)
2010 bytesNeeded
+= strlenW(distPointName
) * sizeof(WCHAR
);
2011 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
2012 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2013 CRL_DIST_POINT_FULL_NAME
)
2014 bytesNeeded
+= strlenW(fullName
) * sizeof(WCHAR
);
2016 bytesNeeded
+= strlenW(rdnName
) * sizeof(WCHAR
);
2017 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
2018 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2019 bytesNeeded
+= 2 * strlenW(indent
) * sizeof(WCHAR
);
2020 /* The indent level (3) is higher than when used as the issuer,
2021 * because the name is subordinate to the name type (full vs.
2024 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2025 &distPoint
->DistPointName
.u
.FullName
, NULL
, &size
);
2027 bytesNeeded
+= size
- sizeof(WCHAR
);
2030 else if (distPoint
->ReasonFlags
.cbData
)
2032 bytesNeeded
+= strlenW(reason
) * sizeof(WCHAR
);
2033 ret
= CRYPT_FormatReason(dwFormatStrType
,
2034 &distPoint
->ReasonFlags
, NULL
, &size
);
2036 bytesNeeded
+= size
- sizeof(WCHAR
);
2039 else if (distPoint
->CRLIssuer
.cAltEntry
)
2041 bytesNeeded
+= strlenW(issuer
) * sizeof(WCHAR
);
2042 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
2043 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2044 &distPoint
->CRLIssuer
, NULL
, &size
);
2046 bytesNeeded
+= size
- sizeof(WCHAR
);
2051 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
2052 sprintfW(distPointNum
, numFmt
, i
+ 1);
2053 bytesNeeded
+= strlenW(distPointNum
) * sizeof(WCHAR
);
2054 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
2055 bytesNeeded
+= strlenW(crlDistPoint
) * sizeof(WCHAR
);
2056 bytesNeeded
+= strlenW(headingSep
) * sizeof(WCHAR
);
2057 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2058 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
2063 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2065 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2066 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
2068 *pcbFormat
= bytesNeeded
;
2069 else if (*pcbFormat
< bytesNeeded
)
2071 *pcbFormat
= bytesNeeded
;
2072 SetLastError(ERROR_MORE_DATA
);
2077 *pcbFormat
= bytesNeeded
;
2078 strcpyW(pbFormat
, infoNotAvailable
);
2084 *pcbFormat
= bytesNeeded
;
2085 else if (*pcbFormat
< bytesNeeded
)
2087 *pcbFormat
= bytesNeeded
;
2088 SetLastError(ERROR_MORE_DATA
);
2093 LPWSTR str
= pbFormat
;
2095 *pcbFormat
= bytesNeeded
;
2096 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2098 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2101 sprintfW(distPointNum
, numFmt
, i
+ 1);
2102 strcpyW(str
, distPointNum
);
2103 str
+= strlenW(distPointNum
);
2105 strcpyW(str
, crlDistPoint
);
2106 str
+= strlenW(crlDistPoint
);
2107 strcpyW(str
, headingSep
);
2108 str
+= strlenW(headingSep
);
2109 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2111 strcpyW(str
, indent
);
2112 str
+= strlenW(indent
);
2114 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2115 CRL_DIST_POINT_NO_NAME
)
2117 DWORD altNameSize
= bytesNeeded
;
2119 strcpyW(str
, distPointName
);
2120 str
+= strlenW(distPointName
);
2121 strcpyW(str
, nameSep
);
2122 str
+= strlenW(nameSep
);
2123 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2125 strcpyW(str
, indent
);
2126 str
+= strlenW(indent
);
2127 strcpyW(str
, indent
);
2128 str
+= strlenW(indent
);
2130 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2131 CRL_DIST_POINT_FULL_NAME
)
2133 strcpyW(str
, fullName
);
2134 str
+= strlenW(fullName
);
2138 strcpyW(str
, rdnName
);
2139 str
+= strlenW(rdnName
);
2141 strcpyW(str
, nameSep
);
2142 str
+= strlenW(nameSep
);
2143 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2144 &distPoint
->DistPointName
.u
.FullName
, str
,
2147 str
+= altNameSize
/ sizeof(WCHAR
) - 1;
2149 else if (distPoint
->ReasonFlags
.cbData
)
2151 DWORD reasonSize
= bytesNeeded
;
2153 strcpyW(str
, reason
);
2154 str
+= strlenW(reason
);
2155 ret
= CRYPT_FormatReason(dwFormatStrType
,
2156 &distPoint
->ReasonFlags
, str
, &reasonSize
);
2158 str
+= reasonSize
/ sizeof(WCHAR
) - 1;
2160 else if (distPoint
->CRLIssuer
.cAltEntry
)
2162 DWORD crlIssuerSize
= bytesNeeded
;
2164 strcpyW(str
, issuer
);
2165 str
+= strlenW(issuer
);
2166 strcpyW(str
, nameSep
);
2167 str
+= strlenW(nameSep
);
2168 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2169 &distPoint
->CRLIssuer
, str
,
2172 str
+= crlIssuerSize
/ sizeof(WCHAR
) - 1;
2182 static BOOL WINAPI
CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType
,
2183 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2184 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2187 CERT_ENHKEY_USAGE
*usage
;
2193 SetLastError(E_INVALIDARG
);
2196 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ENHANCED_KEY_USAGE
,
2197 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &usage
, &size
)))
2199 WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
2201 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
2205 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2208 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
2213 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
2216 LoadStringW(hInstance
, IDS_USAGE_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
2217 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2219 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2220 usage
->rgpszUsageIdentifier
[i
], CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2223 bytesNeeded
+= strlenW(info
->pwszName
) * sizeof(WCHAR
);
2225 bytesNeeded
+= strlenW(unknown
) * sizeof(WCHAR
);
2226 bytesNeeded
+= sizeof(WCHAR
); /* space */
2227 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
2228 bytesNeeded
+= strlen(usage
->rgpszUsageIdentifier
[i
]) *
2230 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
2231 if (i
< usage
->cUsageIdentifier
- 1)
2232 bytesNeeded
+= sepLen
;
2235 *pcbFormat
= bytesNeeded
;
2236 else if (*pcbFormat
< bytesNeeded
)
2238 *pcbFormat
= bytesNeeded
;
2239 SetLastError(ERROR_MORE_DATA
);
2244 LPWSTR str
= pbFormat
;
2246 *pcbFormat
= bytesNeeded
;
2247 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2249 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2250 usage
->rgpszUsageIdentifier
[i
],
2251 CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2256 strcpyW(str
, info
->pwszName
);
2257 str
+= strlenW(info
->pwszName
);
2261 strcpyW(str
, unknown
);
2262 str
+= strlenW(unknown
);
2266 for (oidPtr
= usage
->rgpszUsageIdentifier
[i
]; *oidPtr
; oidPtr
++)
2270 if (i
< usage
->cUsageIdentifier
- 1)
2273 str
+= sepLen
/ sizeof(WCHAR
);
2282 static struct BitToString netscapeCertTypeMap
[] = {
2283 { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_CLIENT
, { 0 } },
2284 { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_SERVER
, { 0 } },
2285 { NETSCAPE_SMIME_CERT_TYPE
, IDS_NETSCAPE_SMIME
, { 0 } },
2286 { NETSCAPE_SIGN_CERT_TYPE
, IDS_NETSCAPE_SIGN
, { 0 } },
2287 { NETSCAPE_SSL_CA_CERT_TYPE
, IDS_NETSCAPE_SSL_CA
, { 0 } },
2288 { NETSCAPE_SMIME_CA_CERT_TYPE
, IDS_NETSCAPE_SMIME_CA
, { 0 } },
2289 { NETSCAPE_SIGN_CA_CERT_TYPE
, IDS_NETSCAPE_SIGN_CA
, { 0 } },
2292 static BOOL WINAPI
CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType
,
2293 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2294 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2298 CRYPT_BIT_BLOB
*bits
;
2303 SetLastError(E_INVALIDARG
);
2306 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BITS
,
2307 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
2309 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2310 DWORD bytesNeeded
= sizeof(WCHAR
);
2312 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2313 if (!bits
->cbData
|| bits
->cbData
> 1)
2315 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
2317 *pcbFormat
= bytesNeeded
;
2318 else if (*pcbFormat
< bytesNeeded
)
2320 *pcbFormat
= bytesNeeded
;
2321 SetLastError(ERROR_MORE_DATA
);
2326 LPWSTR str
= pbFormat
;
2328 *pcbFormat
= bytesNeeded
;
2329 strcpyW(str
, infoNotAvailable
);
2334 static BOOL stringsLoaded
= FALSE
;
2341 for (i
= 0; i
< ARRAY_SIZE(netscapeCertTypeMap
); i
++)
2342 LoadStringW(hInstance
, netscapeCertTypeMap
[i
].id
,
2343 netscapeCertTypeMap
[i
].str
, MAX_STRING_RESOURCE_LEN
);
2344 stringsLoaded
= TRUE
;
2346 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
, ARRAY_SIZE(netscapeCertTypeMap
),
2347 NULL
, &bitStringLen
, &first
);
2348 bytesNeeded
+= bitStringLen
;
2349 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
2350 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2351 bits
->cbData
, NULL
, &size
);
2352 bytesNeeded
+= size
;
2354 *pcbFormat
= bytesNeeded
;
2355 else if (*pcbFormat
< bytesNeeded
)
2357 *pcbFormat
= bytesNeeded
;
2358 SetLastError(ERROR_MORE_DATA
);
2363 LPWSTR str
= pbFormat
;
2365 bitStringLen
= bytesNeeded
;
2367 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
, ARRAY_SIZE(netscapeCertTypeMap
),
2368 str
, &bitStringLen
, &first
);
2369 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
2372 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2373 bits
->cbData
, str
, &size
);
2374 str
+= size
/ sizeof(WCHAR
) - 1;
2384 static WCHAR financialCriteria
[MAX_STRING_RESOURCE_LEN
];
2385 static WCHAR available
[MAX_STRING_RESOURCE_LEN
];
2386 static WCHAR notAvailable
[MAX_STRING_RESOURCE_LEN
];
2387 static WCHAR meetsCriteria
[MAX_STRING_RESOURCE_LEN
];
2388 static WCHAR yes
[MAX_STRING_RESOURCE_LEN
];
2389 static WCHAR no
[MAX_STRING_RESOURCE_LEN
];
2391 static BOOL WINAPI
CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType
,
2392 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2393 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2396 SPC_FINANCIAL_CRITERIA criteria
;
2397 DWORD size
= sizeof(criteria
);
2402 SetLastError(E_INVALIDARG
);
2405 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
2406 SPC_FINANCIAL_CRITERIA_STRUCT
, pbEncoded
, cbEncoded
, 0, NULL
, &criteria
,
2409 static BOOL stringsLoaded
= FALSE
;
2410 DWORD bytesNeeded
= sizeof(WCHAR
);
2416 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA
, financialCriteria
, ARRAY_SIZE(financialCriteria
));
2417 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_AVAILABLE
, available
, ARRAY_SIZE(available
));
2418 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE
, notAvailable
, ARRAY_SIZE(notAvailable
));
2419 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA
, meetsCriteria
, ARRAY_SIZE(meetsCriteria
));
2420 LoadStringW(hInstance
, IDS_YES
, yes
, ARRAY_SIZE(yes
));
2421 LoadStringW(hInstance
, IDS_NO
, no
, ARRAY_SIZE(no
));
2422 stringsLoaded
= TRUE
;
2424 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2427 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
2432 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
2434 bytesNeeded
+= strlenW(financialCriteria
) * sizeof(WCHAR
);
2435 if (criteria
.fFinancialInfoAvailable
)
2437 bytesNeeded
+= strlenW(available
) * sizeof(WCHAR
);
2438 bytesNeeded
+= sepLen
;
2439 bytesNeeded
+= strlenW(meetsCriteria
) * sizeof(WCHAR
);
2440 if (criteria
.fMeetsCriteria
)
2441 bytesNeeded
+= strlenW(yes
) * sizeof(WCHAR
);
2443 bytesNeeded
+= strlenW(no
) * sizeof(WCHAR
);
2446 bytesNeeded
+= strlenW(notAvailable
) * sizeof(WCHAR
);
2448 *pcbFormat
= bytesNeeded
;
2449 else if (*pcbFormat
< bytesNeeded
)
2451 *pcbFormat
= bytesNeeded
;
2452 SetLastError(ERROR_MORE_DATA
);
2457 LPWSTR str
= pbFormat
;
2459 *pcbFormat
= bytesNeeded
;
2460 strcpyW(str
, financialCriteria
);
2461 str
+= strlenW(financialCriteria
);
2462 if (criteria
.fFinancialInfoAvailable
)
2464 strcpyW(str
, available
);
2465 str
+= strlenW(available
);
2467 str
+= sepLen
/ sizeof(WCHAR
);
2468 strcpyW(str
, meetsCriteria
);
2469 str
+= strlenW(meetsCriteria
);
2470 if (criteria
.fMeetsCriteria
)
2477 strcpyW(str
, notAvailable
);
2484 static BOOL WINAPI
CRYPT_FormatUnicodeString(DWORD dwCertEncodingType
,
2485 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2486 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2489 CERT_NAME_VALUE
*value
;
2495 SetLastError(E_INVALIDARG
);
2498 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_UNICODE_ANY_STRING
,
2499 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &value
, &size
)))
2502 *pcbFormat
= value
->Value
.cbData
;
2503 else if (*pcbFormat
< value
->Value
.cbData
)
2505 *pcbFormat
= value
->Value
.cbData
;
2506 SetLastError(ERROR_MORE_DATA
);
2511 LPWSTR str
= pbFormat
;
2513 *pcbFormat
= value
->Value
.cbData
;
2514 strcpyW(str
, (LPWSTR
)value
->Value
.pbData
);
2520 typedef BOOL (WINAPI
*CryptFormatObjectFunc
)(DWORD
, DWORD
, DWORD
, void *,
2521 LPCSTR
, const BYTE
*, DWORD
, void *, DWORD
*);
2523 static CryptFormatObjectFunc
CRYPT_GetBuiltinFormatFunction(DWORD encodingType
,
2524 DWORD formatStrType
, LPCSTR lpszStructType
)
2526 CryptFormatObjectFunc format
= NULL
;
2528 if ((encodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
)
2530 SetLastError(ERROR_FILE_NOT_FOUND
);
2533 if (IS_INTOID(lpszStructType
))
2535 switch (LOWORD(lpszStructType
))
2537 case LOWORD(X509_KEY_USAGE
):
2538 format
= CRYPT_FormatKeyUsage
;
2540 case LOWORD(X509_ALTERNATE_NAME
):
2541 format
= CRYPT_FormatAltName
;
2543 case LOWORD(X509_BASIC_CONSTRAINTS2
):
2544 format
= CRYPT_FormatBasicConstraints2
;
2546 case LOWORD(X509_AUTHORITY_KEY_ID2
):
2547 format
= CRYPT_FormatAuthorityKeyId2
;
2549 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
2550 format
= CRYPT_FormatAuthorityInfoAccess
;
2552 case LOWORD(X509_CRL_DIST_POINTS
):
2553 format
= CRYPT_FormatCRLDistPoints
;
2555 case LOWORD(X509_ENHANCED_KEY_USAGE
):
2556 format
= CRYPT_FormatEnhancedKeyUsage
;
2558 case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT
):
2559 format
= CRYPT_FormatSpcFinancialCriteria
;
2563 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
2564 format
= CRYPT_FormatAltName
;
2565 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
2566 format
= CRYPT_FormatAltName
;
2567 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
2568 format
= CRYPT_FormatKeyUsage
;
2569 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
2570 format
= CRYPT_FormatAltName
;
2571 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
2572 format
= CRYPT_FormatAltName
;
2573 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
2574 format
= CRYPT_FormatBasicConstraints2
;
2575 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
2576 format
= CRYPT_FormatAuthorityInfoAccess
;
2577 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
2578 format
= CRYPT_FormatAuthorityKeyId2
;
2579 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
2580 format
= CRYPT_FormatCRLDistPoints
;
2581 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
2582 format
= CRYPT_FormatEnhancedKeyUsage
;
2583 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_CERT_TYPE
))
2584 format
= CRYPT_FormatNetscapeCertType
;
2585 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_BASE_URL
) ||
2586 !strcmp(lpszStructType
, szOID_NETSCAPE_REVOCATION_URL
) ||
2587 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_REVOCATION_URL
) ||
2588 !strcmp(lpszStructType
, szOID_NETSCAPE_CERT_RENEWAL_URL
) ||
2589 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_POLICY_URL
) ||
2590 !strcmp(lpszStructType
, szOID_NETSCAPE_SSL_SERVER_NAME
) ||
2591 !strcmp(lpszStructType
, szOID_NETSCAPE_COMMENT
))
2592 format
= CRYPT_FormatUnicodeString
;
2593 else if (!strcmp(lpszStructType
, SPC_FINANCIAL_CRITERIA_OBJID
))
2594 format
= CRYPT_FormatSpcFinancialCriteria
;
2598 BOOL WINAPI
CryptFormatObject(DWORD dwCertEncodingType
, DWORD dwFormatType
,
2599 DWORD dwFormatStrType
, void *pFormatStruct
, LPCSTR lpszStructType
,
2600 const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
, DWORD
*pcbFormat
)
2602 CryptFormatObjectFunc format
= NULL
;
2603 HCRYPTOIDFUNCADDR hFunc
= NULL
;
2606 TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType
,
2607 dwFormatType
, dwFormatStrType
, pFormatStruct
, debugstr_a(lpszStructType
),
2608 pbEncoded
, cbEncoded
, pbFormat
, pcbFormat
);
2610 if (!(format
= CRYPT_GetBuiltinFormatFunction(dwCertEncodingType
,
2611 dwFormatStrType
, lpszStructType
)))
2613 static HCRYPTOIDFUNCSET set
= NULL
;
2616 set
= CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC
, 0);
2617 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
2618 (void **)&format
, &hFunc
);
2620 if (!format
&& (dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) ==
2621 X509_ASN_ENCODING
&& !(dwFormatStrType
& CRYPT_FORMAT_STR_NO_HEX
))
2622 format
= CRYPT_FormatHexString
;
2624 ret
= format(dwCertEncodingType
, dwFormatType
, dwFormatStrType
,
2625 pFormatStruct
, lpszStructType
, pbEncoded
, cbEncoded
, pbFormat
,
2628 CryptFreeOIDFunctionAddress(hFunc
, 0);