xref: /openbsd-src/lib/libssl/ssl_rsa.c (revision 24bb5fcea3ed904bc467217bdaadb5dfc618d5bf)
1 /* $OpenBSD: ssl_rsa.c,v 1.34 2021/06/11 11:13:53 jsing 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_internal());
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 ((pkey->type == EVP_PKEY_RSA) &&
192 			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
193 ;
194 		else
195 		if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
196 			X509_free(c->pkeys[i].x509);
197 			c->pkeys[i].x509 = NULL;
198 			return 0;
199 		}
200 	}
201 
202 	EVP_PKEY_free(c->pkeys[i].privatekey);
203 	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
204 	c->pkeys[i].privatekey = pkey;
205 	c->key = &(c->pkeys[i]);
206 
207 	c->valid = 0;
208 	return (1);
209 }
210 
211 int
212 SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
213 {
214 	int j, ret = 0;
215 	BIO *in;
216 	RSA *rsa = NULL;
217 
218 	in = BIO_new(BIO_s_file_internal());
219 	if (in == NULL) {
220 		SSLerror(ssl, ERR_R_BUF_LIB);
221 		goto end;
222 	}
223 
224 	if (BIO_read_filename(in, file) <= 0) {
225 		SSLerror(ssl, ERR_R_SYS_LIB);
226 		goto end;
227 	}
228 	if (type == SSL_FILETYPE_ASN1) {
229 		j = ERR_R_ASN1_LIB;
230 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
231 	} else if (type == SSL_FILETYPE_PEM) {
232 		j = ERR_R_PEM_LIB;
233 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
234 		    ssl->ctx->default_passwd_callback,
235 		    ssl->ctx->default_passwd_callback_userdata);
236 	} else {
237 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
238 		goto end;
239 	}
240 	if (rsa == NULL) {
241 		SSLerror(ssl, j);
242 		goto end;
243 	}
244 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
245 	RSA_free(rsa);
246  end:
247 	BIO_free(in);
248 	return (ret);
249 }
250 
251 int
252 SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
253 {
254 	int ret;
255 	RSA *rsa;
256 
257 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
258 		SSLerror(ssl, ERR_R_ASN1_LIB);
259 		return (0);
260 	}
261 
262 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
263 	RSA_free(rsa);
264 	return (ret);
265 }
266 
267 int
268 SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
269 {
270 	int ret;
271 
272 	if (pkey == NULL) {
273 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
274 		return (0);
275 	}
276 	ret = ssl_set_pkey(ssl->cert, pkey);
277 	return (ret);
278 }
279 
280 int
281 SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
282 {
283 	int j, ret = 0;
284 	BIO *in;
285 	EVP_PKEY *pkey = NULL;
286 
287 	in = BIO_new(BIO_s_file_internal());
288 	if (in == NULL) {
289 		SSLerror(ssl, ERR_R_BUF_LIB);
290 		goto end;
291 	}
292 
293 	if (BIO_read_filename(in, file) <= 0) {
294 		SSLerror(ssl, ERR_R_SYS_LIB);
295 		goto end;
296 	}
297 	if (type == SSL_FILETYPE_PEM) {
298 		j = ERR_R_PEM_LIB;
299 		pkey = PEM_read_bio_PrivateKey(in, NULL,
300 		    ssl->ctx->default_passwd_callback,
301 		    ssl->ctx->default_passwd_callback_userdata);
302 	} else if (type == SSL_FILETYPE_ASN1) {
303 		j = ERR_R_ASN1_LIB;
304 		pkey = d2i_PrivateKey_bio(in, NULL);
305 	} else {
306 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
307 		goto end;
308 	}
309 	if (pkey == NULL) {
310 		SSLerror(ssl, j);
311 		goto end;
312 	}
313 	ret = SSL_use_PrivateKey(ssl, pkey);
314 	EVP_PKEY_free(pkey);
315  end:
316 	BIO_free(in);
317 	return (ret);
318 }
319 
320 int
321 SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
322 {
323 	int ret;
324 	EVP_PKEY *pkey;
325 
326 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
327 		SSLerror(ssl, ERR_R_ASN1_LIB);
328 		return (0);
329 	}
330 
331 	ret = SSL_use_PrivateKey(ssl, pkey);
332 	EVP_PKEY_free(pkey);
333 	return (ret);
334 }
335 
336 int
337 SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
338 {
339 	if (x == NULL) {
340 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
341 		return (0);
342 	}
343 	return (ssl_set_cert(ctx->internal->cert, x));
344 }
345 
346 static int
347 ssl_set_cert(CERT *c, X509 *x)
348 {
349 	EVP_PKEY *pkey;
350 	int i;
351 
352 	pkey = X509_get_pubkey(x);
353 	if (pkey == NULL) {
354 		SSLerrorx(SSL_R_X509_LIB);
355 		return (0);
356 	}
357 
358 	i = ssl_cert_type(x, pkey);
359 	if (i < 0) {
360 		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
361 		EVP_PKEY_free(pkey);
362 		return (0);
363 	}
364 
365 	if (c->pkeys[i].privatekey != NULL) {
366 		EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
367 		ERR_clear_error();
368 
369 		/*
370 		 * Don't check the public/private key, this is mostly
371 		 * for smart cards.
372 		 */
373 		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
374 			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
375 		RSA_METHOD_FLAG_NO_CHECK))
376 ;
377 		else
378 		if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
379 			/*
380 			 * don't fail for a cert/key mismatch, just free
381 			 * current private key (when switching to a different
382 			 * cert & key, first this function should be used,
383 			 * then ssl_set_pkey
384 			 */
385 			EVP_PKEY_free(c->pkeys[i].privatekey);
386 			c->pkeys[i].privatekey = NULL;
387 			/* clear error queue */
388 			ERR_clear_error();
389 		}
390 	}
391 
392 	EVP_PKEY_free(pkey);
393 
394 	X509_free(c->pkeys[i].x509);
395 	CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
396 	c->pkeys[i].x509 = x;
397 	c->key = &(c->pkeys[i]);
398 
399 	c->valid = 0;
400 	return (1);
401 }
402 
403 int
404 SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
405 {
406 	int j;
407 	BIO *in;
408 	int ret = 0;
409 	X509 *x = NULL;
410 
411 	in = BIO_new(BIO_s_file_internal());
412 	if (in == NULL) {
413 		SSLerrorx(ERR_R_BUF_LIB);
414 		goto end;
415 	}
416 
417 	if (BIO_read_filename(in, file) <= 0) {
418 		SSLerrorx(ERR_R_SYS_LIB);
419 		goto end;
420 	}
421 	if (type == SSL_FILETYPE_ASN1) {
422 		j = ERR_R_ASN1_LIB;
423 		x = d2i_X509_bio(in, NULL);
424 	} else if (type == SSL_FILETYPE_PEM) {
425 		j = ERR_R_PEM_LIB;
426 		x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
427 		    ctx->default_passwd_callback_userdata);
428 	} else {
429 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
430 		goto end;
431 	}
432 
433 	if (x == NULL) {
434 		SSLerrorx(j);
435 		goto end;
436 	}
437 
438 	ret = SSL_CTX_use_certificate(ctx, x);
439  end:
440 	X509_free(x);
441 	BIO_free(in);
442 	return (ret);
443 }
444 
445 int
446 SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
447 {
448 	X509 *x;
449 	int ret;
450 
451 	x = d2i_X509(NULL, &d, (long)len);
452 	if (x == NULL) {
453 		SSLerrorx(ERR_R_ASN1_LIB);
454 		return (0);
455 	}
456 
457 	ret = SSL_CTX_use_certificate(ctx, x);
458 	X509_free(x);
459 	return (ret);
460 }
461 
462 int
463 SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
464 {
465 	int ret;
466 	EVP_PKEY *pkey;
467 
468 	if (rsa == NULL) {
469 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
470 		return (0);
471 	}
472 	if ((pkey = EVP_PKEY_new()) == NULL) {
473 		SSLerrorx(ERR_R_EVP_LIB);
474 		return (0);
475 	}
476 
477 	RSA_up_ref(rsa);
478 	EVP_PKEY_assign_RSA(pkey, rsa);
479 
480 	ret = ssl_set_pkey(ctx->internal->cert, pkey);
481 	EVP_PKEY_free(pkey);
482 	return (ret);
483 }
484 
485 int
486 SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
487 {
488 	int j, ret = 0;
489 	BIO *in;
490 	RSA *rsa = NULL;
491 
492 	in = BIO_new(BIO_s_file_internal());
493 	if (in == NULL) {
494 		SSLerrorx(ERR_R_BUF_LIB);
495 		goto end;
496 	}
497 
498 	if (BIO_read_filename(in, file) <= 0) {
499 		SSLerrorx(ERR_R_SYS_LIB);
500 		goto end;
501 	}
502 	if (type == SSL_FILETYPE_ASN1) {
503 		j = ERR_R_ASN1_LIB;
504 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
505 	} else if (type == SSL_FILETYPE_PEM) {
506 		j = ERR_R_PEM_LIB;
507 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
508 		    ctx->default_passwd_callback,
509 		    ctx->default_passwd_callback_userdata);
510 	} else {
511 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
512 		goto end;
513 	}
514 	if (rsa == NULL) {
515 		SSLerrorx(j);
516 		goto end;
517 	}
518 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
519 	RSA_free(rsa);
520  end:
521 	BIO_free(in);
522 	return (ret);
523 }
524 
525 int
526 SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
527 {
528 	int ret;
529 	RSA *rsa;
530 
531 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
532 		SSLerrorx(ERR_R_ASN1_LIB);
533 		return (0);
534 	}
535 
536 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
537 	RSA_free(rsa);
538 	return (ret);
539 }
540 
541 int
542 SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
543 {
544 	if (pkey == NULL) {
545 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
546 		return (0);
547 	}
548 	return (ssl_set_pkey(ctx->internal->cert, pkey));
549 }
550 
551 int
552 SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
553 {
554 	int j, ret = 0;
555 	BIO *in;
556 	EVP_PKEY *pkey = NULL;
557 
558 	in = BIO_new(BIO_s_file_internal());
559 	if (in == NULL) {
560 		SSLerrorx(ERR_R_BUF_LIB);
561 		goto end;
562 	}
563 
564 	if (BIO_read_filename(in, file) <= 0) {
565 		SSLerrorx(ERR_R_SYS_LIB);
566 		goto end;
567 	}
568 	if (type == SSL_FILETYPE_PEM) {
569 		j = ERR_R_PEM_LIB;
570 		pkey = PEM_read_bio_PrivateKey(in, NULL,
571 		    ctx->default_passwd_callback,
572 		    ctx->default_passwd_callback_userdata);
573 	} else if (type == SSL_FILETYPE_ASN1) {
574 		j = ERR_R_ASN1_LIB;
575 		pkey = d2i_PrivateKey_bio(in, NULL);
576 	} else {
577 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
578 		goto end;
579 	}
580 	if (pkey == NULL) {
581 		SSLerrorx(j);
582 		goto end;
583 	}
584 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
585 	EVP_PKEY_free(pkey);
586  end:
587 	BIO_free(in);
588 	return (ret);
589 }
590 
591 int
592 SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
593     long len)
594 {
595 	int ret;
596 	EVP_PKEY *pkey;
597 
598 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
599 		SSLerrorx(ERR_R_ASN1_LIB);
600 		return (0);
601 	}
602 
603 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
604 	EVP_PKEY_free(pkey);
605 	return (ret);
606 }
607 
608 
609 /*
610  * Read a bio that contains our certificate in "PEM" format,
611  * possibly followed by a sequence of CA certificates that should be
612  * sent to the peer in the Certificate message.
613  */
614 static int
615 use_certificate_chain_bio(BIO *in, CERT *cert, pem_password_cb *passwd_cb,
616     void *passwd_arg)
617 {
618 	X509 *ca, *x = NULL;
619 	unsigned long err;
620 	int ret = 0;
621 
622 	if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
623 	    NULL) {
624 		SSLerrorx(ERR_R_PEM_LIB);
625 		goto err;
626 	}
627 
628 	if (!ssl_set_cert(cert, x))
629 		goto err;
630 
631 	if (!ssl_cert_set0_chain(cert, NULL))
632 		goto err;
633 
634 	/* Process any additional CA certificates. */
635 	while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
636 	    NULL) {
637 		if (!ssl_cert_add0_chain_cert(cert, ca)) {
638 			X509_free(ca);
639 			goto err;
640 		}
641 	}
642 
643 	/* When the while loop ends, it's usually just EOF. */
644 	err = ERR_peek_last_error();
645 	if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
646 	    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
647 		ERR_clear_error();
648 		ret = 1;
649 	}
650 
651  err:
652 	X509_free(x);
653 
654 	return (ret);
655 }
656 
657 int
658 use_certificate_chain_file(const char *file, CERT *cert,
659     pem_password_cb *passwd_cb, void *passwd_arg)
660 {
661 	BIO *in;
662 	int ret = 0;
663 
664 	in = BIO_new(BIO_s_file_internal());
665 	if (in == NULL) {
666 		SSLerrorx(ERR_R_BUF_LIB);
667 		goto end;
668 	}
669 
670 	if (BIO_read_filename(in, file) <= 0) {
671 		SSLerrorx(ERR_R_SYS_LIB);
672 		goto end;
673 	}
674 
675 	ret = use_certificate_chain_bio(in, cert, passwd_cb, passwd_arg);
676 
677  end:
678 	BIO_free(in);
679 	return (ret);
680 }
681 
682 int
683 SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
684 {
685 	return use_certificate_chain_file(file, ctx->internal->cert,
686 	    ctx->default_passwd_callback,
687 	    ctx->default_passwd_callback_userdata);
688 }
689 
690 int
691 SSL_use_certificate_chain_file(SSL *ssl, const char *file)
692 {
693 	return use_certificate_chain_file(file, ssl->cert,
694 	    ssl->ctx->default_passwd_callback,
695 	    ssl->ctx->default_passwd_callback_userdata);
696 }
697 
698 int
699 SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
700 {
701 	BIO *in;
702 	int ret = 0;
703 
704 	in = BIO_new_mem_buf(buf, len);
705 	if (in == NULL) {
706 		SSLerrorx(ERR_R_BUF_LIB);
707 		goto end;
708 	}
709 
710 	ret = use_certificate_chain_bio(in, ctx->internal->cert,
711 	    ctx->default_passwd_callback,
712 	    ctx->default_passwd_callback_userdata);
713 
714  end:
715 	BIO_free(in);
716 	return (ret);
717 }
718