Git init
[external/xmlsec1.git] / src / mscrypto / x509.c
1 /** 
2  * XMLSec library
3  *
4  * X509 support
5  *
6  *
7  * This is free software; see Copyright file in the source
8  * distribution for preciese wording.
9  * 
10  * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
11  * Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com>
12  */
13
14 #include "globals.h"
15
16 #ifndef XMLSEC_NO_X509
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <time.h>
24
25 #include <windows.h>
26 #include <wincrypt.h>
27
28 #include <libxml/tree.h>
29
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>
39
40 #include <xmlsec/mscrypto/crypto.h>
41 #include <xmlsec/mscrypto/x509.h>
42 #include <xmlsec/mscrypto/certkeys.h>
43
44 #if defined(__MINGW32__)
45 #  include "xmlsec-mingw.h"
46 #endif
47
48
49 /*************************************************************************
50  *
51  * X509 utility functions
52  *
53  ************************************************************************/
54 static int              xmlSecMSCryptoX509DataNodeRead          (xmlSecKeyDataPtr data,
55                                                                  xmlNodePtr node,
56                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
57 static int              xmlSecMSCryptoX509CertificateNodeRead   (xmlSecKeyDataPtr data,
58                                                                  xmlNodePtr node,
59                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
60 static int              xmlSecMSCryptoX509CertificateNodeWrite  (PCCERT_CONTEXT cert,
61                                                                  xmlNodePtr node,
62                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
63 static int              xmlSecMSCryptoX509SubjectNameNodeRead   (xmlSecKeyDataPtr data,
64                                                                  xmlNodePtr node,
65                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
66 static int              xmlSecMSCryptoX509SubjectNameNodeWrite  (PCCERT_CONTEXT cert,
67                                                                  xmlNodePtr node,
68                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
69 static int              xmlSecMSCryptoX509IssuerSerialNodeRead  (xmlSecKeyDataPtr data,
70                                                                  xmlNodePtr node,
71                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
72 static int              xmlSecMSCryptoX509IssuerSerialNodeWrite (PCCERT_CONTEXT cert,
73                                                                  xmlNodePtr node,
74                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
75 static int              xmlSecMSCryptoX509SKINodeRead           (xmlSecKeyDataPtr data,
76                                                                  xmlNodePtr node,
77                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
78 static int              xmlSecMSCryptoX509SKINodeWrite          (PCCERT_CONTEXT cert,
79                                                                  xmlNodePtr node,
80                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
81 static int              xmlSecMSCryptoX509CRLNodeRead           (xmlSecKeyDataPtr data,
82                                                                  xmlNodePtr node,
83                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
84 static int              xmlSecMSCryptoX509CRLNodeWrite          (PCCRL_CONTEXT crl,
85                                                                  xmlNodePtr node,
86                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
87 static int              xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, 
88                                                                 xmlSecKeyPtr key,
89                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
90
91 static PCCERT_CONTEXT   xmlSecMSCryptoX509CertDerRead           (const xmlSecByte* buf, 
92                                                                  xmlSecSize size);
93 static PCCERT_CONTEXT   xmlSecMSCryptoX509CertBase64DerRead     (xmlChar* buf);
94 static xmlChar*         xmlSecMSCryptoX509CertBase64DerWrite    (PCCERT_CONTEXT cert, 
95                                                                  int base64LineWrap);
96 static PCCRL_CONTEXT    xmlSecMSCryptoX509CrlDerRead            (xmlSecByte* buf, 
97                                                                  xmlSecSize size,
98                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
99 static PCCRL_CONTEXT xmlSecMSCryptoX509CrlBase64DerRead         (xmlChar* buf,
100                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
101 static xmlChar*         xmlSecMSCryptoX509CrlBase64DerWrite     (PCCRL_CONTEXT crl, 
102                                                                  int base64LineWrap);
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, 
108                                                                  FILE* output);
109 static void             xmlSecMSCryptoX509CertDebugXmlDump      (PCCERT_CONTEXT cert, 
110                                                                  FILE* output);
111 static int              xmlSecMSCryptoX509CertGetTime           (FILETIME t,
112                                                                  time_t* res);
113
114 /*************************************************************************
115  *
116  * Internal MSCrypto X509 data CTX
117  *
118  ************************************************************************/
119 typedef struct _xmlSecMSCryptoX509DataCtx       xmlSecMSCryptoX509DataCtx,
120                                                 *xmlSecMSCryptoX509DataCtxPtr;
121
122 struct _xmlSecMSCryptoX509DataCtx {
123     PCCERT_CONTEXT  keyCert;
124
125     HCERTSTORE hMemStore;
126     unsigned int numCerts;
127     unsigned int numCrls;
128 };
129
130 /**************************************************************************
131  *
132  * <dsig:X509Data> processing
133  *
134  *
135  * The X509Data  Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data)
136  *
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:
140  *
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:
142  *  2.
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] 
151  *      certificate, and
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].
156  *
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.
162  *
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.
166  *
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.
170  *
171  * No ordering is implied by the above constraints.
172  *
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 
178  * signature.
179  *
180  * Schema Definition
181  *
182  *  <element name="X509Data" type="ds:X509DataType"/> 
183  *  <complexType name="X509DataType">
184  *    <sequence maxOccurs="unbounded">
185  *      <choice>
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"/>
192  *      </choice>
193  *    </sequence>
194  *  </complexType>
195  *  <complexType name="X509IssuerSerialType"> 
196  *    <sequence> 
197  *       <element name="X509IssuerName" type="string"/> 
198  *       <element name="X509SerialNumber" type="integer"/> 
199  *     </sequence>
200  *  </complexType>
201  *
202  *  DTD
203  *
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) >
213  *
214  * -----------------------------------------------------------------------
215  *
216  * xmlSecMSCryptoX509DataCtx is located after xmlSecTransform
217  *
218  *************************************************************************/
219 #define xmlSecMSCryptoX509DataSize      \
220     (sizeof(xmlSecKeyData) + sizeof(xmlSecMSCryptoX509DataCtx)) 
221 #define xmlSecMSCryptoX509DataGetCtx(data) \
222     ((xmlSecMSCryptoX509DataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
223
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,
229                                                                  xmlSecKeyPtr key,
230                                                                  xmlNodePtr node,
231                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
232 static int              xmlSecMSCryptoKeyDataX509XmlWrite       (xmlSecKeyDataId id,
233                                                                  xmlSecKeyPtr key,
234                                                                  xmlNodePtr node,
235                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
236 static xmlSecKeyDataType xmlSecMSCryptoKeyDataX509GetType       (xmlSecKeyDataPtr data);
237 static const xmlChar* xmlSecMSCryptoKeyDataX509GetIdentifier    (xmlSecKeyDataPtr data);
238
239 static void             xmlSecMSCryptoKeyDataX509DebugDump      (xmlSecKeyDataPtr data,
240                                                                  FILE* output);
241 static void             xmlSecMSCryptoKeyDataX509DebugXmlDump   (xmlSecKeyDataPtr data,
242                                                                  FILE* output);
243
244
245
246 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataX509Klass = {
247     sizeof(xmlSecKeyDataKlass),
248     xmlSecMSCryptoX509DataSize,
249
250     /* data */
251     xmlSecNameX509Data,
252     xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, 
253                                                 /* xmlSecKeyDataUsage usage; */
254     xmlSecHrefX509Data,                         /* const xmlChar* href; */
255     xmlSecNodeX509Data,                         /* const xmlChar* dataNodeName; */
256     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
257     
258     /* constructors/destructor */
259     xmlSecMSCryptoKeyDataX509Initialize,        /* xmlSecKeyDataInitializeMethod initialize; */
260     xmlSecMSCryptoKeyDataX509Duplicate,         /* xmlSecKeyDataDuplicateMethod duplicate; */
261     xmlSecMSCryptoKeyDataX509Finalize,          /* xmlSecKeyDataFinalizeMethod finalize; */
262     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
263
264     /* get info */
265     xmlSecMSCryptoKeyDataX509GetType,           /* xmlSecKeyDataGetTypeMethod getType; */
266     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
267     xmlSecMSCryptoKeyDataX509GetIdentifier,     /* xmlSecKeyDataGetIdentifier getIdentifier; */    
268
269     /* read/write */
270     xmlSecMSCryptoKeyDataX509XmlRead,           /* xmlSecKeyDataXmlReadMethod xmlRead; */
271     xmlSecMSCryptoKeyDataX509XmlWrite,          /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
272     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
273     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
274
275     /* debug */
276     xmlSecMSCryptoKeyDataX509DebugDump,         /* xmlSecKeyDataDebugDumpMethod debugDump; */
277     xmlSecMSCryptoKeyDataX509DebugXmlDump,      /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
278
279     /* reserved for the future */
280     NULL,                                       /* void* reserved0; */
281     NULL,                                       /* void* reserved1; */
282 };
283
284 /** 
285  * xmlSecMSCryptoKeyDataX509GetKlass:
286  * 
287  * The MSCrypto X509 key data klass (http://www.w3.org/TR/xmldsig-core/#sec-X509Data).
288  *
289  * Returns: the X509 data klass.
290  */
291 xmlSecKeyDataId 
292 xmlSecMSCryptoKeyDataX509GetKlass(void) {
293     return(&xmlSecMSCryptoKeyDataX509Klass);
294 }
295
296 /**
297  * xmlSecMSCryptoKeyDataX509GetKeyCert:
298  * @data:               the pointer to X509 key data.
299  *
300  * Gets the certificate from which the key was extracted. 
301  *
302  * Returns: the key's certificate or NULL if key data was not used for key
303  * extraction or an error occurs.
304  */
305 PCCERT_CONTEXT
306 xmlSecMSCryptoKeyDataX509GetKeyCert(xmlSecKeyDataPtr data) {
307     xmlSecMSCryptoX509DataCtxPtr ctx;
308     
309     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
310
311     ctx = xmlSecMSCryptoX509DataGetCtx(data);
312     xmlSecAssert2(ctx != NULL, NULL);
313
314     return(ctx->keyCert);
315 }
316
317 /**
318  * xmlSecMSCryptoKeyDataX509AdoptKeyCert:
319  * @data:               the pointer to X509 key data.
320  * @cert:               the pointer to MSCRYPTO X509 certificate.
321  *
322  * Sets the key's certificate in @data.
323  *
324  * Returns: 0 on success or a negative value if an error occurs.
325  */
326 int
327 xmlSecMSCryptoKeyDataX509AdoptKeyCert(xmlSecKeyDataPtr data, PCCERT_CONTEXT cert) {
328     xmlSecMSCryptoX509DataCtxPtr ctx;
329
330     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
331     xmlSecAssert2(cert != NULL, -1);
332
333     ctx = xmlSecMSCryptoX509DataGetCtx(data);
334     xmlSecAssert2(ctx != NULL, -1);
335
336     if(ctx->keyCert != NULL) {
337         CertFreeCertificateContext(ctx->keyCert);
338         ctx->keyCert = 0;
339     }
340     ctx->keyCert = cert;
341
342     return(0);
343 }
344
345 /**
346  * xmlSecMSCryptoKeyDataX509AdoptCert:
347  * @data:               the pointer to X509 key data.
348  * @cert:               the pointer to MSCRYPTO X509 certificate.
349  *
350  * Adds certificate to the X509 key data.
351  *
352  * Returns: 0 on success or a negative value if an error occurs.
353  */
354 int 
355 xmlSecMSCryptoKeyDataX509AdoptCert(xmlSecKeyDataPtr data, PCCERT_CONTEXT cert) {
356     xmlSecMSCryptoX509DataCtxPtr ctx;
357
358     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
359     xmlSecAssert2(cert != NULL, -1);
360
361     ctx = xmlSecMSCryptoX509DataGetCtx(data);
362     xmlSecAssert2(ctx != NULL, -1);
363     xmlSecAssert2(ctx->hMemStore != 0, -1);
364
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);
371         return(-1);     
372     }
373     CertFreeCertificateContext(cert);
374     ctx->numCerts++;
375       
376     return(0);
377 }
378
379 /**
380  * xmlSecMSCryptoKeyDataX509GetCert:
381  * @data:               the pointer to X509 key data.
382  * @pos:                the desired certificate position.
383  * 
384  * Gets a certificate from X509 key data.
385  *
386  * Returns: the pointer to certificate or NULL if @pos is larger than the 
387  * number of certificates in @data or an error occurs.
388  */
389 PCCERT_CONTEXT 
390 xmlSecMSCryptoKeyDataX509GetCert(xmlSecKeyDataPtr data, xmlSecSize pos) {
391     xmlSecMSCryptoX509DataCtxPtr ctx;
392     PCCERT_CONTEXT pCert = NULL;
393
394     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
395
396     ctx = xmlSecMSCryptoX509DataGetCtx(data);
397     xmlSecAssert2(ctx != NULL, NULL);
398     xmlSecAssert2(ctx->hMemStore != 0, NULL);
399     xmlSecAssert2(ctx->numCerts > pos, NULL);
400
401     while ((pCert = CertEnumCertificatesInStore(ctx->hMemStore, pCert)) && (pos > 0)) {
402         pos--;
403     }
404
405     return(pCert);
406 }
407
408 /**
409  * xmlSecMSCryptoKeyDataX509GetCertsSize:
410  * @data:               the pointer to X509 key data.
411  *
412  * Gets the number of certificates in @data.
413  *
414  * Returns: te number of certificates in @data.
415  */
416 xmlSecSize      
417 xmlSecMSCryptoKeyDataX509GetCertsSize(xmlSecKeyDataPtr data) {
418     xmlSecMSCryptoX509DataCtxPtr ctx;
419
420     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), 0);
421
422     ctx = xmlSecMSCryptoX509DataGetCtx(data);
423     xmlSecAssert2(ctx != NULL, 0);
424
425     return(ctx->numCerts);
426 }
427
428 /**
429  * xmlSecMSCryptoKeyDataX509AdoptCrl:
430  * @data:               the pointer to X509 key data.
431  * @crl:                the pointer to MSCrypto X509 CRL.
432  *
433  * Adds CRL to the X509 key data.
434  *
435  * Returns: 0 on success or a negative value if an error occurs.
436  */
437 int 
438 xmlSecMSCryptoKeyDataX509AdoptCrl(xmlSecKeyDataPtr data, PCCRL_CONTEXT crl) {
439     xmlSecMSCryptoX509DataCtxPtr ctx;
440
441     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
442     xmlSecAssert2(crl != 0, -1);
443
444     ctx = xmlSecMSCryptoX509DataGetCtx(data);
445     xmlSecAssert2(ctx != NULL, -1);
446     xmlSecAssert2(ctx->hMemStore != 0, -1);
447
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);
454         return(-1);     
455     }
456     ctx->numCrls++;
457
458     return(0);
459 }
460
461 /**
462  * xmlSecMSCryptoKeyDataX509GetCrl:
463  * @data:               the pointer to X509 key data.
464  * @pos:                the desired CRL position.
465  *
466  * Gets a CRL from X509 key data.
467  *
468  * Returns: the pointer to CRL or NULL if @pos is larger than the
469  * number of CRLs in @data or an error occurs.
470  */
471 PCCRL_CONTEXT
472 xmlSecMSCryptoKeyDataX509GetCrl(xmlSecKeyDataPtr data, xmlSecSize pos) {
473     xmlSecMSCryptoX509DataCtxPtr ctx;
474     PCCRL_CONTEXT pCRL = NULL;
475
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);
481
482     while ((pCRL = CertEnumCRLsInStore(ctx->hMemStore, pCRL)) && (pos > 0)) {
483         pos--;
484     }
485
486     return(pCRL);
487 }
488
489 /**
490  * xmlSecMSCryptoKeyDataX509GetCrlsSize:
491  * @data:               the pointer to X509 key data.
492  *
493  * Gets the number of CRLs in @data.
494  *
495  * Returns: te number of CRLs in @data.
496  */
497 xmlSecSize
498 xmlSecMSCryptoKeyDataX509GetCrlsSize(xmlSecKeyDataPtr data) {
499     xmlSecMSCryptoX509DataCtxPtr ctx;
500
501     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), 0);
502
503     ctx = xmlSecMSCryptoX509DataGetCtx(data);
504     xmlSecAssert2(ctx != NULL, 0);
505
506     return(ctx->numCrls);
507 }
508
509 static int      
510 xmlSecMSCryptoKeyDataX509Initialize(xmlSecKeyDataPtr data) {
511     xmlSecMSCryptoX509DataCtxPtr ctx;
512
513     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
514
515     ctx = xmlSecMSCryptoX509DataGetCtx(data);
516     xmlSecAssert2(ctx != NULL, -1);
517
518     memset(ctx, 0, sizeof(xmlSecMSCryptoX509DataCtx));
519
520     ctx->hMemStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
521                                    0, 
522                                    0, 
523                                    CERT_STORE_CREATE_NEW_FLAG, 
524                                    NULL);
525     if (ctx->hMemStore == 0) {
526         xmlSecError(XMLSEC_ERRORS_HERE,
527                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
528                     "CertOpenStore",
529                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
530                     XMLSEC_ERRORS_NO_MESSAGE);
531         return(-1);
532     }
533
534     return(0);
535 }
536
537 static int
538 xmlSecMSCryptoKeyDataX509Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
539     PCCERT_CONTEXT certSrc, certDst;
540     PCCRL_CONTEXT crlSrc, crlDst;
541     xmlSecSize size, pos;
542     int ret;
543
544     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataX509Id), -1);
545     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataX509Id), -1);
546
547     /* copy certsList */ 
548     size = xmlSecMSCryptoKeyDataX509GetCertsSize(src);
549     for(pos = 0; pos < size; ++pos) {
550         /* TBD: function below does linear scan, eliminate loop within
551         * loop
552         */
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,
559                         "pos=%d", pos);
560             return(-1);
561         }
562
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);
570             return(-1);
571         }
572
573         ret = xmlSecMSCryptoKeyDataX509AdoptCert(dst, certDst);
574         if(ret < 0) {
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);
581             return(-1);
582         }
583     }
584
585     /* copy crls */
586     size = xmlSecMSCryptoKeyDataX509GetCrlsSize(src);
587     for(pos = 0; pos < size; ++pos) {
588         crlSrc = xmlSecMSCryptoKeyDataX509GetCrl(src, pos);
589         if(crlSrc == NULL) {
590             xmlSecError(XMLSEC_ERRORS_HERE,
591                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
592                         "xmlSecMSCryptoKeyDataX509GetCrl",
593                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
594                         "pos=%d", pos);
595             return(-1);
596         }
597
598         crlDst = CertDuplicateCRLContext(crlSrc);
599         if(crlDst == NULL) {
600             xmlSecError(XMLSEC_ERRORS_HERE,
601                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
602                         "CertDuplicateCRLContext",
603                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
604                         XMLSEC_ERRORS_NO_MESSAGE);
605             return(-1);
606         }
607
608         ret = xmlSecMSCryptoKeyDataX509AdoptCrl(dst, crlDst);
609         if(ret < 0) {
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);
616             return(-1);
617         }
618     }
619
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);
630             return(-1);
631         }
632         ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(dst, certDst);
633         if(ret < 0) {
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);
640             return(-1);
641         }
642     }
643     return(0);
644 }
645
646 static void
647 xmlSecMSCryptoKeyDataX509Finalize(xmlSecKeyDataPtr data) {
648     xmlSecMSCryptoX509DataCtxPtr ctx;
649
650     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
651
652     ctx = xmlSecMSCryptoX509DataGetCtx(data);
653     xmlSecAssert(ctx != NULL);
654
655     if(ctx->keyCert != NULL) {
656         CertFreeCertificateContext(ctx->keyCert);
657         ctx->keyCert = NULL;
658     }
659
660     if (ctx->hMemStore != 0) {
661         if (!CertCloseStore(ctx->hMemStore, CERT_CLOSE_STORE_FORCE_FLAG)) {
662             xmlSecError(XMLSEC_ERRORS_HERE,
663                         NULL,
664                         "CertCloseStore",
665                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
666                         XMLSEC_ERRORS_NO_MESSAGE);
667             return;
668         }
669     }
670
671     memset(ctx, 0, sizeof(xmlSecMSCryptoX509DataCtx));
672 }
673
674 static int
675 xmlSecMSCryptoKeyDataX509XmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
676                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
677     xmlSecKeyDataPtr data;
678     int ret;
679
680     xmlSecAssert2(id == xmlSecMSCryptoKeyDataX509Id, -1);
681     xmlSecAssert2(key != NULL, -1);
682     xmlSecAssert2(node != NULL, -1);
683     xmlSecAssert2(keyInfoCtx != NULL, -1);
684
685     data = xmlSecKeyEnsureData(key, id);
686     if(data == NULL) {
687         xmlSecError(XMLSEC_ERRORS_HERE,
688                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
689                     "xmlSecKeyEnsureData",
690                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
691                     XMLSEC_ERRORS_NO_MESSAGE);
692         return(-1);
693     }
694
695     ret = xmlSecMSCryptoX509DataNodeRead(data, node, keyInfoCtx);
696     if(ret < 0) {
697         xmlSecError(XMLSEC_ERRORS_HERE,
698                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
699                     "xmlSecMSCryptoX509DataNodeRead",
700                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
701                     XMLSEC_ERRORS_NO_MESSAGE);
702         return(-1);
703     }
704
705     if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) {
706         ret = xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
707         if(ret < 0) {
708             xmlSecError(XMLSEC_ERRORS_HERE,
709                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
710                         "xmlSecMSCryptoKeyDataX509VerifyAndExtractKey",
711                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
712                         XMLSEC_ERRORS_NO_MESSAGE);
713             return(-1);
714         }
715     }
716     return(0);
717 }
718
719 static int 
720 xmlSecMSCryptoKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
721                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
722     xmlSecKeyDataPtr data;
723     PCCERT_CONTEXT cert;
724     PCCRL_CONTEXT crl;
725     xmlSecSize size, pos;
726     int content = 0;
727     int ret;
728                                 
729     xmlSecAssert2(id == xmlSecMSCryptoKeyDataX509Id, -1);
730     xmlSecAssert2(key != NULL, -1);
731     xmlSecAssert2(node != NULL, -1);
732     xmlSecAssert2(keyInfoCtx != NULL, -1);
733
734     content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx);
735     if (content < 0) {
736         xmlSecError(XMLSEC_ERRORS_HERE,
737                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
738                     "xmlSecX509DataGetNodeContent",
739                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
740                     "content=%d", content);
741         return(-1);
742     } else if(content == 0) {
743         /* by default we are writing certificates and crls */
744         content = XMLSEC_X509DATA_DEFAULT;
745     }
746
747     /* get x509 data */
748     data = xmlSecKeyGetData(key, id);
749     if(data == NULL) {
750         /* no x509 data in the key */
751         return(0);      
752     }
753
754     /* write certs */
755     size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
756     for(pos = 0; pos < size; ++pos) {
757         cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
758         if(cert == NULL) {
759             xmlSecError(XMLSEC_ERRORS_HERE,
760                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
761                         "xmlSecMSCryptoKeyDataX509GetCert",
762                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
763                         "pos=%d", pos);
764             return(-1);
765         }
766
767         if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) {
768             ret = xmlSecMSCryptoX509CertificateNodeWrite(cert, node, keyInfoCtx);
769             if(ret < 0) {
770                 xmlSecError(XMLSEC_ERRORS_HERE,
771                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
772                             "xmlSecMSCryptoX509CertificateNodeWrite",
773                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
774                             "pos=%d", pos);
775                 return(-1);
776             }
777         }
778
779         if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) {
780             ret = xmlSecMSCryptoX509SubjectNameNodeWrite(cert, node, keyInfoCtx);
781             if(ret < 0) {
782                 xmlSecError(XMLSEC_ERRORS_HERE,
783                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
784                             "xmlSecMSCryptoX509SubjectNameNodeWrite",
785                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
786                             "pos=%d", pos);
787                 return(-1);
788             }
789         }
790
791         if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) {
792             ret = xmlSecMSCryptoX509IssuerSerialNodeWrite(cert, node, keyInfoCtx);
793             if(ret < 0) {
794                 xmlSecError(XMLSEC_ERRORS_HERE,
795                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
796                             "xmlSecMSCryptoX509IssuerSerialNodeWrite",
797                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
798                             "pos=%d", pos);
799                 return(-1);
800             }
801         }
802
803         if((content & XMLSEC_X509DATA_SKI_NODE) != 0) {
804             ret = xmlSecMSCryptoX509SKINodeWrite(cert, node, keyInfoCtx);
805             if(ret < 0) {
806                 xmlSecError(XMLSEC_ERRORS_HERE,
807                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
808                             "xmlSecMSCryptoX509SKINodeWrite",
809                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
810                             "pos=%d", pos);
811                 return(-1);
812             }
813         }
814     }    
815
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);
821             if(crl == NULL) {
822                 xmlSecError(XMLSEC_ERRORS_HERE,
823                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
824                             "xmlSecMSCryptoKeyDataX509GetCrl",
825                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
826                             "pos=%d", pos);
827                 return(-1);
828             }
829
830             ret = xmlSecMSCryptoX509CRLNodeWrite(crl, node, keyInfoCtx);
831             if(ret < 0) {
832                 xmlSecError(XMLSEC_ERRORS_HERE,
833                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
834                             "xmlSecMSCryptoX509CRLNodeWrite",
835                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
836                             "pos=%d", pos);
837                 return(-1);
838             }
839         }
840     }
841
842     return(0);
843 }
844
845 static xmlSecKeyDataType
846 xmlSecMSCryptoKeyDataX509GetType(xmlSecKeyDataPtr data) {
847     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), xmlSecKeyDataTypeUnknown);
848
849     /* TODO: return verified/not verified status */     
850     return(xmlSecKeyDataTypeUnknown);
851 }
852
853 static const xmlChar*
854 xmlSecMSCryptoKeyDataX509GetIdentifier(xmlSecKeyDataPtr data) {
855     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), NULL);
856     
857     /* TODO */    
858     return(NULL);
859 }
860
861 static void 
862 xmlSecMSCryptoKeyDataX509DebugDump(xmlSecKeyDataPtr data, FILE* output) {
863     PCCERT_CONTEXT cert;
864     xmlSecSize size, pos;
865
866     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
867     xmlSecAssert(output != NULL);
868
869     fprintf(output, "=== X509 Data:\n");
870     cert = xmlSecMSCryptoKeyDataX509GetKeyCert(data);
871     if(cert != NULL) {
872         fprintf(output, "==== Key Certificate:\n");
873         xmlSecMSCryptoX509CertDebugDump(cert, output);
874     }
875
876     size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
877     for(pos = 0; pos < size; ++pos) {
878         cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
879         if(cert == NULL) {
880             xmlSecError(XMLSEC_ERRORS_HERE,
881                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
882                         "xmlSecMSCryptoKeyDataX509GetCert",
883                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
884                         "pos=%d", pos);
885             return;
886         }
887         fprintf(output, "==== Certificate:\n");
888         xmlSecMSCryptoX509CertDebugDump(cert, output);
889     }
890
891     /* we don't print out crls */
892 }
893
894 static void
895 xmlSecMSCryptoKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
896     PCCERT_CONTEXT cert;
897     xmlSecSize size, pos;
898
899     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id));
900     xmlSecAssert(output != NULL);
901
902     fprintf(output, "<X509Data>\n");
903     cert = xmlSecMSCryptoKeyDataX509GetKeyCert(data);
904     if(cert != NULL) {
905         fprintf(output, "<KeyCertificate>\n");
906         xmlSecMSCryptoX509CertDebugXmlDump(cert, output);
907         fprintf(output, "</KeyCertificate>\n");
908     }
909
910     size = xmlSecMSCryptoKeyDataX509GetCertsSize(data);
911     for(pos = 0; pos < size; ++pos) {
912         cert = xmlSecMSCryptoKeyDataX509GetCert(data, pos);
913         if(cert == NULL) {
914             xmlSecError(XMLSEC_ERRORS_HERE,
915                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
916                         "xmlSecMSCryptoKeyDataX509GetCert",
917                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
918                         "pos=%d", pos);
919             return;
920         }
921         fprintf(output, "<Certificate>\n");
922         xmlSecMSCryptoX509CertDebugXmlDump(cert, output);
923         fprintf(output, "</Certificate>\n");
924     }
925
926     /* we don't print out crls */
927     fprintf(output, "</X509Data>\n");
928 }
929
930 static int
931 xmlSecMSCryptoX509DataNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
932     xmlNodePtr cur; 
933     int ret;
934         
935     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
936     xmlSecAssert2(node != NULL, -1);
937     xmlSecAssert2(keyInfoCtx != NULL, -1);
938     
939     for(cur = xmlSecGetNextElementNode(node->children);
940         cur != NULL;
941         cur = xmlSecGetNextElementNode(cur->next)) {
942
943         ret = 0;
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);
961             return(-1);
962         }
963         if(ret < 0) {
964             xmlSecError(XMLSEC_ERRORS_HERE,
965                 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
966                 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
967                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
968                 "read node failed");
969             return(-1);  
970         }       
971     }
972     return(0);
973 }
974
975 static int
976 xmlSecMSCryptoX509CertificateNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { 
977     xmlChar *content;
978     PCCERT_CONTEXT cert;
979     int ret;
980
981     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
982     xmlSecAssert2(node != NULL, -1);
983     xmlSecAssert2(keyInfoCtx != NULL, -1);
984
985     content = xmlNodeGetContent(node);
986     if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
987         if(content != NULL) {
988             xmlFree(content);
989         }
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);
996             return(-1);
997         }
998         return(0);
999     }
1000
1001     cert = xmlSecMSCryptoX509CertBase64DerRead(content);
1002     if(cert == NULL) {
1003         xmlSecError(XMLSEC_ERRORS_HERE,
1004                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1005                     "xmlSecMSCryptoX509CertBase64DerRead",
1006                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1007                     XMLSEC_ERRORS_NO_MESSAGE);
1008         xmlFree(content);
1009         return(-1);
1010     }    
1011
1012     ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1013     if(ret < 0) {
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);
1020         xmlFree(content);
1021         return(-1);
1022     }
1023      
1024     xmlFree(content);
1025     return(0);
1026 }
1027
1028 static int 
1029 xmlSecMSCryptoX509CertificateNodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node, 
1030                                        xmlSecKeyInfoCtxPtr keyInfoCtx) {
1031     xmlChar* buf;
1032     xmlNodePtr cur;
1033     
1034     xmlSecAssert2(cert != NULL, -1);
1035     xmlSecAssert2(node != NULL, -1);
1036     xmlSecAssert2(keyInfoCtx != NULL, -1);
1037     
1038     /* set base64 lines size from context */
1039     buf = xmlSecMSCryptoX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize); 
1040     if(buf == NULL) {
1041         xmlSecError(XMLSEC_ERRORS_HERE,
1042                     NULL,
1043                     "xmlSecMSCryptoX509CertBase64DerWrite",
1044                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1045                     XMLSEC_ERRORS_NO_MESSAGE);
1046         return(-1);
1047     }
1048
1049     cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
1050     if(cur == NULL) {
1051         xmlSecError(XMLSEC_ERRORS_HERE,
1052                     NULL,
1053                     "xmlSecAddChild",
1054                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1055                     "node=%s",
1056                     xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
1057         xmlFree(buf);
1058         return(-1);     
1059     }
1060
1061     /* todo: add \n around base64 data - from context */
1062     /* todo: add errors check */
1063     xmlNodeSetContent(cur, xmlSecStringCR);
1064     xmlNodeSetContent(cur, buf);
1065     xmlFree(buf);
1066     return(0);
1067 }
1068
1069 static int              
1070 xmlSecMSCryptoX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { 
1071     xmlSecKeyDataStorePtr x509Store;
1072     xmlChar* subject;
1073     PCCERT_CONTEXT cert;
1074     int ret;
1075     
1076     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1077     xmlSecAssert2(node != NULL, -1);
1078     xmlSecAssert2(keyInfoCtx != NULL, -1);
1079     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1080
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);
1088         return(-1);
1089     }
1090
1091     subject = xmlNodeGetContent(node);
1092     if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) {
1093         if(subject != NULL) {
1094             xmlFree(subject);
1095         }
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);
1102             return(-1);
1103         }
1104         return(0);
1105     }
1106
1107     cert = xmlSecMSCryptoX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx);
1108     if(cert == NULL){
1109         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1110             xmlSecError(XMLSEC_ERRORS_HERE,
1111                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1112                         NULL,
1113                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1114                         "subject=%s", 
1115                         xmlSecErrorsSafeString(subject));
1116             xmlFree(subject);
1117             return(-1);
1118         }
1119         xmlFree(subject);
1120         return(0);
1121     }
1122
1123     ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1124     if(ret < 0) {
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);
1131         xmlFree(subject);
1132         return(-1);
1133     }
1134
1135     xmlFree(subject);
1136     return(0);
1137 }
1138
1139 static int
1140 xmlSecMSCryptoX509SubjectNameNodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1141     xmlChar* buf = NULL;
1142     xmlNodePtr cur = NULL;
1143
1144     xmlSecAssert2(cert != NULL, -1);
1145     xmlSecAssert2(node != NULL, -1);
1146
1147     buf = xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Subject));
1148     if(buf == NULL) {
1149         xmlSecError(XMLSEC_ERRORS_HERE,
1150                     NULL,
1151                     "xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Subject))",
1152                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1153                     XMLSEC_ERRORS_NO_MESSAGE);
1154         return(-1);
1155     }
1156
1157     cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs);
1158     if(cur == NULL) {
1159         xmlSecError(XMLSEC_ERRORS_HERE,
1160                     NULL,
1161                     "xmlSecAddChild",
1162                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1163                     "node=%s",
1164                     xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
1165         xmlFree(buf);
1166         return(-1);
1167     }
1168     xmlSecNodeEncodeAndSetContent(cur, buf);
1169     xmlFree(buf);
1170     return(0);
1171 }
1172
1173 static int 
1174 xmlSecMSCryptoX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1175     xmlSecKeyDataStorePtr x509Store;
1176     xmlNodePtr cur;
1177     xmlChar *issuerName;
1178     xmlChar *issuerSerial;    
1179     PCCERT_CONTEXT cert;
1180     int ret;
1181
1182     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1183     xmlSecAssert2(node != NULL, -1);
1184     xmlSecAssert2(keyInfoCtx != NULL, -1);
1185     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1186
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);
1194         return(-1);
1195     }
1196
1197     cur = xmlSecGetNextElementNode(node->children);
1198     if(cur == NULL) {
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,
1204                         "node=%s",
1205                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1206             return(-1);
1207         }
1208         return(0);
1209     }
1210
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,
1217                     "node=%s",
1218                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1219         return(-1);
1220     }    
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,
1227                     "node=%s",
1228                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1229         return(-1);
1230     }
1231     cur = xmlSecGetNextElementNode(cur->next); 
1232
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,
1239                     "node=%s",
1240                     xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1241         xmlFree(issuerName);
1242         return(-1);
1243     }    
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,
1250                     "node=%s",
1251                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1252         xmlFree(issuerName);
1253         return(-1);
1254     }
1255     cur = xmlSecGetNextElementNode(cur->next); 
1256
1257     if(cur != NULL) {
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);
1265         return(-1);
1266     }
1267
1268     cert = xmlSecMSCryptoX509StoreFindCert(x509Store, NULL, issuerName, issuerSerial, NULL, keyInfoCtx);
1269     if(cert == NULL){
1270         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1271             xmlSecError(XMLSEC_ERRORS_HERE,
1272                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1273                         NULL,
1274                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1275                         "issuerName=%s;issuerSerial=%s",
1276                         xmlSecErrorsSafeString(issuerName), 
1277                         xmlSecErrorsSafeString(issuerSerial));
1278             xmlFree(issuerSerial);
1279             xmlFree(issuerName);
1280             return(-1);
1281         }
1282
1283         xmlFree(issuerSerial);
1284         xmlFree(issuerName);
1285         return(0);    
1286     }
1287
1288     ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1289     if(ret < 0) {
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);
1298         return(-1);
1299     }
1300     
1301     xmlFree(issuerSerial);
1302     xmlFree(issuerName);
1303     return(0);
1304 }
1305
1306 static int
1307 xmlSecMSCryptoX509IssuerSerialNodeWrite(PCCERT_CONTEXT cert, 
1308                                         xmlNodePtr node, 
1309                                         xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1310     xmlNodePtr cur;
1311     xmlNodePtr issuerNameNode;
1312     xmlNodePtr issuerNumberNode;
1313     xmlChar* buf;
1314     int ret;
1315
1316     xmlSecAssert2(cert != NULL, -1);
1317     xmlSecAssert2(node != NULL, -1);
1318
1319     /* create xml nodes */
1320     cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
1321     if(cur == NULL) {
1322         xmlSecError(XMLSEC_ERRORS_HERE,
1323                     NULL,
1324                     "xmlSecAddChild",
1325                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1326                     "node=%s",
1327                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
1328         return(-1);
1329     }
1330
1331     issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs);
1332     if(issuerNameNode == NULL) {
1333         xmlSecError(XMLSEC_ERRORS_HERE,
1334                     NULL,
1335                     "xmlSecAddChild",
1336                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1337                     "node=%s",
1338                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1339         return(-1);
1340     }
1341
1342     issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
1343     if(issuerNumberNode == NULL) {
1344         xmlSecError(XMLSEC_ERRORS_HERE,
1345                     NULL,
1346                     "xmlSecAddChild",
1347                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1348                     "node=%s",
1349                     xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1350         return(-1);
1351     }
1352
1353     /* write data */
1354     buf = xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Issuer));
1355     if(buf == NULL) {
1356         xmlSecError(XMLSEC_ERRORS_HERE,
1357                     NULL,
1358                     "xmlSecMSCryptoX509NameWrite(&(cert->pCertInfo->Issuer))",
1359                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1360                     XMLSEC_ERRORS_NO_MESSAGE);
1361         return(-1);
1362     }
1363     xmlSecNodeEncodeAndSetContent(issuerNameNode, buf);
1364     xmlFree(buf);
1365
1366     ret = xmlSecMSCryptoASN1IntegerWrite(issuerNumberNode, &(cert->pCertInfo->SerialNumber));
1367     if(ret < 0) {
1368         xmlSecError(XMLSEC_ERRORS_HERE,
1369                     NULL,
1370                     "xmlSecMSCryptoASN1IntegerWrite(&(cert->serialNumber))",
1371                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1372                     XMLSEC_ERRORS_NO_MESSAGE);
1373         return(-1);
1374     }
1375     return(0);
1376 }
1377
1378 static int 
1379 xmlSecMSCryptoX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1380     xmlSecKeyDataStorePtr x509Store;
1381     xmlChar* ski;
1382     PCCERT_CONTEXT cert;
1383     int ret;
1384     
1385     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1386     xmlSecAssert2(node != NULL, -1);
1387     xmlSecAssert2(keyInfoCtx != NULL, -1);
1388     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1389
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);
1397         return(-1);
1398     }
1399
1400     ski = xmlNodeGetContent(node);
1401     if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) {
1402         if(ski != NULL) {
1403             xmlFree(ski);
1404         }
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,
1410                         "node=%s",
1411                         xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1412             return(-1);
1413         }
1414         return(0);
1415     }
1416
1417     cert = xmlSecMSCryptoX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx);
1418     if(cert == NULL){
1419         xmlFree(ski);
1420
1421         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1422             xmlSecError(XMLSEC_ERRORS_HERE,
1423                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1424                         NULL,
1425                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1426                         "ski=%s", 
1427                         xmlSecErrorsSafeString(ski));
1428             return(-1);
1429         }
1430         return(0);
1431     }
1432
1433     ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
1434     if(ret < 0) {
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);
1441         xmlFree(ski);
1442         return(-1);
1443     }
1444
1445     xmlFree(ski);
1446     return(0);
1447 }
1448
1449 static int
1450 xmlSecMSCryptoX509SKINodeWrite(PCCERT_CONTEXT cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1451     xmlChar *buf = NULL;
1452     xmlNodePtr cur = NULL;
1453
1454     xmlSecAssert2(cert != NULL, -1);
1455     xmlSecAssert2(node != NULL, -1);
1456
1457     buf = xmlSecMSCryptoX509SKIWrite(cert);
1458     if(buf == NULL) {
1459         xmlSecError(XMLSEC_ERRORS_HERE,
1460                     NULL,
1461                     "xmlSecMSCryptoX509SKIWrite",
1462                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1463                     XMLSEC_ERRORS_NO_MESSAGE);
1464         return(-1);
1465     }
1466
1467     cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs);
1468     if(cur == NULL) {
1469         xmlSecError(XMLSEC_ERRORS_HERE,
1470                     NULL,
1471                     "xmlSecAddChild",
1472                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1473                     "new_node=%s",
1474                     xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1475         xmlFree(buf);
1476         return(-1);
1477     }
1478     xmlSecNodeEncodeAndSetContent(cur, buf);
1479     xmlFree(buf);
1480
1481     return(0);
1482 }
1483
1484 static int 
1485 xmlSecMSCryptoX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1486     xmlChar *content;
1487     PCCRL_CONTEXT crl;
1488
1489     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1490     xmlSecAssert2(node != NULL, -1);
1491     xmlSecAssert2(keyInfoCtx != NULL, -1);
1492
1493     content = xmlNodeGetContent(node);
1494     if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
1495         if(content != NULL) {
1496             xmlFree(content);
1497         }
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);
1504             return(-1);
1505         }
1506         return(0);
1507     }
1508
1509     crl = xmlSecMSCryptoX509CrlBase64DerRead(content, keyInfoCtx);
1510     if(crl == NULL) {
1511         xmlSecError(XMLSEC_ERRORS_HERE,
1512                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1513                     "xmlSecMSCryptoX509CrlBase64DerRead",
1514                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1515                     XMLSEC_ERRORS_NO_MESSAGE);
1516         xmlFree(content);
1517         return(-1);
1518     }    
1519
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);
1526         xmlFree(content);
1527         CertFreeCRLContext(crl); 
1528         return(-1);
1529     }
1530     
1531     xmlFree(content);
1532     return(0);
1533 }
1534
1535 static int
1536 xmlSecMSCryptoX509CRLNodeWrite(PCCRL_CONTEXT crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1537     xmlChar* buf = NULL;
1538     xmlNodePtr cur = NULL;
1539
1540     xmlSecAssert2(crl != NULL, -1);
1541     xmlSecAssert2(node != NULL, -1);
1542     xmlSecAssert2(keyInfoCtx != NULL, -1);
1543
1544     /* set base64 lines size from context */
1545     buf = xmlSecMSCryptoX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize); 
1546     if(buf == NULL) {
1547         xmlSecError(XMLSEC_ERRORS_HERE,
1548                     NULL,
1549                     "xmlSecMSCryptoX509CrlBase64DerWrite",
1550                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1551                     XMLSEC_ERRORS_NO_MESSAGE);
1552         return(-1);
1553     }
1554
1555     cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
1556     if(cur == NULL) {
1557         xmlSecError(XMLSEC_ERRORS_HERE,
1558                     NULL,
1559                     "xmlSecAddChild",
1560                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1561                     "new_node=%s",
1562                     xmlSecErrorsSafeString(xmlSecNodeX509CRL));
1563         xmlFree(buf);
1564         return(-1);
1565     }
1566     /* todo: add \n around base64 data - from context */
1567     /* todo: add errors check */
1568     xmlNodeSetContent(cur, xmlSecStringCR);
1569     xmlNodeSetContent(cur, buf);
1570     xmlFree(buf);
1571
1572     return(0);
1573 }
1574
1575
1576 static int
1577 xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key,
1578                                              xmlSecKeyInfoCtxPtr keyInfoCtx) {
1579     xmlSecMSCryptoX509DataCtxPtr ctx;
1580     xmlSecKeyDataStorePtr x509Store;
1581     int ret;
1582     
1583     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataX509Id), -1);
1584     xmlSecAssert2(key != NULL, -1);
1585     xmlSecAssert2(keyInfoCtx != NULL, -1);
1586     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1587
1588     ctx = xmlSecMSCryptoX509DataGetCtx(data);
1589     xmlSecAssert2(ctx != NULL, -1);
1590     xmlSecAssert2(ctx->hMemStore != 0, -1);
1591
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);
1599         return(-1);
1600     }
1601
1602     if((ctx->keyCert == NULL) && (xmlSecKeyGetValue(key) == NULL)) {
1603         PCCERT_CONTEXT cert;
1604
1605         cert = xmlSecMSCryptoX509StoreVerify(x509Store, ctx->hMemStore, keyInfoCtx);
1606         if(cert != NULL) {
1607             xmlSecKeyDataPtr keyValue = NULL;
1608         PCCERT_CONTEXT pCert = NULL;
1609
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);
1617                     return(-1);
1618             }
1619
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);
1628
1629                         return(-1);
1630                 }
1631
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 ) ;
1641                                 return(-1);
1642                         }
1643                         pCert = NULL ;
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 ) ;
1653                                 return(-1);
1654                         }
1655                         pCert = NULL ;
1656                 }
1657
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);
1666                     return(-1);
1667             }   
1668
1669             ret = xmlSecKeySetValue(key, keyValue);
1670             if(ret < 0) {
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);
1677                     return(-1);
1678             }       
1679
1680             ret = xmlSecMSCryptoX509CertGetTime(ctx->keyCert->pCertInfo->NotBefore, &(key->notValidBefore));
1681             if(ret < 0) {
1682                     xmlSecError(XMLSEC_ERRORS_HERE,
1683                                 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1684                                 "xmlSecMSCryptoX509CertGetTime",
1685                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1686                                 "notValidBefore");
1687                     return(-1);
1688             }
1689
1690             ret = xmlSecMSCryptoX509CertGetTime(ctx->keyCert->pCertInfo->NotAfter, &(key->notValidAfter));
1691             if(ret < 0) {
1692                     xmlSecError(XMLSEC_ERRORS_HERE,
1693                                 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1694                                 "xmlSecMSCryptoX509CertGetTime",
1695                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1696                                 "notValidAfter");
1697                     return(-1);
1698             }
1699         } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT) != 0) {
1700             xmlSecError(XMLSEC_ERRORS_HERE,
1701                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1702                         NULL,
1703                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1704                         XMLSEC_ERRORS_NO_MESSAGE);
1705             return(-1);
1706         }
1707     }
1708     return(0);
1709 }
1710
1711 static int
1712 xmlSecMSCryptoX509CertGetTime(FILETIME t, time_t* res) {
1713     LONGLONG result;
1714     
1715     xmlSecAssert2(res != NULL, -1);
1716     
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 */
1723 #else
1724     result -= 11644473600000;  /* Convert from Windows epoch to Unix epoch */
1725 #endif
1726
1727     (*res) = (time_t)result;
1728
1729     return(0);
1730 }
1731
1732 static PCCERT_CONTEXT
1733 xmlSecMSCryptoX509CertBase64DerRead(xmlChar* buf) {
1734     int ret;
1735
1736     xmlSecAssert2(buf != NULL, NULL);
1737     
1738     /* usual trick with base64 decoding "in-place" */
1739     ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); 
1740     if(ret < 0) {
1741         xmlSecError(XMLSEC_ERRORS_HERE,
1742                     NULL,
1743                     "xmlSecBase64Decode",
1744                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1745                     XMLSEC_ERRORS_NO_MESSAGE);
1746         return(NULL);
1747     }
1748     
1749     return(xmlSecMSCryptoX509CertDerRead((xmlSecByte*)buf, ret));
1750 }
1751
1752
1753 static PCCERT_CONTEXT
1754 xmlSecMSCryptoX509CertDerRead(const xmlSecByte* buf, xmlSecSize size) {
1755     PCCERT_CONTEXT cert;
1756
1757     xmlSecAssert2(buf != NULL, NULL);
1758     xmlSecAssert2(size > 0, NULL);
1759
1760     cert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, buf, size);
1761     if(cert == NULL) {
1762         xmlSecError(XMLSEC_ERRORS_HERE,
1763                     NULL,
1764                     "CertCreateCertificateContext",
1765                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1766                     XMLSEC_ERRORS_NO_MESSAGE);
1767         return(NULL);
1768     }
1769
1770     return(cert);
1771 }
1772
1773 static xmlChar*
1774 xmlSecMSCryptoX509CertBase64DerWrite(PCCERT_CONTEXT cert, int base64LineWrap) {
1775     xmlChar *res = NULL;
1776     xmlSecByte *p = NULL;
1777     long size;
1778
1779     xmlSecAssert2(cert != NULL, NULL);
1780
1781     p = cert->pbCertEncoded;
1782     size = cert->cbCertEncoded;
1783     if((size <= 0) || (p == NULL)){
1784         xmlSecError(XMLSEC_ERRORS_HERE,
1785                     NULL,
1786                     "cert->pbCertEncoded",
1787                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1788                     XMLSEC_ERRORS_NO_MESSAGE);
1789         return(NULL);
1790     }
1791
1792     res = xmlSecBase64Encode(p, size, base64LineWrap);
1793     if(res == NULL) {
1794         xmlSecError(XMLSEC_ERRORS_HERE,
1795                     NULL,
1796                     "xmlSecBase64Encode",
1797                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1798                     XMLSEC_ERRORS_NO_MESSAGE);
1799         return(NULL);
1800     }    
1801
1802     return(res);
1803 }
1804
1805 static PCCRL_CONTEXT
1806 xmlSecMSCryptoX509CrlBase64DerRead(xmlChar* buf, 
1807                                    xmlSecKeyInfoCtxPtr keyInfoCtx) {
1808     int ret;
1809
1810     xmlSecAssert2(buf != NULL, NULL);
1811
1812     /* usual trick with base64 decoding "in-place" */
1813     ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); 
1814     if(ret < 0) {
1815         xmlSecError(XMLSEC_ERRORS_HERE,
1816                     NULL,
1817                     "xmlSecBase64Decode",
1818                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1819                     XMLSEC_ERRORS_NO_MESSAGE);
1820         return(NULL);
1821     }
1822
1823     return(xmlSecMSCryptoX509CrlDerRead((xmlSecByte*)buf, ret, keyInfoCtx));
1824 }
1825
1826
1827 static PCCRL_CONTEXT                      
1828 xmlSecMSCryptoX509CrlDerRead(xmlSecByte* buf, xmlSecSize size,
1829                              xmlSecKeyInfoCtxPtr keyInfoCtx) {
1830     PCCRL_CONTEXT crl = NULL;
1831
1832     xmlSecAssert2(buf != NULL, NULL);
1833     xmlSecAssert2(keyInfoCtx != NULL, NULL);
1834     xmlSecAssert2(size > 0, NULL);
1835
1836     crl = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, buf, size);
1837
1838     if(crl == NULL) {
1839         xmlSecError(XMLSEC_ERRORS_HERE,
1840                     NULL,
1841                     "CertCreateCRLContext",
1842                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1843                     XMLSEC_ERRORS_NO_MESSAGE);
1844         return(NULL);
1845     }
1846
1847     return(crl);
1848                              }
1849
1850 static xmlChar*
1851 xmlSecMSCryptoX509CrlBase64DerWrite(PCCRL_CONTEXT crl, int base64LineWrap) {
1852     xmlChar *res = NULL;
1853     xmlSecByte *p = NULL;
1854     long size;
1855
1856     xmlSecAssert2(crl != NULL, NULL);
1857
1858     p = crl->pbCrlEncoded;
1859     size = crl->cbCrlEncoded;
1860     if((size <= 0) || (p == NULL)){
1861         xmlSecError(XMLSEC_ERRORS_HERE,
1862                     NULL,
1863                     "crl->pbCrlEncoded",
1864                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1865                     XMLSEC_ERRORS_NO_MESSAGE);
1866         return(NULL);
1867     }
1868
1869     res = xmlSecBase64Encode(p, size, base64LineWrap);
1870     if(res == NULL) {
1871         xmlSecError(XMLSEC_ERRORS_HERE,
1872                     NULL,
1873                     "xmlSecBase64Encode",
1874                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1875                     XMLSEC_ERRORS_NO_MESSAGE);
1876         return(NULL);
1877     }   
1878
1879     return(res);
1880 }
1881
1882 static xmlChar*
1883 xmlSecMSCryptoX509NameWrite(PCERT_NAME_BLOB nm) {
1884     xmlChar *res = NULL;
1885     char *str;
1886     DWORD csz;
1887
1888
1889     xmlSecAssert2(nm->pbData != NULL, NULL);
1890     xmlSecAssert2(nm->cbData > 0, NULL);
1891
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);
1894     if (NULL == str) {
1895         xmlSecError(XMLSEC_ERRORS_HERE,
1896                     NULL,
1897                     "xmlMalloc",
1898                     XMLSEC_ERRORS_R_MALLOC_FAILED,
1899                     XMLSEC_ERRORS_NO_MESSAGE);
1900         return (NULL);
1901     }
1902
1903     csz = CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, nm, CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, str, csz);
1904     if (csz < 1) {
1905         xmlSecError(XMLSEC_ERRORS_HERE,
1906                     NULL,
1907                     "CertNameToStr",
1908                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1909                     XMLSEC_ERRORS_NO_MESSAGE);
1910         xmlFree(str);
1911         return(NULL);
1912     }
1913
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. 
1917      */
1918     if(strncmp(str, "E=", 2) == 0) {
1919         res = xmlMalloc(strlen(str) + 13 + 1);
1920         if(res == NULL) {
1921             xmlSecError(XMLSEC_ERRORS_HERE,
1922                             NULL,
1923                             "xmlMalloc",
1924                             XMLSEC_ERRORS_R_MALLOC_FAILED,
1925                             "size=%d",
1926                     strlen(str) + 13 + 1);
1927             xmlFree(str);
1928             return(NULL);
1929         }
1930
1931         memcpy(res, "emailAddress=", 13);
1932         strcpy(res + 13, BAD_CAST (str + 2)); 
1933     } else {
1934         res = xmlStrdup(BAD_CAST str);
1935         if(res == NULL) {
1936             xmlSecError(XMLSEC_ERRORS_HERE,
1937                             NULL,
1938                             "xmlStrdup",
1939                             XMLSEC_ERRORS_R_MALLOC_FAILED,
1940                             XMLSEC_ERRORS_NO_MESSAGE);
1941             xmlFree(str);
1942             return(NULL);
1943         }
1944     }
1945     xmlFree(str);
1946     return(res);
1947 }
1948
1949
1950
1951 static int
1952 xmlSecMSCryptoASN1IntegerWrite(xmlNodePtr node, PCRYPT_INTEGER_BLOB num) {
1953     xmlSecBn bn;
1954     int ret;
1955
1956     xmlSecAssert2(node != NULL, -1);
1957     xmlSecAssert2(num != NULL, -1);
1958
1959     ret = xmlSecBnInitialize(&bn, num->cbData + 1);
1960     if(ret < 0) {
1961         xmlSecError(XMLSEC_ERRORS_HERE,
1962                     NULL,
1963                     "xmlSecBnInitialize",
1964                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1965                     "size=%ld", num->cbData + 1);
1966         return(-1);
1967     }
1968
1969     ret = xmlSecBnSetData(&bn, num->pbData, num->cbData);
1970     if(ret < 0) {
1971         xmlSecError(XMLSEC_ERRORS_HERE,
1972                     NULL,
1973                     "xmlSecBnSetData",
1974                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1975                     XMLSEC_ERRORS_NO_MESSAGE);
1976         xmlSecBnFinalize(&bn);
1977         return(-1);
1978     }
1979
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
1983      */
1984     ret = xmlSecBnSetNodeValue(&bn, node, xmlSecBnDec, 1, 0);
1985     if(ret < 0) {
1986         xmlSecError(XMLSEC_ERRORS_HERE,
1987                     NULL,
1988                     "xmlSecBnSetNodeValue",
1989                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1990                     XMLSEC_ERRORS_NO_MESSAGE);
1991         xmlSecBnFinalize(&bn);
1992         return(-1);
1993     }
1994     
1995     xmlSecBnFinalize(&bn);
1996     return(0);
1997 }
1998
1999 static xmlChar*
2000 xmlSecMSCryptoX509SKIWrite(PCCERT_CONTEXT cert) {
2001     xmlChar *res = NULL;
2002     DWORD dwSize;
2003     BYTE *bSKI = NULL;
2004     PCERT_EXTENSION pCertExt;
2005
2006     xmlSecAssert2(cert != NULL, NULL);
2007
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,
2012                             NULL,
2013                     "CertFindExtension",
2014                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
2015                     XMLSEC_ERRORS_NO_MESSAGE);
2016                 return (NULL);
2017             }
2018
2019     if (!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &dwSize) || dwSize < 1) {
2020                 xmlSecError(XMLSEC_ERRORS_HERE,
2021                             NULL,
2022                     "CertGetCertificateContextProperty",
2023                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
2024                     XMLSEC_ERRORS_NO_MESSAGE);
2025                 return (NULL);
2026             }
2027     bSKI = xmlMalloc(dwSize);
2028     if (NULL == bSKI) {
2029         xmlSecError(XMLSEC_ERRORS_HERE,
2030                     NULL,
2031                     "xmlMalloc",
2032                     XMLSEC_ERRORS_R_MALLOC_FAILED,
2033                     XMLSEC_ERRORS_NO_MESSAGE);
2034         return (NULL);
2035     }
2036
2037     if (!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, bSKI, &dwSize)) {
2038                 xmlSecError(XMLSEC_ERRORS_HERE,
2039                             NULL,
2040                             "CertGetCertificateContextProperty",
2041                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
2042                             XMLSEC_ERRORS_NO_MESSAGE);
2043                 xmlFree(bSKI);
2044                 return (NULL);
2045             }
2046
2047     if (NULL == bSKI) {
2048         return(NULL);
2049     }
2050
2051     res = xmlSecBase64Encode(bSKI, dwSize, 0);
2052     if(res == NULL) {
2053         xmlSecError(XMLSEC_ERRORS_HERE,
2054                     NULL,
2055                     "xmlSecBase64Encode",
2056                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2057                     XMLSEC_ERRORS_NO_MESSAGE);
2058         xmlFree(bSKI);
2059         return(NULL);
2060     }
2061     xmlFree(bSKI);
2062     
2063     return(res);
2064 }
2065
2066
2067 static void 
2068 xmlSecMSCryptoX509CertDebugDump(PCCERT_CONTEXT cert, FILE* output) {
2069     PCRYPT_INTEGER_BLOB sn;
2070     unsigned int i;
2071     LPSTR subject, issuer;
2072     DWORD dwSize;
2073
2074     xmlSecAssert(cert != NULL);
2075     xmlSecAssert(output != NULL);
2076
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);
2084
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);
2091
2092     for (i = 0; i < sn->cbData; i++) {
2093         if (i != sn->cbData - 1) {
2094             fprintf(output, "%02x:", sn->pbData[i]);
2095         } else {
2096             fprintf(output, "%02x", sn->pbData[i]);
2097         }
2098     }
2099     fprintf(output, "\n");
2100 }
2101
2102
2103 static void 
2104 xmlSecMSCryptoX509CertDebugXmlDump(PCCERT_CONTEXT cert, FILE* output) {
2105     PCRYPT_INTEGER_BLOB sn;
2106     unsigned int i;
2107     LPSTR subject, issuer;
2108     DWORD dwSize;
2109
2110     xmlSecAssert(cert != NULL);
2111     xmlSecAssert(output != NULL);
2112
2113     /* todo: add error checks */
2114     
2115     /* subject */
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);
2119
2120     fprintf(output, "<SubjectName>");
2121     xmlSecPrintXmlString(output, BAD_CAST subject);
2122     fprintf(output, "</SubjectName>\n");
2123     xmlFree(subject);
2124     
2125     
2126     /* issuer */
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);
2130
2131     fprintf(output, "<IssuerName>");
2132     xmlSecPrintXmlString(output, BAD_CAST issuer);
2133     fprintf(output, "</IssuerName>\n");
2134     xmlFree(issuer);
2135     
2136     /* serial */
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]);
2142         } else {
2143             fprintf(output, "%02x", sn->pbData[i]);
2144         }
2145     }
2146     fprintf(output, "</SerialNumber>\n");
2147 }
2148
2149
2150 /**************************************************************************
2151  *
2152  * Raw X509 Certificate processing
2153  *
2154  *
2155  *************************************************************************/
2156 static int              xmlSecMSCryptoKeyDataRawX509CertBinRead (xmlSecKeyDataId id,
2157                                                                  xmlSecKeyPtr key,
2158                                                                  const xmlSecByte* buf,
2159                                                                  xmlSecSize bufSize,
2160                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
2161
2162 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataRawX509CertKlass = {
2163     sizeof(xmlSecKeyDataKlass),
2164     sizeof(xmlSecKeyData),
2165
2166     /* data */
2167     xmlSecNameRawX509Cert,
2168     xmlSecKeyDataUsageRetrievalMethodNodeBin, 
2169                                                 /* xmlSecKeyDataUsage usage; */
2170     xmlSecHrefRawX509Cert,                      /* const xmlChar* href; */
2171     NULL,                                       /* const xmlChar* dataNodeName; */
2172     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
2173     
2174     /* constructors/destructor */
2175     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
2176     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
2177     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
2178     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
2179
2180     /* get info */
2181     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
2182     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
2183     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
2184
2185     /* read/write */
2186     NULL,                                       /* xmlSecKeyDataXmlReadMethod xmlRead; */
2187     NULL,                                       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2188     xmlSecMSCryptoKeyDataRawX509CertBinRead,    /* xmlSecKeyDataBinReadMethod binRead; */
2189     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
2190
2191     /* debug */
2192     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
2193     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2194
2195     /* reserved for the future */
2196     NULL,                                       /* void* reserved0; */
2197     NULL,                                       /* void* reserved1; */
2198 };
2199
2200 /**
2201  * xmlSecMSCryptoKeyDataRawX509CertGetKlass:
2202  * 
2203  * The raw X509 certificates key data klass.
2204  *
2205  * Returns: raw X509 certificates key data klass.
2206  */
2207 xmlSecKeyDataId 
2208 xmlSecMSCryptoKeyDataRawX509CertGetKlass(void) {
2209     return(&xmlSecMSCryptoKeyDataRawX509CertKlass);
2210 }
2211
2212 static int
2213 xmlSecMSCryptoKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
2214                                     const xmlSecByte* buf, xmlSecSize bufSize,
2215                                     xmlSecKeyInfoCtxPtr keyInfoCtx) {
2216     xmlSecKeyDataPtr data;
2217     PCCERT_CONTEXT cert;
2218     int ret;
2219     
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);
2225
2226     cert = xmlSecMSCryptoX509CertDerRead(buf, bufSize);
2227     if(cert == NULL) {
2228         xmlSecError(XMLSEC_ERRORS_HERE,
2229                     NULL,
2230                     "xmlSecMSCryptoX509CertDerRead",
2231                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2232                     XMLSEC_ERRORS_NO_MESSAGE);
2233         return(-1);
2234     }
2235
2236     data = xmlSecKeyEnsureData(key, xmlSecMSCryptoKeyDataX509Id);
2237     if(data == NULL) {
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);
2244         return(-1);
2245     }
2246
2247     ret = xmlSecMSCryptoKeyDataX509AdoptCert(data, cert);
2248     if(ret < 0) {
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);
2255         return(-1);
2256     }
2257
2258     ret = xmlSecMSCryptoKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
2259     if(ret < 0) {
2260         xmlSecError(XMLSEC_ERRORS_HERE,
2261                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2262                     "xmlSecMSCryptoKeyDataX509VerifyAndExtractKey",
2263                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2264                     XMLSEC_ERRORS_NO_MESSAGE);
2265         return(-1);
2266     }
2267     return(0);
2268 }
2269
2270 #endif /* XMLSEC_NO_X509 */