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
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("(%ld, %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 %ld\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("(%ld, %p, %08lx, %08lx, %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_BLOB
)
634 WCHAR temp_path
[MAX_PATH
], temp_name
[MAX_PATH
];
635 const CERT_BLOB
*b
= pvObject
;
637 TRACE("cbData %lu, pbData %p.\n", b
->cbData
, b
->pbData
);
639 if (!GetTempPathW(MAX_PATH
, temp_path
) || !GetTempFileNameW(temp_path
, L
"blb", 0, temp_name
))
641 ERR("Failed getting temp file name.\n");
644 file
= CreateFileW(temp_name
, GENERIC_READ
| GENERIC_WRITE
, 0,
645 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_DELETE_ON_CLOSE
, NULL
);
646 if (file
== INVALID_HANDLE_VALUE
)
648 ERR("Could not create temp file.\n");
649 SetLastError(ERROR_OUTOFMEMORY
);
652 if (!WriteFile(file
, b
->pbData
, b
->cbData
, NULL
, NULL
))
655 ERR("Could not write temp file.\n");
656 SetLastError(ERROR_OUTOFMEMORY
);
660 else if (dwObjectType
== CERT_QUERY_OBJECT_FILE
)
662 file
= CreateFileW(pvObject
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
666 WARN("Unknown dwObjectType %lu.\n", dwObjectType
);
667 SetLastError(E_INVALIDARG
);
671 if (file
!= INVALID_HANDLE_VALUE
)
673 ret
= CryptSIPRetrieveSubjectGuid(pvObject
, file
, &subject
);
676 SIP_DISPATCH_INFO sip
;
678 memset(&sip
, 0, sizeof(sip
));
679 sip
.cbSize
= sizeof(sip
);
680 ret
= CryptSIPLoad(&subject
, 0, &sip
);
683 SIP_SUBJECTINFO subjectInfo
;
687 memset(&subjectInfo
, 0, sizeof(subjectInfo
));
688 subjectInfo
.cbSize
= sizeof(subjectInfo
);
689 subjectInfo
.pgSubjectType
= &subject
;
690 subjectInfo
.hFile
= file
;
691 subjectInfo
.pwsFileName
= pvObject
;
692 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0, &blob
.cbData
,
696 blob
.pbData
= CryptMemAlloc(blob
.cbData
);
699 ret
= sip
.pfGet(&subjectInfo
, &encodingType
, 0,
700 &blob
.cbData
, blob
.pbData
);
703 ret
= CRYPT_QueryMessageObject(
704 CERT_QUERY_OBJECT_BLOB
, &blob
,
705 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
,
706 CERT_QUERY_FORMAT_FLAG_BINARY
,
707 pdwMsgAndCertEncodingType
, NULL
, NULL
,
709 if (ret
&& pdwContentType
)
710 *pdwContentType
= CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
;
712 CryptMemFree(blob
.pbData
);
716 SetLastError(ERROR_OUTOFMEMORY
);
724 TRACE("returning %d\n", ret
);
728 static BOOL
CRYPT_QueryPFXObject(DWORD dwObjectType
, const void *pvObject
,
729 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
730 DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
, DWORD
*pdwFormatType
,
731 HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
)
733 CRYPT_DATA_BLOB blob
= {0}, *ptr
;
736 TRACE("(%ld, %p, %08lx, %08lx, %p, %p, %p, %p, %p)\n", dwObjectType
, pvObject
,
737 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
738 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
741 switch (dwObjectType
)
743 case CERT_QUERY_OBJECT_FILE
:
744 if (!CRYPT_ReadBlobFromFile(pvObject
, &blob
)) return FALSE
;
748 case CERT_QUERY_OBJECT_BLOB
:
749 ptr
= (CRYPT_DATA_BLOB
*)pvObject
;
756 ret
= PFXIsPFXBlob(ptr
);
759 if (pdwMsgAndCertEncodingType
) *pdwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
760 if (pdwContentType
) *pdwContentType
= CERT_QUERY_CONTENT_PFX
;
761 if (pdwFormatType
) *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
762 if (phCertStore
) *phCertStore
= NULL
;
763 if (phMsg
) *phMsg
= NULL
;
766 CryptMemFree(blob
.pbData
);
770 BOOL WINAPI
CryptQueryObject(DWORD dwObjectType
, const void *pvObject
,
771 DWORD dwExpectedContentTypeFlags
, DWORD dwExpectedFormatTypeFlags
,
772 DWORD dwFlags
, DWORD
*pdwMsgAndCertEncodingType
, DWORD
*pdwContentType
,
773 DWORD
*pdwFormatType
, HCERTSTORE
*phCertStore
, HCRYPTMSG
*phMsg
,
774 const void **ppvContext
)
776 static const DWORD unimplementedTypes
=
777 CERT_QUERY_CONTENT_FLAG_PKCS10
| CERT_QUERY_CONTENT_FLAG_CERT_PAIR
;
780 TRACE("(%08lx, %p, %08lx, %08lx, %08lx, %p, %p, %p, %p, %p, %p)\n",
781 dwObjectType
, pvObject
, dwExpectedContentTypeFlags
,
782 dwExpectedFormatTypeFlags
, dwFlags
, pdwMsgAndCertEncodingType
,
783 pdwContentType
, pdwFormatType
, phCertStore
, phMsg
, ppvContext
);
785 if (dwObjectType
!= CERT_QUERY_OBJECT_BLOB
&&
786 dwObjectType
!= CERT_QUERY_OBJECT_FILE
)
788 WARN("unsupported type %ld\n", dwObjectType
);
789 SetLastError(E_INVALIDARG
);
794 WARN("missing required argument\n");
795 SetLastError(E_INVALIDARG
);
798 if (dwExpectedContentTypeFlags
& unimplementedTypes
)
799 WARN("unimplemented for types %08lx\n",
800 dwExpectedContentTypeFlags
& unimplementedTypes
);
803 *pdwFormatType
= CERT_QUERY_FORMAT_BINARY
;
812 if ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CERT
) ||
813 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CRL
) ||
814 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_CTL
))
816 ret
= CRYPT_QueryContextObject(dwObjectType
, pvObject
,
817 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
818 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
, phCertStore
,
822 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE
))
824 ret
= CRYPT_QuerySerializedStoreObject(dwObjectType
, pvObject
,
825 pdwMsgAndCertEncodingType
, pdwContentType
, phCertStore
, phMsg
);
828 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT
) ||
829 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL
) ||
830 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL
)))
832 ret
= CRYPT_QuerySerializedContextObject(dwObjectType
, pvObject
,
833 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
834 phCertStore
, ppvContext
);
837 ((dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
) ||
838 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED
)))
840 ret
= CRYPT_QueryMessageObject(dwObjectType
, pvObject
,
841 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
842 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
846 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED
))
848 ret
= CRYPT_QueryEmbeddedMessageObject(dwObjectType
, pvObject
,
849 dwExpectedContentTypeFlags
, pdwMsgAndCertEncodingType
, pdwContentType
,
853 (dwExpectedContentTypeFlags
& CERT_QUERY_CONTENT_FLAG_PFX
))
855 ret
= CRYPT_QueryPFXObject(dwObjectType
, pvObject
,
856 dwExpectedContentTypeFlags
, dwExpectedFormatTypeFlags
,
857 pdwMsgAndCertEncodingType
, pdwContentType
, pdwFormatType
,
861 SetLastError(CRYPT_E_NO_MATCH
);
862 TRACE("returning %d\n", ret
);
866 static BOOL WINAPI
CRYPT_FormatHexString(DWORD dwCertEncodingType
,
867 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
868 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
875 bytesNeeded
= (cbEncoded
* 3) * sizeof(WCHAR
);
877 bytesNeeded
= sizeof(WCHAR
);
880 *pcbFormat
= bytesNeeded
;
883 else if (*pcbFormat
< bytesNeeded
)
885 *pcbFormat
= bytesNeeded
;
886 SetLastError(ERROR_MORE_DATA
);
892 LPWSTR ptr
= pbFormat
;
894 *pcbFormat
= bytesNeeded
;
897 for (i
= 0; i
< cbEncoded
; i
++)
899 if (i
< cbEncoded
- 1)
900 ptr
+= swprintf(ptr
, 4, L
"%02x ", pbEncoded
[i
]);
902 ptr
+= swprintf(ptr
, 3, L
"%02x", pbEncoded
[i
]);
912 #define MAX_STRING_RESOURCE_LEN 128
914 static const WCHAR commaSpace
[] = L
", ";
920 WCHAR str
[MAX_STRING_RESOURCE_LEN
];
923 static BOOL
CRYPT_FormatBits(BYTE bits
, const struct BitToString
*map
,
924 DWORD mapEntries
, void *pbFormat
, DWORD
*pcbFormat
, BOOL
*first
)
926 DWORD bytesNeeded
= sizeof(WCHAR
);
928 BOOL ret
= TRUE
, localFirst
= *first
;
930 for (i
= 0; i
< mapEntries
; i
++)
931 if (bits
& map
[i
].bit
)
934 bytesNeeded
+= lstrlenW(commaSpace
) * sizeof(WCHAR
);
936 bytesNeeded
+= lstrlenW(map
[i
].str
) * sizeof(WCHAR
);
941 *pcbFormat
= bytesNeeded
;
943 else if (*pcbFormat
< bytesNeeded
)
946 *pcbFormat
= bytesNeeded
;
947 SetLastError(ERROR_MORE_DATA
);
952 LPWSTR str
= pbFormat
;
955 *pcbFormat
= bytesNeeded
;
956 for (i
= 0; i
< mapEntries
; i
++)
957 if (bits
& map
[i
].bit
)
961 lstrcpyW(str
, commaSpace
);
962 str
+= lstrlenW(commaSpace
);
965 lstrcpyW(str
, map
[i
].str
);
966 str
+= lstrlenW(map
[i
].str
);
973 static struct BitToString keyUsageByte0Map
[] = {
974 { CERT_DIGITAL_SIGNATURE_KEY_USAGE
, IDS_DIGITAL_SIGNATURE
, { 0 } },
975 { CERT_NON_REPUDIATION_KEY_USAGE
, IDS_NON_REPUDIATION
, { 0 } },
976 { CERT_KEY_ENCIPHERMENT_KEY_USAGE
, IDS_KEY_ENCIPHERMENT
, { 0 } },
977 { CERT_DATA_ENCIPHERMENT_KEY_USAGE
, IDS_DATA_ENCIPHERMENT
, { 0 } },
978 { CERT_KEY_AGREEMENT_KEY_USAGE
, IDS_KEY_AGREEMENT
, { 0 } },
979 { CERT_KEY_CERT_SIGN_KEY_USAGE
, IDS_CERT_SIGN
, { 0 } },
980 { CERT_OFFLINE_CRL_SIGN_KEY_USAGE
, IDS_OFFLINE_CRL_SIGN
, { 0 } },
981 { CERT_CRL_SIGN_KEY_USAGE
, IDS_CRL_SIGN
, { 0 } },
982 { CERT_ENCIPHER_ONLY_KEY_USAGE
, IDS_ENCIPHER_ONLY
, { 0 } },
984 static struct BitToString keyUsageByte1Map
[] = {
985 { CERT_DECIPHER_ONLY_KEY_USAGE
, IDS_DECIPHER_ONLY
, { 0 } },
988 static BOOL WINAPI
CRYPT_FormatKeyUsage(DWORD dwCertEncodingType
,
989 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
990 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
994 CRYPT_BIT_BLOB
*bits
;
999 SetLastError(E_INVALIDARG
);
1002 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_KEY_USAGE
,
1003 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
1005 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
1006 DWORD bytesNeeded
= sizeof(WCHAR
);
1008 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
1009 if (!bits
->cbData
|| bits
->cbData
> 2)
1011 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
1013 *pcbFormat
= bytesNeeded
;
1014 else if (*pcbFormat
< bytesNeeded
)
1016 *pcbFormat
= bytesNeeded
;
1017 SetLastError(ERROR_MORE_DATA
);
1022 LPWSTR str
= pbFormat
;
1024 *pcbFormat
= bytesNeeded
;
1025 lstrcpyW(str
, infoNotAvailable
);
1030 static BOOL stringsLoaded
= FALSE
;
1037 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte0Map
); i
++)
1038 LoadStringW(hInstance
, keyUsageByte0Map
[i
].id
, keyUsageByte0Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1039 for (i
= 0; i
< ARRAY_SIZE(keyUsageByte1Map
); i
++)
1040 LoadStringW(hInstance
, keyUsageByte1Map
[i
].id
, keyUsageByte1Map
[i
].str
, MAX_STRING_RESOURCE_LEN
);
1041 stringsLoaded
= TRUE
;
1043 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1044 NULL
, &bitStringLen
, &first
);
1045 bytesNeeded
+= bitStringLen
;
1046 if (bits
->cbData
== 2)
1048 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1049 NULL
, &bitStringLen
, &first
);
1050 bytesNeeded
+= bitStringLen
;
1052 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
1053 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1054 bits
->cbData
, NULL
, &size
);
1055 bytesNeeded
+= size
;
1057 *pcbFormat
= bytesNeeded
;
1058 else if (*pcbFormat
< bytesNeeded
)
1060 *pcbFormat
= bytesNeeded
;
1061 SetLastError(ERROR_MORE_DATA
);
1066 LPWSTR str
= pbFormat
;
1068 bitStringLen
= bytesNeeded
;
1070 CRYPT_FormatBits(bits
->pbData
[0], keyUsageByte0Map
, ARRAY_SIZE(keyUsageByte0Map
),
1071 str
, &bitStringLen
, &first
);
1072 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1073 if (bits
->cbData
== 2)
1075 bitStringLen
= bytesNeeded
;
1076 CRYPT_FormatBits(bits
->pbData
[1], keyUsageByte1Map
, ARRAY_SIZE(keyUsageByte1Map
),
1077 str
, &bitStringLen
, &first
);
1078 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
1082 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
1083 bits
->cbData
, str
, &size
);
1084 str
+= size
/ sizeof(WCHAR
) - 1;
1094 static const WCHAR crlf
[] = L
"\r\n";
1096 static WCHAR subjectTypeHeader
[MAX_STRING_RESOURCE_LEN
];
1097 static WCHAR subjectTypeCA
[MAX_STRING_RESOURCE_LEN
];
1098 static WCHAR subjectTypeEndCert
[MAX_STRING_RESOURCE_LEN
];
1099 static WCHAR pathLengthHeader
[MAX_STRING_RESOURCE_LEN
];
1101 static BOOL WINAPI
CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType
,
1102 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1103 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1107 CERT_BASIC_CONSTRAINTS2_INFO
*info
;
1112 SetLastError(E_INVALIDARG
);
1115 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BASIC_CONSTRAINTS2
,
1116 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1118 static BOOL stringsLoaded
= FALSE
;
1119 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1120 WCHAR pathLength
[MAX_STRING_RESOURCE_LEN
];
1121 LPCWSTR sep
, subjectType
;
1124 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1127 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1132 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1137 LoadStringW(hInstance
, IDS_SUBJECT_TYPE
, subjectTypeHeader
, ARRAY_SIZE(subjectTypeHeader
));
1138 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_CA
, subjectTypeCA
, ARRAY_SIZE(subjectTypeCA
));
1139 LoadStringW(hInstance
, IDS_SUBJECT_TYPE_END_CERT
, subjectTypeEndCert
, ARRAY_SIZE(subjectTypeEndCert
));
1140 LoadStringW(hInstance
, IDS_PATH_LENGTH
, pathLengthHeader
, ARRAY_SIZE(pathLengthHeader
));
1141 stringsLoaded
= TRUE
;
1143 bytesNeeded
+= lstrlenW(subjectTypeHeader
) * sizeof(WCHAR
);
1145 subjectType
= subjectTypeCA
;
1147 subjectType
= subjectTypeEndCert
;
1148 bytesNeeded
+= lstrlenW(subjectType
) * sizeof(WCHAR
);
1149 bytesNeeded
+= sepLen
;
1150 bytesNeeded
+= lstrlenW(pathLengthHeader
) * sizeof(WCHAR
);
1151 if (info
->fPathLenConstraint
)
1152 swprintf(pathLength
, ARRAY_SIZE(pathLength
), L
"%d", info
->dwPathLenConstraint
);
1154 LoadStringW(hInstance
, IDS_PATH_LENGTH_NONE
, pathLength
, ARRAY_SIZE(pathLength
));
1155 bytesNeeded
+= lstrlenW(pathLength
) * sizeof(WCHAR
);
1157 *pcbFormat
= bytesNeeded
;
1158 else if (*pcbFormat
< bytesNeeded
)
1160 *pcbFormat
= bytesNeeded
;
1161 SetLastError(ERROR_MORE_DATA
);
1166 LPWSTR str
= pbFormat
;
1168 *pcbFormat
= bytesNeeded
;
1169 lstrcpyW(str
, subjectTypeHeader
);
1170 str
+= lstrlenW(subjectTypeHeader
);
1171 lstrcpyW(str
, subjectType
);
1172 str
+= lstrlenW(subjectType
);
1174 str
+= sepLen
/ sizeof(WCHAR
);
1175 lstrcpyW(str
, pathLengthHeader
);
1176 str
+= lstrlenW(pathLengthHeader
);
1177 lstrcpyW(str
, pathLength
);
1184 static BOOL
CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB
*blob
, int id
,
1185 LPWSTR str
, DWORD
*pcbStr
)
1187 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1191 LoadStringW(hInstance
, id
, buf
, ARRAY_SIZE(buf
));
1192 CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1193 blob
->pbData
, blob
->cbData
, NULL
, &bytesNeeded
);
1194 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1197 *pcbStr
= bytesNeeded
;
1200 else if (*pcbStr
< bytesNeeded
)
1202 *pcbStr
= bytesNeeded
;
1203 SetLastError(ERROR_MORE_DATA
);
1208 *pcbStr
= bytesNeeded
;
1210 str
+= lstrlenW(str
);
1211 bytesNeeded
-= lstrlenW(str
) * sizeof(WCHAR
);
1212 ret
= CRYPT_FormatHexString(X509_ASN_ENCODING
, 0, 0, NULL
, NULL
,
1213 blob
->pbData
, blob
->cbData
, str
, &bytesNeeded
);
1218 static BOOL
CRYPT_FormatKeyId(const CRYPT_DATA_BLOB
*keyId
, LPWSTR str
,
1221 return CRYPT_FormatHexStringWithPrefix(keyId
, IDS_KEY_ID
, str
, pcbStr
);
1224 static BOOL
CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB
*serialNum
, LPWSTR str
,
1227 return CRYPT_FormatHexStringWithPrefix(serialNum
, IDS_CERT_SERIAL_NUMBER
,
1231 static const WCHAR indent
[] = L
" ";
1232 static const WCHAR colonCrlf
[] = L
":\r\n";
1234 static BOOL
CRYPT_FormatAltNameEntry(DWORD dwFormatStrType
, DWORD indentLevel
,
1235 const CERT_ALT_NAME_ENTRY
*entry
, LPWSTR str
, DWORD
*pcbStr
)
1238 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1239 WCHAR mask
[MAX_STRING_RESOURCE_LEN
];
1240 WCHAR ipAddrBuf
[32];
1242 DWORD bytesNeeded
= sizeof(WCHAR
);
1243 DWORD strType
= CERT_X500_NAME_STR
| CERT_NAME_STR_REVERSE_FLAG
;
1245 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1246 bytesNeeded
+= indentLevel
* lstrlenW(indent
) * sizeof(WCHAR
);
1247 switch (entry
->dwAltNameChoice
)
1249 case CERT_ALT_NAME_RFC822_NAME
:
1250 LoadStringW(hInstance
, IDS_ALT_NAME_RFC822_NAME
, buf
, ARRAY_SIZE(buf
));
1251 bytesNeeded
+= lstrlenW(entry
->pwszRfc822Name
) * sizeof(WCHAR
);
1254 case CERT_ALT_NAME_DNS_NAME
:
1255 LoadStringW(hInstance
, IDS_ALT_NAME_DNS_NAME
, buf
, ARRAY_SIZE(buf
));
1256 bytesNeeded
+= lstrlenW(entry
->pwszDNSName
) * sizeof(WCHAR
);
1259 case CERT_ALT_NAME_DIRECTORY_NAME
:
1261 DWORD directoryNameLen
;
1263 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1264 strType
|= CERT_NAME_STR_CRLF_FLAG
;
1265 directoryNameLen
= cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1266 indentLevel
+ 1, &entry
->DirectoryName
, strType
, NULL
, 0);
1267 LoadStringW(hInstance
, IDS_ALT_NAME_DIRECTORY_NAME
, buf
, ARRAY_SIZE(buf
));
1268 bytesNeeded
+= (directoryNameLen
- 1) * sizeof(WCHAR
);
1269 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1270 bytesNeeded
+= lstrlenW(colonCrlf
) * sizeof(WCHAR
);
1272 bytesNeeded
+= sizeof(WCHAR
); /* '=' */
1276 case CERT_ALT_NAME_URL
:
1277 LoadStringW(hInstance
, IDS_ALT_NAME_URL
, buf
, ARRAY_SIZE(buf
));
1278 bytesNeeded
+= lstrlenW(entry
->pwszURL
) * sizeof(WCHAR
);
1281 case CERT_ALT_NAME_IP_ADDRESS
:
1283 LoadStringW(hInstance
, IDS_ALT_NAME_IP_ADDRESS
, buf
, ARRAY_SIZE(buf
));
1284 if (entry
->IPAddress
.cbData
== 8)
1286 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1288 LoadStringW(hInstance
, IDS_ALT_NAME_MASK
, mask
, ARRAY_SIZE(mask
));
1289 bytesNeeded
+= lstrlenW(mask
) * sizeof(WCHAR
);
1290 swprintf(ipAddrBuf
, ARRAY_SIZE(ipAddrBuf
), L
"%d.%d.%d.%d",
1291 entry
->IPAddress
.pbData
[0],
1292 entry
->IPAddress
.pbData
[1],
1293 entry
->IPAddress
.pbData
[2],
1294 entry
->IPAddress
.pbData
[3]);
1295 bytesNeeded
+= lstrlenW(ipAddrBuf
) * sizeof(WCHAR
);
1296 /* indent again, for the mask line */
1297 bytesNeeded
+= indentLevel
* lstrlenW(indent
) * sizeof(WCHAR
);
1298 swprintf(maskBuf
, ARRAY_SIZE(maskBuf
), L
"%d.%d.%d.%d",
1299 entry
->IPAddress
.pbData
[4],
1300 entry
->IPAddress
.pbData
[5],
1301 entry
->IPAddress
.pbData
[6],
1302 entry
->IPAddress
.pbData
[7]);
1303 bytesNeeded
+= lstrlenW(maskBuf
) * sizeof(WCHAR
);
1304 bytesNeeded
+= lstrlenW(crlf
) * sizeof(WCHAR
);
1308 swprintf(ipAddrBuf
, ARRAY_SIZE(ipAddrBuf
), L
"%d.%d.%d.%d/%d.%d.%d.%d",
1309 entry
->IPAddress
.pbData
[0],
1310 entry
->IPAddress
.pbData
[1],
1311 entry
->IPAddress
.pbData
[2],
1312 entry
->IPAddress
.pbData
[3],
1313 entry
->IPAddress
.pbData
[4],
1314 entry
->IPAddress
.pbData
[5],
1315 entry
->IPAddress
.pbData
[6],
1316 entry
->IPAddress
.pbData
[7]);
1317 bytesNeeded
+= (lstrlenW(ipAddrBuf
) + 1) * sizeof(WCHAR
);
1323 FIXME("unknown IP address format (%ld bytes)\n",
1324 entry
->IPAddress
.cbData
);
1330 FIXME("unimplemented for %ld\n", entry
->dwAltNameChoice
);
1335 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1337 *pcbStr
= bytesNeeded
;
1338 else if (*pcbStr
< bytesNeeded
)
1340 *pcbStr
= bytesNeeded
;
1341 SetLastError(ERROR_MORE_DATA
);
1348 *pcbStr
= bytesNeeded
;
1349 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1351 for (i
= 0; i
< indentLevel
; i
++)
1353 lstrcpyW(str
, indent
);
1354 str
+= lstrlenW(indent
);
1358 str
+= lstrlenW(str
);
1359 switch (entry
->dwAltNameChoice
)
1361 case CERT_ALT_NAME_RFC822_NAME
:
1362 case CERT_ALT_NAME_DNS_NAME
:
1363 case CERT_ALT_NAME_URL
:
1364 lstrcpyW(str
, entry
->pwszURL
);
1366 case CERT_ALT_NAME_DIRECTORY_NAME
:
1367 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1369 lstrcpyW(str
, colonCrlf
);
1370 str
+= lstrlenW(colonCrlf
);
1374 cert_name_to_str_with_indent(X509_ASN_ENCODING
,
1375 indentLevel
+ 1, &entry
->DirectoryName
, strType
, str
,
1376 bytesNeeded
/ sizeof(WCHAR
));
1378 case CERT_ALT_NAME_IP_ADDRESS
:
1379 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1381 lstrcpyW(str
, ipAddrBuf
);
1382 str
+= lstrlenW(ipAddrBuf
);
1383 lstrcpyW(str
, crlf
);
1384 str
+= lstrlenW(crlf
);
1385 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1387 for (i
= 0; i
< indentLevel
; i
++)
1389 lstrcpyW(str
, indent
);
1390 str
+= lstrlenW(indent
);
1393 lstrcpyW(str
, mask
);
1394 str
+= lstrlenW(mask
);
1395 lstrcpyW(str
, maskBuf
);
1398 lstrcpyW(str
, ipAddrBuf
);
1406 static BOOL
CRYPT_FormatAltNameInfo(DWORD dwFormatStrType
, DWORD indentLevel
,
1407 const CERT_ALT_NAME_INFO
*name
, LPWSTR str
, DWORD
*pcbStr
)
1409 DWORD i
, size
, bytesNeeded
= 0;
1414 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1417 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1422 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1425 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1427 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1428 &name
->rgAltEntry
[i
], NULL
, &size
);
1431 bytesNeeded
+= size
- sizeof(WCHAR
);
1432 if (i
< name
->cAltEntry
- 1)
1433 bytesNeeded
+= sepLen
;
1438 bytesNeeded
+= sizeof(WCHAR
);
1440 *pcbStr
= bytesNeeded
;
1441 else if (*pcbStr
< bytesNeeded
)
1443 *pcbStr
= bytesNeeded
;
1444 SetLastError(ERROR_MORE_DATA
);
1449 *pcbStr
= bytesNeeded
;
1450 for (i
= 0; ret
&& i
< name
->cAltEntry
; i
++)
1452 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, indentLevel
,
1453 &name
->rgAltEntry
[i
], str
, &size
);
1456 str
+= size
/ sizeof(WCHAR
) - 1;
1457 if (i
< name
->cAltEntry
- 1)
1460 str
+= sepLen
/ sizeof(WCHAR
);
1469 static const WCHAR colonSep
[] = L
": ";
1471 static BOOL WINAPI
CRYPT_FormatAltName(DWORD dwCertEncodingType
,
1472 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1473 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1477 CERT_ALT_NAME_INFO
*info
;
1480 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ALTERNATE_NAME
,
1481 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1483 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 0, info
, pbFormat
, pcbFormat
);
1489 static BOOL
CRYPT_FormatCertIssuer(DWORD dwFormatStrType
,
1490 const CERT_ALT_NAME_INFO
*issuer
, LPWSTR str
, DWORD
*pcbStr
)
1492 WCHAR buf
[MAX_STRING_RESOURCE_LEN
];
1493 DWORD bytesNeeded
, sepLen
;
1497 LoadStringW(hInstance
, IDS_CERT_ISSUER
, buf
, ARRAY_SIZE(buf
));
1498 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, NULL
,
1500 bytesNeeded
+= lstrlenW(buf
) * sizeof(WCHAR
);
1501 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1504 sepLen
= lstrlenW(colonCrlf
) * sizeof(WCHAR
);
1509 sepLen
= lstrlenW(colonSep
) * sizeof(WCHAR
);
1511 bytesNeeded
+= sepLen
;
1515 *pcbStr
= bytesNeeded
;
1516 else if (*pcbStr
< bytesNeeded
)
1518 *pcbStr
= bytesNeeded
;
1519 SetLastError(ERROR_MORE_DATA
);
1524 *pcbStr
= bytesNeeded
;
1526 bytesNeeded
-= lstrlenW(str
) * sizeof(WCHAR
);
1527 str
+= lstrlenW(str
);
1529 str
+= sepLen
/ sizeof(WCHAR
);
1530 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 1, issuer
, str
,
1537 static BOOL WINAPI
CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType
,
1538 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1539 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1542 CERT_AUTHORITY_KEY_ID2_INFO
*info
;
1548 SetLastError(E_INVALIDARG
);
1551 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_AUTHORITY_KEY_ID2
,
1552 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1554 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
1557 BOOL needSeparator
= FALSE
;
1559 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1562 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
1567 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
1570 if (info
->KeyId
.cbData
)
1572 needSeparator
= TRUE
;
1573 ret
= CRYPT_FormatKeyId(&info
->KeyId
, NULL
, &size
);
1576 /* don't include NULL-terminator more than once */
1577 bytesNeeded
+= size
- sizeof(WCHAR
);
1580 if (info
->AuthorityCertIssuer
.cAltEntry
)
1583 bytesNeeded
+= sepLen
;
1584 needSeparator
= TRUE
;
1585 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1586 &info
->AuthorityCertIssuer
, NULL
, &size
);
1589 /* don't include NULL-terminator more than once */
1590 bytesNeeded
+= size
- sizeof(WCHAR
);
1593 if (info
->AuthorityCertSerialNumber
.cbData
)
1596 bytesNeeded
+= sepLen
;
1597 ret
= CRYPT_FormatCertSerialNumber(
1598 &info
->AuthorityCertSerialNumber
, NULL
, &size
);
1601 /* don't include NULL-terminator more than once */
1602 bytesNeeded
+= size
- sizeof(WCHAR
);
1608 *pcbFormat
= bytesNeeded
;
1609 else if (*pcbFormat
< bytesNeeded
)
1611 *pcbFormat
= bytesNeeded
;
1612 SetLastError(ERROR_MORE_DATA
);
1617 LPWSTR str
= pbFormat
;
1619 *pcbFormat
= bytesNeeded
;
1620 needSeparator
= FALSE
;
1621 if (info
->KeyId
.cbData
)
1623 needSeparator
= TRUE
;
1624 /* Overestimate size available, it's already been checked
1628 ret
= CRYPT_FormatKeyId(&info
->KeyId
, str
, &size
);
1630 str
+= size
/ sizeof(WCHAR
) - 1;
1632 if (info
->AuthorityCertIssuer
.cAltEntry
)
1637 str
+= sepLen
/ sizeof(WCHAR
);
1639 needSeparator
= TRUE
;
1640 /* Overestimate size available, it's already been checked
1644 ret
= CRYPT_FormatCertIssuer(dwFormatStrType
,
1645 &info
->AuthorityCertIssuer
, str
, &size
);
1647 str
+= size
/ sizeof(WCHAR
) - 1;
1649 if (info
->AuthorityCertSerialNumber
.cbData
)
1654 str
+= sepLen
/ sizeof(WCHAR
);
1656 /* Overestimate size available, it's already been checked
1660 ret
= CRYPT_FormatCertSerialNumber(
1661 &info
->AuthorityCertSerialNumber
, str
, &size
);
1670 static WCHAR aia
[MAX_STRING_RESOURCE_LEN
];
1671 static WCHAR accessMethod
[MAX_STRING_RESOURCE_LEN
];
1672 static WCHAR ocsp
[MAX_STRING_RESOURCE_LEN
];
1673 static WCHAR caIssuers
[MAX_STRING_RESOURCE_LEN
];
1674 static WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
1675 static WCHAR accessLocation
[MAX_STRING_RESOURCE_LEN
];
1677 static BOOL WINAPI
CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType
,
1678 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1679 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1682 CERT_AUTHORITY_INFO_ACCESS
*info
;
1688 SetLastError(E_INVALIDARG
);
1691 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
1692 X509_AUTHORITY_INFO_ACCESS
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
,
1693 NULL
, &info
, &size
)))
1695 DWORD bytesNeeded
= sizeof(WCHAR
);
1697 if (!info
->cAccDescr
)
1699 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
1701 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
1702 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
1704 *pcbFormat
= bytesNeeded
;
1705 else if (*pcbFormat
< bytesNeeded
)
1707 *pcbFormat
= bytesNeeded
;
1708 SetLastError(ERROR_MORE_DATA
);
1713 *pcbFormat
= bytesNeeded
;
1714 lstrcpyW(pbFormat
, infoNotAvailable
);
1719 static const WCHAR equal
[] = L
"=";
1720 static BOOL stringsLoaded
= FALSE
;
1722 LPCWSTR headingSep
, accessMethodSep
, locationSep
;
1723 WCHAR accessDescrNum
[11];
1727 LoadStringW(hInstance
, IDS_AIA
, aia
, ARRAY_SIZE(aia
));
1728 LoadStringW(hInstance
, IDS_ACCESS_METHOD
, accessMethod
, ARRAY_SIZE(accessMethod
));
1729 LoadStringW(hInstance
, IDS_ACCESS_METHOD_OCSP
, ocsp
, ARRAY_SIZE(ocsp
));
1730 LoadStringW(hInstance
, IDS_ACCESS_METHOD_CA_ISSUERS
, caIssuers
, ARRAY_SIZE(caIssuers
));
1731 LoadStringW(hInstance
, IDS_ACCESS_METHOD_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
1732 LoadStringW(hInstance
, IDS_ACCESS_LOCATION
, accessLocation
, ARRAY_SIZE(accessLocation
));
1733 stringsLoaded
= TRUE
;
1735 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1738 accessMethodSep
= crlf
;
1739 locationSep
= colonCrlf
;
1743 headingSep
= colonSep
;
1744 accessMethodSep
= commaSpace
;
1745 locationSep
= equal
;
1748 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1751 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
1752 swprintf(accessDescrNum
, ARRAY_SIZE(accessDescrNum
), L
"%d", i
+ 1);
1753 bytesNeeded
+= lstrlenW(accessDescrNum
) * sizeof(WCHAR
);
1754 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
1755 bytesNeeded
+= lstrlenW(aia
) * sizeof(WCHAR
);
1756 bytesNeeded
+= lstrlenW(headingSep
) * sizeof(WCHAR
);
1758 bytesNeeded
+= lstrlenW(accessMethod
) * sizeof(WCHAR
);
1759 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1760 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
1761 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1763 bytesNeeded
+= lstrlenW(ocsp
) * sizeof(WCHAR
);
1764 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1765 szOID_PKIX_CA_ISSUERS
))
1766 bytesNeeded
+= lstrlenW(caIssuers
) * sizeof(caIssuers
);
1768 bytesNeeded
+= lstrlenW(unknown
) * sizeof(WCHAR
);
1769 bytesNeeded
+= sizeof(WCHAR
); /* space */
1770 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
1771 bytesNeeded
+= strlen(info
->rgAccDescr
[i
].pszAccessMethod
)
1773 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
1774 /* Delimiter between access method and location */
1775 bytesNeeded
+= lstrlenW(accessMethodSep
) * sizeof(WCHAR
);
1776 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1777 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
1778 bytesNeeded
+= lstrlenW(accessLocation
) * sizeof(WCHAR
);
1779 bytesNeeded
+= lstrlenW(locationSep
) * sizeof(WCHAR
);
1780 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1781 &info
->rgAccDescr
[i
].AccessLocation
, NULL
, &size
);
1783 bytesNeeded
+= size
- sizeof(WCHAR
);
1784 /* Need extra delimiter between access method entries */
1785 if (i
< info
->cAccDescr
- 1)
1786 bytesNeeded
+= lstrlenW(accessMethodSep
) * sizeof(WCHAR
);
1791 *pcbFormat
= bytesNeeded
;
1792 else if (*pcbFormat
< bytesNeeded
)
1794 *pcbFormat
= bytesNeeded
;
1795 SetLastError(ERROR_MORE_DATA
);
1800 LPWSTR str
= pbFormat
;
1801 DWORD altNameEntrySize
;
1803 *pcbFormat
= bytesNeeded
;
1804 for (i
= 0; ret
&& i
< info
->cAccDescr
; i
++)
1809 swprintf(accessDescrNum
, ARRAY_SIZE(accessDescrNum
), L
"%d", i
+ 1);
1810 lstrcpyW(str
, accessDescrNum
);
1811 str
+= lstrlenW(accessDescrNum
);
1814 str
+= lstrlenW(aia
);
1815 lstrcpyW(str
, headingSep
);
1816 str
+= lstrlenW(headingSep
);
1817 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1819 lstrcpyW(str
, indent
);
1820 str
+= lstrlenW(indent
);
1822 lstrcpyW(str
, accessMethod
);
1823 str
+= lstrlenW(accessMethod
);
1824 if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1827 lstrcpyW(str
, ocsp
);
1828 str
+= lstrlenW(ocsp
);
1830 else if (!strcmp(info
->rgAccDescr
[i
].pszAccessMethod
,
1831 szOID_PKIX_CA_ISSUERS
))
1833 lstrcpyW(str
, caIssuers
);
1834 str
+= lstrlenW(caIssuers
);
1838 lstrcpyW(str
, unknown
);
1839 str
+= lstrlenW(unknown
);
1843 for (oidPtr
= info
->rgAccDescr
[i
].pszAccessMethod
;
1844 *oidPtr
; oidPtr
++, str
++)
1847 lstrcpyW(str
, accessMethodSep
);
1848 str
+= lstrlenW(accessMethodSep
);
1849 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
1851 lstrcpyW(str
, indent
);
1852 str
+= lstrlenW(indent
);
1854 lstrcpyW(str
, accessLocation
);
1855 str
+= lstrlenW(accessLocation
);
1856 lstrcpyW(str
, locationSep
);
1857 str
+= lstrlenW(locationSep
);
1858 /* This overestimates the size available, but that
1859 * won't matter since we checked earlier whether enough
1860 * space for the entire string was available.
1862 altNameEntrySize
= bytesNeeded
;
1863 ret
= CRYPT_FormatAltNameEntry(dwFormatStrType
, 2,
1864 &info
->rgAccDescr
[i
].AccessLocation
, str
,
1867 str
+= altNameEntrySize
/ sizeof(WCHAR
) - 1;
1868 if (i
< info
->cAccDescr
- 1)
1870 lstrcpyW(str
, accessMethodSep
);
1871 str
+= lstrlenW(accessMethodSep
);
1882 static WCHAR keyCompromise
[MAX_STRING_RESOURCE_LEN
];
1883 static WCHAR caCompromise
[MAX_STRING_RESOURCE_LEN
];
1884 static WCHAR affiliationChanged
[MAX_STRING_RESOURCE_LEN
];
1885 static WCHAR superseded
[MAX_STRING_RESOURCE_LEN
];
1886 static WCHAR operationCeased
[MAX_STRING_RESOURCE_LEN
];
1887 static WCHAR certificateHold
[MAX_STRING_RESOURCE_LEN
];
1889 struct reason_map_entry
1895 static struct reason_map_entry reason_map
[] = {
1896 { CRL_REASON_KEY_COMPROMISE_FLAG
, keyCompromise
, IDS_REASON_KEY_COMPROMISE
},
1897 { CRL_REASON_CA_COMPROMISE_FLAG
, caCompromise
, IDS_REASON_CA_COMPROMISE
},
1898 { CRL_REASON_AFFILIATION_CHANGED_FLAG
, affiliationChanged
,
1899 IDS_REASON_AFFILIATION_CHANGED
},
1900 { CRL_REASON_SUPERSEDED_FLAG
, superseded
, IDS_REASON_SUPERSEDED
},
1901 { CRL_REASON_CESSATION_OF_OPERATION_FLAG
, operationCeased
,
1902 IDS_REASON_CESSATION_OF_OPERATION
},
1903 { CRL_REASON_CERTIFICATE_HOLD_FLAG
, certificateHold
,
1904 IDS_REASON_CERTIFICATE_HOLD
},
1907 static BOOL
CRYPT_FormatReason(DWORD dwFormatStrType
,
1908 const CRYPT_BIT_BLOB
*reasonFlags
, LPWSTR str
, DWORD
*pcbStr
)
1910 static const WCHAR sep
[] = L
", ";
1911 static BOOL stringsLoaded
= FALSE
;
1912 unsigned int i
, numReasons
= 0;
1914 DWORD bytesNeeded
= sizeof(WCHAR
);
1919 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1920 LoadStringW(hInstance
, reason_map
[i
].id
, reason_map
[i
].reason
,
1921 MAX_STRING_RESOURCE_LEN
);
1922 stringsLoaded
= TRUE
;
1924 /* No need to check reasonFlags->cbData, we already know it's positive.
1925 * Ignore any other bytes, as they're for undefined bits.
1927 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1929 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1931 bytesNeeded
+= lstrlenW(reason_map
[i
].reason
) * sizeof(WCHAR
);
1933 bytesNeeded
+= lstrlenW(sep
) * sizeof(WCHAR
);
1936 swprintf(bits
, ARRAY_SIZE(bits
), L
" (%02x)", reasonFlags
->pbData
[0]);
1937 bytesNeeded
+= lstrlenW(bits
);
1939 *pcbStr
= bytesNeeded
;
1940 else if (*pcbStr
< bytesNeeded
)
1942 *pcbStr
= bytesNeeded
;
1943 SetLastError(ERROR_MORE_DATA
);
1948 *pcbStr
= bytesNeeded
;
1949 for (i
= 0; i
< ARRAY_SIZE(reason_map
); i
++)
1951 if (reasonFlags
->pbData
[0] & reason_map
[i
].reasonBit
)
1953 lstrcpyW(str
, reason_map
[i
].reason
);
1954 str
+= lstrlenW(reason_map
[i
].reason
);
1955 if (i
< ARRAY_SIZE(reason_map
) - 1 && numReasons
)
1958 str
+= lstrlenW(sep
);
1962 lstrcpyW(str
, bits
);
1967 static WCHAR crlDistPoint
[MAX_STRING_RESOURCE_LEN
];
1968 static WCHAR distPointName
[MAX_STRING_RESOURCE_LEN
];
1969 static WCHAR fullName
[MAX_STRING_RESOURCE_LEN
];
1970 static WCHAR rdnName
[MAX_STRING_RESOURCE_LEN
];
1971 static WCHAR reason
[MAX_STRING_RESOURCE_LEN
];
1972 static WCHAR issuer
[MAX_STRING_RESOURCE_LEN
];
1974 static BOOL WINAPI
CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType
,
1975 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
1976 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
1979 CRL_DIST_POINTS_INFO
*info
;
1985 SetLastError(E_INVALIDARG
);
1988 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_CRL_DIST_POINTS
,
1989 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
)))
1991 static const WCHAR colon
[] = L
":";
1992 static BOOL stringsLoaded
= FALSE
;
1993 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for NULL terminator */
1994 BOOL haveAnEntry
= FALSE
;
1995 LPCWSTR headingSep
, nameSep
;
1996 WCHAR distPointNum
[11];
2001 LoadStringW(hInstance
, IDS_CRL_DIST_POINT
, crlDistPoint
, ARRAY_SIZE(crlDistPoint
));
2002 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_NAME
, distPointName
, ARRAY_SIZE(distPointName
));
2003 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_FULL_NAME
, fullName
, ARRAY_SIZE(fullName
));
2004 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_RDN_NAME
, rdnName
, ARRAY_SIZE(rdnName
));
2005 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_REASON
, reason
, ARRAY_SIZE(reason
));
2006 LoadStringW(hInstance
, IDS_CRL_DIST_POINT_ISSUER
, issuer
, ARRAY_SIZE(issuer
));
2007 stringsLoaded
= TRUE
;
2009 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2012 nameSep
= colonCrlf
;
2016 headingSep
= colonSep
;
2020 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2022 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2024 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2025 CRL_DIST_POINT_NO_NAME
)
2027 bytesNeeded
+= lstrlenW(distPointName
) * sizeof(WCHAR
);
2028 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
2029 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2030 CRL_DIST_POINT_FULL_NAME
)
2031 bytesNeeded
+= lstrlenW(fullName
) * sizeof(WCHAR
);
2033 bytesNeeded
+= lstrlenW(rdnName
) * sizeof(WCHAR
);
2034 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
2035 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2036 bytesNeeded
+= 2 * lstrlenW(indent
) * sizeof(WCHAR
);
2037 /* The indent level (3) is higher than when used as the issuer,
2038 * because the name is subordinate to the name type (full vs.
2041 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2042 &distPoint
->DistPointName
.FullName
, NULL
, &size
);
2044 bytesNeeded
+= size
- sizeof(WCHAR
);
2047 else if (distPoint
->ReasonFlags
.cbData
)
2049 bytesNeeded
+= lstrlenW(reason
) * sizeof(WCHAR
);
2050 ret
= CRYPT_FormatReason(dwFormatStrType
,
2051 &distPoint
->ReasonFlags
, NULL
, &size
);
2053 bytesNeeded
+= size
- sizeof(WCHAR
);
2056 else if (distPoint
->CRLIssuer
.cAltEntry
)
2058 bytesNeeded
+= lstrlenW(issuer
) * sizeof(WCHAR
);
2059 bytesNeeded
+= lstrlenW(nameSep
) * sizeof(WCHAR
);
2060 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2061 &distPoint
->CRLIssuer
, NULL
, &size
);
2063 bytesNeeded
+= size
- sizeof(WCHAR
);
2068 bytesNeeded
+= sizeof(WCHAR
); /* left bracket */
2069 swprintf(distPointNum
, ARRAY_SIZE(distPointNum
), L
"%d", i
+ 1);
2070 bytesNeeded
+= lstrlenW(distPointNum
) * sizeof(WCHAR
);
2071 bytesNeeded
+= sizeof(WCHAR
); /* right bracket */
2072 bytesNeeded
+= lstrlenW(crlDistPoint
) * sizeof(WCHAR
);
2073 bytesNeeded
+= lstrlenW(headingSep
) * sizeof(WCHAR
);
2074 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2075 bytesNeeded
+= lstrlenW(indent
) * sizeof(WCHAR
);
2080 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2082 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2083 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
2085 *pcbFormat
= bytesNeeded
;
2086 else if (*pcbFormat
< bytesNeeded
)
2088 *pcbFormat
= bytesNeeded
;
2089 SetLastError(ERROR_MORE_DATA
);
2094 *pcbFormat
= bytesNeeded
;
2095 lstrcpyW(pbFormat
, infoNotAvailable
);
2101 *pcbFormat
= bytesNeeded
;
2102 else if (*pcbFormat
< bytesNeeded
)
2104 *pcbFormat
= bytesNeeded
;
2105 SetLastError(ERROR_MORE_DATA
);
2110 LPWSTR str
= pbFormat
;
2112 *pcbFormat
= bytesNeeded
;
2113 for (i
= 0; ret
&& i
< info
->cDistPoint
; i
++)
2115 CRL_DIST_POINT
*distPoint
= &info
->rgDistPoint
[i
];
2118 swprintf(distPointNum
, ARRAY_SIZE(distPointNum
), L
"%d", i
+ 1);
2119 lstrcpyW(str
, distPointNum
);
2120 str
+= lstrlenW(distPointNum
);
2122 lstrcpyW(str
, crlDistPoint
);
2123 str
+= lstrlenW(crlDistPoint
);
2124 lstrcpyW(str
, headingSep
);
2125 str
+= lstrlenW(headingSep
);
2126 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2128 lstrcpyW(str
, indent
);
2129 str
+= lstrlenW(indent
);
2131 if (distPoint
->DistPointName
.dwDistPointNameChoice
!=
2132 CRL_DIST_POINT_NO_NAME
)
2134 DWORD altNameSize
= bytesNeeded
;
2136 lstrcpyW(str
, distPointName
);
2137 str
+= lstrlenW(distPointName
);
2138 lstrcpyW(str
, nameSep
);
2139 str
+= lstrlenW(nameSep
);
2140 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2142 lstrcpyW(str
, indent
);
2143 str
+= lstrlenW(indent
);
2144 lstrcpyW(str
, indent
);
2145 str
+= lstrlenW(indent
);
2147 if (distPoint
->DistPointName
.dwDistPointNameChoice
==
2148 CRL_DIST_POINT_FULL_NAME
)
2150 lstrcpyW(str
, fullName
);
2151 str
+= lstrlenW(fullName
);
2155 lstrcpyW(str
, rdnName
);
2156 str
+= lstrlenW(rdnName
);
2158 lstrcpyW(str
, nameSep
);
2159 str
+= lstrlenW(nameSep
);
2160 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 3,
2161 &distPoint
->DistPointName
.FullName
, str
,
2164 str
+= altNameSize
/ sizeof(WCHAR
) - 1;
2166 else if (distPoint
->ReasonFlags
.cbData
)
2168 DWORD reasonSize
= bytesNeeded
;
2170 lstrcpyW(str
, reason
);
2171 str
+= lstrlenW(reason
);
2172 ret
= CRYPT_FormatReason(dwFormatStrType
,
2173 &distPoint
->ReasonFlags
, str
, &reasonSize
);
2175 str
+= reasonSize
/ sizeof(WCHAR
) - 1;
2177 else if (distPoint
->CRLIssuer
.cAltEntry
)
2179 DWORD crlIssuerSize
= bytesNeeded
;
2181 lstrcpyW(str
, issuer
);
2182 str
+= lstrlenW(issuer
);
2183 lstrcpyW(str
, nameSep
);
2184 str
+= lstrlenW(nameSep
);
2185 ret
= CRYPT_FormatAltNameInfo(dwFormatStrType
, 2,
2186 &distPoint
->CRLIssuer
, str
,
2189 str
+= crlIssuerSize
/ sizeof(WCHAR
) - 1;
2199 static BOOL WINAPI
CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType
,
2200 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2201 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2204 CERT_ENHKEY_USAGE
*usage
;
2210 SetLastError(E_INVALIDARG
);
2213 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_ENHANCED_KEY_USAGE
,
2214 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &usage
, &size
)))
2216 WCHAR unknown
[MAX_STRING_RESOURCE_LEN
];
2218 DWORD bytesNeeded
= sizeof(WCHAR
); /* space for the NULL terminator */
2222 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2225 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
2230 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
2233 LoadStringW(hInstance
, IDS_USAGE_UNKNOWN
, unknown
, ARRAY_SIZE(unknown
));
2234 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2236 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2237 usage
->rgpszUsageIdentifier
[i
], CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2240 bytesNeeded
+= lstrlenW(info
->pwszName
) * sizeof(WCHAR
);
2242 bytesNeeded
+= lstrlenW(unknown
) * sizeof(WCHAR
);
2243 bytesNeeded
+= sizeof(WCHAR
); /* space */
2244 bytesNeeded
+= sizeof(WCHAR
); /* left paren */
2245 bytesNeeded
+= strlen(usage
->rgpszUsageIdentifier
[i
]) *
2247 bytesNeeded
+= sizeof(WCHAR
); /* right paren */
2248 if (i
< usage
->cUsageIdentifier
- 1)
2249 bytesNeeded
+= sepLen
;
2252 *pcbFormat
= bytesNeeded
;
2253 else if (*pcbFormat
< bytesNeeded
)
2255 *pcbFormat
= bytesNeeded
;
2256 SetLastError(ERROR_MORE_DATA
);
2261 LPWSTR str
= pbFormat
;
2263 *pcbFormat
= bytesNeeded
;
2264 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
2266 PCCRYPT_OID_INFO info
= CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY
,
2267 usage
->rgpszUsageIdentifier
[i
],
2268 CRYPT_ENHKEY_USAGE_OID_GROUP_ID
);
2273 lstrcpyW(str
, info
->pwszName
);
2274 str
+= lstrlenW(info
->pwszName
);
2278 lstrcpyW(str
, unknown
);
2279 str
+= lstrlenW(unknown
);
2283 for (oidPtr
= usage
->rgpszUsageIdentifier
[i
]; *oidPtr
; oidPtr
++)
2287 if (i
< usage
->cUsageIdentifier
- 1)
2290 str
+= sepLen
/ sizeof(WCHAR
);
2299 static struct BitToString netscapeCertTypeMap
[] = {
2300 { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_CLIENT
, { 0 } },
2301 { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
, IDS_NETSCAPE_SSL_SERVER
, { 0 } },
2302 { NETSCAPE_SMIME_CERT_TYPE
, IDS_NETSCAPE_SMIME
, { 0 } },
2303 { NETSCAPE_SIGN_CERT_TYPE
, IDS_NETSCAPE_SIGN
, { 0 } },
2304 { NETSCAPE_SSL_CA_CERT_TYPE
, IDS_NETSCAPE_SSL_CA
, { 0 } },
2305 { NETSCAPE_SMIME_CA_CERT_TYPE
, IDS_NETSCAPE_SMIME_CA
, { 0 } },
2306 { NETSCAPE_SIGN_CA_CERT_TYPE
, IDS_NETSCAPE_SIGN_CA
, { 0 } },
2309 static BOOL WINAPI
CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType
,
2310 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2311 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2315 CRYPT_BIT_BLOB
*bits
;
2320 SetLastError(E_INVALIDARG
);
2323 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_BITS
,
2324 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bits
, &size
)))
2326 WCHAR infoNotAvailable
[MAX_STRING_RESOURCE_LEN
];
2327 DWORD bytesNeeded
= sizeof(WCHAR
);
2329 LoadStringW(hInstance
, IDS_INFO_NOT_AVAILABLE
, infoNotAvailable
, ARRAY_SIZE(infoNotAvailable
));
2330 if (!bits
->cbData
|| bits
->cbData
> 1)
2332 bytesNeeded
+= lstrlenW(infoNotAvailable
) * sizeof(WCHAR
);
2334 *pcbFormat
= bytesNeeded
;
2335 else if (*pcbFormat
< bytesNeeded
)
2337 *pcbFormat
= bytesNeeded
;
2338 SetLastError(ERROR_MORE_DATA
);
2343 LPWSTR str
= pbFormat
;
2345 *pcbFormat
= bytesNeeded
;
2346 lstrcpyW(str
, infoNotAvailable
);
2351 static BOOL stringsLoaded
= FALSE
;
2358 for (i
= 0; i
< ARRAY_SIZE(netscapeCertTypeMap
); i
++)
2359 LoadStringW(hInstance
, netscapeCertTypeMap
[i
].id
,
2360 netscapeCertTypeMap
[i
].str
, MAX_STRING_RESOURCE_LEN
);
2361 stringsLoaded
= TRUE
;
2363 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
, ARRAY_SIZE(netscapeCertTypeMap
),
2364 NULL
, &bitStringLen
, &first
);
2365 bytesNeeded
+= bitStringLen
;
2366 bytesNeeded
+= 3 * sizeof(WCHAR
); /* " (" + ")" */
2367 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2368 bits
->cbData
, NULL
, &size
);
2369 bytesNeeded
+= size
;
2371 *pcbFormat
= bytesNeeded
;
2372 else if (*pcbFormat
< bytesNeeded
)
2374 *pcbFormat
= bytesNeeded
;
2375 SetLastError(ERROR_MORE_DATA
);
2380 LPWSTR str
= pbFormat
;
2382 bitStringLen
= bytesNeeded
;
2384 CRYPT_FormatBits(bits
->pbData
[0], netscapeCertTypeMap
, ARRAY_SIZE(netscapeCertTypeMap
),
2385 str
, &bitStringLen
, &first
);
2386 str
+= bitStringLen
/ sizeof(WCHAR
) - 1;
2389 CRYPT_FormatHexString(0, 0, 0, NULL
, NULL
, bits
->pbData
,
2390 bits
->cbData
, str
, &size
);
2391 str
+= size
/ sizeof(WCHAR
) - 1;
2401 static WCHAR financialCriteria
[MAX_STRING_RESOURCE_LEN
];
2402 static WCHAR available
[MAX_STRING_RESOURCE_LEN
];
2403 static WCHAR notAvailable
[MAX_STRING_RESOURCE_LEN
];
2404 static WCHAR meetsCriteria
[MAX_STRING_RESOURCE_LEN
];
2405 static WCHAR yes
[MAX_STRING_RESOURCE_LEN
];
2406 static WCHAR no
[MAX_STRING_RESOURCE_LEN
];
2408 static BOOL WINAPI
CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType
,
2409 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2410 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2413 SPC_FINANCIAL_CRITERIA criteria
;
2414 DWORD size
= sizeof(criteria
);
2419 SetLastError(E_INVALIDARG
);
2422 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
,
2423 SPC_FINANCIAL_CRITERIA_STRUCT
, pbEncoded
, cbEncoded
, 0, NULL
, &criteria
,
2426 static BOOL stringsLoaded
= FALSE
;
2427 DWORD bytesNeeded
= sizeof(WCHAR
);
2433 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA
, financialCriteria
, ARRAY_SIZE(financialCriteria
));
2434 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_AVAILABLE
, available
, ARRAY_SIZE(available
));
2435 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE
, notAvailable
, ARRAY_SIZE(notAvailable
));
2436 LoadStringW(hInstance
, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA
, meetsCriteria
, ARRAY_SIZE(meetsCriteria
));
2437 LoadStringW(hInstance
, IDS_YES
, yes
, ARRAY_SIZE(yes
));
2438 LoadStringW(hInstance
, IDS_NO
, no
, ARRAY_SIZE(no
));
2439 stringsLoaded
= TRUE
;
2441 if (dwFormatStrType
& CRYPT_FORMAT_STR_MULTI_LINE
)
2444 sepLen
= lstrlenW(crlf
) * sizeof(WCHAR
);
2449 sepLen
= lstrlenW(commaSpace
) * sizeof(WCHAR
);
2451 bytesNeeded
+= lstrlenW(financialCriteria
) * sizeof(WCHAR
);
2452 if (criteria
.fFinancialInfoAvailable
)
2454 bytesNeeded
+= lstrlenW(available
) * sizeof(WCHAR
);
2455 bytesNeeded
+= sepLen
;
2456 bytesNeeded
+= lstrlenW(meetsCriteria
) * sizeof(WCHAR
);
2457 if (criteria
.fMeetsCriteria
)
2458 bytesNeeded
+= lstrlenW(yes
) * sizeof(WCHAR
);
2460 bytesNeeded
+= lstrlenW(no
) * sizeof(WCHAR
);
2463 bytesNeeded
+= lstrlenW(notAvailable
) * sizeof(WCHAR
);
2465 *pcbFormat
= bytesNeeded
;
2466 else if (*pcbFormat
< bytesNeeded
)
2468 *pcbFormat
= bytesNeeded
;
2469 SetLastError(ERROR_MORE_DATA
);
2474 LPWSTR str
= pbFormat
;
2476 *pcbFormat
= bytesNeeded
;
2477 lstrcpyW(str
, financialCriteria
);
2478 str
+= lstrlenW(financialCriteria
);
2479 if (criteria
.fFinancialInfoAvailable
)
2481 lstrcpyW(str
, available
);
2482 str
+= lstrlenW(available
);
2484 str
+= sepLen
/ sizeof(WCHAR
);
2485 lstrcpyW(str
, meetsCriteria
);
2486 str
+= lstrlenW(meetsCriteria
);
2487 if (criteria
.fMeetsCriteria
)
2494 lstrcpyW(str
, notAvailable
);
2501 static BOOL WINAPI
CRYPT_FormatUnicodeString(DWORD dwCertEncodingType
,
2502 DWORD dwFormatType
, DWORD dwFormatStrType
, void *pFormatStruct
,
2503 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
,
2506 CERT_NAME_VALUE
*value
;
2512 SetLastError(E_INVALIDARG
);
2515 if ((ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_UNICODE_ANY_STRING
,
2516 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &value
, &size
)))
2519 *pcbFormat
= value
->Value
.cbData
;
2520 else if (*pcbFormat
< value
->Value
.cbData
)
2522 *pcbFormat
= value
->Value
.cbData
;
2523 SetLastError(ERROR_MORE_DATA
);
2528 LPWSTR str
= pbFormat
;
2530 *pcbFormat
= value
->Value
.cbData
;
2531 lstrcpyW(str
, (LPWSTR
)value
->Value
.pbData
);
2537 typedef BOOL (WINAPI
*CryptFormatObjectFunc
)(DWORD
, DWORD
, DWORD
, void *,
2538 LPCSTR
, const BYTE
*, DWORD
, void *, DWORD
*);
2540 static CryptFormatObjectFunc
CRYPT_GetBuiltinFormatFunction(DWORD encodingType
,
2541 DWORD formatStrType
, LPCSTR lpszStructType
)
2543 CryptFormatObjectFunc format
= NULL
;
2545 if ((encodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
)
2547 SetLastError(ERROR_FILE_NOT_FOUND
);
2550 if (IS_INTOID(lpszStructType
))
2552 switch (LOWORD(lpszStructType
))
2554 case LOWORD(X509_KEY_USAGE
):
2555 format
= CRYPT_FormatKeyUsage
;
2557 case LOWORD(X509_ALTERNATE_NAME
):
2558 format
= CRYPT_FormatAltName
;
2560 case LOWORD(X509_BASIC_CONSTRAINTS2
):
2561 format
= CRYPT_FormatBasicConstraints2
;
2563 case LOWORD(X509_AUTHORITY_KEY_ID2
):
2564 format
= CRYPT_FormatAuthorityKeyId2
;
2566 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
2567 format
= CRYPT_FormatAuthorityInfoAccess
;
2569 case LOWORD(X509_CRL_DIST_POINTS
):
2570 format
= CRYPT_FormatCRLDistPoints
;
2572 case LOWORD(X509_ENHANCED_KEY_USAGE
):
2573 format
= CRYPT_FormatEnhancedKeyUsage
;
2575 case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT
):
2576 format
= CRYPT_FormatSpcFinancialCriteria
;
2580 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
2581 format
= CRYPT_FormatAltName
;
2582 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
2583 format
= CRYPT_FormatAltName
;
2584 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
2585 format
= CRYPT_FormatKeyUsage
;
2586 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
2587 format
= CRYPT_FormatAltName
;
2588 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
2589 format
= CRYPT_FormatAltName
;
2590 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
2591 format
= CRYPT_FormatBasicConstraints2
;
2592 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
2593 format
= CRYPT_FormatAuthorityInfoAccess
;
2594 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
2595 format
= CRYPT_FormatAuthorityKeyId2
;
2596 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
2597 format
= CRYPT_FormatCRLDistPoints
;
2598 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
2599 format
= CRYPT_FormatEnhancedKeyUsage
;
2600 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_CERT_TYPE
))
2601 format
= CRYPT_FormatNetscapeCertType
;
2602 else if (!strcmp(lpszStructType
, szOID_NETSCAPE_BASE_URL
) ||
2603 !strcmp(lpszStructType
, szOID_NETSCAPE_REVOCATION_URL
) ||
2604 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_REVOCATION_URL
) ||
2605 !strcmp(lpszStructType
, szOID_NETSCAPE_CERT_RENEWAL_URL
) ||
2606 !strcmp(lpszStructType
, szOID_NETSCAPE_CA_POLICY_URL
) ||
2607 !strcmp(lpszStructType
, szOID_NETSCAPE_SSL_SERVER_NAME
) ||
2608 !strcmp(lpszStructType
, szOID_NETSCAPE_COMMENT
))
2609 format
= CRYPT_FormatUnicodeString
;
2610 else if (!strcmp(lpszStructType
, SPC_FINANCIAL_CRITERIA_OBJID
))
2611 format
= CRYPT_FormatSpcFinancialCriteria
;
2615 BOOL WINAPI
CryptFormatObject(DWORD dwCertEncodingType
, DWORD dwFormatType
,
2616 DWORD dwFormatStrType
, void *pFormatStruct
, LPCSTR lpszStructType
,
2617 const BYTE
*pbEncoded
, DWORD cbEncoded
, void *pbFormat
, DWORD
*pcbFormat
)
2619 CryptFormatObjectFunc format
= NULL
;
2620 HCRYPTOIDFUNCADDR hFunc
= NULL
;
2623 TRACE("(%08lx, %ld, %08lx, %p, %s, %p, %ld, %p, %p)\n", dwCertEncodingType
,
2624 dwFormatType
, dwFormatStrType
, pFormatStruct
, debugstr_a(lpszStructType
),
2625 pbEncoded
, cbEncoded
, pbFormat
, pcbFormat
);
2627 if (!(format
= CRYPT_GetBuiltinFormatFunction(dwCertEncodingType
,
2628 dwFormatStrType
, lpszStructType
)))
2630 static HCRYPTOIDFUNCSET set
= NULL
;
2633 set
= CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC
, 0);
2634 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
2635 (void **)&format
, &hFunc
);
2637 if (!format
&& (dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) ==
2638 X509_ASN_ENCODING
&& !(dwFormatStrType
& CRYPT_FORMAT_STR_NO_HEX
))
2639 format
= CRYPT_FormatHexString
;
2641 ret
= format(dwCertEncodingType
, dwFormatType
, dwFormatStrType
,
2642 pFormatStruct
, lpszStructType
, pbEncoded
, cbEncoded
, pbFormat
,
2645 CryptFreeOIDFunctionAddress(hFunc
, 0);