xref: /openbsd/lib/libssl/ssl_rsa.c (revision d89ec533)
1 /* $OpenBSD: ssl_rsa.c,v 1.37 2021/11/29 18:36:27 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/bio.h>
62 #include <openssl/evp.h>
63 #include <openssl/objects.h>
64 #include <openssl/pem.h>
65 #include <openssl/x509.h>
66 
67 #include "ssl_locl.h"
68 
69 static int ssl_set_cert(CERT *c, X509 *x509);
70 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
71 static int use_certificate_chain_bio(BIO *in, CERT *cert,
72     pem_password_cb *passwd_cb, void *passwd_arg);
73 static int use_certificate_chain_file(const char *file, CERT *cert,
74     pem_password_cb *passwd_cb, void *passwd_arg);
75 
76 int
77 SSL_use_certificate(SSL *ssl, X509 *x)
78 {
79 	if (x == NULL) {
80 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
81 		return (0);
82 	}
83 	return (ssl_set_cert(ssl->cert, x));
84 }
85 
86 int
87 SSL_use_certificate_file(SSL *ssl, const char *file, int type)
88 {
89 	int j;
90 	BIO *in;
91 	int ret = 0;
92 	X509 *x = NULL;
93 
94 	in = BIO_new(BIO_s_file());
95 	if (in == NULL) {
96 		SSLerror(ssl, ERR_R_BUF_LIB);
97 		goto end;
98 	}
99 
100 	if (BIO_read_filename(in, file) <= 0) {
101 		SSLerror(ssl, ERR_R_SYS_LIB);
102 		goto end;
103 	}
104 	if (type == SSL_FILETYPE_ASN1) {
105 		j = ERR_R_ASN1_LIB;
106 		x = d2i_X509_bio(in, NULL);
107 	} else if (type == SSL_FILETYPE_PEM) {
108 		j = ERR_R_PEM_LIB;
109 		x = PEM_read_bio_X509(in, NULL,
110 		    ssl->ctx->default_passwd_callback,
111 		    ssl->ctx->default_passwd_callback_userdata);
112 	} else {
113 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
114 		goto end;
115 	}
116 
117 	if (x == NULL) {
118 		SSLerror(ssl, j);
119 		goto end;
120 	}
121 
122 	ret = SSL_use_certificate(ssl, x);
123  end:
124 	X509_free(x);
125 	BIO_free(in);
126 	return (ret);
127 }
128 
129 int
130 SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
131 {
132 	X509 *x;
133 	int ret;
134 
135 	x = d2i_X509(NULL, &d, (long)len);
136 	if (x == NULL) {
137 		SSLerror(ssl, ERR_R_ASN1_LIB);
138 		return (0);
139 	}
140 
141 	ret = SSL_use_certificate(ssl, x);
142 	X509_free(x);
143 	return (ret);
144 }
145 
146 int
147 SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
148 {
149 	EVP_PKEY *pkey;
150 	int ret;
151 
152 	if (rsa == NULL) {
153 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
154 		return (0);
155 	}
156 	if ((pkey = EVP_PKEY_new()) == NULL) {
157 		SSLerror(ssl, ERR_R_EVP_LIB);
158 		return (0);
159 	}
160 
161 	RSA_up_ref(rsa);
162 	EVP_PKEY_assign_RSA(pkey, rsa);
163 
164 	ret = ssl_set_pkey(ssl->cert, pkey);
165 	EVP_PKEY_free(pkey);
166 	return (ret);
167 }
168 
169 static int
170 ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
171 {
172 	int i;
173 
174 	i = ssl_cert_type(NULL, pkey);
175 	if (i < 0) {
176 		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
177 		return (0);
178 	}
179 
180 	if (c->pkeys[i].x509 != NULL) {
181 		EVP_PKEY *pktmp;
182 		pktmp = X509_get_pubkey(c->pkeys[i].x509);
183 		EVP_PKEY_copy_parameters(pktmp, pkey);
184 		EVP_PKEY_free(pktmp);
185 		ERR_clear_error();
186 
187 		/*
188 		 * Don't check the public/private key, this is mostly
189 		 * for smart cards.
190 		 */
191 		if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
192 		    !(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) {
193 			if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
194 				X509_free(c->pkeys[i].x509);
195 				c->pkeys[i].x509 = NULL;
196 				return 0;
197 			}
198 		}
199 	}
200 
201 	EVP_PKEY_free(c->pkeys[i].privatekey);
202 	EVP_PKEY_up_ref(pkey);
203 	c->pkeys[i].privatekey = pkey;
204 	c->key = &(c->pkeys[i]);
205 
206 	c->valid = 0;
207 	return (1);
208 }
209 
210 int
211 SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
212 {
213 	int j, ret = 0;
214 	BIO *in;
215 	RSA *rsa = NULL;
216 
217 	in = BIO_new(BIO_s_file());
218 	if (in == NULL) {
219 		SSLerror(ssl, ERR_R_BUF_LIB);
220 		goto end;
221 	}
222 
223 	if (BIO_read_filename(in, file) <= 0) {
224 		SSLerror(ssl, ERR_R_SYS_LIB);
225 		goto end;
226 	}
227 	if (type == SSL_FILETYPE_ASN1) {
228 		j = ERR_R_ASN1_LIB;
229 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
230 	} else if (type == SSL_FILETYPE_PEM) {
231 		j = ERR_R_PEM_LIB;
232 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
233 		    ssl->ctx->default_passwd_callback,
234 		    ssl->ctx->default_passwd_callback_userdata);
235 	} else {
236 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
237 		goto end;
238 	}
239 	if (rsa == NULL) {
240 		SSLerror(ssl, j);
241 		goto end;
242 	}
243 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
244 	RSA_free(rsa);
245  end:
246 	BIO_free(in);
247 	return (ret);
248 }
249 
250 int
251 SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
252 {
253 	int ret;
254 	RSA *rsa;
255 
256 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
257 		SSLerror(ssl, ERR_R_ASN1_LIB);
258 		return (0);
259 	}
260 
261 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
262 	RSA_free(rsa);
263 	return (ret);
264 }
265 
266 int
267 SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
268 {
269 	int ret;
270 
271 	if (pkey == NULL) {
272 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
273 		return (0);
274 	}
275 	ret = ssl_set_pkey(ssl->cert, pkey);
276 	return (ret);
277 }
278 
279 int
280 SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
281 {
282 	int j, ret = 0;
283 	BIO *in;
284 	EVP_PKEY *pkey = NULL;
285 
286 	in = BIO_new(BIO_s_file());
287 	if (in == NULL) {
288 		SSLerror(ssl, ERR_R_BUF_LIB);
289 		goto end;
290 	}
291 
292 	if (BIO_read_filename(in, file) <= 0) {
293 		SSLerror(ssl, ERR_R_SYS_LIB);
294 		goto end;
295 	}
296 	if (type == SSL_FILETYPE_PEM) {
297 		j = ERR_R_PEM_LIB;
298 		pkey = PEM_read_bio_PrivateKey(in, NULL,
299 		    ssl->ctx->default_passwd_callback,
300 		    ssl->ctx->default_passwd_callback_userdata);
301 	} else if (type == SSL_FILETYPE_ASN1) {
302 		j = ERR_R_ASN1_LIB;
303 		pkey = d2i_PrivateKey_bio(in, NULL);
304 	} else {
305 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
306 		goto end;
307 	}
308 	if (pkey == NULL) {
309 		SSLerror(ssl, j);
310 		goto end;
311 	}
312 	ret = SSL_use_PrivateKey(ssl, pkey);
313 	EVP_PKEY_free(pkey);
314  end:
315 	BIO_free(in);
316 	return (ret);
317 }
318 
319 int
320 SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
321 {
322 	int ret;
323 	EVP_PKEY *pkey;
324 
325 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
326 		SSLerror(ssl, ERR_R_ASN1_LIB);
327 		return (0);
328 	}
329 
330 	ret = SSL_use_PrivateKey(ssl, pkey);
331 	EVP_PKEY_free(pkey);
332 	return (ret);
333 }
334 
335 int
336 SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
337 {
338 	if (x == NULL) {
339 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
340 		return (0);
341 	}
342 	return (ssl_set_cert(ctx->internal->cert, x));
343 }
344 
345 static int
346 ssl_set_cert(CERT *c, X509 *x)
347 {
348 	EVP_PKEY *pkey;
349 	int i;
350 
351 	pkey = X509_get_pubkey(x);
352 	if (pkey == NULL) {
353 		SSLerrorx(SSL_R_X509_LIB);
354 		return (0);
355 	}
356 
357 	i = ssl_cert_type(x, pkey);
358 	if (i < 0) {
359 		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
360 		EVP_PKEY_free(pkey);
361 		return (0);
362 	}
363 
364 	if (c->pkeys[i].privatekey != NULL) {
365 		EVP_PKEY *priv_key = c->pkeys[i].privatekey;
366 
367 		EVP_PKEY_copy_parameters(pkey, priv_key);
368 		ERR_clear_error();
369 
370 		/*
371 		 * Don't check the public/private key, this is mostly
372 		 * for smart cards.
373 		 */
374 		if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA ||
375 		    !(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) {
376 			if (!X509_check_private_key(x, priv_key)) {
377 				/*
378 				 * don't fail for a cert/key mismatch, just free
379 				 * current private key (when switching to a
380 				 * different cert & key, first this function
381 				 * should be used, then ssl_set_pkey.
382 				 */
383 				EVP_PKEY_free(c->pkeys[i].privatekey);
384 				c->pkeys[i].privatekey = NULL;
385 				ERR_clear_error();
386 			}
387 		}
388 	}
389 
390 	EVP_PKEY_free(pkey);
391 
392 	X509_free(c->pkeys[i].x509);
393 	X509_up_ref(x);
394 	c->pkeys[i].x509 = x;
395 	c->key = &(c->pkeys[i]);
396 
397 	c->valid = 0;
398 	return (1);
399 }
400 
401 int
402 SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
403 {
404 	int j;
405 	BIO *in;
406 	int ret = 0;
407 	X509 *x = NULL;
408 
409 	in = BIO_new(BIO_s_file());
410 	if (in == NULL) {
411 		SSLerrorx(ERR_R_BUF_LIB);
412 		goto end;
413 	}
414 
415 	if (BIO_read_filename(in, file) <= 0) {
416 		SSLerrorx(ERR_R_SYS_LIB);
417 		goto end;
418 	}
419 	if (type == SSL_FILETYPE_ASN1) {
420 		j = ERR_R_ASN1_LIB;
421 		x = d2i_X509_bio(in, NULL);
422 	} else if (type == SSL_FILETYPE_PEM) {
423 		j = ERR_R_PEM_LIB;
424 		x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
425 		    ctx->default_passwd_callback_userdata);
426 	} else {
427 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
428 		goto end;
429 	}
430 
431 	if (x == NULL) {
432 		SSLerrorx(j);
433 		goto end;
434 	}
435 
436 	ret = SSL_CTX_use_certificate(ctx, x);
437  end:
438 	X509_free(x);
439 	BIO_free(in);
440 	return (ret);
441 }
442 
443 int
444 SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
445 {
446 	X509 *x;
447 	int ret;
448 
449 	x = d2i_X509(NULL, &d, (long)len);
450 	if (x == NULL) {
451 		SSLerrorx(ERR_R_ASN1_LIB);
452 		return (0);
453 	}
454 
455 	ret = SSL_CTX_use_certificate(ctx, x);
456 	X509_free(x);
457 	return (ret);
458 }
459 
460 int
461 SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
462 {
463 	int ret;
464 	EVP_PKEY *pkey;
465 
466 	if (rsa == NULL) {
467 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
468 		return (0);
469 	}
470 	if ((pkey = EVP_PKEY_new()) == NULL) {
471 		SSLerrorx(ERR_R_EVP_LIB);
472 		return (0);
473 	}
474 
475 	RSA_up_ref(rsa);
476 	EVP_PKEY_assign_RSA(pkey, rsa);
477 
478 	ret = ssl_set_pkey(ctx->internal->cert, pkey);
479 	EVP_PKEY_free(pkey);
480 	return (ret);
481 }
482 
483 int
484 SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
485 {
486 	int j, ret = 0;
487 	BIO *in;
488 	RSA *rsa = NULL;
489 
490 	in = BIO_new(BIO_s_file());
491 	if (in == NULL) {
492 		SSLerrorx(ERR_R_BUF_LIB);
493 		goto end;
494 	}
495 
496 	if (BIO_read_filename(in, file) <= 0) {
497 		SSLerrorx(ERR_R_SYS_LIB);
498 		goto end;
499 	}
500 	if (type == SSL_FILETYPE_ASN1) {
501 		j = ERR_R_ASN1_LIB;
502 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
503 	} else if (type == SSL_FILETYPE_PEM) {
504 		j = ERR_R_PEM_LIB;
505 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
506 		    ctx->default_passwd_callback,
507 		    ctx->default_passwd_callback_userdata);
508 	} else {
509 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
510 		goto end;
511 	}
512 	if (rsa == NULL) {
513 		SSLerrorx(j);
514 		goto end;
515 	}
516 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
517 	RSA_free(rsa);
518  end:
519 	BIO_free(in);
520 	return (ret);
521 }
522 
523 int
524 SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
525 {
526 	int ret;
527 	RSA *rsa;
528 
529 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
530 		SSLerrorx(ERR_R_ASN1_LIB);
531 		return (0);
532 	}
533 
534 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
535 	RSA_free(rsa);
536 	return (ret);
537 }
538 
539 int
540 SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
541 {
542 	if (pkey == NULL) {
543 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
544 		return (0);
545 	}
546 	return (ssl_set_pkey(ctx->internal->cert, pkey));
547 }
548 
549 int
550 SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
551 {
552 	int j, ret = 0;
553 	BIO *in;
554 	EVP_PKEY *pkey = NULL;
555 
556 	in = BIO_new(BIO_s_file());
557 	if (in == NULL) {
558 		SSLerrorx(ERR_R_BUF_LIB);
559 		goto end;
560 	}
561 
562 	if (BIO_read_filename(in, file) <= 0) {
563 		SSLerrorx(ERR_R_SYS_LIB);
564 		goto end;
565 	}
566 	if (type == SSL_FILETYPE_PEM) {
567 		j = ERR_R_PEM_LIB;
568 		pkey = PEM_read_bio_PrivateKey(in, NULL,
569 		    ctx->default_passwd_callback,
570 		    ctx->default_passwd_callback_userdata);
571 	} else if (type == SSL_FILETYPE_ASN1) {
572 		j = ERR_R_ASN1_LIB;
573 		pkey = d2i_PrivateKey_bio(in, NULL);
574 	} else {
575 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
576 		goto end;
577 	}
578 	if (pkey == NULL) {
579 		SSLerrorx(j);
580 		goto end;
581 	}
582 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
583 	EVP_PKEY_free(pkey);
584  end:
585 	BIO_free(in);
586 	return (ret);
587 }
588 
589 int
590 SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
591     long len)
592 {
593 	int ret;
594 	EVP_PKEY *pkey;
595 
596 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
597 		SSLerrorx(ERR_R_ASN1_LIB);
598 		return (0);
599 	}
600 
601 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
602 	EVP_PKEY_free(pkey);
603 	return (ret);
604 }
605 
606 
607 /*
608  * Read a bio that contains our certificate in "PEM" format,
609  * possibly followed by a sequence of CA certificates that should be
610  * sent to the peer in the Certificate message.
611  */
612 static int
613 use_certificate_chain_bio(BIO *in, CERT *cert, pem_password_cb *passwd_cb,
614     void *passwd_arg)
615 {
616 	X509 *ca, *x = NULL;
617 	unsigned long err;
618 	int ret = 0;
619 
620 	if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
621 	    NULL) {
622 		SSLerrorx(ERR_R_PEM_LIB);
623 		goto err;
624 	}
625 
626 	if (!ssl_set_cert(cert, x))
627 		goto err;
628 
629 	if (!ssl_cert_set0_chain(cert, NULL))
630 		goto err;
631 
632 	/* Process any additional CA certificates. */
633 	while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
634 	    NULL) {
635 		if (!ssl_cert_add0_chain_cert(cert, ca)) {
636 			X509_free(ca);
637 			goto err;
638 		}
639 	}
640 
641 	/* When the while loop ends, it's usually just EOF. */
642 	err = ERR_peek_last_error();
643 	if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
644 	    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
645 		ERR_clear_error();
646 		ret = 1;
647 	}
648 
649  err:
650 	X509_free(x);
651 
652 	return (ret);
653 }
654 
655 int
656 use_certificate_chain_file(const char *file, CERT *cert,
657     pem_password_cb *passwd_cb, void *passwd_arg)
658 {
659 	BIO *in;
660 	int ret = 0;
661 
662 	in = BIO_new(BIO_s_file());
663 	if (in == NULL) {
664 		SSLerrorx(ERR_R_BUF_LIB);
665 		goto end;
666 	}
667 
668 	if (BIO_read_filename(in, file) <= 0) {
669 		SSLerrorx(ERR_R_SYS_LIB);
670 		goto end;
671 	}
672 
673 	ret = use_certificate_chain_bio(in, cert, passwd_cb, passwd_arg);
674 
675  end:
676 	BIO_free(in);
677 	return (ret);
678 }
679 
680 int
681 SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
682 {
683 	return use_certificate_chain_file(file, ctx->internal->cert,
684 	    ctx->default_passwd_callback,
685 	    ctx->default_passwd_callback_userdata);
686 }
687 
688 int
689 SSL_use_certificate_chain_file(SSL *ssl, const char *file)
690 {
691 	return use_certificate_chain_file(file, ssl->cert,
692 	    ssl->ctx->default_passwd_callback,
693 	    ssl->ctx->default_passwd_callback_userdata);
694 }
695 
696 int
697 SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
698 {
699 	BIO *in;
700 	int ret = 0;
701 
702 	in = BIO_new_mem_buf(buf, len);
703 	if (in == NULL) {
704 		SSLerrorx(ERR_R_BUF_LIB);
705 		goto end;
706 	}
707 
708 	ret = use_certificate_chain_bio(in, ctx->internal->cert,
709 	    ctx->default_passwd_callback,
710 	    ctx->default_passwd_callback_userdata);
711 
712  end:
713 	BIO_free(in);
714 	return (ret);
715 }
716