4 * This is free software; see Copyright file in the source
5 * distribution for preciese wording.
7 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
15 #include <libxml/tree.h>
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>
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>
30 #include <xmlsec/openssl/app.h>
31 #include <xmlsec/openssl/crypto.h>
32 #include <xmlsec/openssl/evp.h>
33 #include <xmlsec/openssl/x509.h>
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);
41 * xmlSecOpenSSLAppInit:
42 * @config: the path to certs.
44 * General crypto engine initialization. This function is used
45 * by XMLSec command line utility and called before
46 * @xmlSecInit function.
48 * Returns: 0 on success or a negative value otherwise.
51 xmlSecOpenSSLAppInit(const char* config) {
52 ERR_load_crypto_strings();
54 OpenSSL_add_all_algorithms();
56 if((RAND_status() != 1) && (xmlSecOpenSSLAppLoadRANDFile(NULL) != 1)) {
57 xmlSecError(XMLSEC_ERRORS_HERE,
59 "xmlSecOpenSSLAppLoadRANDFile",
60 XMLSEC_ERRORS_R_XMLSEC_FAILED,
61 XMLSEC_ERRORS_NO_MESSAGE);
65 if((config != NULL) && (xmlSecOpenSSLSetDefaultTrustedCertsFolder(BAD_CAST config) < 0)) {
66 xmlSecError(XMLSEC_ERRORS_HERE,
68 "xmlSecOpenSSLSetDefaultTrustedCertsFolder",
69 XMLSEC_ERRORS_R_XMLSEC_FAILED,
70 XMLSEC_ERRORS_NO_MESSAGE);
78 * xmlSecOpenSSLAppShutdown:
80 * General crypto engine shutdown. This function is used
81 * by XMLSec command line utility and called after
82 * @xmlSecShutdown function.
84 * Returns: 0 on success or a negative value otherwise.
87 xmlSecOpenSSLAppShutdown(void) {
88 xmlSecOpenSSLAppSaveRANDFile(NULL);
92 #ifndef XMLSEC_NO_X509
94 #endif /* XMLSEC_NO_X509 */
96 #ifndef XMLSEC_OPENSSL_096
97 CRYPTO_cleanup_all_ex_data();
98 #endif /* XMLSEC_OPENSSL_096 */
100 /* finally cleanup errors */
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.
115 * Reads key from the a file.
117 * Returns: pointer to the key or NULL if an error occurs.
120 xmlSecOpenSSLAppKeyLoad(const char *filename, xmlSecKeyDataFormat format,
121 const char *pwd, void* pwdCallback,
122 void* pwdCallbackCtx) {
126 xmlSecAssert2(filename != NULL, NULL);
127 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
129 bio = BIO_new_file(filename, "rb");
131 xmlSecError(XMLSEC_ERRORS_HERE,
134 XMLSEC_ERRORS_R_CRYPTO_FAILED,
135 "filename=%s;errno=%d",
136 xmlSecErrorsSafeString(filename),
141 key = xmlSecOpenSSLAppKeyLoadBIO (bio, format, pwd, pwdCallback, pwdCallbackCtx);
143 xmlSecError(XMLSEC_ERRORS_HERE,
145 "xmlSecOpenSSLAppKeyLoadBIO",
146 XMLSEC_ERRORS_R_XMLSEC_FAILED,
147 "filename=%s;errno=%d",
148 xmlSecErrorsSafeString(filename),
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.
167 * Reads key from the memory buffer.
169 * Returns: pointer to the key or NULL if an error occurs.
172 xmlSecOpenSSLAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
173 xmlSecKeyDataFormat format, const char *pwd,
174 void* pwdCallback, void* pwdCallbackCtx) {
178 xmlSecAssert2(data != NULL, NULL);
179 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
181 /* this would be a read only BIO, cast from const is ok */
182 bio = BIO_new_mem_buf((void*)data, dataSize);
184 xmlSecError(XMLSEC_ERRORS_HERE,
187 XMLSEC_ERRORS_R_CRYPTO_FAILED,
193 key = xmlSecOpenSSLAppKeyLoadBIO (bio, format, pwd, pwdCallback, pwdCallbackCtx);
195 xmlSecError(XMLSEC_ERRORS_HERE,
197 "xmlSecOpenSSLAppKeyLoadBIO",
198 XMLSEC_ERRORS_R_XMLSEC_FAILED,
199 XMLSEC_ERRORS_NO_MESSAGE);
210 * xmlSecOpenSSLAppKeyLoadBIO:
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.
217 * Reads key from the an OpenSSL BIO object.
219 * Returns: pointer to the key or NULL if an error occurs.
222 xmlSecOpenSSLAppKeyLoadBIO(BIO* bio, xmlSecKeyDataFormat format,
223 const char *pwd, void* pwdCallback,
224 void* pwdCallbackCtx) {
226 xmlSecKeyPtr key = NULL;
227 xmlSecKeyDataPtr data;
228 EVP_PKEY* pKey = NULL;
231 xmlSecAssert2(bio != NULL, NULL);
232 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
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);
241 /* go to start of the file and try to read public key */
243 pKey = PEM_read_bio_PUBKEY(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
245 xmlSecError(XMLSEC_ERRORS_HERE,
247 "PEM_read_bio_PrivateKey and PEM_read_bio_PUBKEY",
248 XMLSEC_ERRORS_R_CRYPTO_FAILED,
249 XMLSEC_ERRORS_NO_MESSAGE);
254 case xmlSecKeyDataFormatDer:
255 /* try to read private key first */
256 pKey = d2i_PrivateKey_bio(bio, NULL);
258 /* go to start of the file and try to read public key */
260 pKey = d2i_PUBKEY_bio(bio, NULL);
262 xmlSecError(XMLSEC_ERRORS_HERE,
264 "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
265 XMLSEC_ERRORS_R_CRYPTO_FAILED,
266 XMLSEC_ERRORS_NO_MESSAGE);
271 case xmlSecKeyDataFormatPkcs8Pem:
272 /* try to read private key first */
273 pKey = PEM_read_bio_PrivateKey(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
275 xmlSecError(XMLSEC_ERRORS_HERE,
277 "PEM_read_bio_PrivateKey",
278 XMLSEC_ERRORS_R_CRYPTO_FAILED,
279 XMLSEC_ERRORS_NO_MESSAGE);
283 case xmlSecKeyDataFormatPkcs8Der:
284 /* try to read private key first */
285 pKey = d2i_PKCS8PrivateKey_bio(bio, NULL, (pem_password_cb*)pwdCallback, pwdCallbackCtx);
287 xmlSecError(XMLSEC_ERRORS_HERE,
289 "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
290 XMLSEC_ERRORS_R_CRYPTO_FAILED,
291 XMLSEC_ERRORS_NO_MESSAGE);
295 #ifndef XMLSEC_NO_X509
296 case xmlSecKeyDataFormatPkcs12:
297 key = xmlSecOpenSSLAppPkcs12LoadBIO(bio, pwd, pwdCallback, pwdCallbackCtx);
299 xmlSecError(XMLSEC_ERRORS_HERE,
301 "xmlSecOpenSSLAppPkcs12LoadBIO",
302 XMLSEC_ERRORS_R_XMLSEC_FAILED,
303 XMLSEC_ERRORS_NO_MESSAGE);
308 case xmlSecKeyDataFormatCertPem:
309 case xmlSecKeyDataFormatCertDer:
310 key = xmlSecOpenSSLAppKeyFromCertLoadBIO(bio, format);
312 xmlSecError(XMLSEC_ERRORS_HERE,
314 "xmlSecOpenSSLAppKeyFromCertLoadBIO",
315 XMLSEC_ERRORS_R_XMLSEC_FAILED,
316 XMLSEC_ERRORS_NO_MESSAGE);
320 #endif /* XMLSEC_NO_X509 */
323 xmlSecError(XMLSEC_ERRORS_HERE,
326 XMLSEC_ERRORS_R_INVALID_FORMAT,
327 "format=%d", format);
331 data = xmlSecOpenSSLEvpKeyAdopt(pKey);
333 xmlSecError(XMLSEC_ERRORS_HERE,
335 "xmlSecOpenSSLEvpKeyAdopt",
336 XMLSEC_ERRORS_R_XMLSEC_FAILED,
337 XMLSEC_ERRORS_NO_MESSAGE);
342 key = xmlSecKeyCreate();
344 xmlSecError(XMLSEC_ERRORS_HERE,
347 XMLSEC_ERRORS_R_XMLSEC_FAILED,
348 XMLSEC_ERRORS_NO_MESSAGE);
349 xmlSecKeyDataDestroy(data);
353 ret = xmlSecKeySetValue(key, data);
355 xmlSecError(XMLSEC_ERRORS_HERE,
358 XMLSEC_ERRORS_R_XMLSEC_FAILED,
360 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
361 xmlSecKeyDestroy(key);
362 xmlSecKeyDataDestroy(data);
370 #ifndef XMLSEC_NO_X509
371 static X509* xmlSecOpenSSLAppCertLoadBIO (BIO* bio,
372 xmlSecKeyDataFormat format);
374 * xmlSecOpenSSLAppKeyCertLoad:
375 * @key: the pointer to key.
376 * @filename: the certificate filename.
377 * @format: the certificate file format.
379 * Reads the certificate from $@filename and adds it to key.
381 * Returns: 0 on success or a negative value otherwise.
384 xmlSecOpenSSLAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format) {
388 xmlSecAssert2(key != NULL, -1);
389 xmlSecAssert2(filename != NULL, -1);
390 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
392 bio = BIO_new_file(filename, "rb");
394 xmlSecError(XMLSEC_ERRORS_HERE,
397 XMLSEC_ERRORS_R_CRYPTO_FAILED,
398 "filename=%s;errno=%d",
399 xmlSecErrorsSafeString(filename),
404 ret = xmlSecOpenSSLAppKeyCertLoadBIO (key, bio, format);
406 xmlSecError(XMLSEC_ERRORS_HERE,
408 "xmlSecOpenSSLAppKeyCertLoadBIO",
409 XMLSEC_ERRORS_R_XMLSEC_FAILED,
410 "filename=%s;errno=%d",
411 xmlSecErrorsSafeString(filename),
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.
428 * Reads the certificate from memory buffer and adds it to key.
430 * Returns: 0 on success or a negative value otherwise.
433 xmlSecOpenSSLAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize,
434 xmlSecKeyDataFormat format) {
438 xmlSecAssert2(key != NULL, -1);
439 xmlSecAssert2(data != NULL, -1);
440 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
442 /* this would be a read only BIO, cast from const is ok */
443 bio = BIO_new_mem_buf((void*)data, dataSize);
445 xmlSecError(XMLSEC_ERRORS_HERE,
448 XMLSEC_ERRORS_R_CRYPTO_FAILED,
454 ret = xmlSecOpenSSLAppKeyCertLoadBIO (key, bio, format);
456 xmlSecError(XMLSEC_ERRORS_HERE,
458 "xmlSecOpenSSLAppKeyCertLoadBIO",
459 XMLSEC_ERRORS_R_XMLSEC_FAILED,
460 XMLSEC_ERRORS_NO_MESSAGE);
470 * xmlSecOpenSSLAppKeyCertLoadBIO:
471 * @key: the pointer to key.
472 * @bio: the certificate bio.
473 * @format: the certificate file format.
475 * Reads the certificate from memory buffer and adds it to key.
477 * Returns: 0 on success or a negative value otherwise.
480 xmlSecOpenSSLAppKeyCertLoadBIO(xmlSecKeyPtr key, BIO* bio, xmlSecKeyDataFormat format) {
482 xmlSecKeyDataFormat certFormat;
483 xmlSecKeyDataPtr data;
487 xmlSecAssert2(key != NULL, -1);
488 xmlSecAssert2(bio != NULL, -1);
489 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
491 data = xmlSecKeyEnsureData(key, xmlSecOpenSSLKeyDataX509Id);
493 xmlSecError(XMLSEC_ERRORS_HERE,
495 "xmlSecKeyEnsureData",
496 XMLSEC_ERRORS_R_XMLSEC_FAILED,
498 xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLKeyDataX509Id)));
502 /* adjust cert format */
504 case xmlSecKeyDataFormatPkcs8Pem:
505 certFormat = xmlSecKeyDataFormatPem;
507 case xmlSecKeyDataFormatPkcs8Der:
508 certFormat = xmlSecKeyDataFormatDer;
514 cert = xmlSecOpenSSLAppCertLoadBIO(bio, certFormat);
516 xmlSecError(XMLSEC_ERRORS_HERE,
518 "xmlSecOpenSSLAppCertLoad",
519 XMLSEC_ERRORS_R_XMLSEC_FAILED,
520 XMLSEC_ERRORS_NO_MESSAGE);
524 ret = xmlSecOpenSSLKeyDataX509AdoptCert(data, cert);
526 xmlSecError(XMLSEC_ERRORS_HERE,
528 "xmlSecOpenSSLKeyDataX509AdoptCert",
529 XMLSEC_ERRORS_R_XMLSEC_FAILED,
531 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
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.
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.
550 * Returns: pointer to the key or NULL if an error occurs.
553 xmlSecOpenSSLAppPkcs12Load(const char *filename, const char *pwd,
554 void* pwdCallback, void* pwdCallbackCtx) {
558 xmlSecAssert2(filename != NULL, NULL);
560 bio = BIO_new_file(filename, "rb");
562 xmlSecError(XMLSEC_ERRORS_HERE,
565 XMLSEC_ERRORS_R_CRYPTO_FAILED,
566 "filename=%s;errno=%d",
567 xmlSecErrorsSafeString(filename),
572 key = xmlSecOpenSSLAppPkcs12LoadBIO (bio, pwd, pwdCallback, pwdCallbackCtx);
574 xmlSecError(XMLSEC_ERRORS_HERE,
576 "xmlSecOpenSSLAppPkcs12LoadBIO",
577 XMLSEC_ERRORS_R_XMLSEC_FAILED,
578 "filename=%s;errno=%d",
579 xmlSecErrorsSafeString(filename),
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.
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.
601 * Returns: pointer to the key or NULL if an error occurs.
604 xmlSecOpenSSLAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
605 const char *pwd, void* pwdCallback,
606 void* pwdCallbackCtx) {
610 xmlSecAssert2(data != NULL, NULL);
612 /* this would be a read only BIO, cast from const is ok */
613 bio = BIO_new_mem_buf((void*)data, dataSize);
615 xmlSecError(XMLSEC_ERRORS_HERE,
618 XMLSEC_ERRORS_R_CRYPTO_FAILED,
624 key = xmlSecOpenSSLAppPkcs12LoadBIO (bio, pwd, pwdCallback, pwdCallbackCtx);
626 xmlSecError(XMLSEC_ERRORS_HERE,
628 "xmlSecOpenSSLAppPkcs12LoadBIO",
629 XMLSEC_ERRORS_R_XMLSEC_FAILED,
630 XMLSEC_ERRORS_NO_MESSAGE);
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.
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.
650 * Returns: pointer to the key or NULL if an error occurs.
653 xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
654 void* pwdCallback ATTRIBUTE_UNUSED,
655 void* pwdCallbackCtx ATTRIBUTE_UNUSED) {
658 EVP_PKEY *pKey = NULL;
659 STACK_OF(X509) *chain = NULL;
660 xmlSecKeyPtr key = NULL;
661 xmlSecKeyDataPtr data = NULL;
662 xmlSecKeyDataPtr x509Data = NULL;
664 X509 *tmpcert = NULL;
668 xmlSecAssert2(bio != NULL, NULL);
670 p12 = d2i_PKCS12_bio(bio, NULL);
672 xmlSecError(XMLSEC_ERRORS_HERE,
675 XMLSEC_ERRORS_R_CRYPTO_FAILED,
676 XMLSEC_ERRORS_NO_MESSAGE);
680 ret = PKCS12_verify_mac(p12, pwd, (pwd != NULL) ? strlen(pwd) : 0);
682 xmlSecError(XMLSEC_ERRORS_HERE,
685 XMLSEC_ERRORS_R_CRYPTO_FAILED,
686 XMLSEC_ERRORS_NO_MESSAGE);
690 ret = PKCS12_parse(p12, pwd, &pKey, &cert, &chain);
692 xmlSecError(XMLSEC_ERRORS_HERE,
695 XMLSEC_ERRORS_R_CRYPTO_FAILED,
696 XMLSEC_ERRORS_NO_MESSAGE);
700 data = xmlSecOpenSSLEvpKeyAdopt(pKey);
702 xmlSecError(XMLSEC_ERRORS_HERE,
704 "xmlSecOpenSSLEvpKeyAdopt",
705 XMLSEC_ERRORS_R_XMLSEC_FAILED,
706 XMLSEC_ERRORS_NO_MESSAGE);
711 x509Data = xmlSecKeyDataCreate(xmlSecOpenSSLKeyDataX509Id);
712 if(x509Data == NULL) {
713 xmlSecError(XMLSEC_ERRORS_HERE,
715 "xmlSecKeyDataCreate",
716 XMLSEC_ERRORS_R_XMLSEC_FAILED,
718 xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLKeyDataX509Id)));
722 tmpcert = X509_dup(cert);
723 if(tmpcert == NULL) {
724 xmlSecError(XMLSEC_ERRORS_HERE,
727 XMLSEC_ERRORS_R_CRYPTO_FAILED,
729 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
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
737 chain = sk_X509_new_null();
739 xmlSecError(XMLSEC_ERRORS_HERE,
742 XMLSEC_ERRORS_R_CRYPTO_FAILED,
743 XMLSEC_ERRORS_NO_MESSAGE);
748 ret = sk_X509_push(chain, tmpcert);
750 xmlSecError(XMLSEC_ERRORS_HERE,
753 XMLSEC_ERRORS_R_CRYPTO_FAILED,
755 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
760 ret = xmlSecOpenSSLKeyDataX509AdoptKeyCert(x509Data, cert);
762 xmlSecError(XMLSEC_ERRORS_HERE,
764 "xmlSecOpenSSLKeyDataX509AdoptKeyCert",
765 XMLSEC_ERRORS_R_XMLSEC_FAILED,
767 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
772 for(i = 0; i < sk_X509_num(chain); ++i) {
773 xmlSecAssert2(sk_X509_value(chain, i), NULL);
775 tmpcert = X509_dup(sk_X509_value(chain, i));
776 if(tmpcert == NULL) {
777 xmlSecError(XMLSEC_ERRORS_HERE,
780 XMLSEC_ERRORS_R_CRYPTO_FAILED,
782 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
787 ret = xmlSecOpenSSLKeyDataX509AdoptCert(x509Data, tmpcert);
789 xmlSecError(XMLSEC_ERRORS_HERE,
791 "xmlSecOpenSSLKeyDataX509AdoptCert",
792 XMLSEC_ERRORS_R_XMLSEC_FAILED,
794 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
799 key = xmlSecKeyCreate();
801 xmlSecError(XMLSEC_ERRORS_HERE,
804 XMLSEC_ERRORS_R_XMLSEC_FAILED,
805 XMLSEC_ERRORS_NO_MESSAGE);
809 ret = xmlSecKeySetValue(key, data);
811 xmlSecError(XMLSEC_ERRORS_HERE,
814 XMLSEC_ERRORS_R_XMLSEC_FAILED,
816 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
817 xmlSecKeyDestroy(key);
823 ret = xmlSecKeyAdoptData(key, x509Data);
825 xmlSecError(XMLSEC_ERRORS_HERE,
827 "xmlSecKeyAdoptData",
828 XMLSEC_ERRORS_R_XMLSEC_FAILED,
830 xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
831 xmlSecKeyDestroy(key);
838 if(x509Data != NULL) {
839 xmlSecKeyDataDestroy(x509Data);
842 xmlSecKeyDataDestroy(data);
845 sk_X509_pop_free(chain, X509_free);
857 * xmlSecOpenSSLAppKeyFromCertLoadBIO:
859 * @format: the cert format.
861 * Loads public key from cert.
863 * Returns: pointer to key or NULL if an error occurs.
866 xmlSecOpenSSLAppKeyFromCertLoadBIO(BIO* bio, xmlSecKeyDataFormat format) {
868 xmlSecKeyDataPtr keyData;
869 xmlSecKeyDataPtr certData;
873 xmlSecAssert2(bio != NULL, NULL);
874 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
877 cert = xmlSecOpenSSLAppCertLoadBIO(bio, format);
879 xmlSecError(XMLSEC_ERRORS_HERE,
881 "xmlSecOpenSSLAppCertLoadBIO",
882 XMLSEC_ERRORS_R_XMLSEC_FAILED,
883 XMLSEC_ERRORS_NO_MESSAGE);
888 keyData = xmlSecOpenSSLX509CertGetKey(cert);
889 if(keyData == NULL) {
890 xmlSecError(XMLSEC_ERRORS_HERE,
892 "xmlSecOpenSSLX509CertGetKey",
893 XMLSEC_ERRORS_R_XMLSEC_FAILED,
894 XMLSEC_ERRORS_NO_MESSAGE);
900 key = xmlSecKeyCreate();
902 xmlSecError(XMLSEC_ERRORS_HERE,
905 XMLSEC_ERRORS_R_XMLSEC_FAILED,
906 XMLSEC_ERRORS_NO_MESSAGE);
907 xmlSecKeyDataDestroy(keyData);
913 ret = xmlSecKeySetValue(key, keyData);
915 xmlSecError(XMLSEC_ERRORS_HERE,
918 XMLSEC_ERRORS_R_XMLSEC_FAILED,
919 XMLSEC_ERRORS_NO_MESSAGE);
920 xmlSecKeyDestroy(key);
921 xmlSecKeyDataDestroy(keyData);
926 /* create cert data */
927 certData = xmlSecKeyEnsureData(key, xmlSecOpenSSLKeyDataX509Id);
928 if(certData == NULL) {
929 xmlSecError(XMLSEC_ERRORS_HERE,
931 "xmlSecKeyEnsureData",
932 XMLSEC_ERRORS_R_XMLSEC_FAILED,
933 XMLSEC_ERRORS_NO_MESSAGE);
934 xmlSecKeyDestroy(key);
939 /* put cert in the cert data */
940 ret = xmlSecOpenSSLKeyDataX509AdoptCert(certData, cert);
942 xmlSecError(XMLSEC_ERRORS_HERE,
944 "xmlSecOpenSSLKeyDataX509AdoptCert",
945 XMLSEC_ERRORS_R_XMLSEC_FAILED,
946 XMLSEC_ERRORS_NO_MESSAGE);
947 xmlSecKeyDestroy(key);
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
964 * Reads cert from @filename and adds to the list of trusted or known
965 * untrusted certs in @store.
967 * Returns: 0 on success or a negative value otherwise.
970 xmlSecOpenSSLAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename,
971 xmlSecKeyDataFormat format, xmlSecKeyDataType type) {
975 xmlSecAssert2(mngr != NULL, -1);
976 xmlSecAssert2(filename != NULL, -1);
977 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
979 bio = BIO_new_file(filename, "rb");
981 xmlSecError(XMLSEC_ERRORS_HERE,
984 XMLSEC_ERRORS_R_CRYPTO_FAILED,
985 "filename=%s;errno=%d",
986 xmlSecErrorsSafeString(filename),
991 ret = xmlSecOpenSSLAppKeysMngrCertLoadBIO(mngr, bio, format, type);
993 xmlSecError(XMLSEC_ERRORS_HERE,
995 "xmlSecOpenSSLAppKeysMngrCertLoadBIO",
996 XMLSEC_ERRORS_R_XMLSEC_FAILED,
997 "filename=%s;errno=%d",
998 xmlSecErrorsSafeString(filename),
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.
1016 * Reads cert from binary buffer @data and adds to the list of trusted or known
1017 * untrusted certs in @store.
1019 * Returns: 0 on success or a negative value otherwise.
1022 xmlSecOpenSSLAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, const xmlSecByte* data,
1023 xmlSecSize dataSize, xmlSecKeyDataFormat format,
1024 xmlSecKeyDataType type) {
1028 xmlSecAssert2(mngr != NULL, -1);
1029 xmlSecAssert2(data != NULL, -1);
1030 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
1032 /* this would be a read only BIO, cast from const is ok */
1033 bio = BIO_new_mem_buf((void*)data, dataSize);
1035 xmlSecError(XMLSEC_ERRORS_HERE,
1038 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1044 ret = xmlSecOpenSSLAppKeysMngrCertLoadBIO(mngr, bio, format, type);
1046 xmlSecError(XMLSEC_ERRORS_HERE,
1048 "xmlSecOpenSSLAppKeysMngrCertLoadBIO",
1049 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1050 XMLSEC_ERRORS_NO_MESSAGE);
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.
1066 * Reads cert from an OpenSSL BIO object and adds to the list of trusted or known
1067 * untrusted certs in @store.
1069 * Returns: 0 on success or a negative value otherwise.
1072 xmlSecOpenSSLAppKeysMngrCertLoadBIO(xmlSecKeysMngrPtr mngr, BIO* bio,
1073 xmlSecKeyDataFormat format, xmlSecKeyDataType type) {
1074 xmlSecKeyDataStorePtr x509Store;
1078 xmlSecAssert2(mngr != NULL, -1);
1079 xmlSecAssert2(bio != NULL, -1);
1080 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
1082 x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1083 if(x509Store == NULL) {
1084 xmlSecError(XMLSEC_ERRORS_HERE,
1086 "xmlSecKeysMngrGetDataStore",
1087 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1088 "xmlSecOpenSSLX509StoreId");
1092 cert = xmlSecOpenSSLAppCertLoadBIO(bio, format);
1094 xmlSecError(XMLSEC_ERRORS_HERE,
1096 "xmlSecOpenSSLAppCertLoadBIO",
1097 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1098 XMLSEC_ERRORS_NO_MESSAGE);
1102 ret = xmlSecOpenSSLX509StoreAdoptCert(x509Store, cert, type);
1104 xmlSecError(XMLSEC_ERRORS_HERE,
1106 "xmlSecOpenSSLX509StoreAdoptCert",
1107 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1108 XMLSEC_ERRORS_NO_MESSAGE);
1117 * xmlSecOpenSSLAppKeysMngrAddCertsPath:
1118 * @mngr: the keys manager.
1119 * @path: the path to trusted certificates.
1121 * Reads cert from @path and adds to the list of trusted certificates.
1123 * Returns: 0 on success or a negative value otherwise.
1126 xmlSecOpenSSLAppKeysMngrAddCertsPath(xmlSecKeysMngrPtr mngr, const char *path) {
1127 xmlSecKeyDataStorePtr x509Store;
1130 xmlSecAssert2(mngr != NULL, -1);
1131 xmlSecAssert2(path != NULL, -1);
1133 x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1134 if(x509Store == NULL) {
1135 xmlSecError(XMLSEC_ERRORS_HERE,
1137 "xmlSecKeysMngrGetDataStore",
1138 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1139 "xmlSecOpenSSLX509StoreId");
1143 ret = xmlSecOpenSSLX509StoreAddCertsPath(x509Store, path);
1145 xmlSecError(XMLSEC_ERRORS_HERE,
1147 "xmlSecOpenSSLX509StoreAddCertsPath",
1148 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1149 "path=%s", xmlSecErrorsSafeString(path));
1157 * xmlSecOpenSSLAppKeysMngrAddCertsFile:
1158 * @mngr: the keys manager.
1159 * @file: the file containing trusted certificates.
1161 * Reads certs from @file and adds to the list of trusted certificates.
1162 * It is possible for @file to contain multiple certs.
1164 * Returns: 0 on success or a negative value otherwise.
1167 xmlSecOpenSSLAppKeysMngrAddCertsFile(xmlSecKeysMngrPtr mngr, const char *file) {
1168 xmlSecKeyDataStorePtr x509Store;
1171 xmlSecAssert2(mngr != NULL, -1);
1172 xmlSecAssert2(file != NULL, -1);
1174 x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecOpenSSLX509StoreId);
1175 if(x509Store == NULL) {
1176 xmlSecError(XMLSEC_ERRORS_HERE,
1178 "xmlSecKeysMngrGetDataStore",
1179 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1180 "xmlSecOpenSSLX509StoreId");
1184 ret = xmlSecOpenSSLX509StoreAddCertsFile(x509Store, file);
1186 xmlSecError(XMLSEC_ERRORS_HERE,
1188 "xmlSecOpenSSLX509StoreAddCertsFile",
1189 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1190 "file=%s", xmlSecErrorsSafeString(file));
1198 xmlSecOpenSSLAppCertLoadBIO(BIO* bio, xmlSecKeyDataFormat format) {
1201 xmlSecAssert2(bio != NULL, NULL);
1202 xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
1205 case xmlSecKeyDataFormatPem:
1206 case xmlSecKeyDataFormatCertPem:
1207 cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
1209 xmlSecError(XMLSEC_ERRORS_HERE,
1211 "PEM_read_bio_X509_AUX",
1212 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1213 XMLSEC_ERRORS_NO_MESSAGE);
1217 case xmlSecKeyDataFormatDer:
1218 case xmlSecKeyDataFormatCertDer:
1219 cert = d2i_X509_bio(bio, NULL);
1221 xmlSecError(XMLSEC_ERRORS_HERE,
1224 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1225 XMLSEC_ERRORS_NO_MESSAGE);
1230 xmlSecError(XMLSEC_ERRORS_HERE,
1233 XMLSEC_ERRORS_R_INVALID_FORMAT,
1234 "format=%d", format);
1241 #endif /* XMLSEC_NO_X509 */
1244 * xmlSecOpenSSLAppDefaultKeysMngrInit:
1245 * @mngr: the pointer to keys manager.
1247 * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId
1248 * and a default OpenSSL crypto key data stores.
1250 * Returns: 0 on success or a negative value otherwise.
1253 xmlSecOpenSSLAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) {
1256 xmlSecAssert2(mngr != NULL, -1);
1258 /* create simple keys store if needed */
1259 if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) {
1260 xmlSecKeyStorePtr keysStore;
1262 keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId);
1263 if(keysStore == NULL) {
1264 xmlSecError(XMLSEC_ERRORS_HERE,
1266 "xmlSecKeyStoreCreate",
1267 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1268 "xmlSecSimpleKeysStoreId");
1272 ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore);
1274 xmlSecError(XMLSEC_ERRORS_HERE,
1276 "xmlSecKeysMngrAdoptKeysStore",
1277 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1278 XMLSEC_ERRORS_NO_MESSAGE);
1279 xmlSecKeyStoreDestroy(keysStore);
1284 ret = xmlSecOpenSSLKeysMngrInit(mngr);
1286 xmlSecError(XMLSEC_ERRORS_HERE,
1288 "xmlSecOpenSSLKeysMngrInit",
1289 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1290 XMLSEC_ERRORS_NO_MESSAGE);
1295 mngr->getKey = xmlSecKeysMngrGetKey;
1300 * xmlSecOpenSSLAppDefaultKeysMngrAdoptKey:
1301 * @mngr: the pointer to keys manager.
1302 * @key: the pointer to key.
1304 * Adds @key to the keys manager @mngr created with #xmlSecOpenSSLAppDefaultKeysMngrInit
1307 * Returns: 0 on success or a negative value otherwise.
1310 xmlSecOpenSSLAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) {
1311 xmlSecKeyStorePtr store;
1314 xmlSecAssert2(mngr != NULL, -1);
1315 xmlSecAssert2(key != NULL, -1);
1317 store = xmlSecKeysMngrGetKeysStore(mngr);
1319 xmlSecError(XMLSEC_ERRORS_HERE,
1321 "xmlSecKeysMngrGetKeysStore",
1322 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1323 XMLSEC_ERRORS_NO_MESSAGE);
1327 ret = xmlSecSimpleKeysStoreAdoptKey(store, key);
1329 xmlSecError(XMLSEC_ERRORS_HERE,
1331 "xmlSecSimpleKeysStoreAdoptKey",
1332 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1333 XMLSEC_ERRORS_NO_MESSAGE);
1341 * xmlSecOpenSSLAppDefaultKeysMngrLoad:
1342 * @mngr: the pointer to keys manager.
1345 * Loads XML keys file from @uri to the keys manager @mngr created
1346 * with #xmlSecOpenSSLAppDefaultKeysMngrInit function.
1348 * Returns: 0 on success or a negative value otherwise.
1351 xmlSecOpenSSLAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) {
1352 xmlSecKeyStorePtr store;
1355 xmlSecAssert2(mngr != NULL, -1);
1356 xmlSecAssert2(uri != NULL, -1);
1358 store = xmlSecKeysMngrGetKeysStore(mngr);
1360 xmlSecError(XMLSEC_ERRORS_HERE,
1362 "xmlSecKeysMngrGetKeysStore",
1363 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1364 XMLSEC_ERRORS_NO_MESSAGE);
1368 ret = xmlSecSimpleKeysStoreLoad(store, uri, mngr);
1370 xmlSecError(XMLSEC_ERRORS_HERE,
1372 "xmlSecSimpleKeysStoreLoad",
1373 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1374 "uri=%s", xmlSecErrorsSafeString(uri));
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).
1387 * Saves keys from @mngr to XML keys file.
1389 * Returns: 0 on success or a negative value otherwise.
1392 xmlSecOpenSSLAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename,
1393 xmlSecKeyDataType type) {
1394 xmlSecKeyStorePtr store;
1397 xmlSecAssert2(mngr != NULL, -1);
1398 xmlSecAssert2(filename != NULL, -1);
1400 store = xmlSecKeysMngrGetKeysStore(mngr);
1402 xmlSecError(XMLSEC_ERRORS_HERE,
1404 "xmlSecKeysMngrGetKeysStore",
1405 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1406 XMLSEC_ERRORS_NO_MESSAGE);
1410 ret = xmlSecSimpleKeysStoreSave(store, filename, type);
1412 xmlSecError(XMLSEC_ERRORS_HERE,
1414 "xmlSecSimpleKeysStoreSave",
1415 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1416 "filename%s", xmlSecErrorsSafeString(filename));
1425 * Random numbers initialization from openssl (apps/app_rand.c)
1427 static int seeded = 0;
1428 static int egdsocket = 0;
1431 xmlSecOpenSSLAppLoadRANDFile(const char *file) {
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. */
1443 if((file == NULL) || !RAND_load_file(file, -1)) {
1444 if(RAND_status() == 0) {
1445 xmlSecError(XMLSEC_ERRORS_HERE,
1448 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1449 "file=%s", xmlSecErrorsSafeString(file));
1458 xmlSecOpenSSLAppSaveRANDFile(const char *file) {
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. */
1470 file = RAND_file_name(buffer, sizeof(buffer));
1472 if((file == NULL) || !RAND_write_file(file)) {
1473 xmlSecError(XMLSEC_ERRORS_HERE,
1476 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1478 xmlSecErrorsSafeString(file));
1486 * xmlSecOpenSSLAppGetDefaultPwdCallback:
1488 * Gets default password callback.
1490 * Returns: default password callback.
1493 xmlSecOpenSSLAppGetDefaultPwdCallback(void) {
1494 return((void*)xmlSecOpenSSLDefaultPasswordCallback);
1498 xmlSecOpenSSLDefaultPasswordCallback(char *buf, int bufsize, int verify, void *userdata) {
1499 char* filename = (char*)userdata;
1501 xmlChar prompt[2048];
1504 xmlSecAssert2(buf != NULL, -1);
1507 for(i = 0; i < 3; i++) {
1508 if(filename != NULL) {
1509 xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password for \"%s\" file: ", filename);
1511 xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password: ");
1513 ret = EVP_read_pw_string(buf, bufsize, (char*)prompt, 0);
1515 xmlSecError(XMLSEC_ERRORS_HERE,
1517 "EVP_read_pw_string",
1518 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1519 XMLSEC_ERRORS_NO_MESSAGE);
1523 /* if we don't need to verify password then we are done */
1525 return(strlen(buf));
1528 if(filename != NULL) {
1529 xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password for \"%s\" file again: ", filename);
1531 xmlSecStrPrintf(prompt, sizeof(prompt), BAD_CAST "Enter password again: ");
1534 buf2 = (char*)xmlMalloc(bufsize);
1536 xmlSecError(XMLSEC_ERRORS_HERE,
1539 XMLSEC_ERRORS_R_MALLOC_FAILED,
1540 "size=%d", bufsize);
1543 ret = EVP_read_pw_string(buf2, bufsize, (char*)prompt, 0);
1545 xmlSecError(XMLSEC_ERRORS_HERE,
1547 "EVP_read_pw_string",
1548 XMLSEC_ERRORS_R_CRYPTO_FAILED,
1549 XMLSEC_ERRORS_NO_MESSAGE);
1550 memset(buf2, 0, bufsize);
1555 /* check if passwords match */
1556 if(strcmp(buf, buf2) == 0) {
1557 memset(buf2, 0, bufsize);
1559 return(strlen(buf));
1563 memset(buf2, 0, bufsize);
1571 xmlSecOpenSSLDummyPasswordCallback(char *buf, int bufsize, int verify, void *userdata) {
1572 char* password = (char*)userdata;
1574 if((password == NULL) || (strlen(password) + 1 > bufsize)) {
1578 strcpy(buf, password);
1579 return (strlen(buf));