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