Git init
[external/xmlsec1.git] / src / nss / 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  * Copyright (c) 2003 America Online, Inc.  All rights reserved.
11  */
12 #include "globals.h"
13
14 #ifndef XMLSEC_NO_X509
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include <errno.h>
21 #include <time.h>
22
23 #include <prmem.h>
24 #include <pratom.h>
25 #include <keyhi.h>
26 #include <cert.h>
27 #include <certdb.h>
28 #include <pk11func.h>
29
30 #include <libxml/tree.h>
31
32 #include <xmlsec/xmlsec.h>
33 #include <xmlsec/xmltree.h>
34 #include <xmlsec/keys.h>
35 #include <xmlsec/keyinfo.h>
36 #include <xmlsec/keysmngr.h>
37 #include <xmlsec/x509.h>
38 #include <xmlsec/base64.h>
39 #include <xmlsec/errors.h>
40
41 #include <xmlsec/nss/crypto.h>
42 #include <xmlsec/nss/x509.h>
43 #include <xmlsec/nss/pkikeys.h>
44
45
46 /* workaround - NSS exports this but doesn't declare it */
47 extern CERTCertificate * __CERT_NewTempCertificate(CERTCertDBHandle *handle,
48                                                    SECItem *derCert,
49                                                    char *nickname,
50                                                    PRBool isperm,
51                                                    PRBool copyDER);
52
53 /*************************************************************************
54  *
55  * X509 utility functions
56  *
57  ************************************************************************/
58 static int              xmlSecNssX509DataNodeRead               (xmlSecKeyDataPtr data,
59                                                                  xmlNodePtr node,
60                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
61 static int              xmlSecNssX509CertificateNodeRead        (xmlSecKeyDataPtr data,
62                                                                  xmlNodePtr node,
63                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
64 static int              xmlSecNssX509CertificateNodeWrite       (CERTCertificate* cert,
65                                                                  xmlNodePtr node,
66                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
67 static int              xmlSecNssX509SubjectNameNodeRead        (xmlSecKeyDataPtr data,
68                                                                  xmlNodePtr node,
69                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
70 static int              xmlSecNssX509SubjectNameNodeWrite       (CERTCertificate* cert,
71                                                                  xmlNodePtr node,
72                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
73 static int              xmlSecNssX509IssuerSerialNodeRead       (xmlSecKeyDataPtr data,
74                                                                  xmlNodePtr node,
75                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
76 static int              xmlSecNssX509IssuerSerialNodeWrite      (CERTCertificate* cert,
77                                                                  xmlNodePtr node,
78                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
79 static int              xmlSecNssX509SKINodeRead                (xmlSecKeyDataPtr data,
80                                                                  xmlNodePtr node,
81                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
82 static int              xmlSecNssX509SKINodeWrite               (CERTCertificate* cert,
83                                                                  xmlNodePtr node,
84                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
85 static int              xmlSecNssX509CRLNodeRead                (xmlSecKeyDataPtr data,
86                                                                  xmlNodePtr node,
87                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
88 static int              xmlSecNssX509CRLNodeWrite               (CERTSignedCrl* crl,
89                                                                  xmlNodePtr node,
90                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
91 static int              xmlSecNssKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, 
92                                                                 xmlSecKeyPtr key,
93                                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
94
95 static CERTCertificate* xmlSecNssX509CertDerRead                (const xmlSecByte* buf, 
96                                                                  xmlSecSize size);
97 static CERTCertificate* xmlSecNssX509CertBase64DerRead          (xmlChar* buf);
98 static xmlChar*         xmlSecNssX509CertBase64DerWrite         (CERTCertificate* cert, 
99                                                                  int base64LineWrap);
100 static CERTSignedCrl*   xmlSecNssX509CrlDerRead                 (xmlSecByte* buf, 
101                                                                  xmlSecSize size,
102                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
103 static CERTSignedCrl*   xmlSecNssX509CrlBase64DerRead           (xmlChar* buf,
104                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
105 static xmlChar*         xmlSecNssX509CrlBase64DerWrite          (CERTSignedCrl* crl, 
106                                                                  int base64LineWrap);
107 static xmlChar*         xmlSecNssX509NameWrite                  (CERTName* nm);
108 static xmlChar*         xmlSecNssASN1IntegerWrite               (SECItem *num);
109 static xmlChar*         xmlSecNssX509SKIWrite                   (CERTCertificate* cert);
110 static void             xmlSecNssX509CertDebugDump              (CERTCertificate* cert, 
111                                                                  FILE* output);
112 static void             xmlSecNssX509CertDebugXmlDump           (CERTCertificate* cert, 
113                                                                  FILE* output);
114 static int              xmlSecNssX509CertGetTime                (PRTime* t,
115                                                                  time_t* res);
116
117 /*************************************************************************
118  *
119  * Internal NSS X509 data CTX
120  *
121  ************************************************************************/
122 typedef struct _xmlSecNssX509DataCtx            xmlSecNssX509DataCtx,
123                                                 *xmlSecNssX509DataCtxPtr;
124 typedef struct _xmlSecNssX509CrlNode            xmlSecNssX509CrlNode,
125                                                 *xmlSecNssX509CrlNodePtr;
126 struct _xmlSecNssX509CrlNode {
127     xmlSecNssX509CrlNodePtr  next;
128     CERTSignedCrl           *crl;
129 };
130
131 struct _xmlSecNssX509DataCtx {
132     CERTCertificate*  keyCert;
133
134     CERTCertList*    certsList;
135     unsigned int     numCerts;
136
137     xmlSecNssX509CrlNodePtr crlsList; 
138     unsigned int     numCrls;
139 };
140
141 /**************************************************************************
142  *
143  * <dsig:X509Data> processing
144  *
145  *
146  * The X509Data  Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data)
147  *
148  * An X509Data element within KeyInfo contains one or more identifiers of keys 
149  * or X509 certificates (or certificates' identifiers or a revocation list). 
150  * The content of X509Data is:
151  *
152  *  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:
153  *  2.
154  *    * The X509IssuerSerial element, which contains an X.509 issuer 
155  *      distinguished name/serial number pair that SHOULD be compliant 
156  *      with RFC2253 [LDAP-DN],
157  *    * The X509SubjectName element, which contains an X.509 subject 
158  *      distinguished name that SHOULD be compliant with RFC2253 [LDAP-DN],
159  *    * The X509SKI element, which contains the base64 encoded plain (i.e. 
160  *      non-DER-encoded) value of a X509 V.3 SubjectKeyIdentifier extension.
161  *    * The X509Certificate element, which contains a base64-encoded [X509v3] 
162  *      certificate, and
163  *    * Elements from an external namespace which accompanies/complements any 
164  *      of the elements above.
165  *    * The X509CRL element, which contains a base64-encoded certificate 
166  *      revocation list (CRL) [X509v3].
167  *
168  * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear 
169  * MUST refer to the certificate or certificates containing the validation key.
170  * All such elements that refer to a particular individual certificate MUST be 
171  * grouped inside a single X509Data element and if the certificate to which 
172  * they refer appears, it MUST also be in that X509Data element.
173  *
174  * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that relate to 
175  * the same key but different certificates MUST be grouped within a single 
176  * KeyInfo but MAY occur in multiple X509Data elements.
177  *
178  * All certificates appearing in an X509Data element MUST relate to the 
179  * validation key by either containing it or being part of a certification 
180  * chain that terminates in a certificate containing the validation key.
181  *
182  * No ordering is implied by the above constraints.
183  *
184  * Note, there is no direct provision for a PKCS#7 encoded "bag" of 
185  * certificates or CRLs. However, a set of certificates and CRLs can occur 
186  * within an X509Data element and multiple X509Data elements can occur in a 
187  * KeyInfo. Whenever multiple certificates occur in an X509Data element, at 
188  * least one such certificate must contain the public key which verifies the 
189  * signature.
190  *
191  * Schema Definition
192  *
193  *  <element name="X509Data" type="ds:X509DataType"/> 
194  *  <complexType name="X509DataType">
195  *    <sequence maxOccurs="unbounded">
196  *      <choice>
197  *        <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
198  *        <element name="X509SKI" type="base64Binary"/>
199  *        <element name="X509SubjectName" type="string"/>
200  *        <element name="X509Certificate" type="base64Binary"/>
201  *        <element name="X509CRL" type="base64Binary"/>
202  *        <any namespace="##other" processContents="lax"/>
203  *      </choice>
204  *    </sequence>
205  *  </complexType>
206  *  <complexType name="X509IssuerSerialType"> 
207  *    <sequence> 
208  *       <element name="X509IssuerName" type="string"/> 
209  *       <element name="X509SerialNumber" type="integer"/> 
210  *     </sequence>
211  *  </complexType>
212  *
213  *  DTD
214  *
215  *    <!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
216  *                          X509Certificate | X509CRL)+ %X509.ANY;)>
217  *    <!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
218  *    <!ELEMENT X509IssuerName (#PCDATA) >
219  *    <!ELEMENT X509SubjectName (#PCDATA) >
220  *    <!ELEMENT X509SerialNumber (#PCDATA) >
221  *    <!ELEMENT X509SKI (#PCDATA) >
222  *    <!ELEMENT X509Certificate (#PCDATA) >
223  *    <!ELEMENT X509CRL (#PCDATA) >
224  *
225  * -----------------------------------------------------------------------
226  *
227  * xmlSecNssX509DataCtx is located after xmlSecTransform
228  *
229  *************************************************************************/
230 #define xmlSecNssX509DataSize   \
231     (sizeof(xmlSecKeyData) + sizeof(xmlSecNssX509DataCtx))      
232 #define xmlSecNssX509DataGetCtx(data) \
233     ((xmlSecNssX509DataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
234
235 static int              xmlSecNssKeyDataX509Initialize  (xmlSecKeyDataPtr data);
236 static int              xmlSecNssKeyDataX509Duplicate   (xmlSecKeyDataPtr dst,
237                                                          xmlSecKeyDataPtr src);
238 static void             xmlSecNssKeyDataX509Finalize    (xmlSecKeyDataPtr data);
239 static int              xmlSecNssKeyDataX509XmlRead     (xmlSecKeyDataId id,
240                                                          xmlSecKeyPtr key,
241                                                          xmlNodePtr node,
242                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
243 static int              xmlSecNssKeyDataX509XmlWrite    (xmlSecKeyDataId id,
244                                                          xmlSecKeyPtr key,
245                                                          xmlNodePtr node,
246                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
247 static xmlSecKeyDataType xmlSecNssKeyDataX509GetType    (xmlSecKeyDataPtr data);
248 static const xmlChar* xmlSecNssKeyDataX509GetIdentifier (xmlSecKeyDataPtr data);
249
250 static void             xmlSecNssKeyDataX509DebugDump   (xmlSecKeyDataPtr data,
251                                                          FILE* output);
252 static void             xmlSecNssKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data,
253                                                          FILE* output);
254
255
256
257 static xmlSecKeyDataKlass xmlSecNssKeyDataX509Klass = {
258     sizeof(xmlSecKeyDataKlass),
259     xmlSecNssX509DataSize,
260
261     /* data */
262     xmlSecNameX509Data,
263     xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, 
264                                                 /* xmlSecKeyDataUsage usage; */
265     xmlSecHrefX509Data,                         /* const xmlChar* href; */
266     xmlSecNodeX509Data,                         /* const xmlChar* dataNodeName; */
267     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
268     
269     /* constructors/destructor */
270     xmlSecNssKeyDataX509Initialize,             /* xmlSecKeyDataInitializeMethod initialize; */
271     xmlSecNssKeyDataX509Duplicate,              /* xmlSecKeyDataDuplicateMethod duplicate; */
272     xmlSecNssKeyDataX509Finalize,               /* xmlSecKeyDataFinalizeMethod finalize; */
273     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
274
275     /* get info */
276     xmlSecNssKeyDataX509GetType,                /* xmlSecKeyDataGetTypeMethod getType; */
277     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
278     xmlSecNssKeyDataX509GetIdentifier,          /* xmlSecKeyDataGetIdentifier getIdentifier; */    
279
280     /* read/write */
281     xmlSecNssKeyDataX509XmlRead,                /* xmlSecKeyDataXmlReadMethod xmlRead; */
282     xmlSecNssKeyDataX509XmlWrite,               /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
283     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
284     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
285
286     /* debug */
287     xmlSecNssKeyDataX509DebugDump,              /* xmlSecKeyDataDebugDumpMethod debugDump; */
288     xmlSecNssKeyDataX509DebugXmlDump,           /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
289
290     /* reserved for the future */
291     NULL,                                       /* void* reserved0; */
292     NULL,                                       /* void* reserved1; */
293 };
294
295 /** 
296  * xmlSecNssKeyDataX509GetKlass:
297  * 
298  * The NSS X509 key data klass (http://www.w3.org/TR/xmldsig-core/#sec-X509Data).
299  *
300  * Returns: the X509 data klass.
301  */
302 xmlSecKeyDataId 
303 xmlSecNssKeyDataX509GetKlass(void) {
304     return(&xmlSecNssKeyDataX509Klass);
305 }
306
307 /**
308  * xmlSecNssKeyDataX509GetKeyCert:
309  * @data:               the pointer to X509 key data.
310  *
311  * Gets the certificate from which the key was extracted. 
312  *
313  * Returns: the key's certificate or NULL if key data was not used for key
314  * extraction or an error occurs.
315  */
316 CERTCertificate*
317 xmlSecNssKeyDataX509GetKeyCert(xmlSecKeyDataPtr data) {
318     xmlSecNssX509DataCtxPtr ctx;
319     
320     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), NULL);
321
322     ctx = xmlSecNssX509DataGetCtx(data);
323     xmlSecAssert2(ctx != NULL, NULL);
324
325     return(ctx->keyCert);
326 }
327
328 /**
329  * xmlSecNssKeyDataX509AdoptKeyCert:
330  * @data:               the pointer to X509 key data.
331  * @cert:               the pointer to NSS X509 certificate.
332  *
333  * Sets the key's certificate in @data.
334  *
335  * Returns: 0 on success or a negative value if an error occurs.
336  */
337 int
338 xmlSecNssKeyDataX509AdoptKeyCert(xmlSecKeyDataPtr data, CERTCertificate* cert) {
339     xmlSecNssX509DataCtxPtr ctx;
340
341     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
342     xmlSecAssert2(cert != NULL, -1);
343
344     ctx = xmlSecNssX509DataGetCtx(data);
345     xmlSecAssert2(ctx != NULL, -1);
346     
347     if(ctx->keyCert != NULL) {
348         CERT_DestroyCertificate(ctx->keyCert);
349     }
350     ctx->keyCert = cert;
351     return(0);
352 }
353
354 /**
355  * xmlSecNssKeyDataX509AdoptCert:
356  * @data:               the pointer to X509 key data.
357  * @cert:               the pointer to NSS X509 certificate.
358  *
359  * Adds certificate to the X509 key data.
360  *
361  * Returns: 0 on success or a negative value if an error occurs.
362  */
363 int 
364 xmlSecNssKeyDataX509AdoptCert(xmlSecKeyDataPtr data, CERTCertificate* cert) {
365     xmlSecNssX509DataCtxPtr ctx;
366     SECStatus ret;
367     
368     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
369     xmlSecAssert2(cert != NULL, -1);
370
371     ctx = xmlSecNssX509DataGetCtx(data);
372     xmlSecAssert2(ctx != NULL, -1);
373     
374     if(ctx->certsList == NULL) {
375         ctx->certsList = CERT_NewCertList();
376         if(ctx->certsList == NULL) {
377             xmlSecError(XMLSEC_ERRORS_HERE,
378                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
379                         "CERT_NewCertList",
380                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
381                         "error code=%d", PORT_GetError());
382             return(-1); 
383         }
384     }
385     
386     ret = CERT_AddCertToListTail(ctx->certsList, cert);
387     if(ret != SECSuccess) {
388         xmlSecError(XMLSEC_ERRORS_HERE,
389                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
390                     "CERT_AddCertToListTail",
391                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
392                     "error code=%d", PORT_GetError());
393         return(-1);     
394     }
395     ctx->numCerts++;
396         
397     return(0);
398 }
399
400 /**
401  * xmlSecNssKeyDataX509GetCert:
402  * @data:               the pointer to X509 key data.
403  * @pos:                the desired certificate position.
404  * 
405  * Gets a certificate from X509 key data.
406  *
407  * Returns: the pointer to certificate or NULL if @pos is larger than the 
408  * number of certificates in @data or an error occurs.
409  */
410 CERTCertificate* 
411 xmlSecNssKeyDataX509GetCert(xmlSecKeyDataPtr data, xmlSecSize pos) {
412     xmlSecNssX509DataCtxPtr ctx;
413     CERTCertListNode*       head;
414
415     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), NULL);
416
417     ctx = xmlSecNssX509DataGetCtx(data);
418     xmlSecAssert2(ctx != NULL, NULL);
419     xmlSecAssert2(ctx->certsList != NULL, NULL);
420     xmlSecAssert2(pos < ctx->numCerts, NULL);
421
422     head = CERT_LIST_HEAD(ctx->certsList);
423     while (pos > 0)
424     {
425         head = CERT_LIST_NEXT(head);
426         pos--;
427     }
428
429     return (head->cert);
430 }
431
432 /**
433  * xmlSecNssKeyDataX509GetCertsSize:
434  * @data:               the pointer to X509 key data.
435  *
436  * Gets the number of certificates in @data.
437  *
438  * Returns: te number of certificates in @data.
439  */
440 xmlSecSize      
441 xmlSecNssKeyDataX509GetCertsSize(xmlSecKeyDataPtr data) {
442     xmlSecNssX509DataCtxPtr ctx;
443
444     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), 0);
445
446     ctx = xmlSecNssX509DataGetCtx(data);
447     xmlSecAssert2(ctx != NULL, 0);
448
449     return(ctx->numCerts);
450 }
451
452 /**
453  * xmlSecNssKeyDataX509AdoptCrl:
454  * @data:               the pointer to X509 key data.
455  * @crl:                the pointer to NSS X509 CRL.
456  *
457  * Adds CRL to the X509 key data.
458  *
459  * Returns: 0 on success or a negative value if an error occurs.
460  */
461 int 
462 xmlSecNssKeyDataX509AdoptCrl(xmlSecKeyDataPtr data, CERTSignedCrl* crl) {
463     xmlSecNssX509DataCtxPtr ctx;
464     xmlSecNssX509CrlNodePtr crlnode;
465     
466     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
467     xmlSecAssert2(crl != NULL, -1);
468
469     ctx = xmlSecNssX509DataGetCtx(data);
470     xmlSecAssert2(ctx != NULL, -1);
471     
472     crlnode = (xmlSecNssX509CrlNodePtr)PR_Malloc(sizeof(xmlSecNssX509CrlNode));
473
474     if(crlnode == NULL) {
475         xmlSecError(XMLSEC_ERRORS_HERE,
476                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
477                     "PR_Malloc",
478                     XMLSEC_ERRORS_R_MALLOC_FAILED,
479                     XMLSEC_ERRORS_NO_MESSAGE);
480         return(-1);     
481     }
482     
483     memset(crlnode, 0, sizeof(xmlSecNssX509CrlNode));
484     crlnode->next = ctx->crlsList;
485     crlnode->crl = crl;
486     ctx->crlsList = crlnode;
487     ctx->numCrls++;
488
489     return(0);
490 }
491
492 /**
493  * xmlSecNssKeyDataX509GetCrl:
494  * @data:               the pointer to X509 key data.
495  * @pos:                the desired CRL position.
496  *
497  * Gets a CRL from X509 key data.
498  *
499  * Returns: the pointer to CRL or NULL if @pos is larger than the
500  * number of CRLs in @data or an error occurs.
501  */
502 CERTSignedCrl *
503 xmlSecNssKeyDataX509GetCrl(xmlSecKeyDataPtr data, xmlSecSize pos) {
504     xmlSecNssX509DataCtxPtr ctx;
505     xmlSecNssX509CrlNodePtr head;
506
507     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), NULL);
508     ctx = xmlSecNssX509DataGetCtx(data);
509     xmlSecAssert2(ctx != NULL, NULL);
510
511     xmlSecAssert2(ctx->crlsList != NULL, NULL);
512     xmlSecAssert2(pos < ctx->numCrls, NULL);
513
514     head = ctx->crlsList;
515     while (pos > 0)
516     {
517         head = head->next;
518         pos--;
519     }
520
521     return (head->crl);
522 }
523
524 /**
525  * xmlSecNssKeyDataX509GetCrlsSize:
526  * @data:               the pointer to X509 key data.
527  *
528  * Gets the number of CRLs in @data.
529  *
530  * Returns: te number of CRLs in @data.
531  */
532 xmlSecSize
533 xmlSecNssKeyDataX509GetCrlsSize(xmlSecKeyDataPtr data) {
534     xmlSecNssX509DataCtxPtr ctx;
535
536     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), 0);
537
538     ctx = xmlSecNssX509DataGetCtx(data);
539     xmlSecAssert2(ctx != NULL, 0);
540
541     return(ctx->numCrls);
542 }
543
544 static int      
545 xmlSecNssKeyDataX509Initialize(xmlSecKeyDataPtr data) {
546     xmlSecNssX509DataCtxPtr ctx;
547
548     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
549
550     ctx = xmlSecNssX509DataGetCtx(data);
551     xmlSecAssert2(ctx != NULL, -1);
552
553     memset(ctx, 0, sizeof(xmlSecNssX509DataCtx));
554     return(0);
555 }
556
557 static int
558 xmlSecNssKeyDataX509Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
559     CERTCertificate* certSrc;
560     CERTCertificate* certDst;
561     CERTSignedCrl* crlSrc;
562     CERTSignedCrl* crlDst;
563     xmlSecSize size, pos;
564     int ret;
565
566     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecNssKeyDataX509Id), -1);
567     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecNssKeyDataX509Id), -1);
568     
569     /* copy certsList */
570     size = xmlSecNssKeyDataX509GetCertsSize(src);
571     for(pos = 0; pos < size; ++pos) {
572         /* TBD: function below does linear scan, eliminate loop within
573          * loop
574          */
575         certSrc = xmlSecNssKeyDataX509GetCert(src, pos);
576         if(certSrc == NULL) {
577             xmlSecError(XMLSEC_ERRORS_HERE,
578                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
579                         "xmlSecNssKeyDataX509GetCert",
580                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
581                         "pos=%d", pos);
582             return(-1);
583         }
584         
585         certDst = CERT_DupCertificate(certSrc);
586         if(certDst == NULL) {
587             xmlSecError(XMLSEC_ERRORS_HERE,
588                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
589                         "CERT_DupCertificate",
590                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
591                         "error code=%d", PORT_GetError());
592             return(-1);
593         }
594         
595         ret = xmlSecNssKeyDataX509AdoptCert(dst, certDst);
596         if(ret < 0) {
597             xmlSecError(XMLSEC_ERRORS_HERE,
598                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
599                         "xmlSecNssKeyDataX509AdoptCert",
600                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
601                         XMLSEC_ERRORS_NO_MESSAGE);
602             CERT_DestroyCertificate(certDst);
603             return(-1);
604         }
605     }
606
607     /* copy crls */
608     size = xmlSecNssKeyDataX509GetCrlsSize(src);
609     for(pos = 0; pos < size; ++pos) {
610         crlSrc = xmlSecNssKeyDataX509GetCrl(src, pos);
611         if(crlSrc == NULL) {
612             xmlSecError(XMLSEC_ERRORS_HERE,
613                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
614                         "xmlSecNssKeyDataX509GetCrl",
615                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
616                         "pos=%d", pos);
617             return(-1);
618         }
619
620         /* TBD: SEC_DupCrl isn't exported by NSS yet */
621         /*crlDst = SEC_DupCrl(crlSrc);*/
622         crlDst = crlSrc;
623         PR_AtomicIncrement(&(crlSrc->referenceCount));
624
625         if(crlDst == NULL) {
626             xmlSecError(XMLSEC_ERRORS_HERE,
627                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
628                         "SEC_DupCrl",
629                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
630                         "error code=%d", PORT_GetError());
631             return(-1);
632         }
633
634         ret = xmlSecNssKeyDataX509AdoptCrl(dst, crlDst);
635         if(ret < 0) {
636             xmlSecError(XMLSEC_ERRORS_HERE,
637                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
638                         "xmlSecNssKeyDataX509AdoptCrl",
639                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
640                         XMLSEC_ERRORS_NO_MESSAGE);
641             SEC_DestroyCrl(crlDst);
642             return(-1);
643         }
644     }
645
646     /* copy key cert if exist */
647     certSrc = xmlSecNssKeyDataX509GetKeyCert(src);
648     if(certSrc != NULL) {
649         certDst = CERT_DupCertificate(certSrc);
650         if(certDst == NULL) {
651             xmlSecError(XMLSEC_ERRORS_HERE,
652                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
653                         "CERT_DupCertificate",
654                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
655                         "error code=%d", PORT_GetError());
656             return(-1);
657         }
658         ret = xmlSecNssKeyDataX509AdoptKeyCert(dst, certDst);
659         if(ret < 0) {
660             xmlSecError(XMLSEC_ERRORS_HERE,
661                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
662                         "xmlSecNssKeyDataX509AdoptKeyCert",
663                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
664                         XMLSEC_ERRORS_NO_MESSAGE);
665             CERT_DestroyCertificate(certDst);
666             return(-1);
667         }
668     }
669     return(0);
670 }
671
672 static void
673 xmlSecNssKeyDataX509Finalize(xmlSecKeyDataPtr data) {
674     xmlSecNssX509DataCtxPtr ctx;
675
676     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id));
677
678     ctx = xmlSecNssX509DataGetCtx(data);
679     xmlSecAssert(ctx != NULL);
680
681     if(ctx->certsList != NULL) {
682         CERT_DestroyCertList(ctx->certsList);
683     }
684
685     if(ctx->crlsList != NULL) {
686         xmlSecNssX509CrlNodePtr head;
687         xmlSecNssX509CrlNodePtr tmp;
688
689         head = ctx->crlsList;
690         while (head)
691         {
692             tmp = head->next;
693             SEC_DestroyCrl(head->crl);
694             PR_Free(head);
695             head = tmp;
696         }
697     }
698
699     if(ctx->keyCert != NULL) {
700         CERT_DestroyCertificate(ctx->keyCert);
701     }
702
703     memset(ctx, 0, sizeof(xmlSecNssX509DataCtx));
704 }
705
706 static int
707 xmlSecNssKeyDataX509XmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
708                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
709     xmlSecKeyDataPtr data;
710     int ret;
711     
712     xmlSecAssert2(id == xmlSecNssKeyDataX509Id, -1);
713     xmlSecAssert2(key != NULL, -1);
714     xmlSecAssert2(node != NULL, -1);
715     xmlSecAssert2(keyInfoCtx != NULL, -1);
716     
717     data = xmlSecKeyEnsureData(key, id);
718     if(data == NULL) {
719         xmlSecError(XMLSEC_ERRORS_HERE,
720                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
721                     "xmlSecKeyEnsureData",
722                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
723                     XMLSEC_ERRORS_NO_MESSAGE);
724         return(-1);
725     }
726     
727     ret = xmlSecNssX509DataNodeRead(data, node, keyInfoCtx);
728     if(ret < 0) {
729         xmlSecError(XMLSEC_ERRORS_HERE,
730                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
731                     "xmlSecNssX509DataNodeRead",
732                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
733                     XMLSEC_ERRORS_NO_MESSAGE);
734         return(-1);
735     }
736
737     if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) {
738         ret = xmlSecNssKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
739         if(ret < 0) {
740             xmlSecError(XMLSEC_ERRORS_HERE,
741                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
742                         "xmlSecNssKeyDataX509VerifyAndExtractKey",
743                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
744                         XMLSEC_ERRORS_NO_MESSAGE);
745             return(-1);
746         }
747     }
748     return(0);
749 }
750
751 static int 
752 xmlSecNssKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
753                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
754     xmlSecKeyDataPtr data;
755     CERTCertificate* cert;
756     CERTSignedCrl* crl;
757     xmlSecSize size, pos;
758     int content = 0;
759     int ret;
760                                 
761     xmlSecAssert2(id == xmlSecNssKeyDataX509Id, -1);
762     xmlSecAssert2(key != NULL, -1);
763     xmlSecAssert2(node != NULL, -1);
764     xmlSecAssert2(keyInfoCtx != NULL, -1);
765
766     content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx);
767     if (content < 0) {
768         xmlSecError(XMLSEC_ERRORS_HERE,
769                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
770                     "xmlSecX509DataGetNodeContent",
771                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
772                     "content=%d", content);
773         return(-1);
774     } else if(content == 0) {
775         /* by default we are writing certificates and crls */
776         content = XMLSEC_X509DATA_DEFAULT;
777     }
778
779     /* get x509 data */
780     data = xmlSecKeyGetData(key, id);
781     if(data == NULL) {
782         /* no x509 data in the key */
783         return(0);      
784     }
785
786     /* write certs */
787     size = xmlSecNssKeyDataX509GetCertsSize(data);
788     for(pos = 0; pos < size; ++pos) {
789         cert = xmlSecNssKeyDataX509GetCert(data, pos);
790         if(cert == NULL) {
791             xmlSecError(XMLSEC_ERRORS_HERE,
792                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
793                         "xmlSecNssKeyDataX509GetCert",
794                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
795                         "pos=%d", pos);
796             return(-1);
797         }
798
799         if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) {
800             ret = xmlSecNssX509CertificateNodeWrite(cert, node, keyInfoCtx);
801             if(ret < 0) {
802                 xmlSecError(XMLSEC_ERRORS_HERE,
803                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
804                             "xmlSecNssX509CertificateNodeWrite",
805                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
806                             "pos=%d", pos);
807                 return(-1);
808             }
809         }
810
811         if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) {
812             ret = xmlSecNssX509SubjectNameNodeWrite(cert, node, keyInfoCtx);
813             if(ret < 0) {
814                 xmlSecError(XMLSEC_ERRORS_HERE,
815                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
816                             "xmlSecNssX509SubjectNameNodeWrite",
817                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
818                             "pos=%d", pos);
819                 return(-1);
820             }
821         }
822
823         if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) {
824             ret = xmlSecNssX509IssuerSerialNodeWrite(cert, node, keyInfoCtx);
825             if(ret < 0) {
826                 xmlSecError(XMLSEC_ERRORS_HERE,
827                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
828                             "xmlSecNssX509IssuerSerialNodeWrite",
829                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
830                             "pos=%d", pos);
831                 return(-1);
832             }
833         }
834
835         if((content & XMLSEC_X509DATA_SKI_NODE) != 0) {
836             ret = xmlSecNssX509SKINodeWrite(cert, node, keyInfoCtx);
837             if(ret < 0) {
838                 xmlSecError(XMLSEC_ERRORS_HERE,
839                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
840                             "xmlSecNssX509SKINodeWrite",
841                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
842                             "pos=%d", pos);
843                 return(-1);
844             }
845         }
846     }    
847
848     /* write crls if needed */
849     if((content & XMLSEC_X509DATA_CRL_NODE) != 0) {
850         size = xmlSecNssKeyDataX509GetCrlsSize(data);
851         for(pos = 0; pos < size; ++pos) {
852             crl = xmlSecNssKeyDataX509GetCrl(data, pos);
853             if(crl == NULL) {
854                 xmlSecError(XMLSEC_ERRORS_HERE,
855                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
856                             "xmlSecNssKeyDataX509GetCrl",
857                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
858                             "pos=%d", pos);
859                 return(-1);
860             }
861             
862             ret = xmlSecNssX509CRLNodeWrite(crl, node, keyInfoCtx);
863             if(ret < 0) {
864                 xmlSecError(XMLSEC_ERRORS_HERE,
865                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
866                             "xmlSecNssX509CRLNodeWrite",
867                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
868                             "pos=%d", pos);
869                 return(-1);
870             }
871         }
872     }
873
874     return(0);
875 }
876
877 static xmlSecKeyDataType
878 xmlSecNssKeyDataX509GetType(xmlSecKeyDataPtr data) {
879     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), xmlSecKeyDataTypeUnknown);
880
881     /* TODO: return verified/not verified status */    
882     return(xmlSecKeyDataTypeUnknown);
883 }
884
885 static const xmlChar*
886 xmlSecNssKeyDataX509GetIdentifier(xmlSecKeyDataPtr data) {
887     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), NULL);
888     
889     /* TODO */    
890     return(NULL);
891 }
892
893 static void 
894 xmlSecNssKeyDataX509DebugDump(xmlSecKeyDataPtr data, FILE* output) {
895     CERTCertificate* cert;
896     xmlSecSize size, pos;
897
898     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id));
899     xmlSecAssert(output != NULL);
900
901     fprintf(output, "=== X509 Data:\n");
902     cert = xmlSecNssKeyDataX509GetKeyCert(data);
903     if(cert != NULL) {
904         fprintf(output, "==== Key Certificate:\n");
905         xmlSecNssX509CertDebugDump(cert, output);
906     }
907     
908     size = xmlSecNssKeyDataX509GetCertsSize(data);
909     for(pos = 0; pos < size; ++pos) {
910         cert = xmlSecNssKeyDataX509GetCert(data, pos);
911         if(cert == NULL) {
912             xmlSecError(XMLSEC_ERRORS_HERE,
913                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
914                         "xmlSecNssKeyDataX509GetCert",
915                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
916                         "pos=%d", pos);
917             return;
918         }
919         fprintf(output, "==== Certificate:\n");
920         xmlSecNssX509CertDebugDump(cert, output);
921     }
922     
923     /* we don't print out crls */
924 }
925
926 static void
927 xmlSecNssKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
928     CERTCertificate* cert;
929     xmlSecSize size, pos;
930
931     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id));
932     xmlSecAssert(output != NULL);
933
934     fprintf(output, "<X509Data>\n");
935     cert = xmlSecNssKeyDataX509GetKeyCert(data);
936     if(cert != NULL) {
937         fprintf(output, "<KeyCertificate>\n");
938         xmlSecNssX509CertDebugXmlDump(cert, output);
939         fprintf(output, "</KeyCertificate>\n");
940     }
941     
942     size = xmlSecNssKeyDataX509GetCertsSize(data);
943     for(pos = 0; pos < size; ++pos) {
944         cert = xmlSecNssKeyDataX509GetCert(data, pos);
945         if(cert == NULL) {
946             xmlSecError(XMLSEC_ERRORS_HERE,
947                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
948                         "xmlSecNssKeyDataX509GetCert",
949                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
950                         "pos=%d", pos);
951             return;
952         }
953         fprintf(output, "<Certificate>\n");
954         xmlSecNssX509CertDebugXmlDump(cert, output);
955         fprintf(output, "</Certificate>\n");
956     }
957     
958     /* we don't print out crls */
959     fprintf(output, "</X509Data>\n");
960 }
961
962 static int
963 xmlSecNssX509DataNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
964     xmlNodePtr cur; 
965     int ret;
966         
967     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
968     xmlSecAssert2(node != NULL, -1);
969     xmlSecAssert2(keyInfoCtx != NULL, -1);
970     
971     for(cur = xmlSecGetNextElementNode(node->children);
972         cur != NULL;
973         cur = xmlSecGetNextElementNode(cur->next)) {
974         
975         ret = 0;
976         if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
977             ret = xmlSecNssX509CertificateNodeRead(data, cur, keyInfoCtx);
978         } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
979             ret = xmlSecNssX509SubjectNameNodeRead(data, cur, keyInfoCtx);
980         } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
981             ret = xmlSecNssX509IssuerSerialNodeRead(data, cur, keyInfoCtx);
982         } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) {
983             ret = xmlSecNssX509SKINodeRead(data, cur, keyInfoCtx);
984         } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) {
985             ret = xmlSecNssX509CRLNodeRead(data, cur, keyInfoCtx);
986         } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD) != 0) {
987             /* laxi schema validation: ignore unknown nodes */
988             xmlSecError(XMLSEC_ERRORS_HERE,
989                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
990                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
991                         XMLSEC_ERRORS_R_UNEXPECTED_NODE,
992                         XMLSEC_ERRORS_NO_MESSAGE);
993             return(-1);
994         }
995         if(ret < 0) {
996             xmlSecError(XMLSEC_ERRORS_HERE,
997                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
998                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
999                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1000                         "read node failed");
1001             return(-1);  
1002         }       
1003     }
1004     return(0);
1005 }
1006
1007 static int
1008 xmlSecNssX509CertificateNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {      
1009     xmlChar *content;
1010     CERTCertificate* cert;
1011     int ret;
1012
1013     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1014     xmlSecAssert2(node != NULL, -1);
1015     xmlSecAssert2(keyInfoCtx != NULL, -1);
1016
1017     content = xmlNodeGetContent(node);
1018     if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
1019         if(content != NULL) {
1020             xmlFree(content);
1021         }
1022         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1023             xmlSecError(XMLSEC_ERRORS_HERE,
1024                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1025                         xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1026                         XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1027                         XMLSEC_ERRORS_NO_MESSAGE);
1028             return(-1);
1029         }
1030         return(0);
1031     }
1032
1033     cert = xmlSecNssX509CertBase64DerRead(content);
1034     if(cert == NULL) {
1035         xmlSecError(XMLSEC_ERRORS_HERE,
1036                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1037                     "xmlSecNssX509CertBase64DerRead",
1038                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1039                     XMLSEC_ERRORS_NO_MESSAGE);
1040         xmlFree(content);
1041         return(-1);
1042     }    
1043     
1044     ret = xmlSecNssKeyDataX509AdoptCert(data, cert);
1045     if(ret < 0) {
1046         xmlSecError(XMLSEC_ERRORS_HERE,
1047                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1048                     "xmlSecNssKeyDataX509AdoptCert",
1049                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1050                     XMLSEC_ERRORS_NO_MESSAGE);
1051         CERT_DestroyCertificate(cert);
1052         xmlFree(content);
1053         return(-1);
1054     }
1055      
1056     xmlFree(content);
1057     return(0);
1058 }
1059
1060 static int 
1061 xmlSecNssX509CertificateNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1062     xmlChar* buf;
1063     xmlNodePtr cur;
1064     
1065     xmlSecAssert2(cert != NULL, -1);
1066     xmlSecAssert2(node != NULL, -1);
1067     xmlSecAssert2(keyInfoCtx != NULL, -1);
1068     
1069     /* set base64 lines size from context */
1070     buf = xmlSecNssX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize); 
1071     if(buf == NULL) {
1072         xmlSecError(XMLSEC_ERRORS_HERE,
1073                     NULL,
1074                     "xmlSecNssX509CertBase64DerWrite",
1075                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1076                     XMLSEC_ERRORS_NO_MESSAGE);
1077         return(-1);
1078     }
1079         
1080     cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
1081     if(cur == NULL) {
1082         xmlSecError(XMLSEC_ERRORS_HERE,
1083                     NULL,
1084                     "xmlSecAddChild",
1085                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1086                     "node=%s",
1087                     xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
1088         xmlFree(buf);
1089         return(-1);     
1090     }
1091
1092     /* todo: add \n around base64 data - from context */
1093     /* todo: add errors check */
1094     xmlNodeSetContent(cur, xmlSecStringCR);
1095     xmlNodeSetContent(cur, buf);
1096     xmlFree(buf);
1097     return(0);
1098 }
1099
1100 static int              
1101 xmlSecNssX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {      
1102     xmlSecKeyDataStorePtr x509Store;
1103     xmlChar* subject;
1104     CERTCertificate* cert;
1105     int ret;
1106     
1107     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1108     xmlSecAssert2(node != NULL, -1);
1109     xmlSecAssert2(keyInfoCtx != NULL, -1);
1110     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1111
1112     x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecNssX509StoreId);
1113     if(x509Store == NULL) {
1114         xmlSecError(XMLSEC_ERRORS_HERE,
1115                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1116                     "xmlSecKeysMngrGetDataStore",
1117                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1118                     XMLSEC_ERRORS_NO_MESSAGE);
1119         return(-1);
1120     }
1121
1122     subject = xmlNodeGetContent(node);
1123     if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) {
1124         if(subject != NULL) {
1125             xmlFree(subject);
1126         }
1127         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1128             xmlSecError(XMLSEC_ERRORS_HERE,
1129                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1130                         xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1131                         XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1132                         XMLSEC_ERRORS_NO_MESSAGE);
1133             return(-1);
1134         }
1135         return(0);
1136     }
1137
1138     cert = xmlSecNssX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx);
1139     if(cert == NULL){
1140
1141         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1142             xmlSecError(XMLSEC_ERRORS_HERE,
1143                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1144                         NULL,
1145                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1146                         "subject=%s", 
1147                         xmlSecErrorsSafeString(subject));
1148             xmlFree(subject);
1149             return(-1);
1150         }
1151
1152         xmlFree(subject);
1153         return(0);
1154     }
1155
1156     ret = xmlSecNssKeyDataX509AdoptCert(data, cert);
1157     if(ret < 0) {
1158         xmlSecError(XMLSEC_ERRORS_HERE,
1159                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1160                     "xmlSecNssKeyDataX509AdoptCert",
1161                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1162                     XMLSEC_ERRORS_NO_MESSAGE);
1163         CERT_DestroyCertificate(cert);
1164         xmlFree(subject);
1165         return(-1);
1166     }
1167     
1168     xmlFree(subject);
1169     return(0);
1170 }
1171
1172 static int
1173 xmlSecNssX509SubjectNameNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1174     xmlChar* buf = NULL;
1175     xmlNodePtr cur = NULL;
1176
1177     xmlSecAssert2(cert != NULL, -1);
1178     xmlSecAssert2(node != NULL, -1);
1179
1180     buf = xmlSecNssX509NameWrite(&(cert->subject));
1181     if(buf == NULL) {
1182         xmlSecError(XMLSEC_ERRORS_HERE,
1183             NULL,
1184             "xmlSecNssX509NameWrite(&(cert->subject))",
1185             XMLSEC_ERRORS_R_XMLSEC_FAILED,
1186             XMLSEC_ERRORS_NO_MESSAGE);
1187         return(-1);
1188     }
1189
1190     cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs);
1191     if(cur == NULL) {
1192         xmlSecError(XMLSEC_ERRORS_HERE,
1193             NULL,
1194             "xmlSecAddChild",
1195             XMLSEC_ERRORS_R_XMLSEC_FAILED,
1196             "node=%s",
1197             xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
1198         xmlFree(buf);
1199         return(-1);
1200     }
1201     xmlSecNodeEncodeAndSetContent(cur, buf);
1202     xmlFree(buf);
1203     return(0);
1204 }
1205
1206 static int 
1207 xmlSecNssX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1208     xmlSecKeyDataStorePtr x509Store;
1209     xmlNodePtr cur;
1210     xmlChar *issuerName;
1211     xmlChar *issuerSerial;    
1212     CERTCertificate* cert;
1213     int ret;
1214
1215     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1216     xmlSecAssert2(node != NULL, -1);
1217     xmlSecAssert2(keyInfoCtx != NULL, -1);
1218     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1219
1220     x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecNssX509StoreId);
1221     if(x509Store == NULL) {
1222         xmlSecError(XMLSEC_ERRORS_HERE,
1223                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1224                     "xmlSecKeysMngrGetDataStore",
1225                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1226                     XMLSEC_ERRORS_NO_MESSAGE);
1227         return(-1);
1228     }
1229
1230     cur = xmlSecGetNextElementNode(node->children);
1231     if(cur == NULL) {
1232         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1233             xmlSecError(XMLSEC_ERRORS_HERE,
1234                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1235                         xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
1236                         XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1237                         "node=%s",
1238                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1239             return(-1);
1240         }
1241         return(0);
1242     }
1243     
1244     /* the first is required node X509IssuerName */
1245     if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
1246         xmlSecError(XMLSEC_ERRORS_HERE,
1247                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1248                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
1249                     XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1250                     "node=%s",
1251                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1252         return(-1);
1253     }    
1254     issuerName = xmlNodeGetContent(cur);
1255     if(issuerName == NULL) {
1256         xmlSecError(XMLSEC_ERRORS_HERE,
1257                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1258                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1259                     XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1260                     "node=%s",
1261                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1262         return(-1);
1263     }
1264     cur = xmlSecGetNextElementNode(cur->next); 
1265
1266     /* next is required node X509SerialNumber */
1267     if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs)) {
1268         xmlSecError(XMLSEC_ERRORS_HERE,
1269                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1270                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1271                     XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1272                     "node=%s",
1273                     xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1274         xmlFree(issuerName);
1275         return(-1);
1276     }    
1277     issuerSerial = xmlNodeGetContent(cur);
1278     if(issuerSerial == NULL) {
1279         xmlSecError(XMLSEC_ERRORS_HERE,
1280                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1281                     xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber),
1282                     XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1283                     "node=%s",
1284                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
1285         xmlFree(issuerName);
1286         return(-1);
1287     }
1288     cur = xmlSecGetNextElementNode(cur->next); 
1289
1290     if(cur != NULL) {
1291         xmlSecError(XMLSEC_ERRORS_HERE,
1292                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1293                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
1294                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
1295                     XMLSEC_ERRORS_NO_MESSAGE);
1296         xmlFree(issuerSerial);
1297         xmlFree(issuerName);
1298         return(-1);
1299     }
1300
1301     cert = xmlSecNssX509StoreFindCert(x509Store, NULL, issuerName, issuerSerial, NULL, keyInfoCtx);
1302     if(cert == NULL){
1303         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1304             xmlSecError(XMLSEC_ERRORS_HERE,
1305                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1306                         NULL,
1307                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1308                         "issuerName=%s;issuerSerial=%s",
1309                         xmlSecErrorsSafeString(issuerName), 
1310                         xmlSecErrorsSafeString(issuerSerial));
1311             xmlFree(issuerSerial);
1312             xmlFree(issuerName);
1313             return(-1);
1314         }
1315
1316         xmlFree(issuerSerial);
1317         xmlFree(issuerName);
1318         return(0);    
1319     }
1320
1321     ret = xmlSecNssKeyDataX509AdoptCert(data, cert);
1322     if(ret < 0) {
1323         xmlSecError(XMLSEC_ERRORS_HERE,
1324                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1325                     "xmlSecNssKeyDataX509AdoptCert",
1326                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1327                     XMLSEC_ERRORS_NO_MESSAGE);
1328         CERT_DestroyCertificate(cert);
1329         xmlFree(issuerSerial);
1330         xmlFree(issuerName);
1331         return(-1);
1332     }
1333     
1334     xmlFree(issuerSerial);
1335     xmlFree(issuerName);
1336     return(0);
1337 }
1338
1339 static int
1340 xmlSecNssX509IssuerSerialNodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1341     xmlNodePtr cur;
1342     xmlNodePtr issuerNameNode;
1343     xmlNodePtr issuerNumberNode;
1344     xmlChar* buf;
1345     
1346     xmlSecAssert2(cert != NULL, -1);
1347     xmlSecAssert2(node != NULL, -1);
1348
1349     /* create xml nodes */
1350     cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
1351     if(cur == NULL) {
1352         xmlSecError(XMLSEC_ERRORS_HERE,
1353                     NULL,
1354                     "xmlSecAddChild",
1355                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1356                     "node=%s",
1357                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
1358         return(-1);
1359     }
1360
1361     issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs);
1362     if(issuerNameNode == NULL) {
1363         xmlSecError(XMLSEC_ERRORS_HERE,
1364                     NULL,
1365                     "xmlSecAddChild",
1366                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1367                     "node=%s",
1368                     xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
1369         return(-1);
1370     }
1371
1372     issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
1373     if(issuerNumberNode == NULL) {
1374         xmlSecError(XMLSEC_ERRORS_HERE,
1375                     NULL,
1376                     "xmlSecAddChild",
1377                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1378                     "node=%s",
1379                     xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
1380         return(-1);
1381     }
1382
1383     /* write data */
1384     buf = xmlSecNssX509NameWrite(&(cert->issuer));
1385     if(buf == NULL) {
1386         xmlSecError(XMLSEC_ERRORS_HERE,
1387                     NULL,
1388                     "xmlSecNssX509NameWrite(&(cert->issuer))",
1389                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1390                     XMLSEC_ERRORS_NO_MESSAGE);
1391         return(-1);
1392     }
1393     xmlSecNodeEncodeAndSetContent(issuerNameNode, buf);
1394     xmlFree(buf);
1395
1396     buf = xmlSecNssASN1IntegerWrite(&(cert->serialNumber));
1397     if(buf == NULL) {
1398         xmlSecError(XMLSEC_ERRORS_HERE,
1399                     NULL,
1400                     "xmlSecNssASN1IntegerWrite(&(cert->serialNumber))",
1401                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1402                     XMLSEC_ERRORS_NO_MESSAGE);
1403         return(-1);
1404     }
1405     xmlNodeSetContent(issuerNumberNode, buf);
1406     xmlFree(buf);
1407
1408     return(0);
1409 }
1410
1411 static int 
1412 xmlSecNssX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1413     xmlSecKeyDataStorePtr x509Store;
1414     xmlChar* ski;
1415     CERTCertificate* cert;
1416     int ret;
1417     
1418     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1419     xmlSecAssert2(node != NULL, -1);
1420     xmlSecAssert2(keyInfoCtx != NULL, -1);
1421     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1422
1423     x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecNssX509StoreId);
1424     if(x509Store == NULL) {
1425         xmlSecError(XMLSEC_ERRORS_HERE,
1426                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1427                     "xmlSecKeysMngrGetDataStore",
1428                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1429                     XMLSEC_ERRORS_NO_MESSAGE);
1430         return(-1);
1431     }
1432     
1433     ski = xmlNodeGetContent(node);
1434     if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) {
1435         if(ski != NULL) {
1436             xmlFree(ski);
1437         }
1438         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1439             xmlSecError(XMLSEC_ERRORS_HERE,
1440                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1441                         xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1442                         XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1443                         "node=%s",
1444                         xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1445             return(-1);
1446         }
1447         return(0);
1448     }
1449
1450     cert = xmlSecNssX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx);
1451     if(cert == NULL){
1452         xmlFree(ski);
1453
1454         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
1455             xmlSecError(XMLSEC_ERRORS_HERE,
1456                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1457                         NULL,
1458                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1459                         "ski=%s", 
1460                         xmlSecErrorsSafeString(ski));
1461             return(-1);
1462         }
1463         return(0);
1464     }
1465
1466     ret = xmlSecNssKeyDataX509AdoptCert(data, cert);
1467     if(ret < 0) {
1468         xmlSecError(XMLSEC_ERRORS_HERE,
1469                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1470                     "xmlSecNssKeyDataX509AdoptCert",
1471                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1472                     XMLSEC_ERRORS_NO_MESSAGE);
1473         CERT_DestroyCertificate(cert);
1474         xmlFree(ski);
1475         return(-1);
1476     }
1477     
1478     xmlFree(ski);
1479     return(0);
1480 }
1481
1482 static int
1483 xmlSecNssX509SKINodeWrite(CERTCertificate* cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
1484     xmlChar *buf = NULL;
1485     xmlNodePtr cur = NULL;
1486
1487     xmlSecAssert2(cert != NULL, -1);
1488     xmlSecAssert2(node != NULL, -1);
1489
1490     buf = xmlSecNssX509SKIWrite(cert);
1491     if(buf == NULL) {
1492         xmlSecError(XMLSEC_ERRORS_HERE,
1493                     NULL,
1494                     "xmlSecNssX509SKIWrite",
1495                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1496                     XMLSEC_ERRORS_NO_MESSAGE);
1497         return(-1);
1498     }
1499
1500     cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs);
1501     if(cur == NULL) {
1502         xmlSecError(XMLSEC_ERRORS_HERE,
1503                     NULL,
1504                     "xmlSecAddChild",
1505                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1506                     "new_node=%s",
1507                     xmlSecErrorsSafeString(xmlSecNodeX509SKI));
1508         xmlFree(buf);
1509         return(-1);
1510     }
1511     xmlSecNodeEncodeAndSetContent(cur, buf);
1512     xmlFree(buf);
1513
1514     return(0);
1515 }
1516
1517 static int 
1518 xmlSecNssX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1519     xmlChar *content;
1520     CERTSignedCrl* crl;
1521
1522     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1523     xmlSecAssert2(node != NULL, -1);
1524     xmlSecAssert2(keyInfoCtx != NULL, -1);
1525
1526     content = xmlNodeGetContent(node);
1527    if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
1528         if(content != NULL) {
1529             xmlFree(content);
1530         }
1531         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
1532             xmlSecError(XMLSEC_ERRORS_HERE,
1533                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1534                         xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
1535                         XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
1536                         XMLSEC_ERRORS_NO_MESSAGE);
1537             return(-1);
1538         }
1539         return(0);
1540     }
1541
1542     crl = xmlSecNssX509CrlBase64DerRead(content, keyInfoCtx);
1543     if(crl == NULL) {
1544         xmlSecError(XMLSEC_ERRORS_HERE,
1545                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1546                     "xmlSecNssX509CrlBase64DerRead",
1547                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1548                     XMLSEC_ERRORS_NO_MESSAGE);
1549         xmlFree(content);
1550         return(-1);
1551     }    
1552     
1553     SEC_DestroyCrl(crl); 
1554     xmlFree(content);
1555     return(0);
1556 }
1557
1558 static int
1559 xmlSecNssX509CRLNodeWrite(CERTSignedCrl* crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1560     xmlChar* buf = NULL;
1561     xmlNodePtr cur = NULL;
1562
1563     xmlSecAssert2(crl != NULL, -1);
1564     xmlSecAssert2(node != NULL, -1);
1565     xmlSecAssert2(keyInfoCtx != NULL, -1);
1566
1567     /* set base64 lines size from context */
1568     buf = xmlSecNssX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize); 
1569     if(buf == NULL) {
1570         xmlSecError(XMLSEC_ERRORS_HERE,
1571                     NULL,
1572                     "xmlSecNssX509CrlBase64DerWrite",
1573                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1574                     XMLSEC_ERRORS_NO_MESSAGE);
1575         return(-1);
1576     }
1577
1578     cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
1579     if(cur == NULL) {
1580         xmlSecError(XMLSEC_ERRORS_HERE,
1581                     NULL,
1582                     "xmlSecAddChild",
1583                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1584                     "new_node=%s",
1585                     xmlSecErrorsSafeString(xmlSecNodeX509CRL));
1586         xmlFree(buf);
1587         return(-1);
1588     }
1589     /* todo: add \n around base64 data - from context */
1590     /* todo: add errors check */
1591     xmlNodeSetContent(cur, xmlSecStringCR);
1592     xmlNodeSetContent(cur, buf);
1593     xmlFree(buf);
1594
1595     return(0);
1596 }
1597
1598
1599 static int
1600 xmlSecNssKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key,
1601                                     xmlSecKeyInfoCtxPtr keyInfoCtx) {
1602     xmlSecNssX509DataCtxPtr ctx;
1603     xmlSecKeyDataStorePtr x509Store;
1604     int ret;
1605     SECStatus status;
1606     PRTime notBefore, notAfter;
1607     
1608     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecNssKeyDataX509Id), -1);
1609     xmlSecAssert2(key != NULL, -1);
1610     xmlSecAssert2(keyInfoCtx != NULL, -1);
1611     xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
1612
1613     ctx = xmlSecNssX509DataGetCtx(data);
1614     xmlSecAssert2(ctx != NULL, -1);
1615
1616     x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecNssX509StoreId);
1617     if(x509Store == NULL) {
1618         xmlSecError(XMLSEC_ERRORS_HERE,
1619                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1620                     "xmlSecKeysMngrGetDataStore",
1621                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1622                     XMLSEC_ERRORS_NO_MESSAGE);
1623         return(-1);
1624     }
1625
1626     if((ctx->keyCert == NULL) && (ctx->certsList != NULL) && (xmlSecKeyGetValue(key) == NULL)) {
1627         CERTCertificate* cert;
1628         
1629         cert = xmlSecNssX509StoreVerify(x509Store, ctx->certsList, keyInfoCtx);
1630         if(cert != NULL) {
1631             xmlSecKeyDataPtr keyValue;
1632             
1633             ctx->keyCert = CERT_DupCertificate(cert);
1634             if(ctx->keyCert == NULL) {
1635                 xmlSecError(XMLSEC_ERRORS_HERE,
1636                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1637                             "CERT_DupCertificate",
1638                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
1639                             XMLSEC_ERRORS_NO_MESSAGE);
1640                 return(-1);
1641             }
1642         
1643             keyValue = xmlSecNssX509CertGetKey(ctx->keyCert);
1644             if(keyValue == NULL) {
1645                 xmlSecError(XMLSEC_ERRORS_HERE,
1646                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1647                             "xmlSecNssX509CertGetKey",
1648                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
1649                             XMLSEC_ERRORS_NO_MESSAGE);
1650                 return(-1);
1651             }
1652             
1653             /* verify that the key matches our expectations */
1654             if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) {
1655                 xmlSecError(XMLSEC_ERRORS_HERE,
1656                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1657                             "xmlSecKeyReqMatchKeyValue",
1658                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
1659                             XMLSEC_ERRORS_NO_MESSAGE);
1660                 xmlSecKeyDataDestroy(keyValue);
1661                 return(-1);
1662             }   
1663                 
1664             ret = xmlSecKeySetValue(key, keyValue);
1665             if(ret < 0) {
1666                 xmlSecError(XMLSEC_ERRORS_HERE,
1667                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1668                             "xmlSecKeySetValue",
1669                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
1670                             XMLSEC_ERRORS_NO_MESSAGE);
1671                 xmlSecKeyDataDestroy(keyValue);
1672                 return(-1);
1673             }       
1674             
1675             status = CERT_GetCertTimes(ctx->keyCert, &notBefore, &notAfter);
1676             if (status == SECSuccess) {
1677                 ret = xmlSecNssX509CertGetTime(&notBefore, &(key->notValidBefore));
1678                 if(ret < 0) {
1679                     xmlSecError(XMLSEC_ERRORS_HERE,
1680                                 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1681                                 "xmlSecNssX509CertGetTime",
1682                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1683                                 "notValidBefore");
1684                     return(-1);
1685                 }
1686                 ret = xmlSecNssX509CertGetTime(&notAfter, &(key->notValidAfter));
1687                 if(ret < 0) {
1688                     xmlSecError(XMLSEC_ERRORS_HERE,
1689                                 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1690                                 "xmlSecNssX509CertGetTime",
1691                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1692                                 "notValidAfter");
1693                     return(-1);
1694                 }
1695             } else {
1696                 key->notValidBefore = key->notValidAfter = 0;
1697             }
1698         } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT) != 0) {
1699             xmlSecError(XMLSEC_ERRORS_HERE,
1700                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
1701                         NULL,
1702                         XMLSEC_ERRORS_R_CERT_NOT_FOUND,
1703                         XMLSEC_ERRORS_NO_MESSAGE);
1704             return(-1);
1705         }
1706     }
1707     return(0);
1708 }
1709
1710 static int
1711 xmlSecNssX509CertGetTime(PRTime* t, time_t* res) {
1712     
1713     PRTime tmp64_1, tmp64_2;
1714     PRUint32 tmp32 = 1000000;
1715
1716     xmlSecAssert2(t != NULL, -1);
1717     xmlSecAssert2(res != NULL, -1);
1718
1719     /* PRTime is time in microseconds since epoch. Divide by 1000000 to
1720      * convert to seconds, then convert to an unsigned 32 bit number
1721      */
1722     (*res) = 0;
1723     LL_UI2L(tmp64_1, tmp32);
1724     LL_DIV(tmp64_2, *t, tmp64_1);
1725     LL_L2UI(tmp32, tmp64_2);
1726
1727     (*res) = (time_t)(tmp32);
1728
1729     return(0);
1730 }
1731
1732 /** 
1733  * xmlSecNssX509CertGetKey:
1734  * @cert:               the certificate.
1735  * 
1736  * Extracts public key from the @cert.
1737  *
1738  * Returns: public key value or NULL if an error occurs.
1739  */
1740 xmlSecKeyDataPtr        
1741 xmlSecNssX509CertGetKey(CERTCertificate* cert) {
1742     xmlSecKeyDataPtr data;
1743     SECKEYPublicKey *pubkey = NULL;
1744     
1745     xmlSecAssert2(cert != NULL, NULL);
1746
1747     pubkey = CERT_ExtractPublicKey(cert);
1748     if(pubkey == NULL) {
1749         xmlSecError(XMLSEC_ERRORS_HERE,
1750                     NULL,
1751                     "CERT_ExtractPublicKey",
1752                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1753                     "error code=%d", PORT_GetError());
1754         return(NULL);
1755     }    
1756
1757     data = xmlSecNssPKIAdoptKey(NULL, pubkey);
1758     if(data == NULL) {
1759         xmlSecError(XMLSEC_ERRORS_HERE,
1760                     NULL,
1761                     "xmlSecNssPKIAdoptKey",
1762                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1763                     XMLSEC_ERRORS_NO_MESSAGE);
1764         SECKEY_DestroyPublicKey(pubkey);
1765         return(NULL);       
1766     }    
1767     
1768     return(data);
1769 }
1770
1771 static CERTCertificate*
1772 xmlSecNssX509CertBase64DerRead(xmlChar* buf) {
1773     int ret;
1774
1775     xmlSecAssert2(buf != NULL, NULL);
1776     
1777     /* usual trick with base64 decoding "in-place" */
1778     ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); 
1779     if(ret < 0) {
1780         xmlSecError(XMLSEC_ERRORS_HERE,
1781                     NULL,
1782                     "xmlSecBase64Decode",
1783                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1784                     XMLSEC_ERRORS_NO_MESSAGE);
1785         return(NULL);
1786     }
1787     
1788     return(xmlSecNssX509CertDerRead((xmlSecByte*)buf, ret));
1789 }
1790
1791
1792 static CERTCertificate*
1793 xmlSecNssX509CertDerRead(const xmlSecByte* buf, xmlSecSize size) {
1794     CERTCertificate *cert;
1795     SECItem  derCert;
1796
1797     xmlSecAssert2(buf != NULL, NULL);
1798     xmlSecAssert2(size > 0, NULL);
1799     
1800     derCert.data = (unsigned char *)buf;
1801     derCert.len = size;
1802
1803     /* decode cert and import to temporary cert db */
1804     cert = __CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert,
1805                                      NULL, PR_FALSE, PR_TRUE);
1806     if(cert == NULL) {
1807         xmlSecError(XMLSEC_ERRORS_HERE,
1808                     NULL,
1809                     "__CERT_NewTempCertificate",
1810                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1811                     "error code=%d", PORT_GetError());
1812         return(NULL);
1813     }
1814
1815
1816     return(cert);
1817 }
1818
1819 static xmlChar*
1820 xmlSecNssX509CertBase64DerWrite(CERTCertificate* cert, int base64LineWrap) {
1821     xmlChar *res = NULL;
1822     xmlSecByte *p = NULL;
1823     long size;
1824
1825     xmlSecAssert2(cert != NULL, NULL);
1826         
1827     p = cert->derCert.data;
1828     size = cert->derCert.len;
1829     if((size <= 0) || (p == NULL)){
1830         xmlSecError(XMLSEC_ERRORS_HERE,
1831                     NULL,
1832                     "cert->derCert",
1833                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1834                     "error code=%d", PORT_GetError());
1835         return(NULL);
1836     }
1837     
1838     res = xmlSecBase64Encode(p, size, base64LineWrap);
1839     if(res == NULL) {
1840         xmlSecError(XMLSEC_ERRORS_HERE,
1841                     NULL,
1842                     "xmlSecBase64Encode",
1843                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1844                     XMLSEC_ERRORS_NO_MESSAGE);
1845         return(NULL);
1846     }    
1847
1848     return(res);
1849 }
1850
1851 static CERTSignedCrl*
1852 xmlSecNssX509CrlBase64DerRead(xmlChar* buf, 
1853                               xmlSecKeyInfoCtxPtr keyInfoCtx) {
1854     int ret;
1855
1856     xmlSecAssert2(buf != NULL, NULL);
1857     
1858     /* usual trick with base64 decoding "in-place" */
1859     ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); 
1860     if(ret < 0) {
1861         xmlSecError(XMLSEC_ERRORS_HERE,
1862                     NULL,
1863                     "xmlSecBase64Decode",
1864                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1865                     XMLSEC_ERRORS_NO_MESSAGE);
1866         return(NULL);
1867     }
1868     
1869     return(xmlSecNssX509CrlDerRead((xmlSecByte*)buf, ret, keyInfoCtx));
1870 }
1871
1872
1873 static CERTSignedCrl*
1874 xmlSecNssX509CrlDerRead(xmlSecByte* buf, xmlSecSize size,
1875                         xmlSecKeyInfoCtxPtr keyInfoCtx) {
1876     CERTSignedCrl *crl = NULL;
1877     SECItem derCrl;
1878     PK11SlotInfo *slot = NULL;
1879     PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
1880
1881     xmlSecAssert2(buf != NULL, NULL);
1882     xmlSecAssert2(keyInfoCtx != NULL, NULL);
1883     xmlSecAssert2(size > 0, NULL);
1884     
1885     derCrl.data = buf;
1886     derCrl.len = size;
1887
1888     /* we're importing a CRL, it is ok to use the internal slot.
1889      * crlutil does it :)
1890      */
1891     slot = xmlSecNssGetInternalKeySlot();
1892     if (slot == NULL) {
1893         xmlSecError(XMLSEC_ERRORS_HERE,
1894                     NULL,
1895                     "xmlSecNssGetInternalKeySlot",
1896                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1897                         XMLSEC_ERRORS_NO_MESSAGE);
1898         return NULL;
1899     }
1900
1901     if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS) != 0)
1902         importOptions |= CRL_IMPORT_BYPASS_CHECKS;
1903
1904     crl = PK11_ImportCRL(slot, &derCrl, NULL, SEC_CRL_TYPE, NULL, 
1905                          importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS);
1906
1907     if(crl == NULL) {
1908         xmlSecError(XMLSEC_ERRORS_HERE,
1909                     NULL,
1910                     "PK11_ImportCRL",
1911                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1912                     "error code=%d", PORT_GetError());
1913         PK11_FreeSlot(slot);
1914         return(NULL);
1915     }
1916
1917     PK11_FreeSlot(slot);
1918     return(crl);
1919 }
1920
1921 static xmlChar*
1922 xmlSecNssX509CrlBase64DerWrite(CERTSignedCrl* crl, int base64LineWrap) {
1923     xmlChar *res = NULL;
1924     xmlSecByte *p = NULL;
1925     long size;
1926
1927     xmlSecAssert2(crl != NULL && crl->derCrl != NULL, NULL);
1928
1929     p = crl->derCrl->data;
1930     size = crl->derCrl->len;
1931     if((size <= 0) || (p == NULL)){
1932         xmlSecError(XMLSEC_ERRORS_HERE,
1933                     NULL,
1934                     "crl->derCrl",
1935                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1936                     "error code=%d", PORT_GetError());
1937         return(NULL);
1938     }
1939
1940     res = xmlSecBase64Encode(p, size, base64LineWrap);
1941     if(res == NULL) {
1942         xmlSecError(XMLSEC_ERRORS_HERE,
1943                     NULL,
1944                     "xmlSecBase64Encode",
1945                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1946                     XMLSEC_ERRORS_NO_MESSAGE);
1947         return(NULL);
1948     }   
1949
1950     return(res);
1951 }
1952
1953 static xmlChar*
1954 xmlSecNssX509NameWrite(CERTName* nm) {
1955     xmlChar *res = NULL;
1956     char *str;
1957
1958     xmlSecAssert2(nm != NULL, NULL);
1959
1960     str = CERT_NameToAscii(nm);
1961     if (str == NULL) {
1962         xmlSecError(XMLSEC_ERRORS_HERE,
1963                     NULL,
1964                     "CERT_NameToAscii",
1965                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1966                     XMLSEC_ERRORS_NO_MESSAGE);
1967         return(NULL);
1968     }
1969
1970     res = xmlStrdup(BAD_CAST str);
1971     if(res == NULL) {
1972         xmlSecError(XMLSEC_ERRORS_HERE,
1973                     NULL,
1974                     "xmlStrdup",
1975                     XMLSEC_ERRORS_R_MALLOC_FAILED,
1976                     XMLSEC_ERRORS_NO_MESSAGE);
1977         PORT_Free(str);
1978         return(NULL);
1979     }
1980     PORT_Free(str);
1981     return(res);
1982 }
1983
1984 static xmlChar*
1985 xmlSecNssASN1IntegerWrite(SECItem *num) {
1986     xmlChar *res = NULL;
1987     
1988     xmlSecAssert2(num != NULL, NULL);
1989
1990     /* TODO : to be implemented after 
1991      * NSS bug http://bugzilla.mozilla.org/show_bug.cgi?id=212864 is fixed 
1992      */
1993     return(res);
1994 }
1995
1996 static xmlChar*
1997 xmlSecNssX509SKIWrite(CERTCertificate* cert) {
1998     xmlChar *res = NULL;
1999     SECItem ski;
2000     SECStatus rv;
2001
2002     xmlSecAssert2(cert != NULL, NULL);
2003
2004     memset(&ski, 0, sizeof(ski));
2005
2006     rv = CERT_FindSubjectKeyIDExtension(cert, &ski);
2007     if (rv != SECSuccess) {
2008         xmlSecError(XMLSEC_ERRORS_HERE,
2009                     NULL,
2010                     "CERT_FindSubjectKeyIDExtension",
2011                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
2012                     XMLSEC_ERRORS_NO_MESSAGE);
2013         SECITEM_FreeItem(&ski, PR_FALSE);
2014         return(NULL);
2015     }
2016
2017     res = xmlSecBase64Encode(ski.data, ski.len, 0);
2018     if(res == NULL) {
2019         xmlSecError(XMLSEC_ERRORS_HERE,
2020                     NULL,
2021                     "xmlSecBase64Encode",
2022                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2023                     XMLSEC_ERRORS_NO_MESSAGE);
2024         SECITEM_FreeItem(&ski, PR_FALSE);
2025         return(NULL);
2026     }
2027     SECITEM_FreeItem(&ski, PR_FALSE);
2028     
2029     return(res);
2030 }
2031
2032
2033 static void 
2034 xmlSecNssX509CertDebugDump(CERTCertificate* cert, FILE* output) {
2035     SECItem *sn;
2036     unsigned int i;
2037
2038     xmlSecAssert(cert != NULL);
2039     xmlSecAssert(output != NULL);
2040
2041     fprintf(output, "==== Subject Name: %s\n", cert->subjectName);
2042     fprintf(output, "==== Issuer Name: %s\n", cert->issuerName);
2043     sn = &cert->serialNumber;
2044
2045     for (i = 0; i < sn->len; i++) {
2046         if (i != sn->len - 1) {
2047             fprintf(output, "%02x:", sn->data[i]);
2048         } else {
2049             fprintf(output, "%02x", sn->data[i]);
2050         }
2051     }
2052     fprintf(output, "\n");
2053 }
2054
2055
2056 static void 
2057 xmlSecNssX509CertDebugXmlDump(CERTCertificate* cert, FILE* output) {
2058     SECItem *sn;
2059     unsigned int i;
2060
2061     xmlSecAssert(cert != NULL);
2062     xmlSecAssert(output != NULL);
2063
2064     fprintf(output, "<SubjectName>");
2065     xmlSecPrintXmlString(output, BAD_CAST cert->subjectName);
2066     fprintf(output, "</SubjectName>\n");
2067
2068     fprintf(output, "<IssuerName>");
2069     xmlSecPrintXmlString(output, BAD_CAST cert->issuerName);
2070     fprintf(output, "</IssuerName>\n");
2071
2072     fprintf(output, "<SerialNumber>");
2073     sn = &cert->serialNumber;
2074     for (i = 0; i < sn->len; i++) {
2075         if (i != sn->len - 1) {
2076             fprintf(output, "%02x:", sn->data[i]);
2077         } else {
2078             fprintf(output, "%02x", sn->data[i]);
2079         }
2080     }
2081     fprintf(output, "</SerialNumber>\n");
2082 }
2083
2084
2085 /**************************************************************************
2086  *
2087  * Raw X509 Certificate processing
2088  *
2089  *
2090  *************************************************************************/
2091 static int              xmlSecNssKeyDataRawX509CertBinRead      (xmlSecKeyDataId id,
2092                                                                  xmlSecKeyPtr key,
2093                                                                  const xmlSecByte* buf,
2094                                                                  xmlSecSize bufSize,
2095                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
2096
2097 static xmlSecKeyDataKlass xmlSecNssKeyDataRawX509CertKlass = {
2098     sizeof(xmlSecKeyDataKlass),
2099     sizeof(xmlSecKeyData),
2100
2101     /* data */
2102     xmlSecNameRawX509Cert,
2103     xmlSecKeyDataUsageRetrievalMethodNodeBin, 
2104                                                 /* xmlSecKeyDataUsage usage; */
2105     xmlSecHrefRawX509Cert,                      /* const xmlChar* href; */
2106     NULL,                                       /* const xmlChar* dataNodeName; */
2107     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
2108     
2109     /* constructors/destructor */
2110     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
2111     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
2112     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
2113     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
2114
2115     /* get info */
2116     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
2117     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
2118     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
2119
2120     /* read/write */
2121     NULL,                                       /* xmlSecKeyDataXmlReadMethod xmlRead; */
2122     NULL,                                       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2123     xmlSecNssKeyDataRawX509CertBinRead, /* xmlSecKeyDataBinReadMethod binRead; */
2124     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
2125
2126     /* debug */
2127     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
2128     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2129
2130     /* reserved for the future */
2131     NULL,                                       /* void* reserved0; */
2132     NULL,                                       /* void* reserved1; */
2133 };
2134
2135 /**
2136  * xmlSecNssKeyDataRawX509CertGetKlass:
2137  * 
2138  * The raw X509 certificates key data klass.
2139  *
2140  * Returns: raw X509 certificates key data klass.
2141  */
2142 xmlSecKeyDataId 
2143 xmlSecNssKeyDataRawX509CertGetKlass(void) {
2144     return(&xmlSecNssKeyDataRawX509CertKlass);
2145 }
2146
2147 static int
2148 xmlSecNssKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
2149                                     const xmlSecByte* buf, xmlSecSize bufSize,
2150                                     xmlSecKeyInfoCtxPtr keyInfoCtx) {
2151     xmlSecKeyDataPtr data;
2152     CERTCertificate* cert;
2153     int ret;
2154     
2155     xmlSecAssert2(id == xmlSecNssKeyDataRawX509CertId, -1);
2156     xmlSecAssert2(key != NULL, -1);
2157     xmlSecAssert2(buf != NULL, -1);
2158     xmlSecAssert2(bufSize > 0, -1);
2159     xmlSecAssert2(keyInfoCtx != NULL, -1);
2160
2161     cert = xmlSecNssX509CertDerRead(buf, bufSize);
2162     if(cert == NULL) {
2163         xmlSecError(XMLSEC_ERRORS_HERE,
2164                     NULL,
2165                     "xmlSecNssX509CertDerRead",
2166                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2167                     XMLSEC_ERRORS_NO_MESSAGE);
2168         return(-1);
2169     }
2170
2171     data = xmlSecKeyEnsureData(key, xmlSecNssKeyDataX509Id);
2172     if(data == NULL) {
2173         xmlSecError(XMLSEC_ERRORS_HERE,
2174                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2175                     "xmlSecKeyEnsureData",
2176                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2177                     XMLSEC_ERRORS_NO_MESSAGE);
2178         CERT_DestroyCertificate(cert);
2179         return(-1);
2180     }
2181     
2182     ret = xmlSecNssKeyDataX509AdoptCert(data, cert);
2183     if(ret < 0) {
2184         xmlSecError(XMLSEC_ERRORS_HERE,
2185                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2186                     "xmlSecNssKeyDataX509AdoptCert",
2187                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2188                     XMLSEC_ERRORS_NO_MESSAGE);
2189         CERT_DestroyCertificate(cert);
2190         return(-1);
2191     }
2192
2193     ret = xmlSecNssKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
2194     if(ret < 0) {
2195         xmlSecError(XMLSEC_ERRORS_HERE,
2196                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
2197                     "xmlSecNssKeyDataX509VerifyAndExtractKey",
2198                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
2199                     XMLSEC_ERRORS_NO_MESSAGE);
2200         return(-1);
2201     }
2202     return(0);
2203 }
2204
2205 #endif /* XMLSEC_NO_X509 */