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