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
);
60 TRACE("returning %d\n", ret
);
64 static BOOL
CRYPT_QueryContextBlob(const CERT_BLOB
*blob
,
65 DWORD dwExpectedContentTypeFlags
, HCERTSTORE store
,
66 DWORD
*contentType
, const void **ppvContext
)
70 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
)
72 ret
= pCertInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
73 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
74 if (ret
&& contentType
)
75 *contentType
= CERT_QUERY_CONTENT_CERT
;
77 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
))
79 ret
= pCRLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
80 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
81 if (ret
&& contentType
)
82 *contentType
= CERT_QUERY_CONTENT_CRL
;
84 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
86 ret
= pCTLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
87 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
88 if (ret
&& contentType
)
89 *contentType
= CERT_QUERY_CONTENT_CTL
;
94 static BOOL
CRYPT_QueryContextObject(DWORD dwObjectType
, const void *pvObject
,
95 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
96 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
97 HCERTSTORE
*phCertStore
, const void **ppvContext
)
100 const CERT_BLOB
*blob
;
103 DWORD formatType
= 0;
105 switch (dwObjectType
)
107 case CERT_QUERY_OBJECT_FILE
:
108 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
109 * just read the file directly
111 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
114 case CERT_QUERY_OBJECT_BLOB
:
119 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
126 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
127 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
128 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
130 ret
= CRYPT_QueryContextBlob(blob
, dwExpectedContentTypeFlags
, store
,
131 pdwContentType
, ppvContext
);
133 formatType
= CERT_QUERY_FORMAT_BINARY
;
136 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
138 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
139 CRYPT_DATA_BLOB decoded
;
141 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
143 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
144 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
147 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
150 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
151 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
152 &decoded
.cbData
, NULL
, NULL
);
155 ret
= CRYPT_QueryContextBlob(&decoded
,
156 dwExpectedContentTypeFlags
, store
, pdwContentType
,
159 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
161 CryptMemFree(decoded
.pbData
);
169 if (pdwMsgAndCertEncodingType
)
170 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
172 *pdwFormatType
= formatType
;
174 *phCertStore
= CertDuplicateStore(store
);
176 CertCloseStore(store
, 0);
177 if (blob
== &fileBlob
)
178 CryptMemFree(blob
->pbData
);
179 TRACE("returning %d\n", ret
);
183 static BOOL
CRYPT_QuerySerializedContextObject(DWORD dwObjectType
,
184 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
185 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
186 HCERTSTORE
*phCertStore
, const void **ppvContext
)
189 const CERT_BLOB
*blob
;
190 const WINE_CONTEXT_INTERFACE
*contextInterface
= NULL
;
195 switch (dwObjectType
)
197 case CERT_QUERY_OBJECT_FILE
:
198 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
199 * just read the file directly
201 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
204 case CERT_QUERY_OBJECT_BLOB
:
209 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
216 context
= CRYPT_ReadSerializedElement(blob
->pbData
, blob
->cbData
,
217 CERT_STORE_ALL_CONTEXT_FLAG
, &contextType
);
220 DWORD contentType
, certStoreOffset
;
225 case CERT_STORE_CERTIFICATE_CONTEXT
:
226 contextInterface
= pCertInterface
;
227 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CERT
;
228 certStoreOffset
= offsetof(CERT_CONTEXT
, hCertStore
);
229 if (!(dwExpectedContentTypeFlags
&
230 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
))
232 SetLastError(ERROR_INVALID_DATA
);
237 case CERT_STORE_CRL_CONTEXT
:
238 contextInterface
= pCRLInterface
;
239 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CRL
;
240 certStoreOffset
= offsetof(CRL_CONTEXT
, hCertStore
);
241 if (!(dwExpectedContentTypeFlags
&
242 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
))
244 SetLastError(ERROR_INVALID_DATA
);
249 case CERT_STORE_CTL_CONTEXT
:
250 contextInterface
= pCTLInterface
;
251 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CTL
;
252 certStoreOffset
= offsetof(CTL_CONTEXT
, hCertStore
);
253 if (!(dwExpectedContentTypeFlags
&
254 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
))
256 SetLastError(ERROR_INVALID_DATA
);
262 SetLastError(ERROR_INVALID_DATA
);
266 if (pdwMsgAndCertEncodingType
)
267 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
269 *pdwContentType
= contentType
;
271 *phCertStore
= CertDuplicateStore(
272 *(HCERTSTORE
*)((const BYTE
*)context
+ certStoreOffset
));
274 *ppvContext
= contextInterface
->duplicate(context
);
278 if (contextInterface
&& context
)
279 contextInterface
->free(context
);
280 if (blob
== &fileBlob
)
281 CryptMemFree(blob
->pbData
);
282 TRACE("returning %d\n", ret
);
286 static BOOL
CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName
,
287 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
288 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
293 TRACE("%s\n", debugstr_w(fileName
));
294 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
295 OPEN_EXISTING
, 0, NULL
);
296 if (file
!= INVALID_HANDLE_VALUE
)
298 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
299 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
301 ret
= CRYPT_ReadSerializedStoreFromFile(file
, store
);
304 if (pdwMsgAndCertEncodingType
)
305 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
307 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
309 *phCertStore
= CertDuplicateStore(store
);
311 CertCloseStore(store
, 0);
314 TRACE("returning %d\n", ret
);
318 static BOOL
CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB
*blob
,
319 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
320 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
322 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
323 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
326 TRACE("(%d, %p)\n", blob
->cbData
, blob
->pbData
);
328 ret
= CRYPT_ReadSerializedStoreFromBlob(blob
, store
);
331 if (pdwMsgAndCertEncodingType
)
332 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
334 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
336 *phCertStore
= CertDuplicateStore(store
);
338 CertCloseStore(store
, 0);
339 TRACE("returning %d\n", ret
);
343 static BOOL
CRYPT_QuerySerializedStoreObject(DWORD dwObjectType
,
344 const void *pvObject
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
345 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
347 switch (dwObjectType
)
349 case CERT_QUERY_OBJECT_FILE
:
350 return CRYPT_QuerySerializedStoreFromFile(pvObject
,
351 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
352 case CERT_QUERY_OBJECT_BLOB
:
353 return CRYPT_QuerySerializedStoreFromBlob(pvObject
,
354 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
356 FIXME("unimplemented for type %d\n", dwObjectType
);
357 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
362 static BOOL
CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB
*blob
,
363 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
365 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
369 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
371 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
374 DWORD type
, len
= sizeof(type
);
376 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
379 if (type
!= CMSG_SIGNED
)
381 SetLastError(ERROR_INVALID_DATA
);
389 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_SIGNED
, 0, NULL
,
393 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
404 if (pdwMsgAndCertEncodingType
)
405 *pdwMsgAndCertEncodingType
= encodingType
;
407 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
414 static BOOL
CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB
*blob
,
415 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
417 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
421 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
423 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
426 DWORD type
, len
= sizeof(type
);
428 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
431 if (type
!= CMSG_DATA
)
433 SetLastError(ERROR_INVALID_DATA
);
441 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_DATA
, 0,
445 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
456 if (pdwMsgAndCertEncodingType
)
457 *pdwMsgAndCertEncodingType
= encodingType
;
459 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
466 /* Used to decode non-embedded messages */
467 static BOOL
CRYPT_QueryMessageObject(DWORD dwObjectType
, const void *pvObject
,
468 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
469 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
470 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
473 const CERT_BLOB
*blob
;
475 HCRYPTMSG msg
= NULL
;
476 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
477 DWORD formatType
= 0;
479 TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
480 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
481 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
484 switch (dwObjectType
)
486 case CERT_QUERY_OBJECT_FILE
:
487 /* This isn't an embedded PKCS7 message, so just read the file
490 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
493 case CERT_QUERY_OBJECT_BLOB
:
498 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
505 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
507 /* Try it first as a signed message */
508 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
509 ret
= CRYPT_QuerySignedMessage(blob
, pdwMsgAndCertEncodingType
,
510 pdwContentType
, &msg
);
511 /* Failing that, try as an unsigned message */
513 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
514 ret
= CRYPT_QueryUnsignedMessage(blob
, pdwMsgAndCertEncodingType
,
515 pdwContentType
, &msg
);
517 formatType
= CERT_QUERY_FORMAT_BINARY
;
520 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
522 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
523 CRYPT_DATA_BLOB decoded
;
525 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
527 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
528 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
531 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
534 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
535 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
536 &decoded
.cbData
, NULL
, NULL
);
539 /* Try it first as a signed message */
540 if (dwExpectedContentTypeFlags
&
541 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
542 ret
= CRYPT_QuerySignedMessage(&decoded
,
543 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
544 /* Failing that, try as an unsigned message */
545 if (!ret
&& (dwExpectedContentTypeFlags
&
546 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
547 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
548 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
550 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
552 CryptMemFree(decoded
.pbData
);
557 if (!ret
&& !(blob
->cbData
% sizeof(WCHAR
)))
559 CRYPT_DATA_BLOB decoded
;
560 LPWSTR str
= (LPWSTR
)blob
->pbData
;
561 DWORD strLen
= blob
->cbData
/ sizeof(WCHAR
);
563 /* Try again, assuming the input string is UTF-16 base64 */
564 while (strLen
&& !str
[strLen
- 1])
566 ret
= CryptStringToBinaryW(str
, strLen
, CRYPT_STRING_BASE64_ANY
,
567 NULL
, &decoded
.cbData
, NULL
, NULL
);
570 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
573 ret
= CryptStringToBinaryW(str
, strLen
,
574 CRYPT_STRING_BASE64_ANY
, decoded
.pbData
, &decoded
.cbData
,
578 /* Try it first as a signed message */
579 if (dwExpectedContentTypeFlags
&
580 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
581 ret
= CRYPT_QuerySignedMessage(&decoded
,
582 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
583 /* Failing that, try as an unsigned message */
584 if (!ret
&& (dwExpectedContentTypeFlags
&
585 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
586 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
587 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
589 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
591 CryptMemFree(decoded
.pbData
);
601 *pdwFormatType
= formatType
;
603 *phCertStore
= CertOpenStore(CERT_STORE_PROV_MSG
, encodingType
, 0,
610 if (blob
== &fileBlob
)
611 CryptMemFree(blob
->pbData
);
612 TRACE("returning %d\n", ret
);
616 static BOOL
CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType
,
617 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
618 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
619 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
625 TRACE("%s\n", debugstr_w(pvObject
));
627 if (dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
629 WARN("don't know what to do for type %d embedded signed messages\n",
631 SetLastError(E_INVALIDARG
);
634 file
= CreateFileW(pvObject
, GENERIC_READ
, FILE_SHARE_READ
,
635 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
636 if (file
!= INVALID_HANDLE_VALUE
)
638 ret
= CryptSIPRetrieveSubjectGuid(pvObject
, file
, &subject
);
641 SIP_DISPATCH_INFO sip
;
643 memset(&sip
, 0, sizeof(sip
));
644 sip
.cbSize
= sizeof(sip
);
645 ret
= CryptSIPLoad(&subject
, 0, &sip
);
648 SIP_SUBJECTINFO subjectInfo
;
652 memset(&subjectInfo
, 0, sizeof(subjectInfo
));
653 subjectInfo
.cbSize
= sizeof(subjectInfo
);
654 subjectInfo
.pgSubjectType
= &subject
;
655 subjectInfo
.hFile
= file
;
656 subjectInfo
.pwsFileName
= pvObject
;
657 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0, &blob
.cbData
,
661 blob
.pbData
= CryptMemAlloc(blob
.cbData
);
664 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0,
665 &blob
.cbData
, blob
.pbData
);
668 ret
= CRYPT_QueryMessageObject(
669 CERT_QUERY_OBJECT_BLOB
, &blob
,
670 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
,
671 CERT_QUERY_FORMAT_FLAG_BINARY
,
672 pdwMsgAndCertEncodingType
, NULL
, NULL
,
674 if (ret
&& pdwContentType
)
675 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
;
677 CryptMemFree(blob
.pbData
);
681 SetLastError(ERROR_OUTOFMEMORY
);
689 TRACE("returning %d\n", ret
);
693 BOOL WINAPI
CryptQueryObject(DWORD dwObjectType
, const void *pvObject
,
694 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
695 DWORD dwFlags
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
696 DWORD
*pdwFormatType
, HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
,
697 const void **ppvContext
)
699 static const DWORD unimplementedTypes
=
700 CERT_QUERY_CONTENT_FLAG_PKCS10
| CERT_QUERY_CONTENT_FLAG_PFX
|
701 CERT_QUERY_CONTENT_FLAG_CERT_PAIR
;
704 TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
705 dwObjectType
, pvObject
, dwExpectedContentTypeFlags
,
706 dwExpectedFormatTypeFlags
, dwFlags
, pdwMsgAndCertEncodingType
,
707 pdwContentType
, pdwFormatType
, phCertStore
, phMsg
, ppvContext
);
709 if (dwObjectType
!= CERT_QUERY_OBJECT_BLOB
&&
710 dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
712 WARN("unsupported type %d\n", dwObjectType
);
713 SetLastError(E_INVALIDARG
);
718 WARN("missing required argument\n");
719 SetLastError(E_INVALIDARG
);
722 if (dwExpectedContentTypeFlags
& unimplementedTypes
)
723 WARN("unimplemented for types %08x\n",
724 dwExpectedContentTypeFlags
& unimplementedTypes
);
727 *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
736 if ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
) ||
737 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
) ||
738 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
740 ret
= CRYPT_QueryContextObject(dwObjectType
, pvObject
,
741 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
742 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
746 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE
))
748 ret
= CRYPT_QuerySerializedStoreObject(dwObjectType
, pvObject
,
749 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
752 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
) ||
753 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
) ||
754 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
)))
756 ret
= CRYPT_QuerySerializedContextObject(dwObjectType
, pvObject
,
757 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
758 phCertStore
, ppvContext
);
761 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
) ||
762 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
)))
764 ret
= CRYPT_QueryMessageObject(dwObjectType
, pvObject
,
765 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
766 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
770 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED
))
772 ret
= CRYPT_QueryEmbeddedMessageObject(dwObjectType
, pvObject
,
773 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
777 SetLastError(CRYPT_E_NO_MATCH
);
778 TRACE("returning %d\n", ret
);
782 static BOOL WINAPI
CRYPT_FormatHexString(DWORD dwCertEncodingType
,
783 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
784 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
791 bytesNeeded
= (cbEncoded
* 3) * sizeof(WCHAR
);
793 bytesNeeded
= sizeof(WCHAR
);
796 *pcbFormat
= bytesNeeded
;
799 else if (*pcbFormat
< bytesNeeded
)
801 *pcbFormat
= bytesNeeded
;
802 SetLastError(ERROR_MORE_DATA
);
807 static const WCHAR fmt
[] = { '%','0','2','x',' ',0 };
808 static const WCHAR endFmt
[] = { '%','0','2','x',0 };
810 LPWSTR ptr
= pbFormat
;
812 *pcbFormat
= bytesNeeded
;
815 for (i
= 0; i
< cbEncoded
; i
++)
817 if (i
< cbEncoded
- 1)
818 ptr
+= sprintfW(ptr
, fmt
, pbEncoded
[i
]);
820 ptr
+= sprintfW(ptr
, endFmt
, pbEncoded
[i
]);
830 #define MAX_STRING_RESOURCE_LEN 128
832 static const WCHAR commaSpace
[] = { ',',' ',0 };
838 WCHAR str
[MAX_STRING_RESOURCE_LEN
];
841 static BOOL
CRYPT_FormatBits(BYTE bits
, const struct BitToString
*map
,
842 DWORD mapEntries
, void *pbFormat
, DWORD
*pcbFormat
, BOOL
*first
)
844 DWORD bytesNeeded
= sizeof(WCHAR
);
846 BOOL ret
= TRUE
, localFirst
= *first
;
848 for (i
= 0; i
< mapEntries
; i
++)
849 if (bits
& map
[i
].bit
)
852 bytesNeeded
+= strlenW(commaSpace
) * sizeof(WCHAR
);
854 bytesNeeded
+= strlenW(map
[i
].str
) * sizeof(WCHAR
);
859 *pcbFormat
= bytesNeeded
;
861 else if (*pcbFormat
< bytesNeeded
)
864 *pcbFormat
= bytesNeeded
;
865 SetLastError(ERROR_MORE_DATA
);
870 LPWSTR str
= pbFormat
;
873 *pcbFormat
= bytesNeeded
;
874 for (i
= 0; i
< mapEntries
; i
++)
875 if (bits
& map
[i
].bit
)
879 strcpyW(str
, commaSpace
);
880 str
+= strlenW(commaSpace
);
883 strcpyW(str
, map
[i
].str
);
884 str
+= strlenW(map
[i
].str
);
891 static struct BitToString keyUsageByte0Map
[] = {
892 { CERT_DIGITAL_SIGNATURE_KEY_USAGE
, IDS_DIGITAL_SIGNATURE
, { 0 } },
893 { CERT_NON_REPUDIATION_KEY_USAGE
, IDS_NON_REPUDIATION
, { 0 } },
894 { CERT_KEY_ENCIPHERMENT_KEY_USAGE
, IDS_KEY_ENCIPHERMENT
, { 0 } },
895 { CERT_DATA_ENCIPHERMENT_KEY_USAGE
, IDS_DATA_ENCIPHERMENT
, { 0 } },
896 { CERT_KEY_AGREEMENT_KEY_USAGE
, IDS_KEY_AGREEMENT
, { 0 } },
897 { CERT_KEY_CERT_SIGN_KEY_USAGE
, IDS_CERT_SIGN
, { 0 } },
898 { CERT_OFFLINE_CRL_SIGN_KEY_USAGE
, IDS_OFFLINE_CRL_SIGN
, { 0 } },
899 { CERT_CRL_SIGN_KEY_USAGE
, IDS_CRL_SIGN
, { 0 } },
900 { CERT_ENCIPHER_ONLY_KEY_USAGE
, IDS_ENCIPHER_ONLY
, { 0 } },
902 static struct BitToString keyUsageByte1Map
[] = {
903 { CERT_DECIPHER_ONLY_KEY_USAGE
, IDS_DECIPHER_ONLY
, { 0 } },
906 static BOOL WINAPI
CRYPT_FormatKeyUsage(DWORD dwCertEncodingType
,
907 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
908 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
912 CRYPT_BIT_BLOB
*bits
;
917 SetLastError(E_INVALIDARG
);
920 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_KEY_USAGE
,
921 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
923 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
924 DWORD bytesNeeded
= sizeof(WCHAR
);
926 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
,
927 sizeof(infoNotAvailable
) / sizeof(infoNotAvailable
[0]));
928 if (!bits
->cbData
|| bits
->cbData
> 2)
930 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
932 *pcbFormat
= bytesNeeded
;
933 else if (*pcbFormat
< bytesNeeded
)
935 *pcbFormat
= bytesNeeded
;
936 SetLastError(ERROR_MORE_DATA
);
941 LPWSTR str
= pbFormat
;
943 *pcbFormat
= bytesNeeded
;
944 strcpyW(str
, infoNotAvailable
);
949 static BOOL stringsLoaded
= FALSE
;
957 i
< sizeof(keyUsageByte0Map
) / sizeof(keyUsageByte0Map
[0]);
959 LoadStringW(hInstance
, keyUsageByte0Map
[i
].id
,
960 keyUsageByte0Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
962 i
< sizeof(keyUsageByte1Map
) / sizeof(keyUsageByte1Map
[0]);
964 LoadStringW(hInstance
, keyUsageByte1Map
[i
].id
,
965 keyUsageByte1Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
966 stringsLoaded
= TRUE
;
968 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
,
969 sizeof(keyUsageByte0Map
) / sizeof(keyUsageByte0Map
[0]),
970 NULL
, &bitStringLen
, &first
);
971 bytesNeeded
+= bitStringLen
;
972 if (bits
->cbData
== 2)
974 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
,
975 sizeof(keyUsageByte1Map
) / sizeof(keyUsageByte1Map
[0]),
976 NULL
, &bitStringLen
, &first
);
977 bytesNeeded
+= bitStringLen
;
979 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
980 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
981 bits
->cbData
, NULL
, &size
);
984 *pcbFormat
= bytesNeeded
;
985 else if (*pcbFormat
< bytesNeeded
)
987 *pcbFormat
= bytesNeeded
;
988 SetLastError(ERROR_MORE_DATA
);
993 LPWSTR str
= pbFormat
;
995 bitStringLen
= bytesNeeded
;
997 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
,
998 sizeof(keyUsageByte0Map
) / sizeof(keyUsageByte0Map
[0]),
999 str
, &bitStringLen
, &first
);
1000 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1001 if (bits
->cbData
== 2)
1003 bitStringLen
= bytesNeeded
;
1004 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
,
1005 sizeof(keyUsageByte1Map
) / sizeof(keyUsageByte1Map
[0]),
1006 str
, &bitStringLen
, &first
);
1007 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1011 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1012 bits
->cbData
, str
, &size
);
1013 str
+= size
/ sizeof(WCHAR
) - 1;
1023 static const WCHAR crlf
[] = { '\r','\n',0 };
1025 static WCHAR subjectTypeHeader
[MAX_STRING_RESOURCE_LEN
];
1026 static WCHAR subjectTypeCA
[MAX_STRING_RESOURCE_LEN
];
1027 static WCHAR subjectTypeEndCert
[MAX_STRING_RESOURCE_LEN
];
1028 static WCHAR pathLengthHeader
[MAX_STRING_RESOURCE_LEN
];
1030 static BOOL WINAPI
CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType
,
1031 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1032 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1036 CERT_BASIC_CONSTRAINTS2_INFO
*info
;
1041 SetLastError(E_INVALIDARG
);
1044 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BASIC_CONSTRAINTS2
,
1045 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1047 static const WCHAR pathFmt
[] = { '%','d',0 };
1048 static BOOL stringsLoaded
= FALSE
;
1049 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1050 WCHAR pathLength
[MAX_STRING_RESOURCE_LEN
];
1051 LPCWSTR sep
, subjectType
;
1054 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1057 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1062 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1067 LoadStringW(hInstance
, IDS_SUBJECT_TYPE
, subjectTypeHeader
,
1068 sizeof(subjectTypeHeader
) / sizeof(subjectTypeHeader
[0]));
1069 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_CA
, subjectTypeCA
,
1070 sizeof(subjectTypeCA
) / sizeof(subjectTypeCA
[0]));
1071 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_END_CERT
,
1073 sizeof(subjectTypeEndCert
) / sizeof(subjectTypeEndCert
[0]));
1074 LoadStringW(hInstance
, IDS_PATH_LENGTH
, pathLengthHeader
,
1075 sizeof(pathLengthHeader
) / sizeof(pathLengthHeader
[0]));
1076 stringsLoaded
= TRUE
;
1078 bytesNeeded
+= strlenW(subjectTypeHeader
) * sizeof(WCHAR
);
1080 subjectType
= subjectTypeCA
;
1082 subjectType
= subjectTypeEndCert
;
1083 bytesNeeded
+= strlenW(subjectType
) * sizeof(WCHAR
);
1084 bytesNeeded
+= sepLen
;
1085 bytesNeeded
+= strlenW(pathLengthHeader
) * sizeof(WCHAR
);
1086 if (info
->fPathLenConstraint
)
1087 sprintfW(pathLength
, pathFmt
, info
->dwPathLenConstraint
);
1089 LoadStringW(hInstance
, IDS_PATH_LENGTH_NONE
, pathLength
,
1090 sizeof(pathLength
) / sizeof(pathLength
[0]));
1091 bytesNeeded
+= strlenW(pathLength
) * sizeof(WCHAR
);
1093 *pcbFormat
= bytesNeeded
;
1094 else if (*pcbFormat
< bytesNeeded
)
1096 *pcbFormat
= bytesNeeded
;
1097 SetLastError(ERROR_MORE_DATA
);
1102 LPWSTR str
= pbFormat
;
1104 *pcbFormat
= bytesNeeded
;
1105 strcpyW(str
, subjectTypeHeader
);
1106 str
+= strlenW(subjectTypeHeader
);
1107 strcpyW(str
, subjectType
);
1108 str
+= strlenW(subjectType
);
1110 str
+= sepLen
/ sizeof(WCHAR
);
1111 strcpyW(str
, pathLengthHeader
);
1112 str
+= strlenW(pathLengthHeader
);
1113 strcpyW(str
, pathLength
);
1114 str
+= strlenW(pathLength
);
1121 static BOOL
CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB
*blob
, int id
,
1122 LPWSTR str
, DWORD
*pcbStr
)
1124 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1128 LoadStringW(hInstance
, id
, buf
, sizeof(buf
) / sizeof(buf
[0]));
1129 CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1130 blob
->pbData
, blob
->cbData
, NULL
, &bytesNeeded
);
1131 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1134 *pcbStr
= bytesNeeded
;
1137 else if (*pcbStr
< bytesNeeded
)
1139 *pcbStr
= bytesNeeded
;
1140 SetLastError(ERROR_MORE_DATA
);
1145 *pcbStr
= bytesNeeded
;
1147 str
+= strlenW(str
);
1148 bytesNeeded
-= strlenW(str
) * sizeof(WCHAR
);
1149 ret
= CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1150 blob
->pbData
, blob
->cbData
, str
, &bytesNeeded
);
1155 static BOOL
CRYPT_FormatKeyId(const CRYPT_DATA_BLOB
*keyId
, LPWSTR str
,
1158 return CRYPT_FormatHexStringWithPrefix(keyId
, IDS_KEY_ID
, str
, pcbStr
);
1161 static BOOL
CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB
*serialNum
, LPWSTR str
,
1164 return CRYPT_FormatHexStringWithPrefix(serialNum
, IDS_CERT_SERIAL_NUMBER
,
1168 static const WCHAR indent
[] = { ' ',' ',' ',' ',' ',0 };
1169 static const WCHAR colonCrlf
[] = { ':','\r','\n',0 };
1171 static BOOL
CRYPT_FormatAltNameEntry(DWORD dwFormatStrType
, DWORD indentLevel
,
1172 const CERT_ALT_NAME_ENTRY
*entry
, LPWSTR str
, DWORD
*pcbStr
)
1175 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1176 WCHAR mask
[MAX_STRING_RESOURCE_LEN
];
1177 WCHAR ipAddrBuf
[32];
1179 DWORD bytesNeeded
= sizeof(WCHAR
);
1180 DWORD strType
= CERT_X500_NAME_STR
| CERT_NAME_STR_REVERSE_FLAG
;
1182 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1183 bytesNeeded
+= indentLevel
* strlenW(indent
) * sizeof(WCHAR
);
1184 switch (entry
->dwAltNameChoice
)
1186 case CERT_ALT_NAME_RFC822_NAME
:
1187 LoadStringW(hInstance
, IDS_ALT_NAME_RFC822_NAME
, buf
,
1188 sizeof(buf
) / sizeof(buf
[0]));
1189 bytesNeeded
+= strlenW(entry
->u
.pwszRfc822Name
) * sizeof(WCHAR
);
1192 case CERT_ALT_NAME_DNS_NAME
:
1193 LoadStringW(hInstance
, IDS_ALT_NAME_DNS_NAME
, buf
,
1194 sizeof(buf
) / sizeof(buf
[0]));
1195 bytesNeeded
+= strlenW(entry
->u
.pwszDNSName
) * sizeof(WCHAR
);
1198 case CERT_ALT_NAME_DIRECTORY_NAME
:
1200 DWORD directoryNameLen
;
1202 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1203 strType
|= CERT_NAME_STR_CRLF_FLAG
;
1204 directoryNameLen
= cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1205 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, NULL
, 0);
1206 LoadStringW(hInstance
, IDS_ALT_NAME_DIRECTORY_NAME
, buf
,
1207 sizeof(buf
) / sizeof(buf
[0]));
1208 bytesNeeded
+= (directoryNameLen
- 1) * sizeof(WCHAR
);
1209 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1210 bytesNeeded
+= strlenW(colonCrlf
) * sizeof(WCHAR
);
1212 bytesNeeded
+= sizeof(WCHAR
); /* '=' */
1216 case CERT_ALT_NAME_URL
:
1217 LoadStringW(hInstance
, IDS_ALT_NAME_URL
, buf
,
1218 sizeof(buf
) / sizeof(buf
[0]));
1219 bytesNeeded
+= strlenW(entry
->u
.pwszURL
) * sizeof(WCHAR
);
1222 case CERT_ALT_NAME_IP_ADDRESS
:
1224 static const WCHAR ipAddrWithMaskFmt
[] = { '%','d','.','%','d','.',
1225 '%','d','.','%','d','/','%','d','.','%','d','.','%','d','.','%','d',0
1227 static const WCHAR ipAddrFmt
[] = { '%','d','.','%','d','.','%','d',
1230 LoadStringW(hInstance
, IDS_ALT_NAME_IP_ADDRESS
, buf
,
1231 sizeof(buf
) / sizeof(buf
[0]));
1232 if (entry
->u
.IPAddress
.cbData
== 8)
1234 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1236 LoadStringW(hInstance
, IDS_ALT_NAME_MASK
, mask
,
1237 sizeof(mask
) / sizeof(mask
[0]));
1238 bytesNeeded
+= strlenW(mask
) * sizeof(WCHAR
);
1239 sprintfW(ipAddrBuf
, ipAddrFmt
,
1240 entry
->u
.IPAddress
.pbData
[0],
1241 entry
->u
.IPAddress
.pbData
[1],
1242 entry
->u
.IPAddress
.pbData
[2],
1243 entry
->u
.IPAddress
.pbData
[3]);
1244 bytesNeeded
+= strlenW(ipAddrBuf
) * sizeof(WCHAR
);
1245 /* indent again, for the mask line */
1246 bytesNeeded
+= indentLevel
* strlenW(indent
) * sizeof(WCHAR
);
1247 sprintfW(maskBuf
, ipAddrFmt
,
1248 entry
->u
.IPAddress
.pbData
[4],
1249 entry
->u
.IPAddress
.pbData
[5],
1250 entry
->u
.IPAddress
.pbData
[6],
1251 entry
->u
.IPAddress
.pbData
[7]);
1252 bytesNeeded
+= strlenW(maskBuf
) * sizeof(WCHAR
);
1253 bytesNeeded
+= strlenW(crlf
) * sizeof(WCHAR
);
1257 sprintfW(ipAddrBuf
, ipAddrWithMaskFmt
,
1258 entry
->u
.IPAddress
.pbData
[0],
1259 entry
->u
.IPAddress
.pbData
[1],
1260 entry
->u
.IPAddress
.pbData
[2],
1261 entry
->u
.IPAddress
.pbData
[3],
1262 entry
->u
.IPAddress
.pbData
[4],
1263 entry
->u
.IPAddress
.pbData
[5],
1264 entry
->u
.IPAddress
.pbData
[6],
1265 entry
->u
.IPAddress
.pbData
[7]);
1266 bytesNeeded
+= (strlenW(ipAddrBuf
) + 1) * sizeof(WCHAR
);
1272 FIXME("unknown IP address format (%d bytes)\n",
1273 entry
->u
.IPAddress
.cbData
);
1279 FIXME("unimplemented for %d\n", entry
->dwAltNameChoice
);
1284 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1286 *pcbStr
= bytesNeeded
;
1287 else if (*pcbStr
< bytesNeeded
)
1289 *pcbStr
= bytesNeeded
;
1290 SetLastError(ERROR_MORE_DATA
);
1297 *pcbStr
= bytesNeeded
;
1298 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1300 for (i
= 0; i
< indentLevel
; i
++)
1302 strcpyW(str
, indent
);
1303 str
+= strlenW(indent
);
1307 str
+= strlenW(str
);
1308 switch (entry
->dwAltNameChoice
)
1310 case CERT_ALT_NAME_RFC822_NAME
:
1311 case CERT_ALT_NAME_DNS_NAME
:
1312 case CERT_ALT_NAME_URL
:
1313 strcpyW(str
, entry
->u
.pwszURL
);
1315 case CERT_ALT_NAME_DIRECTORY_NAME
:
1316 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1318 strcpyW(str
, colonCrlf
);
1319 str
+= strlenW(colonCrlf
);
1323 cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1324 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, str
,
1325 bytesNeeded
/ sizeof(WCHAR
));
1327 case CERT_ALT_NAME_IP_ADDRESS
:
1328 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1330 strcpyW(str
, ipAddrBuf
);
1331 str
+= strlenW(ipAddrBuf
);
1333 str
+= strlenW(crlf
);
1334 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1336 for (i
= 0; i
< indentLevel
; i
++)
1338 strcpyW(str
, indent
);
1339 str
+= strlenW(indent
);
1343 str
+= strlenW(mask
);
1344 strcpyW(str
, maskBuf
);
1347 strcpyW(str
, ipAddrBuf
);
1355 static BOOL
CRYPT_FormatAltNameInfo(DWORD dwFormatStrType
, DWORD indentLevel
,
1356 const CERT_ALT_NAME_INFO
*name
, LPWSTR str
, DWORD
*pcbStr
)
1358 DWORD i
, size
, bytesNeeded
= 0;
1363 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1366 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1371 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1374 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1376 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1377 &name
->rgAltEntry
[i
], NULL
, &size
);
1380 bytesNeeded
+= size
- sizeof(WCHAR
);
1381 if (i
< name
->cAltEntry
- 1)
1382 bytesNeeded
+= sepLen
;
1387 bytesNeeded
+= sizeof(WCHAR
);
1389 *pcbStr
= bytesNeeded
;
1390 else if (*pcbStr
< bytesNeeded
)
1392 *pcbStr
= bytesNeeded
;
1393 SetLastError(ERROR_MORE_DATA
);
1398 *pcbStr
= bytesNeeded
;
1399 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1401 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1402 &name
->rgAltEntry
[i
], str
, &size
);
1405 str
+= size
/ sizeof(WCHAR
) - 1;
1406 if (i
< name
->cAltEntry
- 1)
1409 str
+= sepLen
/ sizeof(WCHAR
);
1418 static const WCHAR colonSep
[] = { ':',' ',0 };
1420 static BOOL WINAPI
CRYPT_FormatAltName(DWORD dwCertEncodingType
,
1421 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1422 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1426 CERT_ALT_NAME_INFO
*info
;
1429 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ALTERNATE_NAME
,
1430 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1432 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 0, info
, pbFormat
, pcbFormat
);
1438 static BOOL
CRYPT_FormatCertIssuer(DWORD dwFormatStrType
,
1439 const CERT_ALT_NAME_INFO
*issuer
, LPWSTR str
, DWORD
*pcbStr
)
1441 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1442 DWORD bytesNeeded
, sepLen
;
1446 LoadStringW(hInstance
, IDS_CERT_ISSUER
, buf
, sizeof(buf
) / sizeof(buf
[0]));
1447 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, NULL
,
1449 bytesNeeded
+= strlenW(buf
) * sizeof(WCHAR
);
1450 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1453 sepLen
= strlenW(colonCrlf
) * sizeof(WCHAR
);
1458 sepLen
= strlenW(colonSep
) * sizeof(WCHAR
);
1460 bytesNeeded
+= sepLen
;
1464 *pcbStr
= bytesNeeded
;
1465 else if (*pcbStr
< bytesNeeded
)
1467 *pcbStr
= bytesNeeded
;
1468 SetLastError(ERROR_MORE_DATA
);
1473 *pcbStr
= bytesNeeded
;
1475 bytesNeeded
-= strlenW(str
) * sizeof(WCHAR
);
1476 str
+= strlenW(str
);
1478 str
+= sepLen
/ sizeof(WCHAR
);
1479 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, str
,
1486 static BOOL WINAPI
CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType
,
1487 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1488 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1491 CERT_AUTHORITY_KEY_ID2_INFO
*info
;
1497 SetLastError(E_INVALIDARG
);
1500 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_AUTHORITY_KEY_ID2
,
1501 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1503 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1506 BOOL needSeparator
= FALSE
;
1508 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1511 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
1516 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
1519 if (info
->KeyId
.cbData
)
1521 needSeparator
= TRUE
;
1522 ret
= CRYPT_FormatKeyId(&info
->KeyId
, NULL
, &size
);
1525 /* don't include NULL-terminator more than once */
1526 bytesNeeded
+= size
- sizeof(WCHAR
);
1529 if (info
->AuthorityCertIssuer
.cAltEntry
)
1532 bytesNeeded
+= sepLen
;
1533 needSeparator
= TRUE
;
1534 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1535 &info
->AuthorityCertIssuer
, NULL
, &size
);
1538 /* don't include NULL-terminator more than once */
1539 bytesNeeded
+= size
- sizeof(WCHAR
);
1542 if (info
->AuthorityCertSerialNumber
.cbData
)
1545 bytesNeeded
+= sepLen
;
1546 ret
= CRYPT_FormatCertSerialNumber(
1547 &info
->AuthorityCertSerialNumber
, NULL
, &size
);
1550 /* don't include NULL-terminator more than once */
1551 bytesNeeded
+= size
- sizeof(WCHAR
);
1557 *pcbFormat
= bytesNeeded
;
1558 else if (*pcbFormat
< bytesNeeded
)
1560 *pcbFormat
= bytesNeeded
;
1561 SetLastError(ERROR_MORE_DATA
);
1566 LPWSTR str
= pbFormat
;
1568 *pcbFormat
= bytesNeeded
;
1569 needSeparator
= FALSE
;
1570 if (info
->KeyId
.cbData
)
1572 needSeparator
= TRUE
;
1573 /* Overestimate size available, it's already been checked
1577 ret
= CRYPT_FormatKeyId(&info
->KeyId
, str
, &size
);
1579 str
+= size
/ sizeof(WCHAR
) - 1;
1581 if (info
->AuthorityCertIssuer
.cAltEntry
)
1586 str
+= sepLen
/ sizeof(WCHAR
);
1588 needSeparator
= TRUE
;
1589 /* Overestimate size available, it's already been checked
1593 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1594 &info
->AuthorityCertIssuer
, str
, &size
);
1596 str
+= size
/ sizeof(WCHAR
) - 1;
1598 if (info
->AuthorityCertSerialNumber
.cbData
)
1603 str
+= sepLen
/ sizeof(WCHAR
);
1605 /* Overestimate size available, it's already been checked
1609 ret
= CRYPT_FormatCertSerialNumber(
1610 &info
->AuthorityCertSerialNumber
, str
, &size
);
1619 static WCHAR aia
[MAX_STRING_RESOURCE_LEN
];
1620 static WCHAR accessMethod
[MAX_STRING_RESOURCE_LEN
];
1621 static WCHAR ocsp
[MAX_STRING_RESOURCE_LEN
];
1622 static WCHAR caIssuers
[MAX_STRING_RESOURCE_LEN
];
1623 static WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
1624 static WCHAR accessLocation
[MAX_STRING_RESOURCE_LEN
];
1626 static BOOL WINAPI
CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType
,
1627 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1628 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1631 CERT_AUTHORITY_INFO_ACCESS
*info
;
1637 SetLastError(E_INVALIDARG
);
1640 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
1641 X509_AUTHORITY_INFO_ACCESS
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
,
1642 NULL
, &info
, &size
)))
1644 DWORD bytesNeeded
= sizeof(WCHAR
);
1646 if (!info
->cAccDescr
)
1648 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
1650 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
,
1651 sizeof(infoNotAvailable
) / sizeof(infoNotAvailable
[0]));
1652 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
1654 *pcbFormat
= bytesNeeded
;
1655 else if (*pcbFormat
< bytesNeeded
)
1657 *pcbFormat
= bytesNeeded
;
1658 SetLastError(ERROR_MORE_DATA
);
1663 *pcbFormat
= bytesNeeded
;
1664 strcpyW(pbFormat
, infoNotAvailable
);
1669 static const WCHAR numFmt
[] = { '%','d',0 };
1670 static const WCHAR equal
[] = { '=',0 };
1671 static BOOL stringsLoaded
= FALSE
;
1673 LPCWSTR headingSep
, accessMethodSep
, locationSep
;
1674 WCHAR accessDescrNum
[11];
1678 LoadStringW(hInstance
, IDS_AIA
, aia
,
1679 sizeof(aia
) / sizeof(aia
[0]));
1680 LoadStringW(hInstance
, IDS_ACCESS_METHOD
, accessMethod
,
1681 sizeof(accessMethod
) / sizeof(accessMethod
[0]));
1682 LoadStringW(hInstance
, IDS_ACCESS_METHOD_OCSP
, ocsp
,
1683 sizeof(ocsp
) / sizeof(ocsp
[0]));
1684 LoadStringW(hInstance
, IDS_ACCESS_METHOD_CA_ISSUERS
, caIssuers
,
1685 sizeof(caIssuers
) / sizeof(caIssuers
[0]));
1686 LoadStringW(hInstance
, IDS_ACCESS_METHOD_UNKNOWN
, unknown
,
1687 sizeof(unknown
) / sizeof(unknown
[0]));
1688 LoadStringW(hInstance
, IDS_ACCESS_LOCATION
, accessLocation
,
1689 sizeof(accessLocation
) / sizeof(accessLocation
[0]));
1690 stringsLoaded
= TRUE
;
1692 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1695 accessMethodSep
= crlf
;
1696 locationSep
= colonCrlf
;
1700 headingSep
= colonSep
;
1701 accessMethodSep
= commaSpace
;
1702 locationSep
= equal
;
1705 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1708 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
1709 sprintfW(accessDescrNum
, numFmt
, i
+ 1);
1710 bytesNeeded
+= strlenW(accessDescrNum
) * sizeof(WCHAR
);
1711 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
1712 bytesNeeded
+= strlenW(aia
) * sizeof(WCHAR
);
1713 bytesNeeded
+= strlenW(headingSep
) * sizeof(WCHAR
);
1715 bytesNeeded
+= strlenW(accessMethod
) * sizeof(WCHAR
);
1716 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1717 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
1718 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1720 bytesNeeded
+= strlenW(ocsp
) * sizeof(WCHAR
);
1721 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1722 szOID_PKIX_CA_ISSUERS
))
1723 bytesNeeded
+= strlenW(caIssuers
) * sizeof(caIssuers
);
1725 bytesNeeded
+= strlenW(unknown
) * sizeof(WCHAR
);
1726 bytesNeeded
+= sizeof(WCHAR
); /* space */
1727 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
1728 bytesNeeded
+= strlen(info
->rgAccDescr
[i
].pszAccessMethod
)
1730 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
1731 /* Delimiter between access method and location */
1732 bytesNeeded
+= strlenW(accessMethodSep
) * sizeof(WCHAR
);
1733 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1734 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
1735 bytesNeeded
+= strlenW(accessLocation
) * sizeof(WCHAR
);
1736 bytesNeeded
+= strlenW(locationSep
) * sizeof(WCHAR
);
1737 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1738 &info
->rgAccDescr
[i
].AccessLocation
, NULL
, &size
);
1740 bytesNeeded
+= size
- sizeof(WCHAR
);
1741 /* Need extra delimiter between access method entries */
1742 if (i
< info
->cAccDescr
- 1)
1743 bytesNeeded
+= strlenW(accessMethodSep
) * sizeof(WCHAR
);
1748 *pcbFormat
= bytesNeeded
;
1749 else if (*pcbFormat
< bytesNeeded
)
1751 *pcbFormat
= bytesNeeded
;
1752 SetLastError(ERROR_MORE_DATA
);
1757 LPWSTR str
= pbFormat
;
1758 DWORD altNameEntrySize
;
1760 *pcbFormat
= bytesNeeded
;
1761 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1766 sprintfW(accessDescrNum
, numFmt
, i
+ 1);
1767 strcpyW(str
, accessDescrNum
);
1768 str
+= strlenW(accessDescrNum
);
1771 str
+= strlenW(aia
);
1772 strcpyW(str
, headingSep
);
1773 str
+= strlenW(headingSep
);
1774 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1776 strcpyW(str
, indent
);
1777 str
+= strlenW(indent
);
1779 strcpyW(str
, accessMethod
);
1780 str
+= strlenW(accessMethod
);
1781 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1785 str
+= strlenW(ocsp
);
1787 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1788 szOID_PKIX_CA_ISSUERS
))
1790 strcpyW(str
, caIssuers
);
1791 str
+= strlenW(caIssuers
);
1795 strcpyW(str
, unknown
);
1796 str
+= strlenW(unknown
);
1800 for (oidPtr
= info
->rgAccDescr
[i
].pszAccessMethod
;
1801 *oidPtr
; oidPtr
++, str
++)
1804 strcpyW(str
, accessMethodSep
);
1805 str
+= strlenW(accessMethodSep
);
1806 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1808 strcpyW(str
, indent
);
1809 str
+= strlenW(indent
);
1811 strcpyW(str
, accessLocation
);
1812 str
+= strlenW(accessLocation
);
1813 strcpyW(str
, locationSep
);
1814 str
+= strlenW(locationSep
);
1815 /* This overestimates the size available, but that
1816 * won't matter since we checked earlier whether enough
1817 * space for the entire string was available.
1819 altNameEntrySize
= bytesNeeded
;
1820 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1821 &info
->rgAccDescr
[i
].AccessLocation
, str
,
1824 str
+= altNameEntrySize
/ sizeof(WCHAR
) - 1;
1825 if (i
< info
->cAccDescr
- 1)
1827 strcpyW(str
, accessMethodSep
);
1828 str
+= strlenW(accessMethodSep
);
1839 static WCHAR keyCompromise
[MAX_STRING_RESOURCE_LEN
];
1840 static WCHAR caCompromise
[MAX_STRING_RESOURCE_LEN
];
1841 static WCHAR affiliationChanged
[MAX_STRING_RESOURCE_LEN
];
1842 static WCHAR superseded
[MAX_STRING_RESOURCE_LEN
];
1843 static WCHAR operationCeased
[MAX_STRING_RESOURCE_LEN
];
1844 static WCHAR certificateHold
[MAX_STRING_RESOURCE_LEN
];
1846 struct reason_map_entry
1852 static struct reason_map_entry reason_map
[] = {
1853 { CRL_REASON_KEY_COMPROMISE_FLAG
, keyCompromise
, IDS_REASON_KEY_COMPROMISE
},
1854 { CRL_REASON_CA_COMPROMISE_FLAG
, caCompromise
, IDS_REASON_CA_COMPROMISE
},
1855 { CRL_REASON_AFFILIATION_CHANGED_FLAG
, affiliationChanged
,
1856 IDS_REASON_AFFILIATION_CHANGED
},
1857 { CRL_REASON_SUPERSEDED_FLAG
, superseded
, IDS_REASON_SUPERSEDED
},
1858 { CRL_REASON_CESSATION_OF_OPERATION_FLAG
, operationCeased
,
1859 IDS_REASON_CESSATION_OF_OPERATION
},
1860 { CRL_REASON_CERTIFICATE_HOLD_FLAG
, certificateHold
,
1861 IDS_REASON_CERTIFICATE_HOLD
},
1864 static BOOL
CRYPT_FormatReason(DWORD dwFormatStrType
,
1865 const CRYPT_BIT_BLOB
*reasonFlags
, LPWSTR str
, DWORD
*pcbStr
)
1867 static const WCHAR sep
[] = { ',',' ',0 };
1868 static const WCHAR bitsFmt
[] = { ' ','(','%','0','2','x',')',0 };
1869 static BOOL stringsLoaded
= FALSE
;
1870 int i
, numReasons
= 0;
1872 DWORD bytesNeeded
= sizeof(WCHAR
);
1877 for (i
= 0; i
< sizeof(reason_map
) / sizeof(reason_map
[0]); i
++)
1878 LoadStringW(hInstance
, reason_map
[i
].id
, reason_map
[i
].reason
,
1879 MAX_STRING_RESOURCE_LEN
);
1880 stringsLoaded
= TRUE
;
1882 /* No need to check reasonFlags->cbData, we already know it's positive.
1883 * Ignore any other bytes, as they're for undefined bits.
1885 for (i
= 0; i
< sizeof(reason_map
) / sizeof(reason_map
[0]); i
++)
1887 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1889 bytesNeeded
+= strlenW(reason_map
[i
].reason
) * sizeof(WCHAR
);
1891 bytesNeeded
+= strlenW(sep
) * sizeof(WCHAR
);
1894 sprintfW(bits
, bitsFmt
, reasonFlags
->pbData
[0]);
1895 bytesNeeded
+= strlenW(bits
);
1897 *pcbStr
= bytesNeeded
;
1898 else if (*pcbStr
< bytesNeeded
)
1900 *pcbStr
= bytesNeeded
;
1901 SetLastError(ERROR_MORE_DATA
);
1906 *pcbStr
= bytesNeeded
;
1907 for (i
= 0; i
< sizeof(reason_map
) / sizeof(reason_map
[0]); i
++)
1909 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1911 strcpyW(str
, reason_map
[i
].reason
);
1912 str
+= strlenW(reason_map
[i
].reason
);
1913 if (i
< sizeof(reason_map
) / sizeof(reason_map
[0]) - 1 &&
1917 str
+= strlenW(sep
);
1926 static WCHAR crlDistPoint
[MAX_STRING_RESOURCE_LEN
];
1927 static WCHAR distPointName
[MAX_STRING_RESOURCE_LEN
];
1928 static WCHAR fullName
[MAX_STRING_RESOURCE_LEN
];
1929 static WCHAR rdnName
[MAX_STRING_RESOURCE_LEN
];
1930 static WCHAR reason
[MAX_STRING_RESOURCE_LEN
];
1931 static WCHAR issuer
[MAX_STRING_RESOURCE_LEN
];
1933 static BOOL WINAPI
CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType
,
1934 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1935 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1938 CRL_DIST_POINTS_INFO
*info
;
1944 SetLastError(E_INVALIDARG
);
1947 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_CRL_DIST_POINTS
,
1948 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1950 static const WCHAR numFmt
[] = { '%','d',0 };
1951 static const WCHAR colon
[] = { ':',0 };
1952 static BOOL stringsLoaded
= FALSE
;
1953 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for NULL terminator */
1954 BOOL haveAnEntry
= FALSE
;
1955 LPCWSTR headingSep
, nameSep
;
1956 WCHAR distPointNum
[11];
1961 LoadStringW(hInstance
, IDS_CRL_DIST_POINT
, crlDistPoint
,
1962 sizeof(crlDistPoint
) / sizeof(crlDistPoint
[0]));
1963 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_NAME
, distPointName
,
1964 sizeof(distPointName
) / sizeof(distPointName
[0]));
1965 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_FULL_NAME
, fullName
,
1966 sizeof(fullName
) / sizeof(fullName
[0]));
1967 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_RDN_NAME
, rdnName
,
1968 sizeof(rdnName
) / sizeof(rdnName
[0]));
1969 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_REASON
, reason
,
1970 sizeof(reason
) / sizeof(reason
[0]));
1971 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_ISSUER
, issuer
,
1972 sizeof(issuer
) / sizeof(issuer
[0]));
1973 stringsLoaded
= TRUE
;
1975 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1978 nameSep
= colonCrlf
;
1982 headingSep
= colonSep
;
1986 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
1988 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
1990 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
1991 CRL_DIST_POINT_NO_NAME
)
1993 bytesNeeded
+= strlenW(distPointName
) * sizeof(WCHAR
);
1994 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
1995 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
1996 CRL_DIST_POINT_FULL_NAME
)
1997 bytesNeeded
+= strlenW(fullName
) * sizeof(WCHAR
);
1999 bytesNeeded
+= strlenW(rdnName
) * sizeof(WCHAR
);
2000 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
2001 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2002 bytesNeeded
+= 2 * strlenW(indent
) * sizeof(WCHAR
);
2003 /* The indent level (3) is higher than when used as the issuer,
2004 * because the name is subordinate to the name type (full vs.
2007 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2008 &distPoint
->DistPointName
.u
.FullName
, NULL
, &size
);
2010 bytesNeeded
+= size
- sizeof(WCHAR
);
2013 else if (distPoint
->ReasonFlags
.cbData
)
2015 bytesNeeded
+= strlenW(reason
) * sizeof(WCHAR
);
2016 ret
= CRYPT_FormatReason(dwFormatStrType
,
2017 &distPoint
->ReasonFlags
, NULL
, &size
);
2019 bytesNeeded
+= size
- sizeof(WCHAR
);
2022 else if (distPoint
->CRLIssuer
.cAltEntry
)
2024 bytesNeeded
+= strlenW(issuer
) * sizeof(WCHAR
);
2025 bytesNeeded
+= strlenW(nameSep
) * sizeof(WCHAR
);
2026 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2027 &distPoint
->CRLIssuer
, NULL
, &size
);
2029 bytesNeeded
+= size
- sizeof(WCHAR
);
2034 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
2035 sprintfW(distPointNum
, numFmt
, i
+ 1);
2036 bytesNeeded
+= strlenW(distPointNum
) * sizeof(WCHAR
);
2037 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
2038 bytesNeeded
+= strlenW(crlDistPoint
) * sizeof(WCHAR
);
2039 bytesNeeded
+= strlenW(headingSep
) * sizeof(WCHAR
);
2040 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2041 bytesNeeded
+= strlenW(indent
) * sizeof(WCHAR
);
2046 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2048 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
,
2049 sizeof(infoNotAvailable
) / sizeof(infoNotAvailable
[0]));
2050 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
2052 *pcbFormat
= bytesNeeded
;
2053 else if (*pcbFormat
< bytesNeeded
)
2055 *pcbFormat
= bytesNeeded
;
2056 SetLastError(ERROR_MORE_DATA
);
2061 *pcbFormat
= bytesNeeded
;
2062 strcpyW(pbFormat
, infoNotAvailable
);
2068 *pcbFormat
= bytesNeeded
;
2069 else if (*pcbFormat
< bytesNeeded
)
2071 *pcbFormat
= bytesNeeded
;
2072 SetLastError(ERROR_MORE_DATA
);
2077 LPWSTR str
= pbFormat
;
2079 *pcbFormat
= bytesNeeded
;
2080 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2082 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2085 sprintfW(distPointNum
, numFmt
, i
+ 1);
2086 strcpyW(str
, distPointNum
);
2087 str
+= strlenW(distPointNum
);
2089 strcpyW(str
, crlDistPoint
);
2090 str
+= strlenW(crlDistPoint
);
2091 strcpyW(str
, headingSep
);
2092 str
+= strlenW(headingSep
);
2093 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2095 strcpyW(str
, indent
);
2096 str
+= strlenW(indent
);
2098 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2099 CRL_DIST_POINT_NO_NAME
)
2101 DWORD altNameSize
= bytesNeeded
;
2103 strcpyW(str
, distPointName
);
2104 str
+= strlenW(distPointName
);
2105 strcpyW(str
, nameSep
);
2106 str
+= strlenW(nameSep
);
2107 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2109 strcpyW(str
, indent
);
2110 str
+= strlenW(indent
);
2111 strcpyW(str
, indent
);
2112 str
+= strlenW(indent
);
2114 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2115 CRL_DIST_POINT_FULL_NAME
)
2117 strcpyW(str
, fullName
);
2118 str
+= strlenW(fullName
);
2122 strcpyW(str
, rdnName
);
2123 str
+= strlenW(rdnName
);
2125 strcpyW(str
, nameSep
);
2126 str
+= strlenW(nameSep
);
2127 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2128 &distPoint
->DistPointName
.u
.FullName
, str
,
2131 str
+= altNameSize
/ sizeof(WCHAR
) - 1;
2133 else if (distPoint
->ReasonFlags
.cbData
)
2135 DWORD reasonSize
= bytesNeeded
;
2137 strcpyW(str
, reason
);
2138 str
+= strlenW(reason
);
2139 ret
= CRYPT_FormatReason(dwFormatStrType
,
2140 &distPoint
->ReasonFlags
, str
, &reasonSize
);
2142 str
+= reasonSize
/ sizeof(WCHAR
) - 1;
2144 else if (distPoint
->CRLIssuer
.cAltEntry
)
2146 DWORD crlIssuerSize
= bytesNeeded
;
2148 strcpyW(str
, issuer
);
2149 str
+= strlenW(issuer
);
2150 strcpyW(str
, nameSep
);
2151 str
+= strlenW(nameSep
);
2152 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2153 &distPoint
->CRLIssuer
, str
,
2156 str
+= crlIssuerSize
/ sizeof(WCHAR
) - 1;
2166 static BOOL WINAPI
CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType
,
2167 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2168 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2171 CERT_ENHKEY_USAGE
*usage
;
2177 SetLastError(E_INVALIDARG
);
2180 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ENHANCED_KEY_USAGE
,
2181 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &usage
, &size
)))
2183 WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
2185 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
2189 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2192 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
2197 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
2200 LoadStringW(hInstance
, IDS_USAGE_UNKNOWN
, unknown
,
2201 sizeof(unknown
) / sizeof(unknown
[0]));
2202 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2204 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2205 usage
->rgpszUsageIdentifier
[i
], CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2208 bytesNeeded
+= strlenW(info
->pwszName
) * sizeof(WCHAR
);
2210 bytesNeeded
+= strlenW(unknown
) * sizeof(WCHAR
);
2211 bytesNeeded
+= sizeof(WCHAR
); /* space */
2212 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
2213 bytesNeeded
+= strlen(usage
->rgpszUsageIdentifier
[i
]) *
2215 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
2216 if (i
< usage
->cUsageIdentifier
- 1)
2217 bytesNeeded
+= sepLen
;
2220 *pcbFormat
= bytesNeeded
;
2221 else if (*pcbFormat
< bytesNeeded
)
2223 *pcbFormat
= bytesNeeded
;
2224 SetLastError(ERROR_MORE_DATA
);
2229 LPWSTR str
= pbFormat
;
2231 *pcbFormat
= bytesNeeded
;
2232 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2234 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2235 usage
->rgpszUsageIdentifier
[i
],
2236 CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2241 strcpyW(str
, info
->pwszName
);
2242 str
+= strlenW(info
->pwszName
);
2246 strcpyW(str
, unknown
);
2247 str
+= strlenW(unknown
);
2251 for (oidPtr
= usage
->rgpszUsageIdentifier
[i
]; *oidPtr
; oidPtr
++)
2255 if (i
< usage
->cUsageIdentifier
- 1)
2258 str
+= sepLen
/ sizeof(WCHAR
);
2267 static struct BitToString netscapeCertTypeMap
[] = {
2268 { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_CLIENT
, { 0 } },
2269 { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_SERVER
, { 0 } },
2270 { NETSCAPE_SMIME_CERT_TYPE
, IDS_NETSCAPE_SMIME
, { 0 } },
2271 { NETSCAPE_SIGN_CERT_TYPE
, IDS_NETSCAPE_SIGN
, { 0 } },
2272 { NETSCAPE_SSL_CA_CERT_TYPE
, IDS_NETSCAPE_SSL_CA
, { 0 } },
2273 { NETSCAPE_SMIME_CA_CERT_TYPE
, IDS_NETSCAPE_SMIME_CA
, { 0 } },
2274 { NETSCAPE_SIGN_CA_CERT_TYPE
, IDS_NETSCAPE_SIGN_CA
, { 0 } },
2277 static BOOL WINAPI
CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType
,
2278 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2279 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2283 CRYPT_BIT_BLOB
*bits
;
2288 SetLastError(E_INVALIDARG
);
2291 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BITS
,
2292 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
2294 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2295 DWORD bytesNeeded
= sizeof(WCHAR
);
2297 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
,
2298 sizeof(infoNotAvailable
) / sizeof(infoNotAvailable
[0]));
2299 if (!bits
->cbData
|| bits
->cbData
> 1)
2301 bytesNeeded
+= strlenW(infoNotAvailable
) * sizeof(WCHAR
);
2303 *pcbFormat
= bytesNeeded
;
2304 else if (*pcbFormat
< bytesNeeded
)
2306 *pcbFormat
= bytesNeeded
;
2307 SetLastError(ERROR_MORE_DATA
);
2312 LPWSTR str
= pbFormat
;
2314 *pcbFormat
= bytesNeeded
;
2315 strcpyW(str
, infoNotAvailable
);
2320 static BOOL stringsLoaded
= FALSE
;
2327 for (i
= 0; i
< sizeof(netscapeCertTypeMap
) /
2328 sizeof(netscapeCertTypeMap
[0]); i
++)
2329 LoadStringW(hInstance
, netscapeCertTypeMap
[i
].id
,
2330 netscapeCertTypeMap
[i
].str
, MAX_STRING_RESOURCE_LEN
);
2331 stringsLoaded
= TRUE
;
2333 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
,
2334 sizeof(netscapeCertTypeMap
) / sizeof(netscapeCertTypeMap
[0]),
2335 NULL
, &bitStringLen
, &first
);
2336 bytesNeeded
+= bitStringLen
;
2337 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
2338 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2339 bits
->cbData
, NULL
, &size
);
2340 bytesNeeded
+= size
;
2342 *pcbFormat
= bytesNeeded
;
2343 else if (*pcbFormat
< bytesNeeded
)
2345 *pcbFormat
= bytesNeeded
;
2346 SetLastError(ERROR_MORE_DATA
);
2351 LPWSTR str
= pbFormat
;
2353 bitStringLen
= bytesNeeded
;
2355 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
,
2356 sizeof(netscapeCertTypeMap
) / sizeof(netscapeCertTypeMap
[0]),
2357 str
, &bitStringLen
, &first
);
2358 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
2361 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2362 bits
->cbData
, str
, &size
);
2363 str
+= size
/ sizeof(WCHAR
) - 1;
2373 static WCHAR financialCriteria
[MAX_STRING_RESOURCE_LEN
];
2374 static WCHAR available
[MAX_STRING_RESOURCE_LEN
];
2375 static WCHAR notAvailable
[MAX_STRING_RESOURCE_LEN
];
2376 static WCHAR meetsCriteria
[MAX_STRING_RESOURCE_LEN
];
2377 static WCHAR yes
[MAX_STRING_RESOURCE_LEN
];
2378 static WCHAR no
[MAX_STRING_RESOURCE_LEN
];
2380 static BOOL WINAPI
CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType
,
2381 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2382 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2385 SPC_FINANCIAL_CRITERIA criteria
;
2386 DWORD size
= sizeof(criteria
);
2391 SetLastError(E_INVALIDARG
);
2394 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
2395 SPC_FINANCIAL_CRITERIA_STRUCT
, pbEncoded
, cbEncoded
, 0, NULL
, &criteria
,
2398 static BOOL stringsLoaded
= FALSE
;
2399 DWORD bytesNeeded
= sizeof(WCHAR
);
2405 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA
, financialCriteria
,
2406 sizeof(financialCriteria
) / sizeof(financialCriteria
[0]));
2407 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_AVAILABLE
, available
,
2408 sizeof(available
) / sizeof(available
[0]));
2409 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE
,
2410 notAvailable
, sizeof(notAvailable
) / sizeof(notAvailable
[0]));
2411 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA
,
2412 meetsCriteria
, sizeof(meetsCriteria
) / sizeof(meetsCriteria
[0]));
2413 LoadStringW(hInstance
, IDS_YES
, yes
, sizeof(yes
) / sizeof(yes
[0]));
2414 LoadStringW(hInstance
, IDS_NO
, no
, sizeof(no
) / sizeof(no
[0]));
2415 stringsLoaded
= TRUE
;
2417 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2420 sepLen
= strlenW(crlf
) * sizeof(WCHAR
);
2425 sepLen
= strlenW(commaSpace
) * sizeof(WCHAR
);
2427 bytesNeeded
+= strlenW(financialCriteria
) * sizeof(WCHAR
);
2428 if (criteria
.fFinancialInfoAvailable
)
2430 bytesNeeded
+= strlenW(available
) * sizeof(WCHAR
);
2431 bytesNeeded
+= sepLen
;
2432 bytesNeeded
+= strlenW(meetsCriteria
) * sizeof(WCHAR
);
2433 if (criteria
.fMeetsCriteria
)
2434 bytesNeeded
+= strlenW(yes
) * sizeof(WCHAR
);
2436 bytesNeeded
+= strlenW(no
) * sizeof(WCHAR
);
2439 bytesNeeded
+= strlenW(notAvailable
) * sizeof(WCHAR
);
2441 *pcbFormat
= bytesNeeded
;
2442 else if (*pcbFormat
< bytesNeeded
)
2444 *pcbFormat
= bytesNeeded
;
2445 SetLastError(ERROR_MORE_DATA
);
2450 LPWSTR str
= pbFormat
;
2452 *pcbFormat
= bytesNeeded
;
2453 strcpyW(str
, financialCriteria
);
2454 str
+= strlenW(financialCriteria
);
2455 if (criteria
.fFinancialInfoAvailable
)
2457 strcpyW(str
, available
);
2458 str
+= strlenW(available
);
2460 str
+= sepLen
/ sizeof(WCHAR
);
2461 strcpyW(str
, meetsCriteria
);
2462 str
+= strlenW(meetsCriteria
);
2463 if (criteria
.fMeetsCriteria
)
2470 strcpyW(str
, notAvailable
);
2471 str
+= strlenW(notAvailable
);
2478 static BOOL WINAPI
CRYPT_FormatUnicodeString(DWORD dwCertEncodingType
,
2479 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2480 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2483 CERT_NAME_VALUE
*value
;
2489 SetLastError(E_INVALIDARG
);
2492 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_UNICODE_ANY_STRING
,
2493 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &value
, &size
)))
2496 *pcbFormat
= value
->Value
.cbData
;
2497 else if (*pcbFormat
< value
->Value
.cbData
)
2499 *pcbFormat
= value
->Value
.cbData
;
2500 SetLastError(ERROR_MORE_DATA
);
2505 LPWSTR str
= pbFormat
;
2507 *pcbFormat
= value
->Value
.cbData
;
2508 strcpyW(str
, (LPWSTR
)value
->Value
.pbData
);
2514 typedef BOOL (WINAPI
*CryptFormatObjectFunc
)(DWORD
, DWORD
, DWORD
, void *,
2515 LPCSTR
, const BYTE
*, DWORD
, void *, DWORD
*);
2517 static CryptFormatObjectFunc
CRYPT_GetBuiltinFormatFunction(DWORD encodingType
,
2518 DWORD formatStrType
, LPCSTR lpszStructType
)
2520 CryptFormatObjectFunc format
= NULL
;
2522 if ((encodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
)
2524 SetLastError(ERROR_FILE_NOT_FOUND
);
2527 if (IS_INTOID(lpszStructType
))
2529 switch (LOWORD(lpszStructType
))
2531 case LOWORD(X509_KEY_USAGE
):
2532 format
= CRYPT_FormatKeyUsage
;
2534 case LOWORD(X509_ALTERNATE_NAME
):
2535 format
= CRYPT_FormatAltName
;
2537 case LOWORD(X509_BASIC_CONSTRAINTS2
):
2538 format
= CRYPT_FormatBasicConstraints2
;
2540 case LOWORD(X509_AUTHORITY_KEY_ID2
):
2541 format
= CRYPT_FormatAuthorityKeyId2
;
2543 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
2544 format
= CRYPT_FormatAuthorityInfoAccess
;
2546 case LOWORD(X509_CRL_DIST_POINTS
):
2547 format
= CRYPT_FormatCRLDistPoints
;
2549 case LOWORD(X509_ENHANCED_KEY_USAGE
):
2550 format
= CRYPT_FormatEnhancedKeyUsage
;
2552 case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT
):
2553 format
= CRYPT_FormatSpcFinancialCriteria
;
2557 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
2558 format
= CRYPT_FormatAltName
;
2559 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
2560 format
= CRYPT_FormatAltName
;
2561 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
2562 format
= CRYPT_FormatKeyUsage
;
2563 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
2564 format
= CRYPT_FormatAltName
;
2565 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
2566 format
= CRYPT_FormatAltName
;
2567 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
2568 format
= CRYPT_FormatBasicConstraints2
;
2569 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
2570 format
= CRYPT_FormatAuthorityInfoAccess
;
2571 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
2572 format
= CRYPT_FormatAuthorityKeyId2
;
2573 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
2574 format
= CRYPT_FormatCRLDistPoints
;
2575 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
2576 format
= CRYPT_FormatEnhancedKeyUsage
;
2577 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_CERT_TYPE
))
2578 format
= CRYPT_FormatNetscapeCertType
;
2579 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_BASE_URL
) ||
2580 !strcmp(lpszStructType
, szOID_NETSCAPE_REVOCATION_URL
) ||
2581 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_REVOCATION_URL
) ||
2582 !strcmp(lpszStructType
, szOID_NETSCAPE_CERT_RENEWAL_URL
) ||
2583 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_POLICY_URL
) ||
2584 !strcmp(lpszStructType
, szOID_NETSCAPE_SSL_SERVER_NAME
) ||
2585 !strcmp(lpszStructType
, szOID_NETSCAPE_COMMENT
))
2586 format
= CRYPT_FormatUnicodeString
;
2587 else if (!strcmp(lpszStructType
, SPC_FINANCIAL_CRITERIA_OBJID
))
2588 format
= CRYPT_FormatSpcFinancialCriteria
;
2592 BOOL WINAPI
CryptFormatObject(DWORD dwCertEncodingType
, DWORD dwFormatType
,
2593 DWORD dwFormatStrType
, void *pFormatStruct
, LPCSTR lpszStructType
,
2594 const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
, DWORD
*pcbFormat
)
2596 CryptFormatObjectFunc format
= NULL
;
2597 HCRYPTOIDFUNCADDR hFunc
= NULL
;
2600 TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType
,
2601 dwFormatType
, dwFormatStrType
, pFormatStruct
, debugstr_a(lpszStructType
),
2602 pbEncoded
, cbEncoded
, pbFormat
, pcbFormat
);
2604 if (!(format
= CRYPT_GetBuiltinFormatFunction(dwCertEncodingType
,
2605 dwFormatStrType
, lpszStructType
)))
2607 static HCRYPTOIDFUNCSET set
= NULL
;
2610 set
= CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC
, 0);
2611 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
2612 (void **)&format
, &hFunc
);
2614 if (!format
&& (dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) ==
2615 X509_ASN_ENCODING
&& !(dwFormatStrType
& CRYPT_FORMAT_STR_NO_HEX
))
2616 format
= CRYPT_FormatHexString
;
2618 ret
= format(dwCertEncodingType
, dwFormatType
, dwFormatStrType
,
2619 pFormatStruct
, lpszStructType
, pbEncoded
, cbEncoded
, pbFormat
,
2622 CryptFreeOIDFunctionAddress(hFunc
, 0);