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/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
34 static BOOL
CRYPT_ReadBlobFromFile(LPCWSTR fileName
, PCERT_BLOB blob
)
39 TRACE("%s\n", debugstr_w(fileName
));
41 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
42 OPEN_EXISTING
, 0, NULL
);
43 if (file
!= INVALID_HANDLE_VALUE
)
46 blob
->cbData
= GetFileSize(file
, NULL
);
49 blob
->pbData
= CryptMemAlloc(blob
->cbData
);
54 ret
= ReadFile(file
, blob
->pbData
, blob
->cbData
, &read
, NULL
) && read
== blob
->cbData
;
55 if (!ret
) CryptMemFree(blob
->pbData
);
62 TRACE("returning %d\n", ret
);
66 static BOOL
CRYPT_QueryContextBlob(const CERT_BLOB
*blob
,
67 DWORD dwExpectedContentTypeFlags
, HCERTSTORE store
,
68 DWORD
*contentType
, const void **ppvContext
)
72 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
)
74 ret
= pCertInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
75 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
76 if (ret
&& contentType
)
77 *contentType
= CERT_QUERY_CONTENT_CERT
;
79 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
))
81 ret
= pCRLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
82 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
83 if (ret
&& contentType
)
84 *contentType
= CERT_QUERY_CONTENT_CRL
;
86 if (!ret
&& (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
88 ret
= pCTLInterface
->addEncodedToStore(store
, X509_ASN_ENCODING
,
89 blob
->pbData
, blob
->cbData
, CERT_STORE_ADD_ALWAYS
, ppvContext
);
90 if (ret
&& contentType
)
91 *contentType
= CERT_QUERY_CONTENT_CTL
;
96 static BOOL
CRYPT_QueryContextObject(DWORD dwObjectType
, const void *pvObject
,
97 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
98 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
99 HCERTSTORE
*phCertStore
, const void **ppvContext
)
102 const CERT_BLOB
*blob
;
105 DWORD formatType
= 0;
107 switch (dwObjectType
)
109 case CERT_QUERY_OBJECT_FILE
:
110 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
111 * just read the file directly
113 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
116 case CERT_QUERY_OBJECT_BLOB
:
121 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
128 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
129 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
130 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
132 ret
= CRYPT_QueryContextBlob(blob
, dwExpectedContentTypeFlags
, store
,
133 pdwContentType
, ppvContext
);
135 formatType
= CERT_QUERY_FORMAT_BINARY
;
138 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
140 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
141 CRYPT_DATA_BLOB decoded
;
143 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
145 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
146 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
149 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
152 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
153 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
154 &decoded
.cbData
, NULL
, NULL
);
157 ret
= CRYPT_QueryContextBlob(&decoded
,
158 dwExpectedContentTypeFlags
, store
, pdwContentType
,
161 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
163 CryptMemFree(decoded
.pbData
);
171 if (pdwMsgAndCertEncodingType
)
172 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
174 *pdwFormatType
= formatType
;
176 *phCertStore
= CertDuplicateStore(store
);
178 CertCloseStore(store
, 0);
179 if (blob
== &fileBlob
)
180 CryptMemFree(blob
->pbData
);
181 TRACE("returning %d\n", ret
);
185 static BOOL
CRYPT_QuerySerializedContextObject(DWORD dwObjectType
,
186 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
187 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
188 HCERTSTORE
*phCertStore
, const void **ppvContext
)
191 const CERT_BLOB
*blob
;
192 const WINE_CONTEXT_INTERFACE
*contextInterface
= NULL
;
197 switch (dwObjectType
)
199 case CERT_QUERY_OBJECT_FILE
:
200 /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
201 * just read the file directly
203 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
206 case CERT_QUERY_OBJECT_BLOB
:
211 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
218 context
= CRYPT_ReadSerializedElement(blob
->pbData
, blob
->cbData
,
219 CERT_STORE_ALL_CONTEXT_FLAG
, &contextType
);
222 DWORD contentType
, certStoreOffset
;
227 case CERT_STORE_CERTIFICATE_CONTEXT
:
228 contextInterface
= pCertInterface
;
229 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CERT
;
230 certStoreOffset
= offsetof(CERT_CONTEXT
, hCertStore
);
231 if (!(dwExpectedContentTypeFlags
&
232 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
))
234 SetLastError(ERROR_INVALID_DATA
);
239 case CERT_STORE_CRL_CONTEXT
:
240 contextInterface
= pCRLInterface
;
241 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CRL
;
242 certStoreOffset
= offsetof(CRL_CONTEXT
, hCertStore
);
243 if (!(dwExpectedContentTypeFlags
&
244 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
))
246 SetLastError(ERROR_INVALID_DATA
);
251 case CERT_STORE_CTL_CONTEXT
:
252 contextInterface
= pCTLInterface
;
253 contentType
= CERT_QUERY_CONTENT_SERIALIZED_CTL
;
254 certStoreOffset
= offsetof(CTL_CONTEXT
, hCertStore
);
255 if (!(dwExpectedContentTypeFlags
&
256 CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
))
258 SetLastError(ERROR_INVALID_DATA
);
264 SetLastError(ERROR_INVALID_DATA
);
268 if (pdwMsgAndCertEncodingType
)
269 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
271 *pdwContentType
= contentType
;
273 *phCertStore
= CertDuplicateStore(
274 *(HCERTSTORE
*)((const BYTE
*)context
+ certStoreOffset
));
277 *ppvContext
= context
;
278 Context_AddRef(context_from_ptr(context
));
283 if (contextInterface
&& context
)
284 Context_Release(context_from_ptr(context
));
285 if (blob
== &fileBlob
)
286 CryptMemFree(blob
->pbData
);
287 TRACE("returning %d\n", ret
);
291 static BOOL
CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName
,
292 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
293 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
298 TRACE("%s\n", debugstr_w(fileName
));
299 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
300 OPEN_EXISTING
, 0, NULL
);
301 if (file
!= INVALID_HANDLE_VALUE
)
303 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
304 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
306 ret
= CRYPT_ReadSerializedStoreFromFile(file
, store
);
309 if (pdwMsgAndCertEncodingType
)
310 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
312 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
314 *phCertStore
= CertDuplicateStore(store
);
316 CertCloseStore(store
, 0);
319 TRACE("returning %d\n", ret
);
323 static BOOL
CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB
*blob
,
324 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
325 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
327 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
328 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
331 TRACE("(%d, %p)\n", blob
->cbData
, blob
->pbData
);
333 ret
= CRYPT_ReadSerializedStoreFromBlob(blob
, store
);
336 if (pdwMsgAndCertEncodingType
)
337 *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
339 *pdwContentType
= CERT_QUERY_CONTENT_SERIALIZED_STORE
;
341 *phCertStore
= CertDuplicateStore(store
);
343 CertCloseStore(store
, 0);
344 TRACE("returning %d\n", ret
);
348 static BOOL
CRYPT_QuerySerializedStoreObject(DWORD dwObjectType
,
349 const void *pvObject
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
350 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
352 switch (dwObjectType
)
354 case CERT_QUERY_OBJECT_FILE
:
355 return CRYPT_QuerySerializedStoreFromFile(pvObject
,
356 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
357 case CERT_QUERY_OBJECT_BLOB
:
358 return CRYPT_QuerySerializedStoreFromBlob(pvObject
,
359 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
361 FIXME("unimplemented for type %d\n", dwObjectType
);
362 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
367 static BOOL
CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB
*blob
,
368 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
370 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
374 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
376 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
379 DWORD type
, len
= sizeof(type
);
381 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
384 if (type
!= CMSG_SIGNED
)
386 SetLastError(ERROR_INVALID_DATA
);
394 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_SIGNED
, 0, NULL
,
398 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
409 if (pdwMsgAndCertEncodingType
)
410 *pdwMsgAndCertEncodingType
= encodingType
;
412 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
419 static BOOL
CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB
*blob
,
420 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, HCRYPTMSG
*phMsg
)
422 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
426 if ((msg
= CryptMsgOpenToDecode(encodingType
, 0, 0, 0, NULL
, NULL
)))
428 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
431 DWORD type
, len
= sizeof(type
);
433 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &len
);
436 if (type
!= CMSG_DATA
)
438 SetLastError(ERROR_INVALID_DATA
);
446 msg
= CryptMsgOpenToDecode(encodingType
, 0, CMSG_DATA
, 0,
450 ret
= CryptMsgUpdate(msg
, blob
->pbData
, blob
->cbData
, TRUE
);
461 if (pdwMsgAndCertEncodingType
)
462 *pdwMsgAndCertEncodingType
= encodingType
;
464 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED
;
471 /* Used to decode non-embedded messages */
472 static BOOL
CRYPT_QueryMessageObject(DWORD dwObjectType
, const void *pvObject
,
473 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
474 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
475 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
478 const CERT_BLOB
*blob
;
480 HCRYPTMSG msg
= NULL
;
481 DWORD encodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
482 DWORD formatType
= 0;
484 TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
485 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
486 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
489 switch (dwObjectType
)
491 case CERT_QUERY_OBJECT_FILE
:
492 /* This isn't an embedded PKCS7 message, so just read the file
495 ret
= CRYPT_ReadBlobFromFile(pvObject
, &fileBlob
);
498 case CERT_QUERY_OBJECT_BLOB
:
503 SetLastError(E_INVALIDARG
); /* FIXME: is this the correct error? */
510 if (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BINARY
)
512 /* Try it first as a signed message */
513 if (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
514 ret
= CRYPT_QuerySignedMessage(blob
, pdwMsgAndCertEncodingType
,
515 pdwContentType
, &msg
);
516 /* Failing that, try as an unsigned message */
518 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
519 ret
= CRYPT_QueryUnsignedMessage(blob
, pdwMsgAndCertEncodingType
,
520 pdwContentType
, &msg
);
522 formatType
= CERT_QUERY_FORMAT_BINARY
;
525 (dwExpectedFormatTypeFlags
& CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED
))
527 CRYPT_DATA_BLOB trimmed
= { blob
->cbData
, blob
->pbData
};
528 CRYPT_DATA_BLOB decoded
;
530 while (trimmed
.cbData
&& !trimmed
.pbData
[trimmed
.cbData
- 1])
532 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
, trimmed
.cbData
,
533 CRYPT_STRING_BASE64_ANY
, NULL
, &decoded
.cbData
, NULL
, NULL
);
536 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
539 ret
= CryptStringToBinaryA((LPSTR
)trimmed
.pbData
,
540 trimmed
.cbData
, CRYPT_STRING_BASE64_ANY
, decoded
.pbData
,
541 &decoded
.cbData
, NULL
, NULL
);
544 /* Try it first as a signed message */
545 if (dwExpectedContentTypeFlags
&
546 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
547 ret
= CRYPT_QuerySignedMessage(&decoded
,
548 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
549 /* Failing that, try as an unsigned message */
550 if (!ret
&& (dwExpectedContentTypeFlags
&
551 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
552 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
553 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
555 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
557 CryptMemFree(decoded
.pbData
);
562 if (!ret
&& !(blob
->cbData
% sizeof(WCHAR
)))
564 CRYPT_DATA_BLOB decoded
;
565 LPWSTR str
= (LPWSTR
)blob
->pbData
;
566 DWORD strLen
= blob
->cbData
/ sizeof(WCHAR
);
568 /* Try again, assuming the input string is UTF-16 base64 */
569 while (strLen
&& !str
[strLen
- 1])
571 ret
= CryptStringToBinaryW(str
, strLen
, CRYPT_STRING_BASE64_ANY
,
572 NULL
, &decoded
.cbData
, NULL
, NULL
);
575 decoded
.pbData
= CryptMemAlloc(decoded
.cbData
);
578 ret
= CryptStringToBinaryW(str
, strLen
,
579 CRYPT_STRING_BASE64_ANY
, decoded
.pbData
, &decoded
.cbData
,
583 /* Try it first as a signed message */
584 if (dwExpectedContentTypeFlags
&
585 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
)
586 ret
= CRYPT_QuerySignedMessage(&decoded
,
587 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
588 /* Failing that, try as an unsigned message */
589 if (!ret
&& (dwExpectedContentTypeFlags
&
590 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
))
591 ret
= CRYPT_QueryUnsignedMessage(&decoded
,
592 pdwMsgAndCertEncodingType
, pdwContentType
, &msg
);
594 formatType
= CERT_QUERY_FORMAT_BASE64_ENCODED
;
596 CryptMemFree(decoded
.pbData
);
606 *pdwFormatType
= formatType
;
608 *phCertStore
= CertOpenStore(CERT_STORE_PROV_MSG
, encodingType
, 0,
615 if (blob
== &fileBlob
)
616 CryptMemFree(blob
->pbData
);
617 TRACE("returning %d\n", ret
);
621 static BOOL
CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType
,
622 const void *pvObject
, DWORD dwExpectedContentTypeFlags
,
623 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
624 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
630 TRACE("%s\n", debugstr_w(pvObject
));
632 if (dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
634 WARN("don't know what to do for type %d embedded signed messages\n",
636 SetLastError(E_INVALIDARG
);
639 file
= CreateFileW(pvObject
, GENERIC_READ
, FILE_SHARE_READ
,
640 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
641 if (file
!= INVALID_HANDLE_VALUE
)
643 ret
= CryptSIPRetrieveSubjectGuid(pvObject
, file
, &subject
);
646 SIP_DISPATCH_INFO sip
;
648 memset(&sip
, 0, sizeof(sip
));
649 sip
.cbSize
= sizeof(sip
);
650 ret
= CryptSIPLoad(&subject
, 0, &sip
);
653 SIP_SUBJECTINFO subjectInfo
;
657 memset(&subjectInfo
, 0, sizeof(subjectInfo
));
658 subjectInfo
.cbSize
= sizeof(subjectInfo
);
659 subjectInfo
.pgSubjectType
= &subject
;
660 subjectInfo
.hFile
= file
;
661 subjectInfo
.pwsFileName
= pvObject
;
662 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0, &blob
.cbData
,
666 blob
.pbData
= CryptMemAlloc(blob
.cbData
);
669 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0,
670 &blob
.cbData
, blob
.pbData
);
673 ret
= CRYPT_QueryMessageObject(
674 CERT_QUERY_OBJECT_BLOB
, &blob
,
675 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
,
676 CERT_QUERY_FORMAT_FLAG_BINARY
,
677 pdwMsgAndCertEncodingType
, NULL
, NULL
,
679 if (ret
&& pdwContentType
)
680 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
;
682 CryptMemFree(blob
.pbData
);
686 SetLastError(ERROR_OUTOFMEMORY
);
694 TRACE("returning %d\n", ret
);
698 static BOOL
CRYPT_QueryPFXObject(DWORD dwObjectType
, const void *pvObject
,
699 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
700 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
701 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
703 CRYPT_DATA_BLOB blob
= {0}, *ptr
;
706 TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
707 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
708 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
711 switch (dwObjectType
)
713 case CERT_QUERY_OBJECT_FILE
:
714 if (!CRYPT_ReadBlobFromFile(pvObject
, &blob
)) return FALSE
;
718 case CERT_QUERY_OBJECT_BLOB
:
719 ptr
= (CRYPT_DATA_BLOB
*)pvObject
;
726 ret
= PFXIsPFXBlob(ptr
);
729 if (pdwMsgAndCertEncodingType
) *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
730 if (pdwContentType
) *pdwContentType
= CERT_QUERY_CONTENT_PFX
;
731 if (pdwFormatType
) *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
732 if (phCertStore
) *phCertStore
= NULL
;
733 if (phMsg
) *phMsg
= NULL
;
736 CryptMemFree(blob
.pbData
);
740 BOOL WINAPI
CryptQueryObject(DWORD dwObjectType
, const void *pvObject
,
741 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
742 DWORD dwFlags
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
743 DWORD
*pdwFormatType
, HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
,
744 const void **ppvContext
)
746 static const DWORD unimplementedTypes
=
747 CERT_QUERY_CONTENT_FLAG_PKCS10
| CERT_QUERY_CONTENT_FLAG_CERT_PAIR
;
750 TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
751 dwObjectType
, pvObject
, dwExpectedContentTypeFlags
,
752 dwExpectedFormatTypeFlags
, dwFlags
, pdwMsgAndCertEncodingType
,
753 pdwContentType
, pdwFormatType
, phCertStore
, phMsg
, ppvContext
);
755 if (dwObjectType
!= CERT_QUERY_OBJECT_BLOB
&&
756 dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
758 WARN("unsupported type %d\n", dwObjectType
);
759 SetLastError(E_INVALIDARG
);
764 WARN("missing required argument\n");
765 SetLastError(E_INVALIDARG
);
768 if (dwExpectedContentTypeFlags
& unimplementedTypes
)
769 WARN("unimplemented for types %08x\n",
770 dwExpectedContentTypeFlags
& unimplementedTypes
);
773 *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
782 if ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
) ||
783 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
) ||
784 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
786 ret
= CRYPT_QueryContextObject(dwObjectType
, pvObject
,
787 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
788 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
792 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE
))
794 ret
= CRYPT_QuerySerializedStoreObject(dwObjectType
, pvObject
,
795 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
798 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
) ||
799 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
) ||
800 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
)))
802 ret
= CRYPT_QuerySerializedContextObject(dwObjectType
, pvObject
,
803 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
804 phCertStore
, ppvContext
);
807 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
) ||
808 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
)))
810 ret
= CRYPT_QueryMessageObject(dwObjectType
, pvObject
,
811 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
812 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
816 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED
))
818 ret
= CRYPT_QueryEmbeddedMessageObject(dwObjectType
, pvObject
,
819 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
823 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PFX
))
825 ret
= CRYPT_QueryPFXObject(dwObjectType
, pvObject
,
826 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
827 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
831 SetLastError(CRYPT_E_NO_MATCH
);
832 TRACE("returning %d\n", ret
);
836 static BOOL WINAPI
CRYPT_FormatHexString(DWORD dwCertEncodingType
,
837 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
838 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
845 bytesNeeded
= (cbEncoded
* 3) * sizeof(WCHAR
);
847 bytesNeeded
= sizeof(WCHAR
);
850 *pcbFormat
= bytesNeeded
;
853 else if (*pcbFormat
< bytesNeeded
)
855 *pcbFormat
= bytesNeeded
;
856 SetLastError(ERROR_MORE_DATA
);
862 LPWSTR ptr
= pbFormat
;
864 *pcbFormat
= bytesNeeded
;
867 for (i
= 0; i
< cbEncoded
; i
++)
869 if (i
< cbEncoded
- 1)
870 ptr
+= swprintf(ptr
, 4, L
"%02x ", pbEncoded
[i
]);
872 ptr
+= swprintf(ptr
, 3, L
"%02x", pbEncoded
[i
]);
882 #define MAX_STRING_RESOURCE_LEN 128
884 static const WCHAR commaSpace
[] = L
", ";
890 WCHAR str
[MAX_STRING_RESOURCE_LEN
];
893 static BOOL
CRYPT_FormatBits(BYTE bits
, const struct BitToString
*map
,
894 DWORD mapEntries
, void *pbFormat
, DWORD
*pcbFormat
, BOOL
*first
)
896 DWORD bytesNeeded
= sizeof(WCHAR
);
898 BOOL ret
= TRUE
, localFirst
= *first
;
900 for (i
= 0; i
< mapEntries
; i
++)
901 if (bits
& map
[i
].bit
)
904 bytesNeeded
+= lstrlenW(commaSpace
) * sizeof(WCHAR
);
906 bytesNeeded
+= lstrlenW(map
[i
].str
) * sizeof(WCHAR
);
911 *pcbFormat
= bytesNeeded
;
913 else if (*pcbFormat
< bytesNeeded
)
916 *pcbFormat
= bytesNeeded
;
917 SetLastError(ERROR_MORE_DATA
);
922 LPWSTR str
= pbFormat
;
925 *pcbFormat
= bytesNeeded
;
926 for (i
= 0; i
< mapEntries
; i
++)
927 if (bits
& map
[i
].bit
)
931 lstrcpyW(str
, commaSpace
);
932 str
+= lstrlenW(commaSpace
);
935 lstrcpyW(str
, map
[i
].str
);
936 str
+= lstrlenW(map
[i
].str
);
943 static struct BitToString keyUsageByte0Map
[] = {
944 { CERT_DIGITAL_SIGNATURE_KEY_USAGE
, IDS_DIGITAL_SIGNATURE
, { 0 } },
945 { CERT_NON_REPUDIATION_KEY_USAGE
, IDS_NON_REPUDIATION
, { 0 } },
946 { CERT_KEY_ENCIPHERMENT_KEY_USAGE
, IDS_KEY_ENCIPHERMENT
, { 0 } },
947 { CERT_DATA_ENCIPHERMENT_KEY_USAGE
, IDS_DATA_ENCIPHERMENT
, { 0 } },
948 { CERT_KEY_AGREEMENT_KEY_USAGE
, IDS_KEY_AGREEMENT
, { 0 } },
949 { CERT_KEY_CERT_SIGN_KEY_USAGE
, IDS_CERT_SIGN
, { 0 } },
950 { CERT_OFFLINE_CRL_SIGN_KEY_USAGE
, IDS_OFFLINE_CRL_SIGN
, { 0 } },
951 { CERT_CRL_SIGN_KEY_USAGE
, IDS_CRL_SIGN
, { 0 } },
952 { CERT_ENCIPHER_ONLY_KEY_USAGE
, IDS_ENCIPHER_ONLY
, { 0 } },
954 static struct BitToString keyUsageByte1Map
[] = {
955 { CERT_DECIPHER_ONLY_KEY_USAGE
, IDS_DECIPHER_ONLY
, { 0 } },
958 static BOOL WINAPI
CRYPT_FormatKeyUsage(DWORD dwCertEncodingType
,
959 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
960 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
964 CRYPT_BIT_BLOB
*bits
;
969 SetLastError(E_INVALIDARG
);
972 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_KEY_USAGE
,
973 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
975 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
976 DWORD bytesNeeded
= sizeof(WCHAR
);
978 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
979 if (!bits
->cbData
|| bits
->cbData
> 2)
981 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
983 *pcbFormat
= bytesNeeded
;
984 else if (*pcbFormat
< bytesNeeded
)
986 *pcbFormat
= bytesNeeded
;
987 SetLastError(ERROR_MORE_DATA
);
992 LPWSTR str
= pbFormat
;
994 *pcbFormat
= bytesNeeded
;
995 lstrcpyW(str
, infoNotAvailable
);
1000 static BOOL stringsLoaded
= FALSE
;
1007 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte0Map
); i
++)
1008 LoadStringW(hInstance
, keyUsageByte0Map
[i
].id
, keyUsageByte0Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1009 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte1Map
); i
++)
1010 LoadStringW(hInstance
, keyUsageByte1Map
[i
].id
, keyUsageByte1Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1011 stringsLoaded
= TRUE
;
1013 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1014 NULL
, &bitStringLen
, &first
);
1015 bytesNeeded
+= bitStringLen
;
1016 if (bits
->cbData
== 2)
1018 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1019 NULL
, &bitStringLen
, &first
);
1020 bytesNeeded
+= bitStringLen
;
1022 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
1023 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1024 bits
->cbData
, NULL
, &size
);
1025 bytesNeeded
+= size
;
1027 *pcbFormat
= bytesNeeded
;
1028 else if (*pcbFormat
< bytesNeeded
)
1030 *pcbFormat
= bytesNeeded
;
1031 SetLastError(ERROR_MORE_DATA
);
1036 LPWSTR str
= pbFormat
;
1038 bitStringLen
= bytesNeeded
;
1040 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1041 str
, &bitStringLen
, &first
);
1042 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1043 if (bits
->cbData
== 2)
1045 bitStringLen
= bytesNeeded
;
1046 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1047 str
, &bitStringLen
, &first
);
1048 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1052 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1053 bits
->cbData
, str
, &size
);
1054 str
+= size
/ sizeof(WCHAR
) - 1;
1064 static const WCHAR crlf
[] = L
"\r\n";
1066 static WCHAR subjectTypeHeader
[MAX_STRING_RESOURCE_LEN
];
1067 static WCHAR subjectTypeCA
[MAX_STRING_RESOURCE_LEN
];
1068 static WCHAR subjectTypeEndCert
[MAX_STRING_RESOURCE_LEN
];
1069 static WCHAR pathLengthHeader
[MAX_STRING_RESOURCE_LEN
];
1071 static BOOL WINAPI
CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType
,
1072 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1073 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1077 CERT_BASIC_CONSTRAINTS2_INFO
*info
;
1082 SetLastError(E_INVALIDARG
);
1085 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BASIC_CONSTRAINTS2
,
1086 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1088 static BOOL stringsLoaded
= FALSE
;
1089 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1090 WCHAR pathLength
[MAX_STRING_RESOURCE_LEN
];
1091 LPCWSTR sep
, subjectType
;
1094 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1097 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1102 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1107 LoadStringW(hInstance
, IDS_SUBJECT_TYPE
, subjectTypeHeader
, ARRAY_SIZE(subjectTypeHeader
));
1108 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_CA
, subjectTypeCA
, ARRAY_SIZE(subjectTypeCA
));
1109 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_END_CERT
, subjectTypeEndCert
, ARRAY_SIZE(subjectTypeEndCert
));
1110 LoadStringW(hInstance
, IDS_PATH_LENGTH
, pathLengthHeader
, ARRAY_SIZE(pathLengthHeader
));
1111 stringsLoaded
= TRUE
;
1113 bytesNeeded
+= lstrlenW(subjectTypeHeader
) * sizeof(WCHAR
);
1115 subjectType
= subjectTypeCA
;
1117 subjectType
= subjectTypeEndCert
;
1118 bytesNeeded
+= lstrlenW(subjectType
) * sizeof(WCHAR
);
1119 bytesNeeded
+= sepLen
;
1120 bytesNeeded
+= lstrlenW(pathLengthHeader
) * sizeof(WCHAR
);
1121 if (info
->fPathLenConstraint
)
1122 swprintf(pathLength
, ARRAY_SIZE(pathLength
), L
"%d", info
->dwPathLenConstraint
);
1124 LoadStringW(hInstance
, IDS_PATH_LENGTH_NONE
, pathLength
, ARRAY_SIZE(pathLength
));
1125 bytesNeeded
+= lstrlenW(pathLength
) * sizeof(WCHAR
);
1127 *pcbFormat
= bytesNeeded
;
1128 else if (*pcbFormat
< bytesNeeded
)
1130 *pcbFormat
= bytesNeeded
;
1131 SetLastError(ERROR_MORE_DATA
);
1136 LPWSTR str
= pbFormat
;
1138 *pcbFormat
= bytesNeeded
;
1139 lstrcpyW(str
, subjectTypeHeader
);
1140 str
+= lstrlenW(subjectTypeHeader
);
1141 lstrcpyW(str
, subjectType
);
1142 str
+= lstrlenW(subjectType
);
1144 str
+= sepLen
/ sizeof(WCHAR
);
1145 lstrcpyW(str
, pathLengthHeader
);
1146 str
+= lstrlenW(pathLengthHeader
);
1147 lstrcpyW(str
, pathLength
);
1154 static BOOL
CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB
*blob
, int id
,
1155 LPWSTR str
, DWORD
*pcbStr
)
1157 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1161 LoadStringW(hInstance
, id
, buf
, ARRAY_SIZE(buf
));
1162 CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1163 blob
->pbData
, blob
->cbData
, NULL
, &bytesNeeded
);
1164 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1167 *pcbStr
= bytesNeeded
;
1170 else if (*pcbStr
< bytesNeeded
)
1172 *pcbStr
= bytesNeeded
;
1173 SetLastError(ERROR_MORE_DATA
);
1178 *pcbStr
= bytesNeeded
;
1180 str
+= lstrlenW(str
);
1181 bytesNeeded
-= lstrlenW(str
) * sizeof(WCHAR
);
1182 ret
= CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1183 blob
->pbData
, blob
->cbData
, str
, &bytesNeeded
);
1188 static BOOL
CRYPT_FormatKeyId(const CRYPT_DATA_BLOB
*keyId
, LPWSTR str
,
1191 return CRYPT_FormatHexStringWithPrefix(keyId
, IDS_KEY_ID
, str
, pcbStr
);
1194 static BOOL
CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB
*serialNum
, LPWSTR str
,
1197 return CRYPT_FormatHexStringWithPrefix(serialNum
, IDS_CERT_SERIAL_NUMBER
,
1201 static const WCHAR indent
[] = L
" ";
1202 static const WCHAR colonCrlf
[] = L
":\r\n";
1204 static BOOL
CRYPT_FormatAltNameEntry(DWORD dwFormatStrType
, DWORD indentLevel
,
1205 const CERT_ALT_NAME_ENTRY
*entry
, LPWSTR str
, DWORD
*pcbStr
)
1208 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1209 WCHAR mask
[MAX_STRING_RESOURCE_LEN
];
1210 WCHAR ipAddrBuf
[32];
1212 DWORD bytesNeeded
= sizeof(WCHAR
);
1213 DWORD strType
= CERT_X500_NAME_STR
| CERT_NAME_STR_REVERSE_FLAG
;
1215 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1216 bytesNeeded
+= indentLevel
* lstrlenW(indent
) * sizeof(WCHAR
);
1217 switch (entry
->dwAltNameChoice
)
1219 case CERT_ALT_NAME_RFC822_NAME
:
1220 LoadStringW(hInstance
, IDS_ALT_NAME_RFC822_NAME
, buf
, ARRAY_SIZE(buf
));
1221 bytesNeeded
+= lstrlenW(entry
->u
.pwszRfc822Name
) * sizeof(WCHAR
);
1224 case CERT_ALT_NAME_DNS_NAME
:
1225 LoadStringW(hInstance
, IDS_ALT_NAME_DNS_NAME
, buf
, ARRAY_SIZE(buf
));
1226 bytesNeeded
+= lstrlenW(entry
->u
.pwszDNSName
) * sizeof(WCHAR
);
1229 case CERT_ALT_NAME_DIRECTORY_NAME
:
1231 DWORD directoryNameLen
;
1233 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1234 strType
|= CERT_NAME_STR_CRLF_FLAG
;
1235 directoryNameLen
= cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1236 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, NULL
, 0);
1237 LoadStringW(hInstance
, IDS_ALT_NAME_DIRECTORY_NAME
, buf
, ARRAY_SIZE(buf
));
1238 bytesNeeded
+= (directoryNameLen
- 1) * sizeof(WCHAR
);
1239 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1240 bytesNeeded
+= lstrlenW(colonCrlf
) * sizeof(WCHAR
);
1242 bytesNeeded
+= sizeof(WCHAR
); /* '=' */
1246 case CERT_ALT_NAME_URL
:
1247 LoadStringW(hInstance
, IDS_ALT_NAME_URL
, buf
, ARRAY_SIZE(buf
));
1248 bytesNeeded
+= lstrlenW(entry
->u
.pwszURL
) * sizeof(WCHAR
);
1251 case CERT_ALT_NAME_IP_ADDRESS
:
1253 LoadStringW(hInstance
, IDS_ALT_NAME_IP_ADDRESS
, buf
, ARRAY_SIZE(buf
));
1254 if (entry
->u
.IPAddress
.cbData
== 8)
1256 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1258 LoadStringW(hInstance
, IDS_ALT_NAME_MASK
, mask
, ARRAY_SIZE(mask
));
1259 bytesNeeded
+= lstrlenW(mask
) * sizeof(WCHAR
);
1260 swprintf(ipAddrBuf
, ARRAY_SIZE(ipAddrBuf
), L
"%d.%d.%d.%d",
1261 entry
->u
.IPAddress
.pbData
[0],
1262 entry
->u
.IPAddress
.pbData
[1],
1263 entry
->u
.IPAddress
.pbData
[2],
1264 entry
->u
.IPAddress
.pbData
[3]);
1265 bytesNeeded
+= lstrlenW(ipAddrBuf
) * sizeof(WCHAR
);
1266 /* indent again, for the mask line */
1267 bytesNeeded
+= indentLevel
* lstrlenW(indent
) * sizeof(WCHAR
);
1268 swprintf(maskBuf
, ARRAY_SIZE(maskBuf
), L
"%d.%d.%d.%d",
1269 entry
->u
.IPAddress
.pbData
[4],
1270 entry
->u
.IPAddress
.pbData
[5],
1271 entry
->u
.IPAddress
.pbData
[6],
1272 entry
->u
.IPAddress
.pbData
[7]);
1273 bytesNeeded
+= lstrlenW(maskBuf
) * sizeof(WCHAR
);
1274 bytesNeeded
+= lstrlenW(crlf
) * sizeof(WCHAR
);
1278 swprintf(ipAddrBuf
, ARRAY_SIZE(ipAddrBuf
), L
"%d.%d.%d.%d/%d.%d.%d.%d",
1279 entry
->u
.IPAddress
.pbData
[0],
1280 entry
->u
.IPAddress
.pbData
[1],
1281 entry
->u
.IPAddress
.pbData
[2],
1282 entry
->u
.IPAddress
.pbData
[3],
1283 entry
->u
.IPAddress
.pbData
[4],
1284 entry
->u
.IPAddress
.pbData
[5],
1285 entry
->u
.IPAddress
.pbData
[6],
1286 entry
->u
.IPAddress
.pbData
[7]);
1287 bytesNeeded
+= (lstrlenW(ipAddrBuf
) + 1) * sizeof(WCHAR
);
1293 FIXME("unknown IP address format (%d bytes)\n",
1294 entry
->u
.IPAddress
.cbData
);
1300 FIXME("unimplemented for %d\n", entry
->dwAltNameChoice
);
1305 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1307 *pcbStr
= bytesNeeded
;
1308 else if (*pcbStr
< bytesNeeded
)
1310 *pcbStr
= bytesNeeded
;
1311 SetLastError(ERROR_MORE_DATA
);
1318 *pcbStr
= bytesNeeded
;
1319 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1321 for (i
= 0; i
< indentLevel
; i
++)
1323 lstrcpyW(str
, indent
);
1324 str
+= lstrlenW(indent
);
1328 str
+= lstrlenW(str
);
1329 switch (entry
->dwAltNameChoice
)
1331 case CERT_ALT_NAME_RFC822_NAME
:
1332 case CERT_ALT_NAME_DNS_NAME
:
1333 case CERT_ALT_NAME_URL
:
1334 lstrcpyW(str
, entry
->u
.pwszURL
);
1336 case CERT_ALT_NAME_DIRECTORY_NAME
:
1337 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1339 lstrcpyW(str
, colonCrlf
);
1340 str
+= lstrlenW(colonCrlf
);
1344 cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1345 indentLevel
+ 1, &entry
->u
.DirectoryName
, strType
, str
,
1346 bytesNeeded
/ sizeof(WCHAR
));
1348 case CERT_ALT_NAME_IP_ADDRESS
:
1349 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1351 lstrcpyW(str
, ipAddrBuf
);
1352 str
+= lstrlenW(ipAddrBuf
);
1353 lstrcpyW(str
, crlf
);
1354 str
+= lstrlenW(crlf
);
1355 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1357 for (i
= 0; i
< indentLevel
; i
++)
1359 lstrcpyW(str
, indent
);
1360 str
+= lstrlenW(indent
);
1363 lstrcpyW(str
, mask
);
1364 str
+= lstrlenW(mask
);
1365 lstrcpyW(str
, maskBuf
);
1368 lstrcpyW(str
, ipAddrBuf
);
1376 static BOOL
CRYPT_FormatAltNameInfo(DWORD dwFormatStrType
, DWORD indentLevel
,
1377 const CERT_ALT_NAME_INFO
*name
, LPWSTR str
, DWORD
*pcbStr
)
1379 DWORD i
, size
, bytesNeeded
= 0;
1384 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1387 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1392 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1395 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1397 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1398 &name
->rgAltEntry
[i
], NULL
, &size
);
1401 bytesNeeded
+= size
- sizeof(WCHAR
);
1402 if (i
< name
->cAltEntry
- 1)
1403 bytesNeeded
+= sepLen
;
1408 bytesNeeded
+= sizeof(WCHAR
);
1410 *pcbStr
= bytesNeeded
;
1411 else if (*pcbStr
< bytesNeeded
)
1413 *pcbStr
= bytesNeeded
;
1414 SetLastError(ERROR_MORE_DATA
);
1419 *pcbStr
= bytesNeeded
;
1420 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1422 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1423 &name
->rgAltEntry
[i
], str
, &size
);
1426 str
+= size
/ sizeof(WCHAR
) - 1;
1427 if (i
< name
->cAltEntry
- 1)
1430 str
+= sepLen
/ sizeof(WCHAR
);
1439 static const WCHAR colonSep
[] = L
": ";
1441 static BOOL WINAPI
CRYPT_FormatAltName(DWORD dwCertEncodingType
,
1442 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1443 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1447 CERT_ALT_NAME_INFO
*info
;
1450 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ALTERNATE_NAME
,
1451 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1453 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 0, info
, pbFormat
, pcbFormat
);
1459 static BOOL
CRYPT_FormatCertIssuer(DWORD dwFormatStrType
,
1460 const CERT_ALT_NAME_INFO
*issuer
, LPWSTR str
, DWORD
*pcbStr
)
1462 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1463 DWORD bytesNeeded
, sepLen
;
1467 LoadStringW(hInstance
, IDS_CERT_ISSUER
, buf
, ARRAY_SIZE(buf
));
1468 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, NULL
,
1470 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1471 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1474 sepLen
= lstrlenW(colonCrlf
) * sizeof(WCHAR
);
1479 sepLen
= lstrlenW(colonSep
) * sizeof(WCHAR
);
1481 bytesNeeded
+= sepLen
;
1485 *pcbStr
= bytesNeeded
;
1486 else if (*pcbStr
< bytesNeeded
)
1488 *pcbStr
= bytesNeeded
;
1489 SetLastError(ERROR_MORE_DATA
);
1494 *pcbStr
= bytesNeeded
;
1496 bytesNeeded
-= lstrlenW(str
) * sizeof(WCHAR
);
1497 str
+= lstrlenW(str
);
1499 str
+= sepLen
/ sizeof(WCHAR
);
1500 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, str
,
1507 static BOOL WINAPI
CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType
,
1508 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1509 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1512 CERT_AUTHORITY_KEY_ID2_INFO
*info
;
1518 SetLastError(E_INVALIDARG
);
1521 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_AUTHORITY_KEY_ID2
,
1522 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1524 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1527 BOOL needSeparator
= FALSE
;
1529 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1532 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1537 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1540 if (info
->KeyId
.cbData
)
1542 needSeparator
= TRUE
;
1543 ret
= CRYPT_FormatKeyId(&info
->KeyId
, NULL
, &size
);
1546 /* don't include NULL-terminator more than once */
1547 bytesNeeded
+= size
- sizeof(WCHAR
);
1550 if (info
->AuthorityCertIssuer
.cAltEntry
)
1553 bytesNeeded
+= sepLen
;
1554 needSeparator
= TRUE
;
1555 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1556 &info
->AuthorityCertIssuer
, NULL
, &size
);
1559 /* don't include NULL-terminator more than once */
1560 bytesNeeded
+= size
- sizeof(WCHAR
);
1563 if (info
->AuthorityCertSerialNumber
.cbData
)
1566 bytesNeeded
+= sepLen
;
1567 ret
= CRYPT_FormatCertSerialNumber(
1568 &info
->AuthorityCertSerialNumber
, NULL
, &size
);
1571 /* don't include NULL-terminator more than once */
1572 bytesNeeded
+= size
- sizeof(WCHAR
);
1578 *pcbFormat
= bytesNeeded
;
1579 else if (*pcbFormat
< bytesNeeded
)
1581 *pcbFormat
= bytesNeeded
;
1582 SetLastError(ERROR_MORE_DATA
);
1587 LPWSTR str
= pbFormat
;
1589 *pcbFormat
= bytesNeeded
;
1590 needSeparator
= FALSE
;
1591 if (info
->KeyId
.cbData
)
1593 needSeparator
= TRUE
;
1594 /* Overestimate size available, it's already been checked
1598 ret
= CRYPT_FormatKeyId(&info
->KeyId
, str
, &size
);
1600 str
+= size
/ sizeof(WCHAR
) - 1;
1602 if (info
->AuthorityCertIssuer
.cAltEntry
)
1607 str
+= sepLen
/ sizeof(WCHAR
);
1609 needSeparator
= TRUE
;
1610 /* Overestimate size available, it's already been checked
1614 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1615 &info
->AuthorityCertIssuer
, str
, &size
);
1617 str
+= size
/ sizeof(WCHAR
) - 1;
1619 if (info
->AuthorityCertSerialNumber
.cbData
)
1624 str
+= sepLen
/ sizeof(WCHAR
);
1626 /* Overestimate size available, it's already been checked
1630 ret
= CRYPT_FormatCertSerialNumber(
1631 &info
->AuthorityCertSerialNumber
, str
, &size
);
1640 static WCHAR aia
[MAX_STRING_RESOURCE_LEN
];
1641 static WCHAR accessMethod
[MAX_STRING_RESOURCE_LEN
];
1642 static WCHAR ocsp
[MAX_STRING_RESOURCE_LEN
];
1643 static WCHAR caIssuers
[MAX_STRING_RESOURCE_LEN
];
1644 static WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
1645 static WCHAR accessLocation
[MAX_STRING_RESOURCE_LEN
];
1647 static BOOL WINAPI
CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType
,
1648 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1649 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1652 CERT_AUTHORITY_INFO_ACCESS
*info
;
1658 SetLastError(E_INVALIDARG
);
1661 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
1662 X509_AUTHORITY_INFO_ACCESS
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
,
1663 NULL
, &info
, &size
)))
1665 DWORD bytesNeeded
= sizeof(WCHAR
);
1667 if (!info
->cAccDescr
)
1669 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
1671 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
1672 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
1674 *pcbFormat
= bytesNeeded
;
1675 else if (*pcbFormat
< bytesNeeded
)
1677 *pcbFormat
= bytesNeeded
;
1678 SetLastError(ERROR_MORE_DATA
);
1683 *pcbFormat
= bytesNeeded
;
1684 lstrcpyW(pbFormat
, infoNotAvailable
);
1689 static const WCHAR equal
[] = L
"=";
1690 static BOOL stringsLoaded
= FALSE
;
1692 LPCWSTR headingSep
, accessMethodSep
, locationSep
;
1693 WCHAR accessDescrNum
[11];
1697 LoadStringW(hInstance
, IDS_AIA
, aia
, ARRAY_SIZE(aia
));
1698 LoadStringW(hInstance
, IDS_ACCESS_METHOD
, accessMethod
, ARRAY_SIZE(accessMethod
));
1699 LoadStringW(hInstance
, IDS_ACCESS_METHOD_OCSP
, ocsp
, ARRAY_SIZE(ocsp
));
1700 LoadStringW(hInstance
, IDS_ACCESS_METHOD_CA_ISSUERS
, caIssuers
, ARRAY_SIZE(caIssuers
));
1701 LoadStringW(hInstance
, IDS_ACCESS_METHOD_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
1702 LoadStringW(hInstance
, IDS_ACCESS_LOCATION
, accessLocation
, ARRAY_SIZE(accessLocation
));
1703 stringsLoaded
= TRUE
;
1705 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1708 accessMethodSep
= crlf
;
1709 locationSep
= colonCrlf
;
1713 headingSep
= colonSep
;
1714 accessMethodSep
= commaSpace
;
1715 locationSep
= equal
;
1718 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1721 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
1722 swprintf(accessDescrNum
, ARRAY_SIZE(accessDescrNum
), L
"%d", i
+ 1);
1723 bytesNeeded
+= lstrlenW(accessDescrNum
) * sizeof(WCHAR
);
1724 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
1725 bytesNeeded
+= lstrlenW(aia
) * sizeof(WCHAR
);
1726 bytesNeeded
+= lstrlenW(headingSep
) * sizeof(WCHAR
);
1728 bytesNeeded
+= lstrlenW(accessMethod
) * sizeof(WCHAR
);
1729 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1730 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
1731 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1733 bytesNeeded
+= lstrlenW(ocsp
) * sizeof(WCHAR
);
1734 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1735 szOID_PKIX_CA_ISSUERS
))
1736 bytesNeeded
+= lstrlenW(caIssuers
) * sizeof(caIssuers
);
1738 bytesNeeded
+= lstrlenW(unknown
) * sizeof(WCHAR
);
1739 bytesNeeded
+= sizeof(WCHAR
); /* space */
1740 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
1741 bytesNeeded
+= strlen(info
->rgAccDescr
[i
].pszAccessMethod
)
1743 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
1744 /* Delimiter between access method and location */
1745 bytesNeeded
+= lstrlenW(accessMethodSep
) * sizeof(WCHAR
);
1746 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1747 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
1748 bytesNeeded
+= lstrlenW(accessLocation
) * sizeof(WCHAR
);
1749 bytesNeeded
+= lstrlenW(locationSep
) * sizeof(WCHAR
);
1750 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1751 &info
->rgAccDescr
[i
].AccessLocation
, NULL
, &size
);
1753 bytesNeeded
+= size
- sizeof(WCHAR
);
1754 /* Need extra delimiter between access method entries */
1755 if (i
< info
->cAccDescr
- 1)
1756 bytesNeeded
+= lstrlenW(accessMethodSep
) * sizeof(WCHAR
);
1761 *pcbFormat
= bytesNeeded
;
1762 else if (*pcbFormat
< bytesNeeded
)
1764 *pcbFormat
= bytesNeeded
;
1765 SetLastError(ERROR_MORE_DATA
);
1770 LPWSTR str
= pbFormat
;
1771 DWORD altNameEntrySize
;
1773 *pcbFormat
= bytesNeeded
;
1774 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1779 swprintf(accessDescrNum
, ARRAY_SIZE(accessDescrNum
), L
"%d", i
+ 1);
1780 lstrcpyW(str
, accessDescrNum
);
1781 str
+= lstrlenW(accessDescrNum
);
1784 str
+= lstrlenW(aia
);
1785 lstrcpyW(str
, headingSep
);
1786 str
+= lstrlenW(headingSep
);
1787 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1789 lstrcpyW(str
, indent
);
1790 str
+= lstrlenW(indent
);
1792 lstrcpyW(str
, accessMethod
);
1793 str
+= lstrlenW(accessMethod
);
1794 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1797 lstrcpyW(str
, ocsp
);
1798 str
+= lstrlenW(ocsp
);
1800 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1801 szOID_PKIX_CA_ISSUERS
))
1803 lstrcpyW(str
, caIssuers
);
1804 str
+= lstrlenW(caIssuers
);
1808 lstrcpyW(str
, unknown
);
1809 str
+= lstrlenW(unknown
);
1813 for (oidPtr
= info
->rgAccDescr
[i
].pszAccessMethod
;
1814 *oidPtr
; oidPtr
++, str
++)
1817 lstrcpyW(str
, accessMethodSep
);
1818 str
+= lstrlenW(accessMethodSep
);
1819 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1821 lstrcpyW(str
, indent
);
1822 str
+= lstrlenW(indent
);
1824 lstrcpyW(str
, accessLocation
);
1825 str
+= lstrlenW(accessLocation
);
1826 lstrcpyW(str
, locationSep
);
1827 str
+= lstrlenW(locationSep
);
1828 /* This overestimates the size available, but that
1829 * won't matter since we checked earlier whether enough
1830 * space for the entire string was available.
1832 altNameEntrySize
= bytesNeeded
;
1833 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1834 &info
->rgAccDescr
[i
].AccessLocation
, str
,
1837 str
+= altNameEntrySize
/ sizeof(WCHAR
) - 1;
1838 if (i
< info
->cAccDescr
- 1)
1840 lstrcpyW(str
, accessMethodSep
);
1841 str
+= lstrlenW(accessMethodSep
);
1852 static WCHAR keyCompromise
[MAX_STRING_RESOURCE_LEN
];
1853 static WCHAR caCompromise
[MAX_STRING_RESOURCE_LEN
];
1854 static WCHAR affiliationChanged
[MAX_STRING_RESOURCE_LEN
];
1855 static WCHAR superseded
[MAX_STRING_RESOURCE_LEN
];
1856 static WCHAR operationCeased
[MAX_STRING_RESOURCE_LEN
];
1857 static WCHAR certificateHold
[MAX_STRING_RESOURCE_LEN
];
1859 struct reason_map_entry
1865 static struct reason_map_entry reason_map
[] = {
1866 { CRL_REASON_KEY_COMPROMISE_FLAG
, keyCompromise
, IDS_REASON_KEY_COMPROMISE
},
1867 { CRL_REASON_CA_COMPROMISE_FLAG
, caCompromise
, IDS_REASON_CA_COMPROMISE
},
1868 { CRL_REASON_AFFILIATION_CHANGED_FLAG
, affiliationChanged
,
1869 IDS_REASON_AFFILIATION_CHANGED
},
1870 { CRL_REASON_SUPERSEDED_FLAG
, superseded
, IDS_REASON_SUPERSEDED
},
1871 { CRL_REASON_CESSATION_OF_OPERATION_FLAG
, operationCeased
,
1872 IDS_REASON_CESSATION_OF_OPERATION
},
1873 { CRL_REASON_CERTIFICATE_HOLD_FLAG
, certificateHold
,
1874 IDS_REASON_CERTIFICATE_HOLD
},
1877 static BOOL
CRYPT_FormatReason(DWORD dwFormatStrType
,
1878 const CRYPT_BIT_BLOB
*reasonFlags
, LPWSTR str
, DWORD
*pcbStr
)
1880 static const WCHAR sep
[] = L
", ";
1881 static BOOL stringsLoaded
= FALSE
;
1882 unsigned int i
, numReasons
= 0;
1884 DWORD bytesNeeded
= sizeof(WCHAR
);
1889 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1890 LoadStringW(hInstance
, reason_map
[i
].id
, reason_map
[i
].reason
,
1891 MAX_STRING_RESOURCE_LEN
);
1892 stringsLoaded
= TRUE
;
1894 /* No need to check reasonFlags->cbData, we already know it's positive.
1895 * Ignore any other bytes, as they're for undefined bits.
1897 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1899 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1901 bytesNeeded
+= lstrlenW(reason_map
[i
].reason
) * sizeof(WCHAR
);
1903 bytesNeeded
+= lstrlenW(sep
) * sizeof(WCHAR
);
1906 swprintf(bits
, ARRAY_SIZE(bits
), L
" (%02x)", reasonFlags
->pbData
[0]);
1907 bytesNeeded
+= lstrlenW(bits
);
1909 *pcbStr
= bytesNeeded
;
1910 else if (*pcbStr
< bytesNeeded
)
1912 *pcbStr
= bytesNeeded
;
1913 SetLastError(ERROR_MORE_DATA
);
1918 *pcbStr
= bytesNeeded
;
1919 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1921 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1923 lstrcpyW(str
, reason_map
[i
].reason
);
1924 str
+= lstrlenW(reason_map
[i
].reason
);
1925 if (i
< ARRAY_SIZE(reason_map
) - 1 && numReasons
)
1928 str
+= lstrlenW(sep
);
1932 lstrcpyW(str
, bits
);
1937 static WCHAR crlDistPoint
[MAX_STRING_RESOURCE_LEN
];
1938 static WCHAR distPointName
[MAX_STRING_RESOURCE_LEN
];
1939 static WCHAR fullName
[MAX_STRING_RESOURCE_LEN
];
1940 static WCHAR rdnName
[MAX_STRING_RESOURCE_LEN
];
1941 static WCHAR reason
[MAX_STRING_RESOURCE_LEN
];
1942 static WCHAR issuer
[MAX_STRING_RESOURCE_LEN
];
1944 static BOOL WINAPI
CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType
,
1945 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1946 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1949 CRL_DIST_POINTS_INFO
*info
;
1955 SetLastError(E_INVALIDARG
);
1958 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_CRL_DIST_POINTS
,
1959 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1961 static const WCHAR colon
[] = L
":";
1962 static BOOL stringsLoaded
= FALSE
;
1963 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for NULL terminator */
1964 BOOL haveAnEntry
= FALSE
;
1965 LPCWSTR headingSep
, nameSep
;
1966 WCHAR distPointNum
[11];
1971 LoadStringW(hInstance
, IDS_CRL_DIST_POINT
, crlDistPoint
, ARRAY_SIZE(crlDistPoint
));
1972 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_NAME
, distPointName
, ARRAY_SIZE(distPointName
));
1973 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_FULL_NAME
, fullName
, ARRAY_SIZE(fullName
));
1974 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_RDN_NAME
, rdnName
, ARRAY_SIZE(rdnName
));
1975 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_REASON
, reason
, ARRAY_SIZE(reason
));
1976 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_ISSUER
, issuer
, ARRAY_SIZE(issuer
));
1977 stringsLoaded
= TRUE
;
1979 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1982 nameSep
= colonCrlf
;
1986 headingSep
= colonSep
;
1990 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
1992 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
1994 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
1995 CRL_DIST_POINT_NO_NAME
)
1997 bytesNeeded
+= lstrlenW(distPointName
) * sizeof(WCHAR
);
1998 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
1999 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2000 CRL_DIST_POINT_FULL_NAME
)
2001 bytesNeeded
+= lstrlenW(fullName
) * sizeof(WCHAR
);
2003 bytesNeeded
+= lstrlenW(rdnName
) * sizeof(WCHAR
);
2004 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
2005 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2006 bytesNeeded
+= 2 * lstrlenW(indent
) * sizeof(WCHAR
);
2007 /* The indent level (3) is higher than when used as the issuer,
2008 * because the name is subordinate to the name type (full vs.
2011 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2012 &distPoint
->DistPointName
.u
.FullName
, NULL
, &size
);
2014 bytesNeeded
+= size
- sizeof(WCHAR
);
2017 else if (distPoint
->ReasonFlags
.cbData
)
2019 bytesNeeded
+= lstrlenW(reason
) * sizeof(WCHAR
);
2020 ret
= CRYPT_FormatReason(dwFormatStrType
,
2021 &distPoint
->ReasonFlags
, NULL
, &size
);
2023 bytesNeeded
+= size
- sizeof(WCHAR
);
2026 else if (distPoint
->CRLIssuer
.cAltEntry
)
2028 bytesNeeded
+= lstrlenW(issuer
) * sizeof(WCHAR
);
2029 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
2030 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2031 &distPoint
->CRLIssuer
, NULL
, &size
);
2033 bytesNeeded
+= size
- sizeof(WCHAR
);
2038 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
2039 swprintf(distPointNum
, ARRAY_SIZE(distPointNum
), L
"%d", i
+ 1);
2040 bytesNeeded
+= lstrlenW(distPointNum
) * sizeof(WCHAR
);
2041 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
2042 bytesNeeded
+= lstrlenW(crlDistPoint
) * sizeof(WCHAR
);
2043 bytesNeeded
+= lstrlenW(headingSep
) * sizeof(WCHAR
);
2044 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2045 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
2050 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2052 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2053 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
2055 *pcbFormat
= bytesNeeded
;
2056 else if (*pcbFormat
< bytesNeeded
)
2058 *pcbFormat
= bytesNeeded
;
2059 SetLastError(ERROR_MORE_DATA
);
2064 *pcbFormat
= bytesNeeded
;
2065 lstrcpyW(pbFormat
, infoNotAvailable
);
2071 *pcbFormat
= bytesNeeded
;
2072 else if (*pcbFormat
< bytesNeeded
)
2074 *pcbFormat
= bytesNeeded
;
2075 SetLastError(ERROR_MORE_DATA
);
2080 LPWSTR str
= pbFormat
;
2082 *pcbFormat
= bytesNeeded
;
2083 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2085 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2088 swprintf(distPointNum
, ARRAY_SIZE(distPointNum
), L
"%d", i
+ 1);
2089 lstrcpyW(str
, distPointNum
);
2090 str
+= lstrlenW(distPointNum
);
2092 lstrcpyW(str
, crlDistPoint
);
2093 str
+= lstrlenW(crlDistPoint
);
2094 lstrcpyW(str
, headingSep
);
2095 str
+= lstrlenW(headingSep
);
2096 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2098 lstrcpyW(str
, indent
);
2099 str
+= lstrlenW(indent
);
2101 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2102 CRL_DIST_POINT_NO_NAME
)
2104 DWORD altNameSize
= bytesNeeded
;
2106 lstrcpyW(str
, distPointName
);
2107 str
+= lstrlenW(distPointName
);
2108 lstrcpyW(str
, nameSep
);
2109 str
+= lstrlenW(nameSep
);
2110 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2112 lstrcpyW(str
, indent
);
2113 str
+= lstrlenW(indent
);
2114 lstrcpyW(str
, indent
);
2115 str
+= lstrlenW(indent
);
2117 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2118 CRL_DIST_POINT_FULL_NAME
)
2120 lstrcpyW(str
, fullName
);
2121 str
+= lstrlenW(fullName
);
2125 lstrcpyW(str
, rdnName
);
2126 str
+= lstrlenW(rdnName
);
2128 lstrcpyW(str
, nameSep
);
2129 str
+= lstrlenW(nameSep
);
2130 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2131 &distPoint
->DistPointName
.u
.FullName
, str
,
2134 str
+= altNameSize
/ sizeof(WCHAR
) - 1;
2136 else if (distPoint
->ReasonFlags
.cbData
)
2138 DWORD reasonSize
= bytesNeeded
;
2140 lstrcpyW(str
, reason
);
2141 str
+= lstrlenW(reason
);
2142 ret
= CRYPT_FormatReason(dwFormatStrType
,
2143 &distPoint
->ReasonFlags
, str
, &reasonSize
);
2145 str
+= reasonSize
/ sizeof(WCHAR
) - 1;
2147 else if (distPoint
->CRLIssuer
.cAltEntry
)
2149 DWORD crlIssuerSize
= bytesNeeded
;
2151 lstrcpyW(str
, issuer
);
2152 str
+= lstrlenW(issuer
);
2153 lstrcpyW(str
, nameSep
);
2154 str
+= lstrlenW(nameSep
);
2155 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2156 &distPoint
->CRLIssuer
, str
,
2159 str
+= crlIssuerSize
/ sizeof(WCHAR
) - 1;
2169 static BOOL WINAPI
CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType
,
2170 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2171 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2174 CERT_ENHKEY_USAGE
*usage
;
2180 SetLastError(E_INVALIDARG
);
2183 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ENHANCED_KEY_USAGE
,
2184 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &usage
, &size
)))
2186 WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
2188 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
2192 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2195 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
2200 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
2203 LoadStringW(hInstance
, IDS_USAGE_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
2204 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2206 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2207 usage
->rgpszUsageIdentifier
[i
], CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2210 bytesNeeded
+= lstrlenW(info
->pwszName
) * sizeof(WCHAR
);
2212 bytesNeeded
+= lstrlenW(unknown
) * sizeof(WCHAR
);
2213 bytesNeeded
+= sizeof(WCHAR
); /* space */
2214 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
2215 bytesNeeded
+= strlen(usage
->rgpszUsageIdentifier
[i
]) *
2217 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
2218 if (i
< usage
->cUsageIdentifier
- 1)
2219 bytesNeeded
+= sepLen
;
2222 *pcbFormat
= bytesNeeded
;
2223 else if (*pcbFormat
< bytesNeeded
)
2225 *pcbFormat
= bytesNeeded
;
2226 SetLastError(ERROR_MORE_DATA
);
2231 LPWSTR str
= pbFormat
;
2233 *pcbFormat
= bytesNeeded
;
2234 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2236 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2237 usage
->rgpszUsageIdentifier
[i
],
2238 CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2243 lstrcpyW(str
, info
->pwszName
);
2244 str
+= lstrlenW(info
->pwszName
);
2248 lstrcpyW(str
, unknown
);
2249 str
+= lstrlenW(unknown
);
2253 for (oidPtr
= usage
->rgpszUsageIdentifier
[i
]; *oidPtr
; oidPtr
++)
2257 if (i
< usage
->cUsageIdentifier
- 1)
2260 str
+= sepLen
/ sizeof(WCHAR
);
2269 static struct BitToString netscapeCertTypeMap
[] = {
2270 { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_CLIENT
, { 0 } },
2271 { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_SERVER
, { 0 } },
2272 { NETSCAPE_SMIME_CERT_TYPE
, IDS_NETSCAPE_SMIME
, { 0 } },
2273 { NETSCAPE_SIGN_CERT_TYPE
, IDS_NETSCAPE_SIGN
, { 0 } },
2274 { NETSCAPE_SSL_CA_CERT_TYPE
, IDS_NETSCAPE_SSL_CA
, { 0 } },
2275 { NETSCAPE_SMIME_CA_CERT_TYPE
, IDS_NETSCAPE_SMIME_CA
, { 0 } },
2276 { NETSCAPE_SIGN_CA_CERT_TYPE
, IDS_NETSCAPE_SIGN_CA
, { 0 } },
2279 static BOOL WINAPI
CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType
,
2280 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2281 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2285 CRYPT_BIT_BLOB
*bits
;
2290 SetLastError(E_INVALIDARG
);
2293 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BITS
,
2294 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
2296 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2297 DWORD bytesNeeded
= sizeof(WCHAR
);
2299 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2300 if (!bits
->cbData
|| bits
->cbData
> 1)
2302 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
2304 *pcbFormat
= bytesNeeded
;
2305 else if (*pcbFormat
< bytesNeeded
)
2307 *pcbFormat
= bytesNeeded
;
2308 SetLastError(ERROR_MORE_DATA
);
2313 LPWSTR str
= pbFormat
;
2315 *pcbFormat
= bytesNeeded
;
2316 lstrcpyW(str
, infoNotAvailable
);
2321 static BOOL stringsLoaded
= FALSE
;
2328 for (i
= 0; i
< ARRAY_SIZE(netscapeCertTypeMap
); 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
, ARRAY_SIZE(netscapeCertTypeMap
),
2334 NULL
, &bitStringLen
, &first
);
2335 bytesNeeded
+= bitStringLen
;
2336 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
2337 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2338 bits
->cbData
, NULL
, &size
);
2339 bytesNeeded
+= size
;
2341 *pcbFormat
= bytesNeeded
;
2342 else if (*pcbFormat
< bytesNeeded
)
2344 *pcbFormat
= bytesNeeded
;
2345 SetLastError(ERROR_MORE_DATA
);
2350 LPWSTR str
= pbFormat
;
2352 bitStringLen
= bytesNeeded
;
2354 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
, ARRAY_SIZE(netscapeCertTypeMap
),
2355 str
, &bitStringLen
, &first
);
2356 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
2359 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2360 bits
->cbData
, str
, &size
);
2361 str
+= size
/ sizeof(WCHAR
) - 1;
2371 static WCHAR financialCriteria
[MAX_STRING_RESOURCE_LEN
];
2372 static WCHAR available
[MAX_STRING_RESOURCE_LEN
];
2373 static WCHAR notAvailable
[MAX_STRING_RESOURCE_LEN
];
2374 static WCHAR meetsCriteria
[MAX_STRING_RESOURCE_LEN
];
2375 static WCHAR yes
[MAX_STRING_RESOURCE_LEN
];
2376 static WCHAR no
[MAX_STRING_RESOURCE_LEN
];
2378 static BOOL WINAPI
CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType
,
2379 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2380 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2383 SPC_FINANCIAL_CRITERIA criteria
;
2384 DWORD size
= sizeof(criteria
);
2389 SetLastError(E_INVALIDARG
);
2392 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
2393 SPC_FINANCIAL_CRITERIA_STRUCT
, pbEncoded
, cbEncoded
, 0, NULL
, &criteria
,
2396 static BOOL stringsLoaded
= FALSE
;
2397 DWORD bytesNeeded
= sizeof(WCHAR
);
2403 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA
, financialCriteria
, ARRAY_SIZE(financialCriteria
));
2404 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_AVAILABLE
, available
, ARRAY_SIZE(available
));
2405 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE
, notAvailable
, ARRAY_SIZE(notAvailable
));
2406 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA
, meetsCriteria
, ARRAY_SIZE(meetsCriteria
));
2407 LoadStringW(hInstance
, IDS_YES
, yes
, ARRAY_SIZE(yes
));
2408 LoadStringW(hInstance
, IDS_NO
, no
, ARRAY_SIZE(no
));
2409 stringsLoaded
= TRUE
;
2411 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2414 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
2419 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
2421 bytesNeeded
+= lstrlenW(financialCriteria
) * sizeof(WCHAR
);
2422 if (criteria
.fFinancialInfoAvailable
)
2424 bytesNeeded
+= lstrlenW(available
) * sizeof(WCHAR
);
2425 bytesNeeded
+= sepLen
;
2426 bytesNeeded
+= lstrlenW(meetsCriteria
) * sizeof(WCHAR
);
2427 if (criteria
.fMeetsCriteria
)
2428 bytesNeeded
+= lstrlenW(yes
) * sizeof(WCHAR
);
2430 bytesNeeded
+= lstrlenW(no
) * sizeof(WCHAR
);
2433 bytesNeeded
+= lstrlenW(notAvailable
) * sizeof(WCHAR
);
2435 *pcbFormat
= bytesNeeded
;
2436 else if (*pcbFormat
< bytesNeeded
)
2438 *pcbFormat
= bytesNeeded
;
2439 SetLastError(ERROR_MORE_DATA
);
2444 LPWSTR str
= pbFormat
;
2446 *pcbFormat
= bytesNeeded
;
2447 lstrcpyW(str
, financialCriteria
);
2448 str
+= lstrlenW(financialCriteria
);
2449 if (criteria
.fFinancialInfoAvailable
)
2451 lstrcpyW(str
, available
);
2452 str
+= lstrlenW(available
);
2454 str
+= sepLen
/ sizeof(WCHAR
);
2455 lstrcpyW(str
, meetsCriteria
);
2456 str
+= lstrlenW(meetsCriteria
);
2457 if (criteria
.fMeetsCriteria
)
2464 lstrcpyW(str
, notAvailable
);
2471 static BOOL WINAPI
CRYPT_FormatUnicodeString(DWORD dwCertEncodingType
,
2472 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2473 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2476 CERT_NAME_VALUE
*value
;
2482 SetLastError(E_INVALIDARG
);
2485 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_UNICODE_ANY_STRING
,
2486 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &value
, &size
)))
2489 *pcbFormat
= value
->Value
.cbData
;
2490 else if (*pcbFormat
< value
->Value
.cbData
)
2492 *pcbFormat
= value
->Value
.cbData
;
2493 SetLastError(ERROR_MORE_DATA
);
2498 LPWSTR str
= pbFormat
;
2500 *pcbFormat
= value
->Value
.cbData
;
2501 lstrcpyW(str
, (LPWSTR
)value
->Value
.pbData
);
2507 typedef BOOL (WINAPI
*CryptFormatObjectFunc
)(DWORD
, DWORD
, DWORD
, void *,
2508 LPCSTR
, const BYTE
*, DWORD
, void *, DWORD
*);
2510 static CryptFormatObjectFunc
CRYPT_GetBuiltinFormatFunction(DWORD encodingType
,
2511 DWORD formatStrType
, LPCSTR lpszStructType
)
2513 CryptFormatObjectFunc format
= NULL
;
2515 if ((encodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
)
2517 SetLastError(ERROR_FILE_NOT_FOUND
);
2520 if (IS_INTOID(lpszStructType
))
2522 switch (LOWORD(lpszStructType
))
2524 case LOWORD(X509_KEY_USAGE
):
2525 format
= CRYPT_FormatKeyUsage
;
2527 case LOWORD(X509_ALTERNATE_NAME
):
2528 format
= CRYPT_FormatAltName
;
2530 case LOWORD(X509_BASIC_CONSTRAINTS2
):
2531 format
= CRYPT_FormatBasicConstraints2
;
2533 case LOWORD(X509_AUTHORITY_KEY_ID2
):
2534 format
= CRYPT_FormatAuthorityKeyId2
;
2536 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
2537 format
= CRYPT_FormatAuthorityInfoAccess
;
2539 case LOWORD(X509_CRL_DIST_POINTS
):
2540 format
= CRYPT_FormatCRLDistPoints
;
2542 case LOWORD(X509_ENHANCED_KEY_USAGE
):
2543 format
= CRYPT_FormatEnhancedKeyUsage
;
2545 case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT
):
2546 format
= CRYPT_FormatSpcFinancialCriteria
;
2550 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
2551 format
= CRYPT_FormatAltName
;
2552 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
2553 format
= CRYPT_FormatAltName
;
2554 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
2555 format
= CRYPT_FormatKeyUsage
;
2556 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
2557 format
= CRYPT_FormatAltName
;
2558 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
2559 format
= CRYPT_FormatAltName
;
2560 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
2561 format
= CRYPT_FormatBasicConstraints2
;
2562 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
2563 format
= CRYPT_FormatAuthorityInfoAccess
;
2564 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
2565 format
= CRYPT_FormatAuthorityKeyId2
;
2566 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
2567 format
= CRYPT_FormatCRLDistPoints
;
2568 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
2569 format
= CRYPT_FormatEnhancedKeyUsage
;
2570 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_CERT_TYPE
))
2571 format
= CRYPT_FormatNetscapeCertType
;
2572 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_BASE_URL
) ||
2573 !strcmp(lpszStructType
, szOID_NETSCAPE_REVOCATION_URL
) ||
2574 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_REVOCATION_URL
) ||
2575 !strcmp(lpszStructType
, szOID_NETSCAPE_CERT_RENEWAL_URL
) ||
2576 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_POLICY_URL
) ||
2577 !strcmp(lpszStructType
, szOID_NETSCAPE_SSL_SERVER_NAME
) ||
2578 !strcmp(lpszStructType
, szOID_NETSCAPE_COMMENT
))
2579 format
= CRYPT_FormatUnicodeString
;
2580 else if (!strcmp(lpszStructType
, SPC_FINANCIAL_CRITERIA_OBJID
))
2581 format
= CRYPT_FormatSpcFinancialCriteria
;
2585 BOOL WINAPI
CryptFormatObject(DWORD dwCertEncodingType
, DWORD dwFormatType
,
2586 DWORD dwFormatStrType
, void *pFormatStruct
, LPCSTR lpszStructType
,
2587 const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
, DWORD
*pcbFormat
)
2589 CryptFormatObjectFunc format
= NULL
;
2590 HCRYPTOIDFUNCADDR hFunc
= NULL
;
2593 TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType
,
2594 dwFormatType
, dwFormatStrType
, pFormatStruct
, debugstr_a(lpszStructType
),
2595 pbEncoded
, cbEncoded
, pbFormat
, pcbFormat
);
2597 if (!(format
= CRYPT_GetBuiltinFormatFunction(dwCertEncodingType
,
2598 dwFormatStrType
, lpszStructType
)))
2600 static HCRYPTOIDFUNCSET set
= NULL
;
2603 set
= CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC
, 0);
2604 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
2605 (void **)&format
, &hFunc
);
2607 if (!format
&& (dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) ==
2608 X509_ASN_ENCODING
&& !(dwFormatStrType
& CRYPT_FORMAT_STR_NO_HEX
))
2609 format
= CRYPT_FormatHexString
;
2611 ret
= format(dwCertEncodingType
, dwFormatType
, dwFormatStrType
,
2612 pFormatStruct
, lpszStructType
, pbEncoded
, cbEncoded
, pbFormat
,
2615 CryptFreeOIDFunctionAddress(hFunc
, 0);