Git init
[external/xmlsec1.git] / src / openssl / app.c
1 /** 
2  * XMLSec library
3  *
4  * This is free software; see Copyright file in the source
5  * distribution for preciese wording.
6  * 
7  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
8  */
9 #include "globals.h"
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14
15 #include <libxml/tree.h>
16
17 #include <openssl/evp.h>
18 #include <openssl/rand.h>
19 #include <openssl/pem.h>
20 #include <openssl/pkcs12.h>
21 #include <openssl/conf.h>
22
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/keys.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/xmltree.h>
27 #include <xmlsec/private.h>
28 #include <xmlsec/errors.h>
29
30 #include <xmlsec/openssl/app.h>
31 #include <xmlsec/openssl/crypto.h>
32 #include <xmlsec/openssl/evp.h>
33 #include <xmlsec/openssl/x509.h>
34
35 static int              xmlSecOpenSSLAppLoadRANDFile            (const char *file);
36 static int              xmlSecOpenSSLAppSaveRANDFile            (const char *file);
37 static int              xmlSecOpenSSLDefaultPasswordCallback(char *buf, int bufsiz, int verify, void *userdata);
38 static int      xmlSecOpenSSLDummyPasswordCallback  (char *buf, int bufsize, int verify, void *userdata);
39
40 /**
41  * xmlSecOpenSSLAppInit:
42  * @config:             the path to certs.
43  *
44  * General crypto engine initialization. This function is used
45  * by XMLSec command line utility and called before 
46  * @xmlSecInit function.
47  *
48  * Returns: 0 on success or a negative value otherwise.
49  */
50 int
51 xmlSecOpenSSLAppInit(const char* config) {
52     ERR_load_crypto_strings();
53     OPENSSL_config(NULL);
54     OpenSSL_add_all_algorithms();
55
56     if((RAND_status() != 1) && (xmlSecOpenSSLAppLoadRANDFile(NULL) != 1)) {
57         xmlSecError(XMLSEC_ERRORS_HERE,
58                     NULL,
59                     "xmlSecOpenSSLAppLoadRANDFile",
60                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
61                     XMLSEC_ERRORS_NO_MESSAGE);
62         return(-1);
63     }
64     
65     if((config != NULL) && (xmlSecOpenSSLSetDefaultTrustedCertsFolder(BAD_CAST config) < 0)) {
66         xmlSecError(XMLSEC_ERRORS_HERE,
67                     NULL,
68                     "xmlSecOpenSSLSetDefaultTrustedCertsFolder",
69                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
70                     XMLSEC_ERRORS_NO_MESSAGE);
71         return(-1);
72     }
73
74     return(0);
75 }
76
77 /**
78  * xmlSecOpenSSLAppShutdown:
79  * 
80  * General crypto engine shutdown. This function is used
81  * by XMLSec command line utility and called after 
82  * @xmlSecShutdown function.
83  *
84  * Returns: 0 on success or a negative value otherwise.
85  */
86 int
87 xmlSecOpenSSLAppShutdown(void) {
88     xmlSecOpenSSLAppSaveRANDFile(NULL);
89     RAND_cleanup();
90     EVP_cleanup();    
91
92 #ifndef XMLSEC_NO_X509
93     X509_TRUST_cleanup();
94 #endif /* XMLSEC_NO_X509 */    
95
96 #ifndef XMLSEC_OPENSSL_096
97     CRYPTO_cleanup_all_ex_data();
98 #endif /* XMLSEC_OPENSSL_096 */     
99
100     /* finally cleanup errors */
101     ERR_remove_state(0);
102     ERR_free_strings();
103
104     return(0);
105 }
106
107 /**
108  * xmlSecOpenSSLAppKeyLoad:
109  * @filename:           the key filename.
110  * @format:             the key file format.
111  * @pwd:                the key file password.
112  * @pwdCallback:        the key password callback.
113  * @pwdCallbackCtx:     the user context for password callback.
114  *
115  * Reads key from the a file.
116  *
117  * Returns: pointer to the key or NULL if an error occurs.
118  */
119 xmlSecKeyPtr
120 xmlSecOpenSSLAppKeyLoad(const char *filename, xmlSecKeyDataFormat format,
121                         const char *pwd, void* pwdCallback, 
122                         void* pwdCallbackCtx) {
123     BIO* bio;
124     xmlSecKeyPtr key;
125     
126     xmlSecAssert2(filename != NULL, NULL);
127     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
128
129     bio = BIO_new_file(filename, "rb");
130     if(bio == NULL) {
131         xmlSecError(XMLSEC_ERRORS_HERE,
132                     NULL,
133                     "BIO_new_file",
134                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
135                     "filename=%s;errno=%d", 
136                     xmlSecErrorsSafeString(filename), 
137                     errno);
138         return(NULL);    
139     }
140
141     key = xmlSecOpenSSLAppKeyLoadBIO (bio, format, pwd, pwdCallback, pwdCallbackCtx);
142     if(key == NULL) {
143         xmlSecError(XMLSEC_ERRORS_HERE,
144                     NULL,
145                     "xmlSecOpenSSLAppKeyLoadBIO",
146                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
147                     "filename=%s;errno=%d", 
148                     xmlSecErrorsSafeString(filename), 
149                     errno);
150         BIO_free(bio);
151         return(NULL);
152     }
153     
154     BIO_free(bio);
155     return(key);
156 }
157
158 /**
159  * xmlSecOpenSSLAppKeyLoadMemory:
160  * @data:               the binary key data.
161  * @dataSize:           the size of binary key.
162  * @format:             the key file format.
163  * @pwd:                the key file password.
164  * @pwdCallback:        the key password callback.
165  * @pwdCallbackCtx:     the user context for password callback.
166  *
167  * Reads key from the memory buffer.
168  *
169  * Returns: pointer to the key or NULL if an error occurs.
170  */
171 xmlSecKeyPtr
172 xmlSecOpenSSLAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, 
173                         xmlSecKeyDataFormat format, const char *pwd, 
174                         void* pwdCallback, void* pwdCallbackCtx) {
175     BIO* bio;
176     xmlSecKeyPtr key;
177     
178     xmlSecAssert2(data != NULL, NULL);
179     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
180     
181     /* this would be a read only BIO, cast from const is ok */
182     bio = BIO_new_mem_buf((void*)data, dataSize);
183     if(bio == NULL) {
184         xmlSecError(XMLSEC_ERRORS_HERE,
185                     NULL,
186                     "BIO_new_mem_buf",
187                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
188                     "errno=%d", 
189                     errno);
190         return(NULL);    
191     }
192
193     key = xmlSecOpenSSLAppKeyLoadBIO (bio, format, pwd, pwdCallback, pwdCallbackCtx);
194     if(key == NULL) {
195         xmlSecError(XMLSEC_ERRORS_HERE,
196                     NULL,
197                     "xmlSecOpenSSLAppKeyLoadBIO",
198                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
199                     XMLSEC_ERRORS_NO_MESSAGE);
200         BIO_free(bio);
201         return(NULL);
202     }
203     
204     BIO_free(bio);
205     return(key);
206 }
207
208
209 /**
210  * xmlSecOpenSSLAppKeyLoadBIO:
211  * @bio:                the key BIO.
212  * @format:             the key file format.
213  * @pwd:                the key file password.
214  * @pwdCallback:        the key password callback.
215  * @pwdCallbackCtx:     the user context for password callback.
216  *
217  * Reads key from the an OpenSSL BIO object.
218  *
219  * Returns: pointer to the key or NULL if an error occurs.
220  */
221 xmlSecKeyPtr
222 xmlSecOpenSSLAppKeyLoadBIO(BIO* bio, xmlSecKeyDataFormat format,
223                         const char *pwd, void* pwdCallback, 
224                         void* pwdCallbackCtx) {
225
226     xmlSecKeyPtr key = NULL;
227     xmlSecKeyDataPtr data;
228     EVP_PKEY* pKey = NULL;    
229     int ret;
230
231     xmlSecAssert2(bio != NULL, NULL);
232     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
233
234     switch(format) {
235     case xmlSecKeyDataFormatPem:
236         /* try to read private key first */    
237             pKey = PEM_read_bio_PrivateKey(bio, NULL, 
238             (pwd != NULL) ? xmlSecOpenSSLDummyPasswordCallback : (pem_password_cb*)pwdCallback, 
239             (pwd != NULL) ? pwd : pwdCallbackCtx);
240         if(pKey == NULL) {
241             /* go to start of the file and try to read public key */
242             BIO_reset(bio); 
243             pKey = PEM_read_bio_PUBKEY(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
244             if(pKey == NULL) {
245                 xmlSecError(XMLSEC_ERRORS_HERE,
246                             NULL,
247                             "PEM_read_bio_PrivateKey and PEM_read_bio_PUBKEY",
248                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
249                             XMLSEC_ERRORS_NO_MESSAGE);
250                 return(NULL);
251             }
252         }
253         break;
254     case xmlSecKeyDataFormatDer:
255         /* try to read private key first */    
256         pKey = d2i_PrivateKey_bio(bio, NULL);
257         if(pKey == NULL) {
258             /* go to start of the file and try to read public key */
259             BIO_reset(bio); 
260             pKey = d2i_PUBKEY_bio(bio, NULL);
261             if(pKey == NULL) {
262                 xmlSecError(XMLSEC_ERRORS_HERE,
263                             NULL,
264                             "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
265                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
266                             XMLSEC_ERRORS_NO_MESSAGE);
267                 return(NULL);
268             }
269         }
270         break;
271     case xmlSecKeyDataFormatPkcs8Pem:
272         /* try to read private key first */    
273         pKey = PEM_read_bio_PrivateKey(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
274         if(pKey == NULL) {
275             xmlSecError(XMLSEC_ERRORS_HERE,
276                         NULL,
277                         "PEM_read_bio_PrivateKey",
278                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
279                         XMLSEC_ERRORS_NO_MESSAGE);
280             return(NULL);       
281         }
282         break;
283     case xmlSecKeyDataFormatPkcs8Der:
284         /* try to read private key first */    
285         pKey = d2i_PKCS8PrivateKey_bio(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
286         if(pKey == NULL) {
287             xmlSecError(XMLSEC_ERRORS_HERE,
288                         NULL,
289                         "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
290                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
291                         XMLSEC_ERRORS_NO_MESSAGE);
292             return(NULL);
293         }
294         break;
295 #ifndef XMLSEC_NO_X509
296     case xmlSecKeyDataFormatPkcs12:
297         key = xmlSecOpenSSLAppPkcs12LoadBIO(bio, pwd, pwdCallback, pwdCallbackCtx);
298         if(key == NULL) {
299             xmlSecError(XMLSEC_ERRORS_HERE,
300                         NULL,
301                         "xmlSecOpenSSLAppPkcs12LoadBIO",
302                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
303                         XMLSEC_ERRORS_NO_MESSAGE);
304             return(NULL);       
305         }
306         return(key);
307         
308     case xmlSecKeyDataFormatCertPem:
309     case xmlSecKeyDataFormatCertDer: 
310         key = xmlSecOpenSSLAppKeyFromCertLoadBIO(bio, format);
311         if(key == NULL) {
312             xmlSecError(XMLSEC_ERRORS_HERE,
313                         NULL,
314                         "xmlSecOpenSSLAppKeyFromCertLoadBIO",
315                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
316                         XMLSEC_ERRORS_NO_MESSAGE);
317             return(NULL);       
318         }
319         return(key);
320 #endif /* XMLSEC_NO_X509 */
321
322     default:
323         xmlSecError(XMLSEC_ERRORS_HERE,
324                     NULL,
325                     NULL,
326                     XMLSEC_ERRORS_R_INVALID_FORMAT,
327                     "format=%d", format); 
328         return(NULL);
329     }           
330
331     data = xmlSecOpenSSLEvpKeyAdopt(pKey);
332     if(data == NULL) {
333         xmlSecError(XMLSEC_ERRORS_HERE,
334                     NULL,
335                     "xmlSecOpenSSLEvpKeyAdopt",
336                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
337                     XMLSEC_ERRORS_NO_MESSAGE);
338         EVP_PKEY_free(pKey);
339         return(NULL);       
340     }    
341
342     key = xmlSecKeyCreate();
343     if(key == NULL) {
344         xmlSecError(XMLSEC_ERRORS_HERE,
345                     NULL,
346                     "xmlSecKeyCreate",
347                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
348                     XMLSEC_ERRORS_NO_MESSAGE);
349         xmlSecKeyDataDestroy(data);
350         return(NULL);
351     }
352     
353     ret = xmlSecKeySetValue(key, data);
354     if(ret < 0) {
355         xmlSecError(XMLSEC_ERRORS_HERE,
356                     NULL,
357                     "xmlSecKeySetValue",
358                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
359                     "data=%s",
360                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
361         xmlSecKeyDestroy(key);
362         xmlSecKeyDataDestroy(data);
363         return(NULL);
364     }
365     
366     return(key);
367 }
368
369
370 #ifndef XMLSEC_NO_X509
371 static X509*            xmlSecOpenSSLAppCertLoadBIO             (BIO* bio,
372                                                                  xmlSecKeyDataFormat format);
373 /**
374  * xmlSecOpenSSLAppKeyCertLoad:
375  * @key:                the pointer to key.
376  * @filename:           the certificate filename.
377  * @format:             the certificate file format.
378  *
379  * Reads the certificate from $@filename and adds it to key.
380  * 
381  * Returns: 0 on success or a negative value otherwise.
382  */
383 int             
384 xmlSecOpenSSLAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format) {
385     BIO* bio;
386     int ret;
387         
388     xmlSecAssert2(key != NULL, -1);
389     xmlSecAssert2(filename != NULL, -1);
390     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
391
392     bio = BIO_new_file(filename, "rb");
393     if(bio == NULL) {
394         xmlSecError(XMLSEC_ERRORS_HERE,
395                     NULL,
396                     "BIO_new_file",
397                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
398                     "filename=%s;errno=%d", 
399                     xmlSecErrorsSafeString(filename), 
400                     errno);
401         return(-1);    
402     }
403
404     ret = xmlSecOpenSSLAppKeyCertLoadBIO (key, bio, format);
405     if(ret < 0) {
406         xmlSecError(XMLSEC_ERRORS_HERE,
407                     NULL,
408                     "xmlSecOpenSSLAppKeyCertLoadBIO",
409                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
410                     "filename=%s;errno=%d", 
411                     xmlSecErrorsSafeString(filename), 
412                     errno);
413         BIO_free(bio);
414         return(-1);
415     }
416     
417     BIO_free(bio);
418     return(0);
419 }
420
421 /**
422  * xmlSecOpenSSLAppKeyCertLoadMemory:
423  * @key:                the pointer to key.
424  * @data:               the certificate binary data.
425  * @dataSize:           the certificate binary data size.
426  * @format:             the certificate file format.
427  *
428  * Reads the certificate from memory buffer and adds it to key.
429  * 
430  * Returns: 0 on success or a negative value otherwise.
431  */
432 int             
433 xmlSecOpenSSLAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize, 
434                                 xmlSecKeyDataFormat format) {
435     BIO* bio;
436     int ret;
437         
438     xmlSecAssert2(key != NULL, -1);
439     xmlSecAssert2(data != NULL, -1);
440     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
441
442     /* this would be a read only BIO, cast from const is ok */
443     bio = BIO_new_mem_buf((void*)data, dataSize);
444     if(bio == NULL) {
445         xmlSecError(XMLSEC_ERRORS_HERE,
446                     NULL,
447                     "BIO_new_mem_buf",
448                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
449                     "errno=%d", 
450                     errno);
451         return(-1);    
452     }
453
454     ret = xmlSecOpenSSLAppKeyCertLoadBIO (key, bio, format);
455     if(ret < 0) {
456         xmlSecError(XMLSEC_ERRORS_HERE,
457                     NULL,
458                     "xmlSecOpenSSLAppKeyCertLoadBIO",
459                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
460                     XMLSEC_ERRORS_NO_MESSAGE);
461         BIO_free(bio);
462         return(-1);
463     }
464     
465     BIO_free(bio);
466     return(0);
467 }
468
469 /**
470  * xmlSecOpenSSLAppKeyCertLoadBIO:
471  * @key:                the pointer to key.
472  * @bio:                the certificate bio.
473  * @format:             the certificate file format.
474  *
475  * Reads the certificate from memory buffer and adds it to key.
476  * 
477  * Returns: 0 on success or a negative value otherwise.
478  */
479 int             
480 xmlSecOpenSSLAppKeyCertLoadBIO(xmlSecKeyPtr key, BIO* bio, xmlSecKeyDataFormat format) {
481
482     xmlSecKeyDataFormat certFormat;
483     xmlSecKeyDataPtr data;
484     X509 *cert;
485     int ret;
486     
487     xmlSecAssert2(key != NULL, -1);
488     xmlSecAssert2(bio != NULL, -1);
489     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
490     
491     data = xmlSecKeyEnsureData(key, xmlSecOpenSSLKeyDataX509Id);
492     if(data == NULL) {
493         xmlSecError(XMLSEC_ERRORS_HERE,
494                     NULL,
495                     "xmlSecKeyEnsureData",                  
496                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
497                     "transform=%s",
498                     xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLKeyDataX509Id)));
499         return(-1);
500     }
501
502     /* adjust cert format */
503     switch(format) {
504     case xmlSecKeyDataFormatPkcs8Pem:
505         certFormat = xmlSecKeyDataFormatPem;
506         break;
507     case xmlSecKeyDataFormatPkcs8Der:
508         certFormat = xmlSecKeyDataFormatDer;
509         break;
510     default:
511         certFormat = format;
512     }
513
514     cert = xmlSecOpenSSLAppCertLoadBIO(bio, certFormat);
515     if(cert == NULL) {
516         xmlSecError(XMLSEC_ERRORS_HERE,
517                     NULL,
518                     "xmlSecOpenSSLAppCertLoad", 
519                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
520                     XMLSEC_ERRORS_NO_MESSAGE);
521         return(-1);    
522     }           
523     
524     ret = xmlSecOpenSSLKeyDataX509AdoptCert(data, cert);
525     if(ret < 0) {
526         xmlSecError(XMLSEC_ERRORS_HERE,
527                     NULL,
528                     "xmlSecOpenSSLKeyDataX509AdoptCert",
529                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
530                     "data=%s",
531                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
532         X509_free(cert);
533         return(-1);    
534     }
535     
536     return(0);        
537 }
538
539 /**
540  * xmlSecOpenSSLAppPkcs12Load:
541  * @filename:           the PKCS12 key filename.
542  * @pwd:                the PKCS12 file password.
543  * @pwdCallback:        the password callback.
544  * @pwdCallbackCtx:     the user context for password callback.
545  *
546  * Reads key and all associated certificates from the PKCS12 file.
547  * For uniformity, call xmlSecOpenSSLAppKeyLoad instead of this function. Pass
548  * in format=xmlSecKeyDataFormatPkcs12.
549  *
550  * Returns: pointer to the key or NULL if an error occurs.
551  */
552 xmlSecKeyPtr    
553 xmlSecOpenSSLAppPkcs12Load(const char *filename, const char *pwd,
554                            void* pwdCallback, void* pwdCallbackCtx) {
555     BIO* bio;
556     xmlSecKeyPtr key;
557     
558     xmlSecAssert2(filename != NULL, NULL);
559
560     bio = BIO_new_file(filename, "rb");
561     if(bio == NULL) {
562         xmlSecError(XMLSEC_ERRORS_HERE,
563                     NULL,
564                     "BIO_new_file",
565                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
566                     "filename=%s;errno=%d", 
567                     xmlSecErrorsSafeString(filename), 
568                     errno);
569         return(NULL);    
570     }
571
572     key = xmlSecOpenSSLAppPkcs12LoadBIO (bio, pwd, pwdCallback, pwdCallbackCtx);
573     if(key == NULL) {
574         xmlSecError(XMLSEC_ERRORS_HERE,
575                     NULL,
576                     "xmlSecOpenSSLAppPkcs12LoadBIO",
577                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
578                     "filename=%s;errno=%d", 
579                     xmlSecErrorsSafeString(filename), 
580                     errno);
581         BIO_free(bio);
582         return(NULL);
583     }
584     
585     BIO_free(bio);
586     return(key);
587 }
588
589 /**
590  * xmlSecOpenSSLAppPkcs12LoadMemory:
591  * @data:               the PKCS12 binary data.
592  * @dataSize:           the PKCS12 binary data size.
593  * @pwd:                the PKCS12 file password.
594  * @pwdCallback:        the password callback.
595  * @pwdCallbackCtx:     the user context for password callback.
596  *
597  * Reads key and all associated certificates from the PKCS12 data in memory buffer.
598  * For uniformity, call xmlSecOpenSSLAppKeyLoad instead of this function. Pass
599  * in format=xmlSecKeyDataFormatPkcs12.
600  *
601  * Returns: pointer to the key or NULL if an error occurs.
602  */
603 xmlSecKeyPtr    
604 xmlSecOpenSSLAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, 
605                            const char *pwd, void* pwdCallback, 
606                            void* pwdCallbackCtx) {
607     BIO* bio;
608     xmlSecKeyPtr key;
609     
610     xmlSecAssert2(data != NULL, NULL);
611
612     /* this would be a read only BIO, cast from const is ok */
613     bio = BIO_new_mem_buf((void*)data, dataSize);
614     if(bio == NULL) {
615         xmlSecError(XMLSEC_ERRORS_HERE,
616                     NULL,
617                     "BIO_new_mem_buf",
618                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
619                     "errno=%d", 
620                     errno);
621         return(NULL);    
622     }
623
624     key = xmlSecOpenSSLAppPkcs12LoadBIO (bio, pwd, pwdCallback, pwdCallbackCtx);
625     if(key == NULL) {
626         xmlSecError(XMLSEC_ERRORS_HERE,
627                     NULL,
628                     "xmlSecOpenSSLAppPkcs12LoadBIO",
629                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
630                     XMLSEC_ERRORS_NO_MESSAGE);
631         BIO_free(bio);
632         return(NULL);
633     }
634     
635     BIO_free(bio);
636     return(key);
637 }
638
639 /**
640  * xmlSecOpenSSLAppPkcs12LoadBIO:
641  * @bio:                the PKCS12 key bio.
642  * @pwd:                the PKCS12 file password.
643  * @pwdCallback:        the password callback.
644  * @pwdCallbackCtx:     the user context for password callback.
645  *
646  * Reads key and all associated certificates from the PKCS12 data in an OpenSSL BIO object.
647  * For uniformity, call xmlSecOpenSSLAppKeyLoad instead of this function. Pass
648  * in format=xmlSecKeyDataFormatPkcs12.
649  *
650  * Returns: pointer to the key or NULL if an error occurs.
651  */
652 xmlSecKeyPtr    
653 xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
654                            void* pwdCallback ATTRIBUTE_UNUSED, 
655                            void* pwdCallbackCtx ATTRIBUTE_UNUSED) {
656
657     PKCS12 *p12 = NULL;
658     EVP_PKEY *pKey = NULL;
659     STACK_OF(X509) *chain = NULL;
660     xmlSecKeyPtr key = NULL;
661     xmlSecKeyDataPtr data = NULL;
662     xmlSecKeyDataPtr x509Data = NULL;
663     X509 *cert = NULL;
664     X509 *tmpcert = NULL;
665     int i;
666     int ret;
667
668     xmlSecAssert2(bio != NULL, NULL);
669         
670     p12 = d2i_PKCS12_bio(bio, NULL);
671     if(p12 == NULL) {
672         xmlSecError(XMLSEC_ERRORS_HERE,
673                     NULL,
674                     "d2i_PKCS12_fp",
675                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
676                     XMLSEC_ERRORS_NO_MESSAGE);
677         goto done;
678     }
679
680     ret = PKCS12_verify_mac(p12, pwd, (pwd != NULL) ? strlen(pwd) : 0);
681     if(ret != 1) {
682         xmlSecError(XMLSEC_ERRORS_HERE,
683                     NULL,
684                     "PKCS12_verify_mac",
685                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
686                     XMLSEC_ERRORS_NO_MESSAGE);
687         goto done;
688     }    
689         
690     ret = PKCS12_parse(p12, pwd, &pKey, &cert, &chain);
691     if(ret < 0) {
692         xmlSecError(XMLSEC_ERRORS_HERE,
693                     NULL,
694                     "PKCS12_parse",
695                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
696                     XMLSEC_ERRORS_NO_MESSAGE);
697         goto done;
698     }    
699
700     data = xmlSecOpenSSLEvpKeyAdopt(pKey);
701     if(data == NULL) {
702         xmlSecError(XMLSEC_ERRORS_HERE,
703                     NULL,
704                     "xmlSecOpenSSLEvpKeyAdopt",
705                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
706                     XMLSEC_ERRORS_NO_MESSAGE);
707         EVP_PKEY_free(pKey);    
708         goto done;
709     }    
710
711     x509Data = xmlSecKeyDataCreate(xmlSecOpenSSLKeyDataX509Id);
712     if(x509Data == NULL) {
713         xmlSecError(XMLSEC_ERRORS_HERE,
714                     NULL,
715                     "xmlSecKeyDataCreate",
716                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
717                     "transform=%s",
718                     xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLKeyDataX509Id)));
719         goto done;
720     }    
721
722     tmpcert = X509_dup(cert);
723     if(tmpcert == NULL) {
724         xmlSecError(XMLSEC_ERRORS_HERE,
725                     NULL,
726                     "X509_dup",
727                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
728                     "data=%s",
729                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
730         goto done;      
731     }
732
733     /* starting from openssl 1.0.0 the PKCS12_parse() call will not create certs 
734        chain object if there is no certificates in the pkcs12 file and it will be null
735      */
736     if(chain == NULL) {
737         chain = sk_X509_new_null();
738         if(chain == NULL) {
739             xmlSecError(XMLSEC_ERRORS_HERE,
740                         NULL,
741                         "sk_X509_new_null",
742                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
743                         XMLSEC_ERRORS_NO_MESSAGE);
744             goto done;
745         }    
746     } 
747         
748     ret = sk_X509_push(chain, tmpcert);
749     if(ret < 1) {
750         xmlSecError(XMLSEC_ERRORS_HERE,
751                     NULL,
752                     "sk_X509_push",
753                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
754                     "data=%s",
755                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
756         X509_free(tmpcert);
757         goto done;      
758     }
759     
760     ret = xmlSecOpenSSLKeyDataX509AdoptKeyCert(x509Data, cert);
761     if(ret < 0) {
762         xmlSecError(XMLSEC_ERRORS_HERE,
763                     NULL,
764                     "xmlSecOpenSSLKeyDataX509AdoptKeyCert",
765                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
766                     "data=%s",
767                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
768         goto done;
769     }
770     cert = NULL;
771
772     for(i = 0; i < sk_X509_num(chain); ++i) {
773         xmlSecAssert2(sk_X509_value(chain, i), NULL);
774
775         tmpcert = X509_dup(sk_X509_value(chain, i));
776         if(tmpcert == NULL) {
777             xmlSecError(XMLSEC_ERRORS_HERE,
778                         NULL,
779                         "X509_dup",
780                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
781                         "data=%s",
782                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
783             X509_free(tmpcert);
784             goto done;  
785         }
786         
787         ret = xmlSecOpenSSLKeyDataX509AdoptCert(x509Data, tmpcert);
788         if(ret < 0) {
789             xmlSecError(XMLSEC_ERRORS_HERE,
790                         NULL,
791                         "xmlSecOpenSSLKeyDataX509AdoptCert",
792                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
793                         "data=%s",
794                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
795             goto done;
796         }
797     }
798         
799     key = xmlSecKeyCreate();
800     if(key == NULL) {
801         xmlSecError(XMLSEC_ERRORS_HERE,
802                     NULL,
803                     "xmlSecKeyCreate",
804                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
805                     XMLSEC_ERRORS_NO_MESSAGE);
806         goto done;
807     }    
808     
809     ret = xmlSecKeySetValue(key, data);
810     if(ret < 0) {
811         xmlSecError(XMLSEC_ERRORS_HERE,
812                     NULL,
813                     "xmlSecKeySetValue",
814                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
815                     "data=%s",
816                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
817         xmlSecKeyDestroy(key);
818         key = NULL;
819         goto done;
820     }
821     data = NULL;
822
823     ret = xmlSecKeyAdoptData(key, x509Data);
824     if(ret < 0) {
825         xmlSecError(XMLSEC_ERRORS_HERE,
826                     NULL,
827                     "xmlSecKeyAdoptData",
828                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
829                     "data=%s",
830                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
831         xmlSecKeyDestroy(key);
832         key = NULL;
833         goto done;
834     }
835     x509Data = NULL;
836     
837 done: 
838     if(x509Data != NULL) {
839         xmlSecKeyDataDestroy(x509Data);
840     }
841     if(data != NULL) {
842         xmlSecKeyDataDestroy(data);
843     }
844     if(chain != NULL) {
845         sk_X509_pop_free(chain, X509_free); 
846     }
847     if(cert != NULL) {
848         X509_free(cert);
849     }
850     if(p12 != NULL) {
851         PKCS12_free(p12);
852     }
853     return(key);    
854 }
855
856 /**
857  * xmlSecOpenSSLAppKeyFromCertLoadBIO:
858  * @bio:                the BIO.
859  * @format:             the cert format.
860  *
861  * Loads public key from cert.
862  *
863  * Returns: pointer to key or NULL if an error occurs.
864  */
865 xmlSecKeyPtr 
866 xmlSecOpenSSLAppKeyFromCertLoadBIO(BIO* bio, xmlSecKeyDataFormat format) {
867     xmlSecKeyPtr key;
868     xmlSecKeyDataPtr keyData;
869     xmlSecKeyDataPtr certData;
870     X509 *cert;
871     int ret;
872
873     xmlSecAssert2(bio != NULL, NULL);
874     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
875     
876     /* load cert */
877     cert = xmlSecOpenSSLAppCertLoadBIO(bio, format);
878     if(cert == NULL) {
879         xmlSecError(XMLSEC_ERRORS_HERE,
880                     NULL,
881                     "xmlSecOpenSSLAppCertLoadBIO",
882                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
883                     XMLSEC_ERRORS_NO_MESSAGE);
884         return(NULL);    
885     }
886
887     /* get key value */
888     keyData = xmlSecOpenSSLX509CertGetKey(cert);
889     if(keyData == NULL) {
890         xmlSecError(XMLSEC_ERRORS_HERE,
891                     NULL,
892                     "xmlSecOpenSSLX509CertGetKey",
893                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
894                     XMLSEC_ERRORS_NO_MESSAGE);
895         X509_free(cert);
896         return(NULL);    
897     }
898     
899     /* create key */
900     key = xmlSecKeyCreate();
901     if(key == NULL) {
902         xmlSecError(XMLSEC_ERRORS_HERE,
903                     NULL,
904                     "xmlSecKeyCreate",
905                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
906                     XMLSEC_ERRORS_NO_MESSAGE);
907         xmlSecKeyDataDestroy(keyData);
908         X509_free(cert);
909         return(NULL);    
910     }    
911     
912     /* set key value */
913     ret = xmlSecKeySetValue(key, keyData);
914     if(ret < 0) {
915         xmlSecError(XMLSEC_ERRORS_HERE,
916                     NULL,
917                     "xmlSecKeySetValue",
918                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
919                     XMLSEC_ERRORS_NO_MESSAGE);
920         xmlSecKeyDestroy(key);
921         xmlSecKeyDataDestroy(keyData);
922         X509_free(cert);
923         return(NULL);    
924     }
925
926     /* create cert data */ 
927     certData = xmlSecKeyEnsureData(key, xmlSecOpenSSLKeyDataX509Id);
928     if(certData == NULL) {
929         xmlSecError(XMLSEC_ERRORS_HERE,
930                     NULL,
931                     "xmlSecKeyEnsureData",                  
932                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
933                     XMLSEC_ERRORS_NO_MESSAGE);
934         xmlSecKeyDestroy(key);
935         X509_free(cert);
936         return(NULL);    
937     }
938
939     /* put cert in the cert data */
940     ret = xmlSecOpenSSLKeyDataX509AdoptCert(certData, cert);
941     if(ret < 0) {
942         xmlSecError(XMLSEC_ERRORS_HERE,
943                     NULL,
944                     "xmlSecOpenSSLKeyDataX509AdoptCert",
945                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
946                     XMLSEC_ERRORS_NO_MESSAGE);
947         xmlSecKeyDestroy(key);
948         X509_free(cert);
949         return(NULL);    
950     }
951     
952     return(key);
953 }
954
955
956 /**
957  * xmlSecOpenSSLAppKeysMngrCertLoad:
958  * @mngr:               the keys manager.
959  * @filename:           the certificate file.
960  * @format:             the certificate file format.
961  * @type:               the flag that indicates is the certificate in @filename
962  *                      trusted or not.
963  * 
964  * Reads cert from @filename and adds to the list of trusted or known
965  * untrusted certs in @store.
966  *
967  * Returns: 0 on success or a negative value otherwise.
968  */
969 int
970 xmlSecOpenSSLAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, 
971                             xmlSecKeyDataFormat format, xmlSecKeyDataType type) {
972     BIO* bio;
973     int ret;
974         
975     xmlSecAssert2(mngr != NULL, -1);
976     xmlSecAssert2(filename != NULL, -1);
977     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
978
979     bio = BIO_new_file(filename, "rb");
980     if(bio == NULL) {
981         xmlSecError(XMLSEC_ERRORS_HERE,
982                     NULL,
983                     "BIO_new_file",
984                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
985                     "filename=%s;errno=%d", 
986                     xmlSecErrorsSafeString(filename), 
987                     errno);
988         return(-1);    
989     }
990
991     ret = xmlSecOpenSSLAppKeysMngrCertLoadBIO(mngr, bio, format, type);
992     if(ret < 0) {
993         xmlSecError(XMLSEC_ERRORS_HERE,
994                     NULL,
995                     "xmlSecOpenSSLAppKeysMngrCertLoadBIO",
996                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
997                     "filename=%s;errno=%d", 
998                     xmlSecErrorsSafeString(filename), 
999                     errno);
1000         BIO_free(bio);
1001         return(-1);
1002     }
1003     
1004     BIO_free(bio);
1005     return(0);
1006 }
1007
1008 /**
1009  * xmlSecOpenSSLAppKeysMngrCertLoadMemory:
1010  * @mngr:               the keys manager.
1011  * @data:               the certificate binary data.
1012  * @dataSize:           the certificate binary data size.
1013  * @format:             the certificate file format.
1014  * @type:               the flag that indicates is the certificate trusted or not.
1015  * 
1016  * Reads cert from binary buffer @data and adds to the list of trusted or known
1017  * untrusted certs in @store.
1018  *
1019  * Returns: 0 on success or a negative value otherwise.
1020  */
1021 int
1022 xmlSecOpenSSLAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, const xmlSecByte* data,
1023                                     xmlSecSize dataSize, xmlSecKeyDataFormat format, 
1024                                     xmlSecKeyDataType type) {
1025     BIO* bio;
1026     int ret;
1027         
1028     xmlSecAssert2(mngr != NULL, -1);
1029     xmlSecAssert2(data != NULL, -1);
1030     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
1031
1032     /* this would be a read only BIO, cast from const is ok */
1033     bio = BIO_new_mem_buf((void*)data, dataSize);
1034     if(bio == NULL) {
1035         xmlSecError(XMLSEC_ERRORS_HERE,
1036                     NULL,
1037                     "BIO_new_mem_buf",
1038                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1039                     "errno=%d", 
1040                     errno);
1041         return(-1);    
1042     }
1043
1044     ret = xmlSecOpenSSLAppKeysMngrCertLoadBIO(mngr, bio, format, type);
1045     if(ret < 0) {
1046         xmlSecError(XMLSEC_ERRORS_HERE,
1047                     NULL,
1048                     "xmlSecOpenSSLAppKeysMngrCertLoadBIO",
1049                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1050                     XMLSEC_ERRORS_NO_MESSAGE);
1051         BIO_free(bio);
1052         return(-1);
1053     }
1054     
1055     BIO_free(bio);
1056     return(0);
1057 }
1058
1059 /**
1060  * xmlSecOpenSSLAppKeysMngrCertLoadBIO:
1061  * @mngr:               the keys manager.
1062  * @bio:                the certificate BIO.
1063  * @format:             the certificate file format.
1064  * @type:               the flag that indicates is the certificate trusted or not.
1065  * 
1066  * Reads cert from an OpenSSL BIO object and adds to the list of trusted or known
1067  * untrusted certs in @store.
1068  *
1069  * Returns: 0 on success or a negative value otherwise.
1070  */
1071 int
1072 xmlSecOpenSSLAppKeysMngrCertLoadBIO(xmlSecKeysMngrPtr mngr, BIO* bio, 
1073                                     xmlSecKeyDataFormat format, xmlSecKeyDataType type) {
1074     xmlSecKeyDataStorePtr x509Store;
1075     X509* cert;
1076     int ret;
1077
1078     xmlSecAssert2(mngr != NULL, -1);
1079     xmlSecAssert2(bio != NULL, -1);
1080     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
1081     
1082     x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1083     if(x509Store == NULL) {
1084         xmlSecError(XMLSEC_ERRORS_HERE,
1085                     NULL,
1086                     "xmlSecKeysMngrGetDataStore",
1087                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1088                     "xmlSecOpenSSLX509StoreId");
1089         return(-1);
1090     }
1091
1092     cert = xmlSecOpenSSLAppCertLoadBIO(bio, format);
1093     if(cert == NULL) {
1094         xmlSecError(XMLSEC_ERRORS_HERE,
1095                     NULL,
1096                     "xmlSecOpenSSLAppCertLoadBIO",
1097                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1098                     XMLSEC_ERRORS_NO_MESSAGE);
1099         return(-1);    
1100     }           
1101     
1102     ret = xmlSecOpenSSLX509StoreAdoptCert(x509Store, cert, type);
1103     if(ret < 0) {
1104         xmlSecError(XMLSEC_ERRORS_HERE,
1105                     NULL,
1106                     "xmlSecOpenSSLX509StoreAdoptCert",              
1107                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1108                     XMLSEC_ERRORS_NO_MESSAGE);
1109         X509_free(cert);
1110         return(-1);    
1111     }
1112     
1113     return(0);
1114 }
1115
1116 /**
1117  * xmlSecOpenSSLAppKeysMngrAddCertsPath:
1118  * @mngr:               the keys manager.
1119  * @path:               the path to trusted certificates.
1120  * 
1121  * Reads cert from @path and adds to the list of trusted certificates.
1122  *
1123  * Returns: 0 on success or a negative value otherwise.
1124  */
1125 int
1126 xmlSecOpenSSLAppKeysMngrAddCertsPath(xmlSecKeysMngrPtr mngr, const char *path) {
1127     xmlSecKeyDataStorePtr x509Store;
1128     int ret;
1129
1130     xmlSecAssert2(mngr != NULL, -1);
1131     xmlSecAssert2(path != NULL, -1);
1132     
1133     x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1134     if(x509Store == NULL) {
1135         xmlSecError(XMLSEC_ERRORS_HERE,
1136                     NULL,
1137                     "xmlSecKeysMngrGetDataStore",
1138                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1139                     "xmlSecOpenSSLX509StoreId");
1140         return(-1);
1141     }
1142     
1143     ret = xmlSecOpenSSLX509StoreAddCertsPath(x509Store, path);
1144     if(ret < 0) {
1145         xmlSecError(XMLSEC_ERRORS_HERE,
1146                     NULL,
1147                     "xmlSecOpenSSLX509StoreAddCertsPath",
1148                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1149                     "path=%s", xmlSecErrorsSafeString(path));
1150         return(-1);    
1151     }
1152     
1153     return(0);
1154 }
1155
1156 /**
1157  * xmlSecOpenSSLAppKeysMngrAddCertsFile:
1158  * @mngr:               the keys manager.
1159  * @file:               the file containing trusted certificates.
1160  *
1161  * Reads certs from @file and adds to the list of trusted certificates.
1162  * It is possible for @file to contain multiple certs.
1163  *
1164  * Returns: 0 on success or a negative value otherwise.
1165  */
1166 int
1167 xmlSecOpenSSLAppKeysMngrAddCertsFile(xmlSecKeysMngrPtr mngr, const char *file) {
1168     xmlSecKeyDataStorePtr x509Store;
1169     int ret;
1170
1171     xmlSecAssert2(mngr != NULL, -1);
1172     xmlSecAssert2(file != NULL, -1);
1173
1174     x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1175     if(x509Store == NULL) {
1176         xmlSecError(XMLSEC_ERRORS_HERE,
1177                     NULL,
1178                     "xmlSecKeysMngrGetDataStore",
1179                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1180                     "xmlSecOpenSSLX509StoreId");
1181         return(-1);
1182     }
1183
1184     ret = xmlSecOpenSSLX509StoreAddCertsFile(x509Store, file);
1185     if(ret < 0) {
1186         xmlSecError(XMLSEC_ERRORS_HERE,
1187                     NULL,
1188                     "xmlSecOpenSSLX509StoreAddCertsFile",
1189                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1190                     "file=%s", xmlSecErrorsSafeString(file));
1191         return(-1);
1192     }
1193
1194     return(0);
1195 }
1196
1197 static X509*    
1198 xmlSecOpenSSLAppCertLoadBIO(BIO* bio, xmlSecKeyDataFormat format) {
1199     X509 *cert;
1200     
1201     xmlSecAssert2(bio != NULL, NULL);
1202     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
1203
1204     switch(format) {
1205     case xmlSecKeyDataFormatPem:
1206     case xmlSecKeyDataFormatCertPem:
1207         cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
1208         if(cert == NULL) {
1209             xmlSecError(XMLSEC_ERRORS_HERE,
1210                         NULL,
1211                         "PEM_read_bio_X509_AUX",
1212                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
1213                         XMLSEC_ERRORS_NO_MESSAGE);
1214             return(NULL);    
1215         }
1216         break;
1217     case xmlSecKeyDataFormatDer:
1218     case xmlSecKeyDataFormatCertDer:
1219         cert = d2i_X509_bio(bio, NULL);
1220         if(cert == NULL) {
1221             xmlSecError(XMLSEC_ERRORS_HERE,
1222                         NULL,
1223                         "d2i_X509_bio",
1224                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
1225                         XMLSEC_ERRORS_NO_MESSAGE);
1226             return(NULL);    
1227         }
1228         break;
1229     default:
1230         xmlSecError(XMLSEC_ERRORS_HERE,
1231                     NULL,
1232                     NULL,
1233                     XMLSEC_ERRORS_R_INVALID_FORMAT,
1234                     "format=%d", format); 
1235         return(NULL);
1236     }
1237                 
1238     return(cert);
1239 }
1240
1241 #endif /* XMLSEC_NO_X509 */
1242
1243 /**
1244  * xmlSecOpenSSLAppDefaultKeysMngrInit:
1245  * @mngr:               the pointer to keys manager.
1246  *
1247  * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId
1248  * and a default OpenSSL crypto key data stores.
1249  *
1250  * Returns: 0 on success or a negative value otherwise.
1251  */ 
1252 int
1253 xmlSecOpenSSLAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) {
1254     int ret;
1255     
1256     xmlSecAssert2(mngr != NULL, -1);
1257
1258     /* create simple keys store if needed */        
1259     if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) {
1260         xmlSecKeyStorePtr keysStore;
1261
1262         keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId);
1263         if(keysStore == NULL) {
1264             xmlSecError(XMLSEC_ERRORS_HERE,
1265                         NULL,
1266                         "xmlSecKeyStoreCreate",
1267                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1268                         "xmlSecSimpleKeysStoreId");
1269             return(-1);
1270         }
1271         
1272         ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore);
1273         if(ret < 0) {
1274             xmlSecError(XMLSEC_ERRORS_HERE,
1275                         NULL,
1276                         "xmlSecKeysMngrAdoptKeysStore",
1277                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1278                         XMLSEC_ERRORS_NO_MESSAGE);
1279             xmlSecKeyStoreDestroy(keysStore);
1280             return(-1);        
1281         }
1282     }
1283
1284     ret = xmlSecOpenSSLKeysMngrInit(mngr);    
1285     if(ret < 0) {
1286         xmlSecError(XMLSEC_ERRORS_HERE,
1287                     NULL,
1288                     "xmlSecOpenSSLKeysMngrInit",
1289                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1290                     XMLSEC_ERRORS_NO_MESSAGE);
1291         return(-1); 
1292     }
1293     
1294     /* TODO */
1295     mngr->getKey = xmlSecKeysMngrGetKey;
1296     return(0);
1297 }
1298
1299 /**
1300  * xmlSecOpenSSLAppDefaultKeysMngrAdoptKey:
1301  * @mngr:               the pointer to keys manager.
1302  * @key:                the pointer to key.
1303  *
1304  * Adds @key to the keys manager @mngr created with #xmlSecOpenSSLAppDefaultKeysMngrInit
1305  * function.
1306  *  
1307  * Returns: 0 on success or a negative value otherwise.
1308  */ 
1309 int 
1310 xmlSecOpenSSLAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) {
1311     xmlSecKeyStorePtr store;
1312     int ret;
1313     
1314     xmlSecAssert2(mngr != NULL, -1);
1315     xmlSecAssert2(key != NULL, -1);
1316     
1317     store = xmlSecKeysMngrGetKeysStore(mngr);
1318     if(store == NULL) {
1319         xmlSecError(XMLSEC_ERRORS_HERE,
1320                     NULL,
1321                     "xmlSecKeysMngrGetKeysStore",
1322                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1323                     XMLSEC_ERRORS_NO_MESSAGE);
1324         return(-1);
1325     }
1326     
1327     ret = xmlSecSimpleKeysStoreAdoptKey(store, key);
1328     if(ret < 0) {
1329         xmlSecError(XMLSEC_ERRORS_HERE,
1330                     NULL,
1331                     "xmlSecSimpleKeysStoreAdoptKey",
1332                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1333                     XMLSEC_ERRORS_NO_MESSAGE);
1334         return(-1);
1335     }
1336     
1337     return(0);
1338 }
1339
1340 /**
1341  * xmlSecOpenSSLAppDefaultKeysMngrLoad:
1342  * @mngr:               the pointer to keys manager.
1343  * @uri:                the uri.
1344  *
1345  * Loads XML keys file from @uri to the keys manager @mngr created 
1346  * with #xmlSecOpenSSLAppDefaultKeysMngrInit function.
1347  *  
1348  * Returns: 0 on success or a negative value otherwise.
1349  */ 
1350 int 
1351 xmlSecOpenSSLAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) {
1352     xmlSecKeyStorePtr store;
1353     int ret;
1354     
1355     xmlSecAssert2(mngr != NULL, -1);
1356     xmlSecAssert2(uri != NULL, -1);
1357     
1358     store = xmlSecKeysMngrGetKeysStore(mngr);
1359     if(store == NULL) {
1360         xmlSecError(XMLSEC_ERRORS_HERE,
1361                     NULL,
1362                     "xmlSecKeysMngrGetKeysStore",
1363                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1364                     XMLSEC_ERRORS_NO_MESSAGE);
1365         return(-1);
1366     }
1367     
1368     ret = xmlSecSimpleKeysStoreLoad(store, uri, mngr);
1369     if(ret < 0) {
1370         xmlSecError(XMLSEC_ERRORS_HERE,
1371                     NULL,
1372                     "xmlSecSimpleKeysStoreLoad",
1373                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1374                     "uri=%s", xmlSecErrorsSafeString(uri));
1375         return(-1);
1376     }
1377     
1378     return(0);
1379 }
1380
1381 /**
1382  * xmlSecOpenSSLAppDefaultKeysMngrSave:
1383  * @mngr:               the pointer to keys manager.
1384  * @filename:           the destination filename.
1385  * @type:               the type of keys to save (public/private/symmetric).
1386  *
1387  * Saves keys from @mngr to  XML keys file.
1388  *  
1389  * Returns: 0 on success or a negative value otherwise.
1390  */ 
1391 int 
1392 xmlSecOpenSSLAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, 
1393                                     xmlSecKeyDataType type) {
1394     xmlSecKeyStorePtr store;
1395     int ret;
1396     
1397     xmlSecAssert2(mngr != NULL, -1);
1398     xmlSecAssert2(filename != NULL, -1);
1399     
1400     store = xmlSecKeysMngrGetKeysStore(mngr);
1401     if(store == NULL) {
1402         xmlSecError(XMLSEC_ERRORS_HERE,
1403                     NULL,
1404                     "xmlSecKeysMngrGetKeysStore",
1405                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1406                     XMLSEC_ERRORS_NO_MESSAGE);
1407         return(-1);
1408     }
1409     
1410     ret = xmlSecSimpleKeysStoreSave(store, filename, type);
1411     if(ret < 0) {
1412         xmlSecError(XMLSEC_ERRORS_HERE,
1413                     NULL,
1414                     "xmlSecSimpleKeysStoreSave",
1415                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1416                     "filename%s", xmlSecErrorsSafeString(filename));
1417         return(-1);
1418     }
1419     
1420     return(0);
1421 }
1422
1423
1424 /**
1425  * Random numbers initialization from openssl (apps/app_rand.c)
1426  */
1427 static int seeded = 0;
1428 static int egdsocket = 0;
1429
1430 static int 
1431 xmlSecOpenSSLAppLoadRANDFile(const char *file) {
1432     char buffer[1024];
1433         
1434     if(file == NULL) {
1435         file = RAND_file_name(buffer, sizeof(buffer));
1436     }else if(RAND_egd(file) > 0) {
1437         /* we try if the given filename is an EGD socket.
1438          * if it is, we don't write anything back to the file. */
1439         egdsocket = 1;
1440         return 1;
1441     }
1442
1443     if((file == NULL) || !RAND_load_file(file, -1)) {
1444         if(RAND_status() == 0) {
1445             xmlSecError(XMLSEC_ERRORS_HERE,
1446                         NULL,
1447                         "RAND_load_file",
1448                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
1449                         "file=%s", xmlSecErrorsSafeString(file));
1450             return 0;
1451         }
1452     }
1453     seeded = 1;
1454     return 1;
1455 }
1456
1457 static int 
1458 xmlSecOpenSSLAppSaveRANDFile(const char *file) {
1459     char buffer[1024];
1460         
1461     if(egdsocket || !seeded) {
1462         /* If we did not manage to read the seed file,
1463          * we should not write a low-entropy seed file back --
1464          * it would suppress a crucial warning the next time
1465          * we want to use it. */
1466         return 0;
1467     }
1468     
1469     if(file == NULL) {
1470         file = RAND_file_name(buffer, sizeof(buffer));
1471     }
1472     if((file == NULL) || !RAND_write_file(file)) {
1473         xmlSecError(XMLSEC_ERRORS_HERE,
1474                     NULL,
1475                     "RAND_write_file",
1476                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
1477                     "file=%s", 
1478                     xmlSecErrorsSafeString(file));
1479         return 0;
1480     }
1481
1482     return 1;
1483 }
1484
1485 /**
1486  * xmlSecOpenSSLAppGetDefaultPwdCallback:
1487  *
1488  * Gets default password callback.
1489  *
1490  * Returns: default password callback.
1491  */
1492 void*
1493 xmlSecOpenSSLAppGetDefaultPwdCallback(void) {
1494     return((void*)xmlSecOpenSSLDefaultPasswordCallback);
1495 }
1496
1497 static int
1498 xmlSecOpenSSLDefaultPasswordCallback(char *buf, int bufsize, int verify, void *userdata) {
1499     char* filename = (char*)userdata;
1500     char* buf2;
1501     xmlChar prompt[2048];
1502     int i, ret;
1503         
1504     xmlSecAssert2(buf != NULL, -1);
1505
1506     /* try 3 times */
1507     for(i = 0; i < 3; i++) {
1508         if(filename != NULL) {
1509             xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password for \"%s\" file: ", filename); 
1510         } else {
1511             xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password: "); 
1512         }
1513         ret = EVP_read_pw_string(buf, bufsize, (char*)prompt, 0);
1514         if(ret != 0) {
1515             xmlSecError(XMLSEC_ERRORS_HERE,
1516                         NULL,
1517                         "EVP_read_pw_string",
1518                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
1519                         XMLSEC_ERRORS_NO_MESSAGE);
1520             return(-1);
1521         }
1522     
1523         /* if we don't need to verify password then we are done */
1524         if(verify == 0) {
1525             return(strlen(buf));
1526         }
1527
1528         if(filename != NULL) {
1529             xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password for \"%s\" file again: ", filename); 
1530         } else {
1531             xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password again: "); 
1532         }
1533
1534         buf2 = (char*)xmlMalloc(bufsize);
1535         if(buf2 == NULL) {
1536             xmlSecError(XMLSEC_ERRORS_HERE,
1537                         NULL,
1538                         NULL,
1539                         XMLSEC_ERRORS_R_MALLOC_FAILED,
1540                         "size=%d", bufsize);
1541             return(-1);
1542         }
1543         ret = EVP_read_pw_string(buf2, bufsize, (char*)prompt, 0);
1544         if(ret != 0) {
1545             xmlSecError(XMLSEC_ERRORS_HERE,
1546                         NULL,
1547                         "EVP_read_pw_string",
1548                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
1549                         XMLSEC_ERRORS_NO_MESSAGE);
1550             memset(buf2, 0, bufsize);
1551             xmlFree(buf2);
1552             return(-1);
1553         }
1554     
1555         /* check if passwords match */
1556         if(strcmp(buf, buf2) == 0) {
1557             memset(buf2, 0, bufsize);
1558         xmlFree(buf2);
1559             return(strlen(buf));            
1560         }
1561         
1562         /* try again */
1563         memset(buf2, 0, bufsize);
1564         xmlFree(buf2);
1565     }
1566     
1567     return(-1);
1568 }
1569
1570 static int
1571 xmlSecOpenSSLDummyPasswordCallback(char *buf, int bufsize, int verify, void *userdata) {
1572     char* password = (char*)userdata;
1573     
1574     if((password == NULL) || (strlen(password) + 1 > bufsize)) {
1575         return(-1);
1576     }
1577     
1578     strcpy(buf, password);
1579     return (strlen(buf));
1580 }
1581