7 * This is free software; see Copyright file in the source
8 * distribution for preciese wording.
10 * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
11 * Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com>
16 #ifndef XMLSEC_NO_X509
28 #include <libxml/tree.h>
30 #include <xmlsec/xmlsec.h>
31 #include <xmlsec/xmltree.h>
32 #include <xmlsec/keys.h>
33 #include <xmlsec/keyinfo.h>
34 #include <xmlsec/keysmngr.h>
35 #include <xmlsec/x509.h>
36 #include <xmlsec/base64.h>
37 #include <xmlsec/bn.h>
38 #include <xmlsec/errors.h>
40 #include <xmlsec/mscrypto/crypto.h>
41 #include <xmlsec/mscrypto/x509.h>
42 #include <xmlsec/mscrypto/certkeys.h>
44 #if defined(__MINGW32__)
45 # include "xmlsec-mingw.h"
49 /*************************************************************************
51 * X509 utility functions
53 ************************************************************************/
54 static int xmlSecMSCryptoX509DataNodeRead (xmlSecKeyDataPtr data,
56 xmlSecKeyInfoCtxPtr keyInfoCtx);
57 static int xmlSecMSCryptoX509CertificateNodeRead (xmlSecKeyDataPtr data,
59 xmlSecKeyInfoCtxPtr keyInfoCtx);
60 static int xmlSecMSCryptoX509CertificateNodeWrite (PCCERT_CONTEXT cert,
62 xmlSecKeyInfoCtxPtr keyInfoCtx);
63 static int xmlSecMSCryptoX509SubjectNameNodeRead (xmlSecKeyDataPtr data,
65 xmlSecKeyInfoCtxPtr keyInfoCtx);
66 static int xmlSecMSCryptoX509SubjectNameNodeWrite (PCCERT_CONTEXT cert,
68 xmlSecKeyInfoCtxPtr keyInfoCtx);
69 static int xmlSecMSCryptoX509IssuerSerialNodeRead (xmlSecKeyDataPtr data,
71 xmlSecKeyInfoCtxPtr keyInfoCtx);
72 static int xmlSecMSCryptoX509IssuerSerialNodeWrite (PCCERT_CONTEXT cert,
74 xmlSecKeyInfoCtxPtr keyInfoCtx);
75 static int xmlSecMSCryptoX509SKINodeRead (xmlSecKeyDataPtr data,
77 xmlSecKeyInfoCtxPtr keyInfoCtx);
78 static int xmlSecMSCryptoX509SKINodeWrite (PCCERT_CONTEXT cert,
80 xmlSecKeyInfoCtxPtr keyInfoCtx);
81 static int xmlSecMSCryptoX509CRLNodeRead (xmlSecKeyDataPtr data,
83 xmlSecKeyInfoCtxPtr keyInfoCtx);
84 static int xmlSecMSCryptoX509CRLNodeWrite (PCCRL_CONTEXT crl,
86 xmlSecKeyInfoCtxPtr keyInfoCtx);
87 static int xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data,
89 xmlSecKeyInfoCtxPtr keyInfoCtx);
91 static PCCERT_CONTEXT xmlSecMSCryptoX509CertDerRead (const xmlSecByte* buf,
93 static PCCERT_CONTEXT xmlSecMSCryptoX509CertBase64DerRead (xmlChar* buf);
94 static xmlChar* xmlSecMSCryptoX509CertBase64DerWrite (PCCERT_CONTEXT cert,
96 static PCCRL_CONTEXT xmlSecMSCryptoX509CrlDerRead (xmlSecByte* buf,
98 xmlSecKeyInfoCtxPtr keyInfoCtx);
99 static PCCRL_CONTEXT xmlSecMSCryptoX509CrlBase64DerRead (xmlChar* buf,
100 xmlSecKeyInfoCtxPtr keyInfoCtx);
101 static xmlChar* xmlSecMSCryptoX509CrlBase64DerWrite (PCCRL_CONTEXT crl,
103 static xmlChar* xmlSecMSCryptoX509NameWrite(PCERT_NAME_BLOB nm);
104 static int xmlSecMSCryptoASN1IntegerWrite (xmlNodePtr node,
105 PCRYPT_INTEGER_BLOB num);
106 static xmlChar* xmlSecMSCryptoX509SKIWrite (PCCERT_CONTEXT cert);
107 static void xmlSecMSCryptoX509CertDebugDump (PCCERT_CONTEXT cert,
109 static void xmlSecMSCryptoX509CertDebugXmlDump (PCCERT_CONTEXT cert,
111 static int xmlSecMSCryptoX509CertGetTime (FILETIME t,
114 /*************************************************************************
116 * Internal MSCrypto X509 data CTX
118 ************************************************************************/
119 typedef struct _xmlSecMSCryptoX509DataCtx xmlSecMSCryptoX509DataCtx,
120 *xmlSecMSCryptoX509DataCtxPtr;
122 struct _xmlSecMSCryptoX509DataCtx {
123 PCCERT_CONTEXT keyCert;
125 HCERTSTORE hMemStore;
126 unsigned int numCerts;
127 unsigned int numCrls;
130 /**************************************************************************
132 * <dsig:X509Data> processing
135 * The X509Data Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data)
137 * An X509Data element within KeyInfo contains one or more identifiers of keys
138 * or X509 certificates (or certificates' identifiers or a revocation list).
139 * The content of X509Data is:
141 * 1. At least one element, from the following set of element types; any of these may appear together or more than once iff (if and only if) each instance describes or is related to the same certificate:
143 * * The X509IssuerSerial element, which contains an X.509 issuer
144 * distinguished name/serial number pair that SHOULD be compliant
145 * with RFC2253 [LDAP-DN],
146 * * The X509SubjectName element, which contains an X.509 subject
147 * distinguished name that SHOULD be compliant with RFC2253 [LDAP-DN],
148 * * The X509SKI element, which contains the base64 encoded plain (i.e.
149 * non-DER-encoded) value of a X509 V.3 SubjectKeyIdentifier extension.
150 * * The X509Certificate element, which contains a base64-encoded [X509v3]
152 * * Elements from an external namespace which accompanies/complements any
153 * of the elements above.
154 * * The X509CRL element, which contains a base64-encoded certificate
155 * revocation list (CRL) [X509v3].
157 * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear
158 * MUST refer to the certificate or certificates containing the validation key.
159 * All such elements that refer to a particular individual certificate MUST be
160 * grouped inside a single X509Data element and if the certificate to which
161 * they refer appears, it MUST also be in that X509Data element.
163 * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that relate to
164 * the same key but different certificates MUST be grouped within a single
165 * KeyInfo but MAY occur in multiple X509Data elements.
167 * All certificates appearing in an X509Data element MUST relate to the
168 * validation key by either containing it or being part of a certification
169 * chain that terminates in a certificate containing the validation key.
171 * No ordering is implied by the above constraints.
173 * Note, there is no direct provision for a PKCS#7 encoded "bag" of
174 * certificates or CRLs. However, a set of certificates and CRLs can occur
175 * within an X509Data element and multiple X509Data elements can occur in a
176 * KeyInfo. Whenever multiple certificates occur in an X509Data element, at
177 * least one such certificate must contain the public key which verifies the
182 * <element name="X509Data" type="ds:X509DataType"/>
183 * <complexType name="X509DataType">
184 * <sequence maxOccurs="unbounded">
186 * <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
187 * <element name="X509SKI" type="base64Binary"/>
188 * <element name="X509SubjectName" type="string"/>
189 * <element name="X509Certificate" type="base64Binary"/>
190 * <element name="X509CRL" type="base64Binary"/>
191 * <any namespace="##other" processContents="lax"/>
195 * <complexType name="X509IssuerSerialType">
197 * <element name="X509IssuerName" type="string"/>
198 * <element name="X509SerialNumber" type="integer"/>
204 * <!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
205 * X509Certificate | X509CRL)+ %X509.ANY;)>
206 * <!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
207 * <!ELEMENT X509IssuerName (#PCDATA) >
208 * <!ELEMENT X509SubjectName (#PCDATA) >
209 * <!ELEMENT X509SerialNumber (#PCDATA) >
210 * <!ELEMENT X509SKI (#PCDATA) >
211 * <!ELEMENT X509Certificate (#PCDATA) >
212 * <!ELEMENT X509CRL (#PCDATA) >
214 * -----------------------------------------------------------------------
216 * xmlSecMSCryptoX509DataCtx is located after xmlSecTransform
218 *************************************************************************/
219 #define xmlSecMSCryptoX509DataSize \
220 (sizeof(xmlSecKeyData) + sizeof(xmlSecMSCryptoX509DataCtx))
221 #define xmlSecMSCryptoX509DataGetCtx(data) \
222 ((xmlSecMSCryptoX509DataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
224 static int xmlSecMSCryptoKeyDataX509Initialize (xmlSecKeyDataPtr data);
225 static int xmlSecMSCryptoKeyDataX509Duplicate (xmlSecKeyDataPtr dst,
226 xmlSecKeyDataPtr src);
227 static void xmlSecMSCryptoKeyDataX509Finalize (xmlSecKeyDataPtr data);
228 static int xmlSecMSCryptoKeyDataX509XmlRead (xmlSecKeyDataId id,
231 xmlSecKeyInfoCtxPtr keyInfoCtx);
232 static int xmlSecMSCryptoKeyDataX509XmlWrite (xmlSecKeyDataId id,
235 xmlSecKeyInfoCtxPtr keyInfoCtx);
236 static xmlSecKeyDataType xmlSecMSCryptoKeyDataX509GetType (xmlSecKeyDataPtr data);
237 static const xmlChar* xmlSecMSCryptoKeyDataX509GetIdentifier (xmlSecKeyDataPtr data);
239 static void xmlSecMSCryptoKeyDataX509DebugDump (xmlSecKeyDataPtr data,
241 static void xmlSecMSCryptoKeyDataX509DebugXmlDump (xmlSecKeyDataPtr data,
246 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataX509Klass = {
247 sizeof(xmlSecKeyDataKlass),
248 xmlSecMSCryptoX509DataSize,
252 xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
253 /* xmlSecKeyDataUsage usage; */
254 xmlSecHrefX509Data, /* const xmlChar* href; */
255 xmlSecNodeX509Data, /* const xmlChar* dataNodeName; */
256 xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
258 /* constructors/destructor */
259 xmlSecMSCryptoKeyDataX509Initialize, /* xmlSecKeyDataInitializeMethod initialize; */
260 xmlSecMSCryptoKeyDataX509Duplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */
261 xmlSecMSCryptoKeyDataX509Finalize, /* xmlSecKeyDataFinalizeMethod finalize; */
262 NULL, /* xmlSecKeyDataGenerateMethod generate; */
265 xmlSecMSCryptoKeyDataX509GetType, /* xmlSecKeyDataGetTypeMethod getType; */
266 NULL, /* xmlSecKeyDataGetSizeMethod getSize; */
267 xmlSecMSCryptoKeyDataX509GetIdentifier, /* xmlSecKeyDataGetIdentifier getIdentifier; */
270 xmlSecMSCryptoKeyDataX509XmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */
271 xmlSecMSCryptoKeyDataX509XmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
272 NULL, /* xmlSecKeyDataBinReadMethod binRead; */
273 NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
276 xmlSecMSCryptoKeyDataX509DebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */
277 xmlSecMSCryptoKeyDataX509DebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
279 /* reserved for the future */
280 NULL, /* void* reserved0; */
281 NULL, /* void* reserved1; */
285 * xmlSecMSCryptoKeyDataX509GetKlass:
287 * The MSCrypto X509 key data klass (http://www.w3.org/TR/xmldsig-core/#sec-X509Data).
289 * Returns: the X509 data klass.
292 xmlSecMSCryptoKeyDataX509GetKlass(void) {
293 return(&xmlSecMSCryptoKeyDataX509Klass);
297 * xmlSecMSCryptoKeyDataX509GetKeyCert:
298 * @data: the pointer to X509 key data.
300 * Gets the certificate from which the key was extracted.
302 * Returns: the key's certificate or NULL if key data was not used for key
303 * extraction or an error occurs.
306 xmlSecMSCryptoKeyDataX509GetKeyCert(xmlSecKeyDataPtr data) {
307 xmlSecMSCryptoX509DataCtxPtr ctx;
309 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
311 ctx = xmlSecMSCryptoX509DataGetCtx(data);
312 xmlSecAssert2(ctx != NULL, NULL);
314 return(ctx->keyCert);
318 * xmlSecMSCryptoKeyDataX509AdoptKeyCert:
319 * @data: the pointer to X509 key data.
320 * @cert: the pointer to MSCRYPTO X509 certificate.
322 * Sets the key's certificate in @data.
324 * Returns: 0 on success or a negative value if an error occurs.
327 xmlSecMSCryptoKeyDataX509AdoptKeyCert(xmlSecKeyDataPtr data, PCCERT_CONTEXT cert) {
328 xmlSecMSCryptoX509DataCtxPtr ctx;
330 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
331 xmlSecAssert2(cert != NULL, -1);
333 ctx = xmlSecMSCryptoX509DataGetCtx(data);
334 xmlSecAssert2(ctx != NULL, -1);
336 if(ctx->keyCert != NULL) {
337 CertFreeCertificateContext(ctx->keyCert);
346 * xmlSecMSCryptoKeyDataX509AdoptCert:
347 * @data: the pointer to X509 key data.
348 * @cert: the pointer to MSCRYPTO X509 certificate.
350 * Adds certificate to the X509 key data.
352 * Returns: 0 on success or a negative value if an error occurs.
355 xmlSecMSCryptoKeyDataX509AdoptCert(xmlSecKeyDataPtr data, PCCERT_CONTEXT cert) {
356 xmlSecMSCryptoX509DataCtxPtr ctx;
358 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
359 xmlSecAssert2(cert != NULL, -1);
361 ctx = xmlSecMSCryptoX509DataGetCtx(data);
362 xmlSecAssert2(ctx != NULL, -1);
363 xmlSecAssert2(ctx->hMemStore != 0, -1);
365 if (!CertAddCertificateContextToStore(ctx->hMemStore, cert, CERT_STORE_ADD_ALWAYS, NULL)) {
366 xmlSecError(XMLSEC_ERRORS_HERE,
367 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
368 "CertAddCertificateContextToStore",
369 XMLSEC_ERRORS_R_CRYPTO_FAILED,
370 XMLSEC_ERRORS_NO_MESSAGE);
373 CertFreeCertificateContext(cert);
380 * xmlSecMSCryptoKeyDataX509GetCert:
381 * @data: the pointer to X509 key data.
382 * @pos: the desired certificate position.
384 * Gets a certificate from X509 key data.
386 * Returns: the pointer to certificate or NULL if @pos is larger than the
387 * number of certificates in @data or an error occurs.
390 xmlSecMSCryptoKeyDataX509GetCert(xmlSecKeyDataPtr data, xmlSecSize pos) {
391 xmlSecMSCryptoX509DataCtxPtr ctx;
392 PCCERT_CONTEXT pCert = NULL;
394 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
396 ctx = xmlSecMSCryptoX509DataGetCtx(data);
397 xmlSecAssert2(ctx != NULL, NULL);
398 xmlSecAssert2(ctx->hMemStore != 0, NULL);
399 xmlSecAssert2(ctx->numCerts > pos, NULL);
401 while ((pCert = CertEnumCertificatesInStore(ctx->hMemStore, pCert)) && (pos > 0)) {
409 * xmlSecMSCryptoKeyDataX509GetCertsSize:
410 * @data: the pointer to X509 key data.
412 * Gets the number of certificates in @data.
414 * Returns: te number of certificates in @data.
417 xmlSecMSCryptoKeyDataX509GetCertsSize(xmlSecKeyDataPtr data) {
418 xmlSecMSCryptoX509DataCtxPtr ctx;
420 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), 0);
422 ctx = xmlSecMSCryptoX509DataGetCtx(data);
423 xmlSecAssert2(ctx != NULL, 0);
425 return(ctx->numCerts);
429 * xmlSecMSCryptoKeyDataX509AdoptCrl:
430 * @data: the pointer to X509 key data.
431 * @crl: the pointer to MSCrypto X509 CRL.
433 * Adds CRL to the X509 key data.
435 * Returns: 0 on success or a negative value if an error occurs.
438 xmlSecMSCryptoKeyDataX509AdoptCrl(xmlSecKeyDataPtr data, PCCRL_CONTEXT crl) {
439 xmlSecMSCryptoX509DataCtxPtr ctx;
441 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
442 xmlSecAssert2(crl != 0, -1);
444 ctx = xmlSecMSCryptoX509DataGetCtx(data);
445 xmlSecAssert2(ctx != NULL, -1);
446 xmlSecAssert2(ctx->hMemStore != 0, -1);
448 if (!CertAddCRLContextToStore(ctx->hMemStore, crl, CERT_STORE_ADD_ALWAYS, NULL)) {
449 xmlSecError(XMLSEC_ERRORS_HERE,
450 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
451 "CertAddCRLContextToStore",
452 XMLSEC_ERRORS_R_CRYPTO_FAILED,
453 XMLSEC_ERRORS_NO_MESSAGE);
462 * xmlSecMSCryptoKeyDataX509GetCrl:
463 * @data: the pointer to X509 key data.
464 * @pos: the desired CRL position.
466 * Gets a CRL from X509 key data.
468 * Returns: the pointer to CRL or NULL if @pos is larger than the
469 * number of CRLs in @data or an error occurs.
472 xmlSecMSCryptoKeyDataX509GetCrl(xmlSecKeyDataPtr data, xmlSecSize pos) {
473 xmlSecMSCryptoX509DataCtxPtr ctx;
474 PCCRL_CONTEXT pCRL = NULL;
476 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
477 ctx = xmlSecMSCryptoX509DataGetCtx(data);
478 xmlSecAssert2(ctx != NULL, NULL);
479 xmlSecAssert2(ctx->hMemStore != 0, NULL);
480 xmlSecAssert2(ctx->numCrls > pos, NULL);
482 while ((pCRL = CertEnumCRLsInStore(ctx->hMemStore, pCRL)) && (pos > 0)) {
490 * xmlSecMSCryptoKeyDataX509GetCrlsSize:
491 * @data: the pointer to X509 key data.
493 * Gets the number of CRLs in @data.
495 * Returns: te number of CRLs in @data.
498 xmlSecMSCryptoKeyDataX509GetCrlsSize(xmlSecKeyDataPtr data) {
499 xmlSecMSCryptoX509DataCtxPtr ctx;
501 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), 0);
503 ctx = xmlSecMSCryptoX509DataGetCtx(data);
504 xmlSecAssert2(ctx != NULL, 0);
506 return(ctx->numCrls);
510 xmlSecMSCryptoKeyDataX509Initialize(xmlSecKeyDataPtr data) {
511 xmlSecMSCryptoX509DataCtxPtr ctx;
513 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
515 ctx = xmlSecMSCryptoX509DataGetCtx(data);
516 xmlSecAssert2(ctx != NULL, -1);
518 memset(ctx, 0, sizeof(xmlSecMSCryptoX509DataCtx));
520 ctx->hMemStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
523 CERT_STORE_CREATE_NEW_FLAG,
525 if (ctx->hMemStore == 0) {
526 xmlSecError(XMLSEC_ERRORS_HERE,
527 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
529 XMLSEC_ERRORS_R_CRYPTO_FAILED,
530 XMLSEC_ERRORS_NO_MESSAGE);
538 xmlSecMSCryptoKeyDataX509Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
539 PCCERT_CONTEXT certSrc, certDst;
540 PCCRL_CONTEXT crlSrc, crlDst;
541 xmlSecSize size, pos;
544 xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataX509Id), -1);
545 xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataX509Id), -1);
548 size = xmlSecMSCryptoKeyDataX509GetCertsSize(src);
549 for(pos = 0; pos < size; ++pos) {
550 /* TBD: function below does linear scan, eliminate loop within
553 certSrc = xmlSecMSCryptoKeyDataX509GetCert(src, pos);
554 if(certSrc == NULL) {
555 xmlSecError(XMLSEC_ERRORS_HERE,
556 xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
557 "xmlSecMSCryptoKeyDataX509GetCert",
558 XMLSEC_ERRORS_R_XMLSEC_FAILED,
563 certDst = CertDuplicateCertificateContext(certSrc);
564 if(certDst == NULL) {
565 xmlSecError(XMLSEC_ERRORS_HERE,
566 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
567 "CertDuplicateCertificateContext",
568 XMLSEC_ERRORS_R_CRYPTO_FAILED,
569 XMLSEC_ERRORS_NO_MESSAGE);
573 ret = xmlSecMSCryptoKeyDataX509AdoptCert(dst, certDst);
575 xmlSecError(XMLSEC_ERRORS_HERE,
576 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
577 "xmlSecMSCryptoKeyDataX509AdoptCert",
578 XMLSEC_ERRORS_R_XMLSEC_FAILED,
579 XMLSEC_ERRORS_NO_MESSAGE);
580 CertFreeCertificateContext(certDst);
586 size = xmlSecMSCryptoKeyDataX509GetCrlsSize(src);
587 for(pos = 0; pos < size; ++pos) {
588 crlSrc = xmlSecMSCryptoKeyDataX509GetCrl(src, pos);
590 xmlSecError(XMLSEC_ERRORS_HERE,
591 xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
592 "xmlSecMSCryptoKeyDataX509GetCrl",
593 XMLSEC_ERRORS_R_XMLSEC_FAILED,
598 crlDst = CertDuplicateCRLContext(crlSrc);
600 xmlSecError(XMLSEC_ERRORS_HERE,
601 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
602 "CertDuplicateCRLContext",
603 XMLSEC_ERRORS_R_CRYPTO_FAILED,
604 XMLSEC_ERRORS_NO_MESSAGE);
608 ret = xmlSecMSCryptoKeyDataX509AdoptCrl(dst, crlDst);
610 xmlSecError(XMLSEC_ERRORS_HERE,
611 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
612 "xmlSecMSCryptoKeyDataX509AdoptCrl",
613 XMLSEC_ERRORS_R_XMLSEC_FAILED,
614 XMLSEC_ERRORS_NO_MESSAGE);
615 CertFreeCRLContext(crlDst);
620 /* copy key cert if exist */
621 certSrc = xmlSecMSCryptoKeyDataX509GetKeyCert(src);
622 if(certSrc != NULL) {
623 certDst = CertDuplicateCertificateContext(certSrc);
624 if(certDst == NULL) {
625 xmlSecError(XMLSEC_ERRORS_HERE,
626 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
627 "CertDuplicateCertificateContext",
628 XMLSEC_ERRORS_R_CRYPTO_FAILED,
629 XMLSEC_ERRORS_NO_MESSAGE);
632 ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(dst, certDst);
634 xmlSecError(XMLSEC_ERRORS_HERE,
635 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
636 "xmlSecMSCryptoKeyDataX509AdoptKeyCert",
637 XMLSEC_ERRORS_R_XMLSEC_FAILED,
638 XMLSEC_ERRORS_NO_MESSAGE);
639 CertFreeCertificateContext(certDst);
647 xmlSecMSCryptoKeyDataX509Finalize(xmlSecKeyDataPtr data) {
648 xmlSecMSCryptoX509DataCtxPtr ctx;
650 xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
652 ctx = xmlSecMSCryptoX509DataGetCtx(data);
653 xmlSecAssert(ctx != NULL);
655 if(ctx->keyCert != NULL) {
656 CertFreeCertificateContext(ctx->keyCert);
660 if (ctx->hMemStore != 0) {
661 if (!CertCloseStore(ctx->hMemStore, CERT_CLOSE_STORE_FORCE_FLAG)) {
662 xmlSecError(XMLSEC_ERRORS_HERE,
665 XMLSEC_ERRORS_R_XMLSEC_FAILED,
666 XMLSEC_ERRORS_NO_MESSAGE);
671 memset(ctx, 0, sizeof(xmlSecMSCryptoX509DataCtx));
675 xmlSecMSCryptoKeyDataX509XmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
676 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
677 xmlSecKeyDataPtr data;
680 xmlSecAssert2(id == xmlSecMSCryptoKeyDataX509Id, -1);
681 xmlSecAssert2(key != NULL, -1);
682 xmlSecAssert2(node != NULL, -1);
683 xmlSecAssert2(keyInfoCtx != NULL, -1);
685 data = xmlSecKeyEnsureData(key, id);
687 xmlSecError(XMLSEC_ERRORS_HERE,
688 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
689 "xmlSecKeyEnsureData",
690 XMLSEC_ERRORS_R_XMLSEC_FAILED,
691 XMLSEC_ERRORS_NO_MESSAGE);
695 ret = xmlSecMSCryptoX509DataNodeRead(data, node, keyInfoCtx);
697 xmlSecError(XMLSEC_ERRORS_HERE,
698 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
699 "xmlSecMSCryptoX509DataNodeRead",
700 XMLSEC_ERRORS_R_XMLSEC_FAILED,
701 XMLSEC_ERRORS_NO_MESSAGE);
705 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) {
706 ret = xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
708 xmlSecError(XMLSEC_ERRORS_HERE,
709 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
710 "xmlSecMSCryptoKeyDataX509VerifyAndExtractKey",
711 XMLSEC_ERRORS_R_XMLSEC_FAILED,
712 XMLSEC_ERRORS_NO_MESSAGE);
720 xmlSecMSCryptoKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
721 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
722 xmlSecKeyDataPtr data;
725 xmlSecSize size, pos;
729 xmlSecAssert2(id == xmlSecMSCryptoKeyDataX509Id, -1);
730 xmlSecAssert2(key != NULL, -1);
731 xmlSecAssert2(node != NULL, -1);
732 xmlSecAssert2(keyInfoCtx != NULL, -1);
734 content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx);
736 xmlSecError(XMLSEC_ERRORS_HERE,
737 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
738 "xmlSecX509DataGetNodeContent",
739 XMLSEC_ERRORS_R_XMLSEC_FAILED,
740 "content=%d", content);
742 } else if(content == 0) {
743 /* by default we are writing certificates and crls */
744 content = XMLSEC_X509DATA_DEFAULT;
748 data = xmlSecKeyGetData(key, id);
750 /* no x509 data in the key */
755 size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
756 for(pos = 0; pos < size; ++pos) {
757 cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
759 xmlSecError(XMLSEC_ERRORS_HERE,
760 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
761 "xmlSecMSCryptoKeyDataX509GetCert",
762 XMLSEC_ERRORS_R_XMLSEC_FAILED,
767 if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) {
768 ret = xmlSecMSCryptoX509CertificateNodeWrite(cert, node, keyInfoCtx);
770 xmlSecError(XMLSEC_ERRORS_HERE,
771 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
772 "xmlSecMSCryptoX509CertificateNodeWrite",
773 XMLSEC_ERRORS_R_XMLSEC_FAILED,
779 if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) {
780 ret = xmlSecMSCryptoX509SubjectNameNodeWrite(cert, node, keyInfoCtx);
782 xmlSecError(XMLSEC_ERRORS_HERE,
783 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
784 "xmlSecMSCryptoX509SubjectNameNodeWrite",
785 XMLSEC_ERRORS_R_XMLSEC_FAILED,
791 if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) {
792 ret = xmlSecMSCryptoX509IssuerSerialNodeWrite(cert, node, keyInfoCtx);
794 xmlSecError(XMLSEC_ERRORS_HERE,
795 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
796 "xmlSecMSCryptoX509IssuerSerialNodeWrite",
797 XMLSEC_ERRORS_R_XMLSEC_FAILED,
803 if((content & XMLSEC_X509DATA_SKI_NODE) != 0) {
804 ret = xmlSecMSCryptoX509SKINodeWrite(cert, node, keyInfoCtx);
806 xmlSecError(XMLSEC_ERRORS_HERE,
807 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
808 "xmlSecMSCryptoX509SKINodeWrite",
809 XMLSEC_ERRORS_R_XMLSEC_FAILED,
816 /* write crls if needed */
817 if((content & XMLSEC_X509DATA_CRL_NODE) != 0) {
818 size = xmlSecMSCryptoKeyDataX509GetCrlsSize(data);
819 for(pos = 0; pos < size; ++pos) {
820 crl = xmlSecMSCryptoKeyDataX509GetCrl(data, pos);
822 xmlSecError(XMLSEC_ERRORS_HERE,
823 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
824 "xmlSecMSCryptoKeyDataX509GetCrl",
825 XMLSEC_ERRORS_R_XMLSEC_FAILED,
830 ret = xmlSecMSCryptoX509CRLNodeWrite(crl, node, keyInfoCtx);
832 xmlSecError(XMLSEC_ERRORS_HERE,
833 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
834 "xmlSecMSCryptoX509CRLNodeWrite",
835 XMLSEC_ERRORS_R_XMLSEC_FAILED,
845 static xmlSecKeyDataType
846 xmlSecMSCryptoKeyDataX509GetType(xmlSecKeyDataPtr data) {
847 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), xmlSecKeyDataTypeUnknown);
849 /* TODO: return verified/not verified status */
850 return(xmlSecKeyDataTypeUnknown);
853 static const xmlChar*
854 xmlSecMSCryptoKeyDataX509GetIdentifier(xmlSecKeyDataPtr data) {
855 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
862 xmlSecMSCryptoKeyDataX509DebugDump(xmlSecKeyDataPtr data, FILE* output) {
864 xmlSecSize size, pos;
866 xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
867 xmlSecAssert(output != NULL);
869 fprintf(output, "=== X509 Data:\n");
870 cert = xmlSecMSCryptoKeyDataX509GetKeyCert(data);
872 fprintf(output, "==== Key Certificate:\n");
873 xmlSecMSCryptoX509CertDebugDump(cert, output);
876 size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
877 for(pos = 0; pos < size; ++pos) {
878 cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
880 xmlSecError(XMLSEC_ERRORS_HERE,
881 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
882 "xmlSecMSCryptoKeyDataX509GetCert",
883 XMLSEC_ERRORS_R_XMLSEC_FAILED,
887 fprintf(output, "==== Certificate:\n");
888 xmlSecMSCryptoX509CertDebugDump(cert, output);
891 /* we don't print out crls */
895 xmlSecMSCryptoKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
897 xmlSecSize size, pos;
899 xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
900 xmlSecAssert(output != NULL);
902 fprintf(output, "<X509Data>\n");
903 cert = xmlSecMSCryptoKeyDataX509GetKeyCert(data);
905 fprintf(output, "<KeyCertificate>\n");
906 xmlSecMSCryptoX509CertDebugXmlDump(cert, output);
907 fprintf(output, "</KeyCertificate>\n");
910 size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
911 for(pos = 0; pos < size; ++pos) {
912 cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
914 xmlSecError(XMLSEC_ERRORS_HERE,
915 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
916 "xmlSecMSCryptoKeyDataX509GetCert",
917 XMLSEC_ERRORS_R_XMLSEC_FAILED,
921 fprintf(output, "<Certificate>\n");
922 xmlSecMSCryptoX509CertDebugXmlDump(cert, output);
923 fprintf(output, "</Certificate>\n");
926 /* we don't print out crls */
927 fprintf(output, "</X509Data>\n");
931 xmlSecMSCryptoX509DataNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
935 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
936 xmlSecAssert2(node != NULL, -1);
937 xmlSecAssert2(keyInfoCtx != NULL, -1);
939 for(cur = xmlSecGetNextElementNode(node->children);
941 cur = xmlSecGetNextElementNode(cur->next)) {
944 if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
945 ret = xmlSecMSCryptoX509CertificateNodeRead(data, cur, keyInfoCtx);
946 } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
947 ret = xmlSecMSCryptoX509SubjectNameNodeRead(data, cur, keyInfoCtx);
948 } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
949 ret = xmlSecMSCryptoX509IssuerSerialNodeRead(data, cur, keyInfoCtx);
950 } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) {
951 ret = xmlSecMSCryptoX509SKINodeRead(data, cur, keyInfoCtx);
952 } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) {
953 ret = xmlSecMSCryptoX509CRLNodeRead(data, cur, keyInfoCtx);
954 } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD) != 0) {
955 /* laxi schema validation: ignore unknown nodes */
956 xmlSecError(XMLSEC_ERRORS_HERE,
957 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
958 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
959 XMLSEC_ERRORS_R_UNEXPECTED_NODE,
960 XMLSEC_ERRORS_NO_MESSAGE);
964 xmlSecError(XMLSEC_ERRORS_HERE,
965 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
966 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
967 XMLSEC_ERRORS_R_XMLSEC_FAILED,
976 xmlSecMSCryptoX509CertificateNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
981 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
982 xmlSecAssert2(node != NULL, -1);
983 xmlSecAssert2(keyInfoCtx != NULL, -1);
985 content = xmlNodeGetContent(node);
986 if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
987 if(content != NULL) {
990 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
991 xmlSecError(XMLSEC_ERRORS_HERE,
992 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
993 xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
994 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
995 XMLSEC_ERRORS_NO_MESSAGE);
1001 cert = xmlSecMSCryptoX509CertBase64DerRead(content);
1003 xmlSecError(XMLSEC_ERRORS_HERE,
1004 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1005 "xmlSecMSCryptoX509CertBase64DerRead",
1006 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1007 XMLSEC_ERRORS_NO_MESSAGE);
1012 ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1014 xmlSecError(XMLSEC_ERRORS_HERE,
1015 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1016 "xmlSecMSCryptoKeyDataX509AdoptCert",
1017 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1018 XMLSEC_ERRORS_NO_MESSAGE);
1019 CertFreeCertificateContext(cert);
1029 xmlSecMSCryptoX509CertificateNodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node,
1030 xmlSecKeyInfoCtxPtr keyInfoCtx) {
1034 xmlSecAssert2(cert != NULL, -1);
1035 xmlSecAssert2(node != NULL, -1);
1036 xmlSecAssert2(keyInfoCtx != NULL, -1);
1038 /* set base64 lines size from context */
1039 buf = xmlSecMSCryptoX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize);
1041 xmlSecError(XMLSEC_ERRORS_HERE,
1043 "xmlSecMSCryptoX509CertBase64DerWrite",
1044 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1045 XMLSEC_ERRORS_NO_MESSAGE);
1049 cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
1051 xmlSecError(XMLSEC_ERRORS_HERE,
1054 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1056 xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
1061 /* todo: add \n around base64 data - from context */
1062 /* todo: add errors check */
1063 xmlNodeSetContent(cur, xmlSecStringCR);
1064 xmlNodeSetContent(cur, buf);
1070 xmlSecMSCryptoX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1071 xmlSecKeyDataStorePtr x509Store;
1073 PCCERT_CONTEXT cert;
1076 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1077 xmlSecAssert2(node != NULL, -1);
1078 xmlSecAssert2(keyInfoCtx != NULL, -1);
1079 xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1081 x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecMSCryptoX509StoreId);
1082 if(x509Store == NULL) {
1083 xmlSecError(XMLSEC_ERRORS_HERE,
1084 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1085 "xmlSecKeysMngrGetDataStore",
1086 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1087 XMLSEC_ERRORS_NO_MESSAGE);
1091 subject = xmlNodeGetContent(node);
1092 if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) {
1093 if(subject != NULL) {
1096 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1097 xmlSecError(XMLSEC_ERRORS_HERE,
1098 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1099 xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1100 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1101 XMLSEC_ERRORS_NO_MESSAGE);
1107 cert = xmlSecMSCryptoX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx);
1109 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1110 xmlSecError(XMLSEC_ERRORS_HERE,
1111 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1113 XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1115 xmlSecErrorsSafeString(subject));
1123 ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1125 xmlSecError(XMLSEC_ERRORS_HERE,
1126 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1127 "xmlSecMSCryptoKeyDataX509AdoptCert",
1128 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1129 XMLSEC_ERRORS_NO_MESSAGE);
1130 CertFreeCertificateContext(cert);
1140 xmlSecMSCryptoX509SubjectNameNodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1141 xmlChar* buf = NULL;
1142 xmlNodePtr cur = NULL;
1144 xmlSecAssert2(cert != NULL, -1);
1145 xmlSecAssert2(node != NULL, -1);
1147 buf = xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Subject));
1149 xmlSecError(XMLSEC_ERRORS_HERE,
1151 "xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Subject))",
1152 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1153 XMLSEC_ERRORS_NO_MESSAGE);
1157 cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs);
1159 xmlSecError(XMLSEC_ERRORS_HERE,
1162 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1164 xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
1168 xmlSecNodeEncodeAndSetContent(cur, buf);
1174 xmlSecMSCryptoX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1175 xmlSecKeyDataStorePtr x509Store;
1177 xmlChar *issuerName;
1178 xmlChar *issuerSerial;
1179 PCCERT_CONTEXT cert;
1182 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1183 xmlSecAssert2(node != NULL, -1);
1184 xmlSecAssert2(keyInfoCtx != NULL, -1);
1185 xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1187 x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecMSCryptoX509StoreId);
1188 if(x509Store == NULL) {
1189 xmlSecError(XMLSEC_ERRORS_HERE,
1190 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1191 "xmlSecKeysMngrGetDataStore",
1192 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1193 XMLSEC_ERRORS_NO_MESSAGE);
1197 cur = xmlSecGetNextElementNode(node->children);
1199 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1200 xmlSecError(XMLSEC_ERRORS_HERE,
1201 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1202 xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
1203 XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1205 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1211 /* the first is required node X509IssuerName */
1212 if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
1213 xmlSecError(XMLSEC_ERRORS_HERE,
1214 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1215 xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
1216 XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1218 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1221 issuerName = xmlNodeGetContent(cur);
1222 if(issuerName == NULL) {
1223 xmlSecError(XMLSEC_ERRORS_HERE,
1224 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1225 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1226 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1228 xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1231 cur = xmlSecGetNextElementNode(cur->next);
1233 /* next is required node X509SerialNumber */
1234 if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs)) {
1235 xmlSecError(XMLSEC_ERRORS_HERE,
1236 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1237 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1238 XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1240 xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1241 xmlFree(issuerName);
1244 issuerSerial = xmlNodeGetContent(cur);
1245 if(issuerSerial == NULL) {
1246 xmlSecError(XMLSEC_ERRORS_HERE,
1247 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1248 xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber),
1249 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1251 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1252 xmlFree(issuerName);
1255 cur = xmlSecGetNextElementNode(cur->next);
1258 xmlSecError(XMLSEC_ERRORS_HERE,
1259 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1260 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1261 XMLSEC_ERRORS_R_UNEXPECTED_NODE,
1262 XMLSEC_ERRORS_NO_MESSAGE);
1263 xmlFree(issuerSerial);
1264 xmlFree(issuerName);
1268 cert = xmlSecMSCryptoX509StoreFindCert(x509Store, NULL, issuerName, issuerSerial, NULL, keyInfoCtx);
1270 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1271 xmlSecError(XMLSEC_ERRORS_HERE,
1272 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1274 XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1275 "issuerName=%s;issuerSerial=%s",
1276 xmlSecErrorsSafeString(issuerName),
1277 xmlSecErrorsSafeString(issuerSerial));
1278 xmlFree(issuerSerial);
1279 xmlFree(issuerName);
1283 xmlFree(issuerSerial);
1284 xmlFree(issuerName);
1288 ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1290 xmlSecError(XMLSEC_ERRORS_HERE,
1291 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1292 "xmlSecMSCryptoKeyDataX509AdoptCert",
1293 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1294 XMLSEC_ERRORS_NO_MESSAGE);
1295 CertFreeCertificateContext(cert);
1296 xmlFree(issuerSerial);
1297 xmlFree(issuerName);
1301 xmlFree(issuerSerial);
1302 xmlFree(issuerName);
1307 xmlSecMSCryptoX509IssuerSerialNodeWrite(PCCERT_CONTEXT cert,
1309 xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1311 xmlNodePtr issuerNameNode;
1312 xmlNodePtr issuerNumberNode;
1316 xmlSecAssert2(cert != NULL, -1);
1317 xmlSecAssert2(node != NULL, -1);
1319 /* create xml nodes */
1320 cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
1322 xmlSecError(XMLSEC_ERRORS_HERE,
1325 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1327 xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
1331 issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs);
1332 if(issuerNameNode == NULL) {
1333 xmlSecError(XMLSEC_ERRORS_HERE,
1336 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1338 xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1342 issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
1343 if(issuerNumberNode == NULL) {
1344 xmlSecError(XMLSEC_ERRORS_HERE,
1347 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1349 xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1354 buf = xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Issuer));
1356 xmlSecError(XMLSEC_ERRORS_HERE,
1358 "xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Issuer))",
1359 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1360 XMLSEC_ERRORS_NO_MESSAGE);
1363 xmlSecNodeEncodeAndSetContent(issuerNameNode, buf);
1366 ret = xmlSecMSCryptoASN1IntegerWrite(issuerNumberNode, &(cert->pCertInfo->SerialNumber));
1368 xmlSecError(XMLSEC_ERRORS_HERE,
1370 "xmlSecMSCryptoASN1IntegerWrite(&(cert->serialNumber))",
1371 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1372 XMLSEC_ERRORS_NO_MESSAGE);
1379 xmlSecMSCryptoX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1380 xmlSecKeyDataStorePtr x509Store;
1382 PCCERT_CONTEXT cert;
1385 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1386 xmlSecAssert2(node != NULL, -1);
1387 xmlSecAssert2(keyInfoCtx != NULL, -1);
1388 xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1390 x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecMSCryptoX509StoreId);
1391 if(x509Store == NULL) {
1392 xmlSecError(XMLSEC_ERRORS_HERE,
1393 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1394 "xmlSecKeysMngrGetDataStore",
1395 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1396 XMLSEC_ERRORS_NO_MESSAGE);
1400 ski = xmlNodeGetContent(node);
1401 if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) {
1405 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1406 xmlSecError(XMLSEC_ERRORS_HERE,
1407 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1408 xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1409 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1411 xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1417 cert = xmlSecMSCryptoX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx);
1421 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1422 xmlSecError(XMLSEC_ERRORS_HERE,
1423 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1425 XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1427 xmlSecErrorsSafeString(ski));
1433 ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1435 xmlSecError(XMLSEC_ERRORS_HERE,
1436 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1437 "xmlSecMSCryptoKeyDataX509AdoptCert",
1438 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1439 XMLSEC_ERRORS_NO_MESSAGE);
1440 CertFreeCertificateContext(cert);
1450 xmlSecMSCryptoX509SKINodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1451 xmlChar *buf = NULL;
1452 xmlNodePtr cur = NULL;
1454 xmlSecAssert2(cert != NULL, -1);
1455 xmlSecAssert2(node != NULL, -1);
1457 buf = xmlSecMSCryptoX509SKIWrite(cert);
1459 xmlSecError(XMLSEC_ERRORS_HERE,
1461 "xmlSecMSCryptoX509SKIWrite",
1462 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1463 XMLSEC_ERRORS_NO_MESSAGE);
1467 cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs);
1469 xmlSecError(XMLSEC_ERRORS_HERE,
1472 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1474 xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1478 xmlSecNodeEncodeAndSetContent(cur, buf);
1485 xmlSecMSCryptoX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1489 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1490 xmlSecAssert2(node != NULL, -1);
1491 xmlSecAssert2(keyInfoCtx != NULL, -1);
1493 content = xmlNodeGetContent(node);
1494 if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
1495 if(content != NULL) {
1498 if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1499 xmlSecError(XMLSEC_ERRORS_HERE,
1500 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1501 xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1502 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1503 XMLSEC_ERRORS_NO_MESSAGE);
1509 crl = xmlSecMSCryptoX509CrlBase64DerRead(content, keyInfoCtx);
1511 xmlSecError(XMLSEC_ERRORS_HERE,
1512 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1513 "xmlSecMSCryptoX509CrlBase64DerRead",
1514 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1515 XMLSEC_ERRORS_NO_MESSAGE);
1520 if (0 != xmlSecMSCryptoKeyDataX509AdoptCrl(data, crl)) {
1521 xmlSecError(XMLSEC_ERRORS_HERE,
1522 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1523 "xmlSecMSCryptoKeyDataX509AdoptCrl",
1524 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1525 XMLSEC_ERRORS_NO_MESSAGE);
1527 CertFreeCRLContext(crl);
1536 xmlSecMSCryptoX509CRLNodeWrite(PCCRL_CONTEXT crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1537 xmlChar* buf = NULL;
1538 xmlNodePtr cur = NULL;
1540 xmlSecAssert2(crl != NULL, -1);
1541 xmlSecAssert2(node != NULL, -1);
1542 xmlSecAssert2(keyInfoCtx != NULL, -1);
1544 /* set base64 lines size from context */
1545 buf = xmlSecMSCryptoX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize);
1547 xmlSecError(XMLSEC_ERRORS_HERE,
1549 "xmlSecMSCryptoX509CrlBase64DerWrite",
1550 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1551 XMLSEC_ERRORS_NO_MESSAGE);
1555 cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
1557 xmlSecError(XMLSEC_ERRORS_HERE,
1560 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1562 xmlSecErrorsSafeString(xmlSecNodeX509CRL));
1566 /* todo: add \n around base64 data - from context */
1567 /* todo: add errors check */
1568 xmlNodeSetContent(cur, xmlSecStringCR);
1569 xmlNodeSetContent(cur, buf);
1577 xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key,
1578 xmlSecKeyInfoCtxPtr keyInfoCtx) {
1579 xmlSecMSCryptoX509DataCtxPtr ctx;
1580 xmlSecKeyDataStorePtr x509Store;
1583 xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1584 xmlSecAssert2(key != NULL, -1);
1585 xmlSecAssert2(keyInfoCtx != NULL, -1);
1586 xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1588 ctx = xmlSecMSCryptoX509DataGetCtx(data);
1589 xmlSecAssert2(ctx != NULL, -1);
1590 xmlSecAssert2(ctx->hMemStore != 0, -1);
1592 x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecMSCryptoX509StoreId);
1593 if(x509Store == NULL) {
1594 xmlSecError(XMLSEC_ERRORS_HERE,
1595 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1596 "xmlSecKeysMngrGetDataStore",
1597 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1598 XMLSEC_ERRORS_NO_MESSAGE);
1602 if((ctx->keyCert == NULL) && (xmlSecKeyGetValue(key) == NULL)) {
1603 PCCERT_CONTEXT cert;
1605 cert = xmlSecMSCryptoX509StoreVerify(x509Store, ctx->hMemStore, keyInfoCtx);
1607 xmlSecKeyDataPtr keyValue = NULL;
1608 PCCERT_CONTEXT pCert = NULL;
1610 ctx->keyCert = CertDuplicateCertificateContext(cert);
1611 if(ctx->keyCert == NULL) {
1612 xmlSecError(XMLSEC_ERRORS_HERE,
1613 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1614 "CertDuplicateCertificateContext",
1615 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1616 XMLSEC_ERRORS_NO_MESSAGE);
1620 /* search key according to KeyReq */
1621 pCert = CertDuplicateCertificateContext( ctx->keyCert ) ;
1622 if( pCert == NULL ) {
1623 xmlSecError( XMLSEC_ERRORS_HERE,
1624 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1625 "CertDuplicateCertificateContext",
1626 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1627 XMLSEC_ERRORS_NO_MESSAGE);
1632 if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate ) == xmlSecKeyDataTypePrivate ) {
1633 keyValue = xmlSecMSCryptoCertAdopt( pCert, xmlSecKeyDataTypePrivate ) ;
1634 if(keyValue == NULL) {
1635 xmlSecError(XMLSEC_ERRORS_HERE,
1636 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1637 "xmlSecMSCryptoCertAdopt",
1638 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1639 XMLSEC_ERRORS_NO_MESSAGE);
1640 CertFreeCertificateContext( pCert ) ;
1644 } else if( ( keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePublic ) == xmlSecKeyDataTypePublic ) {
1645 keyValue = xmlSecMSCryptoCertAdopt( pCert, xmlSecKeyDataTypePublic ) ;
1646 if(keyValue == NULL) {
1647 xmlSecError(XMLSEC_ERRORS_HERE,
1648 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1649 "xmlSecMSCryptoCertAdopt",
1650 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1651 XMLSEC_ERRORS_NO_MESSAGE);
1652 CertFreeCertificateContext( pCert ) ;
1658 /* verify that the key matches our expectations */
1659 if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) {
1660 xmlSecError(XMLSEC_ERRORS_HERE,
1661 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1662 "xmlSecKeyReqMatchKeyValue",
1663 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1664 XMLSEC_ERRORS_NO_MESSAGE);
1665 xmlSecKeyDataDestroy(keyValue);
1669 ret = xmlSecKeySetValue(key, keyValue);
1671 xmlSecError(XMLSEC_ERRORS_HERE,
1672 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1673 "xmlSecKeySetValue",
1674 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1675 XMLSEC_ERRORS_NO_MESSAGE);
1676 xmlSecKeyDataDestroy(keyValue);
1680 ret = xmlSecMSCryptoX509CertGetTime(ctx->keyCert->pCertInfo->NotBefore, &(key->notValidBefore));
1682 xmlSecError(XMLSEC_ERRORS_HERE,
1683 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1684 "xmlSecMSCryptoX509CertGetTime",
1685 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1690 ret = xmlSecMSCryptoX509CertGetTime(ctx->keyCert->pCertInfo->NotAfter, &(key->notValidAfter));
1692 xmlSecError(XMLSEC_ERRORS_HERE,
1693 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1694 "xmlSecMSCryptoX509CertGetTime",
1695 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1699 } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT) != 0) {
1700 xmlSecError(XMLSEC_ERRORS_HERE,
1701 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1703 XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1704 XMLSEC_ERRORS_NO_MESSAGE);
1712 xmlSecMSCryptoX509CertGetTime(FILETIME t, time_t* res) {
1715 xmlSecAssert2(res != NULL, -1);
1717 result = t.dwHighDateTime;
1718 result = (result) << 32;
1719 result |= t.dwLowDateTime;
1720 result /= 10000; /* Convert from 100 nano-sec periods to seconds. */
1721 #if defined(__MINGW32__)
1722 result -= 11644473600000ULL; /* Convert from Windows epoch to Unix epoch */
1724 result -= 11644473600000; /* Convert from Windows epoch to Unix epoch */
1727 (*res) = (time_t)result;
1732 static PCCERT_CONTEXT
1733 xmlSecMSCryptoX509CertBase64DerRead(xmlChar* buf) {
1736 xmlSecAssert2(buf != NULL, NULL);
1738 /* usual trick with base64 decoding "in-place" */
1739 ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf));
1741 xmlSecError(XMLSEC_ERRORS_HERE,
1743 "xmlSecBase64Decode",
1744 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1745 XMLSEC_ERRORS_NO_MESSAGE);
1749 return(xmlSecMSCryptoX509CertDerRead((xmlSecByte*)buf, ret));
1753 static PCCERT_CONTEXT
1754 xmlSecMSCryptoX509CertDerRead(const xmlSecByte* buf, xmlSecSize size) {
1755 PCCERT_CONTEXT cert;
1757 xmlSecAssert2(buf != NULL, NULL);
1758 xmlSecAssert2(size > 0, NULL);
1760 cert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, buf, size);
1762 xmlSecError(XMLSEC_ERRORS_HERE,
1764 "CertCreateCertificateContext",
1765 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1766 XMLSEC_ERRORS_NO_MESSAGE);
1774 xmlSecMSCryptoX509CertBase64DerWrite(PCCERT_CONTEXT cert, int base64LineWrap) {
1775 xmlChar *res = NULL;
1776 xmlSecByte *p = NULL;
1779 xmlSecAssert2(cert != NULL, NULL);
1781 p = cert->pbCertEncoded;
1782 size = cert->cbCertEncoded;
1783 if((size <= 0) || (p == NULL)){
1784 xmlSecError(XMLSEC_ERRORS_HERE,
1786 "cert->pbCertEncoded",
1787 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1788 XMLSEC_ERRORS_NO_MESSAGE);
1792 res = xmlSecBase64Encode(p, size, base64LineWrap);
1794 xmlSecError(XMLSEC_ERRORS_HERE,
1796 "xmlSecBase64Encode",
1797 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1798 XMLSEC_ERRORS_NO_MESSAGE);
1805 static PCCRL_CONTEXT
1806 xmlSecMSCryptoX509CrlBase64DerRead(xmlChar* buf,
1807 xmlSecKeyInfoCtxPtr keyInfoCtx) {
1810 xmlSecAssert2(buf != NULL, NULL);
1812 /* usual trick with base64 decoding "in-place" */
1813 ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf));
1815 xmlSecError(XMLSEC_ERRORS_HERE,
1817 "xmlSecBase64Decode",
1818 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1819 XMLSEC_ERRORS_NO_MESSAGE);
1823 return(xmlSecMSCryptoX509CrlDerRead((xmlSecByte*)buf, ret, keyInfoCtx));
1827 static PCCRL_CONTEXT
1828 xmlSecMSCryptoX509CrlDerRead(xmlSecByte* buf, xmlSecSize size,
1829 xmlSecKeyInfoCtxPtr keyInfoCtx) {
1830 PCCRL_CONTEXT crl = NULL;
1832 xmlSecAssert2(buf != NULL, NULL);
1833 xmlSecAssert2(keyInfoCtx != NULL, NULL);
1834 xmlSecAssert2(size > 0, NULL);
1836 crl = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, buf, size);
1839 xmlSecError(XMLSEC_ERRORS_HERE,
1841 "CertCreateCRLContext",
1842 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1843 XMLSEC_ERRORS_NO_MESSAGE);
1851 xmlSecMSCryptoX509CrlBase64DerWrite(PCCRL_CONTEXT crl, int base64LineWrap) {
1852 xmlChar *res = NULL;
1853 xmlSecByte *p = NULL;
1856 xmlSecAssert2(crl != NULL, NULL);
1858 p = crl->pbCrlEncoded;
1859 size = crl->cbCrlEncoded;
1860 if((size <= 0) || (p == NULL)){
1861 xmlSecError(XMLSEC_ERRORS_HERE,
1863 "crl->pbCrlEncoded",
1864 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1865 XMLSEC_ERRORS_NO_MESSAGE);
1869 res = xmlSecBase64Encode(p, size, base64LineWrap);
1871 xmlSecError(XMLSEC_ERRORS_HERE,
1873 "xmlSecBase64Encode",
1874 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1875 XMLSEC_ERRORS_NO_MESSAGE);
1883 xmlSecMSCryptoX509NameWrite(PCERT_NAME_BLOB nm) {
1884 xmlChar *res = NULL;
1889 xmlSecAssert2(nm->pbData != NULL, NULL);
1890 xmlSecAssert2(nm->cbData > 0, NULL);
1892 csz = CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, nm, CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, NULL, 0);
1893 str = (char *)xmlMalloc(csz);
1895 xmlSecError(XMLSEC_ERRORS_HERE,
1898 XMLSEC_ERRORS_R_MALLOC_FAILED,
1899 XMLSEC_ERRORS_NO_MESSAGE);
1903 csz = CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, nm, CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, str, csz);
1905 xmlSecError(XMLSEC_ERRORS_HERE,
1908 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1909 XMLSEC_ERRORS_NO_MESSAGE);
1914 /* aleksey: this is a hack, but mscrypto can not read E= flag and wants Email= instead.
1915 * don't ask me how is it possible not to read something you wrote yourself but also
1916 * see comment in the xmlSecMSCryptoX509FindCert function.
1918 if(strncmp(str, "E=", 2) == 0) {
1919 res = xmlMalloc(strlen(str) + 13 + 1);
1921 xmlSecError(XMLSEC_ERRORS_HERE,
1924 XMLSEC_ERRORS_R_MALLOC_FAILED,
1926 strlen(str) + 13 + 1);
1931 memcpy(res, "emailAddress=", 13);
1932 strcpy(res + 13, BAD_CAST (str + 2));
1934 res = xmlStrdup(BAD_CAST str);
1936 xmlSecError(XMLSEC_ERRORS_HERE,
1939 XMLSEC_ERRORS_R_MALLOC_FAILED,
1940 XMLSEC_ERRORS_NO_MESSAGE);
1952 xmlSecMSCryptoASN1IntegerWrite(xmlNodePtr node, PCRYPT_INTEGER_BLOB num) {
1956 xmlSecAssert2(node != NULL, -1);
1957 xmlSecAssert2(num != NULL, -1);
1959 ret = xmlSecBnInitialize(&bn, num->cbData + 1);
1961 xmlSecError(XMLSEC_ERRORS_HERE,
1963 "xmlSecBnInitialize",
1964 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1965 "size=%ld", num->cbData + 1);
1969 ret = xmlSecBnSetData(&bn, num->pbData, num->cbData);
1971 xmlSecError(XMLSEC_ERRORS_HERE,
1974 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1975 XMLSEC_ERRORS_NO_MESSAGE);
1976 xmlSecBnFinalize(&bn);
1980 /* I have no clue why at a sudden a swap is needed to
1981 * convert from lsb... This code is purely based upon
1982 * trial and error :( WK
1984 ret = xmlSecBnSetNodeValue(&bn, node, xmlSecBnDec, 1, 0);
1986 xmlSecError(XMLSEC_ERRORS_HERE,
1988 "xmlSecBnSetNodeValue",
1989 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1990 XMLSEC_ERRORS_NO_MESSAGE);
1991 xmlSecBnFinalize(&bn);
1995 xmlSecBnFinalize(&bn);
2000 xmlSecMSCryptoX509SKIWrite(PCCERT_CONTEXT cert) {
2001 xmlChar *res = NULL;
2004 PCERT_EXTENSION pCertExt;
2006 xmlSecAssert2(cert != NULL, NULL);
2008 /* First check if the SKI extension actually exists, otherwise we get a SHA1 hash o fthe key/cert */
2009 pCertExt = CertFindExtension(szOID_SUBJECT_KEY_IDENTIFIER, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
2010 if (pCertExt == NULL) {
2011 xmlSecError(XMLSEC_ERRORS_HERE,
2013 "CertFindExtension",
2014 XMLSEC_ERRORS_R_CRYPTO_FAILED,
2015 XMLSEC_ERRORS_NO_MESSAGE);
2019 if (!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &dwSize) || dwSize < 1) {
2020 xmlSecError(XMLSEC_ERRORS_HERE,
2022 "CertGetCertificateContextProperty",
2023 XMLSEC_ERRORS_R_CRYPTO_FAILED,
2024 XMLSEC_ERRORS_NO_MESSAGE);
2027 bSKI = xmlMalloc(dwSize);
2029 xmlSecError(XMLSEC_ERRORS_HERE,
2032 XMLSEC_ERRORS_R_MALLOC_FAILED,
2033 XMLSEC_ERRORS_NO_MESSAGE);
2037 if (!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, bSKI, &dwSize)) {
2038 xmlSecError(XMLSEC_ERRORS_HERE,
2040 "CertGetCertificateContextProperty",
2041 XMLSEC_ERRORS_R_CRYPTO_FAILED,
2042 XMLSEC_ERRORS_NO_MESSAGE);
2051 res = xmlSecBase64Encode(bSKI, dwSize, 0);
2053 xmlSecError(XMLSEC_ERRORS_HERE,
2055 "xmlSecBase64Encode",
2056 XMLSEC_ERRORS_R_XMLSEC_FAILED,
2057 XMLSEC_ERRORS_NO_MESSAGE);
2068 xmlSecMSCryptoX509CertDebugDump(PCCERT_CONTEXT cert, FILE* output) {
2069 PCRYPT_INTEGER_BLOB sn;
2071 LPSTR subject, issuer;
2074 xmlSecAssert(cert != NULL);
2075 xmlSecAssert(output != NULL);
2077 /* todo: add error checks */
2078 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, NULL, 0);
2079 subject = (LPSTR)xmlMalloc(dwSize);
2080 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, subject, dwSize);
2081 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
2082 issuer = (LPSTR)xmlMalloc(dwSize);
2083 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, CERT_NAME_ISSUER_FLAG, NULL, issuer, dwSize);
2085 fprintf(output, "=== X509 Certificate\n");
2086 fprintf(output, "==== Subject Name: %s\n", subject);
2087 fprintf(output, "==== Issuer Name: %s\n", issuer);
2088 if (subject) xmlFree(subject);
2089 if (issuer) xmlFree(issuer);
2090 sn = &(cert->pCertInfo->SerialNumber);
2092 for (i = 0; i < sn->cbData; i++) {
2093 if (i != sn->cbData - 1) {
2094 fprintf(output, "%02x:", sn->pbData[i]);
2096 fprintf(output, "%02x", sn->pbData[i]);
2099 fprintf(output, "\n");
2104 xmlSecMSCryptoX509CertDebugXmlDump(PCCERT_CONTEXT cert, FILE* output) {
2105 PCRYPT_INTEGER_BLOB sn;
2107 LPSTR subject, issuer;
2110 xmlSecAssert(cert != NULL);
2111 xmlSecAssert(output != NULL);
2113 /* todo: add error checks */
2116 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, NULL, 0);
2117 subject = (LPSTR)xmlMalloc(dwSize);
2118 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, subject, dwSize);
2120 fprintf(output, "<SubjectName>");
2121 xmlSecPrintXmlString(output, BAD_CAST subject);
2122 fprintf(output, "</SubjectName>\n");
2127 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
2128 issuer = (LPSTR)xmlMalloc(dwSize);
2129 dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, CERT_NAME_ISSUER_FLAG, NULL, issuer, dwSize);
2131 fprintf(output, "<IssuerName>");
2132 xmlSecPrintXmlString(output, BAD_CAST issuer);
2133 fprintf(output, "</IssuerName>\n");
2137 fprintf(output, "<SerialNumber>");
2138 sn = &(cert->pCertInfo->SerialNumber);
2139 for (i = 0; i < sn->cbData; i++) {
2140 if (i != sn->cbData - 1) {
2141 fprintf(output, "%02x:", sn->pbData[i]);
2143 fprintf(output, "%02x", sn->pbData[i]);
2146 fprintf(output, "</SerialNumber>\n");
2150 /**************************************************************************
2152 * Raw X509 Certificate processing
2155 *************************************************************************/
2156 static int xmlSecMSCryptoKeyDataRawX509CertBinRead (xmlSecKeyDataId id,
2158 const xmlSecByte* buf,
2160 xmlSecKeyInfoCtxPtr keyInfoCtx);
2162 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataRawX509CertKlass = {
2163 sizeof(xmlSecKeyDataKlass),
2164 sizeof(xmlSecKeyData),
2167 xmlSecNameRawX509Cert,
2168 xmlSecKeyDataUsageRetrievalMethodNodeBin,
2169 /* xmlSecKeyDataUsage usage; */
2170 xmlSecHrefRawX509Cert, /* const xmlChar* href; */
2171 NULL, /* const xmlChar* dataNodeName; */
2172 xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
2174 /* constructors/destructor */
2175 NULL, /* xmlSecKeyDataInitializeMethod initialize; */
2176 NULL, /* xmlSecKeyDataDuplicateMethod duplicate; */
2177 NULL, /* xmlSecKeyDataFinalizeMethod finalize; */
2178 NULL, /* xmlSecKeyDataGenerateMethod generate; */
2181 NULL, /* xmlSecKeyDataGetTypeMethod getType; */
2182 NULL, /* xmlSecKeyDataGetSizeMethod getSize; */
2183 NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */
2186 NULL, /* xmlSecKeyDataXmlReadMethod xmlRead; */
2187 NULL, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2188 xmlSecMSCryptoKeyDataRawX509CertBinRead, /* xmlSecKeyDataBinReadMethod binRead; */
2189 NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
2192 NULL, /* xmlSecKeyDataDebugDumpMethod debugDump; */
2193 NULL, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2195 /* reserved for the future */
2196 NULL, /* void* reserved0; */
2197 NULL, /* void* reserved1; */
2201 * xmlSecMSCryptoKeyDataRawX509CertGetKlass:
2203 * The raw X509 certificates key data klass.
2205 * Returns: raw X509 certificates key data klass.
2208 xmlSecMSCryptoKeyDataRawX509CertGetKlass(void) {
2209 return(&xmlSecMSCryptoKeyDataRawX509CertKlass);
2213 xmlSecMSCryptoKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
2214 const xmlSecByte* buf, xmlSecSize bufSize,
2215 xmlSecKeyInfoCtxPtr keyInfoCtx) {
2216 xmlSecKeyDataPtr data;
2217 PCCERT_CONTEXT cert;
2220 xmlSecAssert2(id == xmlSecMSCryptoKeyDataRawX509CertId, -1);
2221 xmlSecAssert2(key != NULL, -1);
2222 xmlSecAssert2(buf != NULL, -1);
2223 xmlSecAssert2(bufSize > 0, -1);
2224 xmlSecAssert2(keyInfoCtx != NULL, -1);
2226 cert = xmlSecMSCryptoX509CertDerRead(buf, bufSize);
2228 xmlSecError(XMLSEC_ERRORS_HERE,
2230 "xmlSecMSCryptoX509CertDerRead",
2231 XMLSEC_ERRORS_R_XMLSEC_FAILED,
2232 XMLSEC_ERRORS_NO_MESSAGE);
2236 data = xmlSecKeyEnsureData(key, xmlSecMSCryptoKeyDataX509Id);
2238 xmlSecError(XMLSEC_ERRORS_HERE,
2239 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2240 "xmlSecKeyEnsureData",
2241 XMLSEC_ERRORS_R_XMLSEC_FAILED,
2242 XMLSEC_ERRORS_NO_MESSAGE);
2243 CertFreeCertificateContext(cert);
2247 ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
2249 xmlSecError(XMLSEC_ERRORS_HERE,
2250 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2251 "xmlSecMSCryptoKeyDataX509AdoptCert",
2252 XMLSEC_ERRORS_R_XMLSEC_FAILED,
2253 XMLSEC_ERRORS_NO_MESSAGE);
2254 CertFreeCertificateContext(cert);
2258 ret = xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
2260 xmlSecError(XMLSEC_ERRORS_HERE,
2261 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2262 "xmlSecMSCryptoKeyDataX509VerifyAndExtractKey",
2263 XMLSEC_ERRORS_R_XMLSEC_FAILED,
2264 XMLSEC_ERRORS_NO_MESSAGE);
2270 #endif /* XMLSEC_NO_X509 */