xref: /dragonfly/crypto/libressl/ssl/ssl_rsa.c (revision 72c33676)
1 /* $OpenBSD: ssl_rsa.c,v 1.31 2019/03/25 16:46:48 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 "ssl_locl.h"
62 
63 #include <openssl/bio.h>
64 #include <openssl/evp.h>
65 #include <openssl/objects.h>
66 #include <openssl/pem.h>
67 #include <openssl/x509.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 ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *);
72 
73 int
74 SSL_use_certificate(SSL *ssl, X509 *x)
75 {
76 	if (x == NULL) {
77 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
78 		return (0);
79 	}
80 	return (ssl_set_cert(ssl->cert, x));
81 }
82 
83 int
84 SSL_use_certificate_file(SSL *ssl, const char *file, int type)
85 {
86 	int j;
87 	BIO *in;
88 	int ret = 0;
89 	X509 *x = NULL;
90 
91 	in = BIO_new(BIO_s_file_internal());
92 	if (in == NULL) {
93 		SSLerror(ssl, ERR_R_BUF_LIB);
94 		goto end;
95 	}
96 
97 	if (BIO_read_filename(in, file) <= 0) {
98 		SSLerror(ssl, ERR_R_SYS_LIB);
99 		goto end;
100 	}
101 	if (type == SSL_FILETYPE_ASN1) {
102 		j = ERR_R_ASN1_LIB;
103 		x = d2i_X509_bio(in, NULL);
104 	} else if (type == SSL_FILETYPE_PEM) {
105 		j = ERR_R_PEM_LIB;
106 		x = PEM_read_bio_X509(in, NULL,
107 		    ssl->ctx->default_passwd_callback,
108 		    ssl->ctx->default_passwd_callback_userdata);
109 	} else {
110 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
111 		goto end;
112 	}
113 
114 	if (x == NULL) {
115 		SSLerror(ssl, j);
116 		goto end;
117 	}
118 
119 	ret = SSL_use_certificate(ssl, x);
120 end:
121 	X509_free(x);
122 	BIO_free(in);
123 	return (ret);
124 }
125 
126 int
127 SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
128 {
129 	X509 *x;
130 	int ret;
131 
132 	x = d2i_X509(NULL, &d, (long)len);
133 	if (x == NULL) {
134 		SSLerror(ssl, ERR_R_ASN1_LIB);
135 		return (0);
136 	}
137 
138 	ret = SSL_use_certificate(ssl, x);
139 	X509_free(x);
140 	return (ret);
141 }
142 
143 int
144 SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
145 {
146 	EVP_PKEY *pkey;
147 	int ret;
148 
149 	if (rsa == NULL) {
150 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
151 		return (0);
152 	}
153 	if ((pkey = EVP_PKEY_new()) == NULL) {
154 		SSLerror(ssl, ERR_R_EVP_LIB);
155 		return (0);
156 	}
157 
158 	RSA_up_ref(rsa);
159 	EVP_PKEY_assign_RSA(pkey, rsa);
160 
161 	ret = ssl_set_pkey(ssl->cert, pkey);
162 	EVP_PKEY_free(pkey);
163 	return (ret);
164 }
165 
166 static int
167 ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
168 {
169 	int i;
170 
171 	i = ssl_cert_type(NULL, pkey);
172 	if (i < 0) {
173 		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
174 		return (0);
175 	}
176 
177 	if (c->pkeys[i].x509 != NULL) {
178 		EVP_PKEY *pktmp;
179 		pktmp = X509_get_pubkey(c->pkeys[i].x509);
180 		EVP_PKEY_copy_parameters(pktmp, pkey);
181 		EVP_PKEY_free(pktmp);
182 		ERR_clear_error();
183 
184 		/*
185 		 * Don't check the public/private key, this is mostly
186 		 * for smart cards.
187 		 */
188 		if ((pkey->type == EVP_PKEY_RSA) &&
189 			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
190 ;
191 		else
192 		if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
193 			X509_free(c->pkeys[i].x509);
194 			c->pkeys[i].x509 = NULL;
195 			return 0;
196 		}
197 	}
198 
199 	EVP_PKEY_free(c->pkeys[i].privatekey);
200 	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
201 	c->pkeys[i].privatekey = pkey;
202 	c->key = &(c->pkeys[i]);
203 
204 	c->valid = 0;
205 	return (1);
206 }
207 
208 int
209 SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
210 {
211 	int j, ret = 0;
212 	BIO *in;
213 	RSA *rsa = NULL;
214 
215 	in = BIO_new(BIO_s_file_internal());
216 	if (in == NULL) {
217 		SSLerror(ssl, ERR_R_BUF_LIB);
218 		goto end;
219 	}
220 
221 	if (BIO_read_filename(in, file) <= 0) {
222 		SSLerror(ssl, ERR_R_SYS_LIB);
223 		goto end;
224 	}
225 	if (type == SSL_FILETYPE_ASN1) {
226 		j = ERR_R_ASN1_LIB;
227 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
228 	} else if (type == SSL_FILETYPE_PEM) {
229 		j = ERR_R_PEM_LIB;
230 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
231 		    ssl->ctx->default_passwd_callback,
232 		    ssl->ctx->default_passwd_callback_userdata);
233 	} else {
234 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
235 		goto end;
236 	}
237 	if (rsa == NULL) {
238 		SSLerror(ssl, j);
239 		goto end;
240 	}
241 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
242 	RSA_free(rsa);
243 end:
244 	BIO_free(in);
245 	return (ret);
246 }
247 
248 int
249 SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
250 {
251 	int ret;
252 	RSA *rsa;
253 
254 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
255 		SSLerror(ssl, ERR_R_ASN1_LIB);
256 		return (0);
257 	}
258 
259 	ret = SSL_use_RSAPrivateKey(ssl, rsa);
260 	RSA_free(rsa);
261 	return (ret);
262 }
263 
264 int
265 SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
266 {
267 	int ret;
268 
269 	if (pkey == NULL) {
270 		SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
271 		return (0);
272 	}
273 	ret = ssl_set_pkey(ssl->cert, pkey);
274 	return (ret);
275 }
276 
277 int
278 SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
279 {
280 	int j, ret = 0;
281 	BIO *in;
282 	EVP_PKEY *pkey = NULL;
283 
284 	in = BIO_new(BIO_s_file_internal());
285 	if (in == NULL) {
286 		SSLerror(ssl, ERR_R_BUF_LIB);
287 		goto end;
288 	}
289 
290 	if (BIO_read_filename(in, file) <= 0) {
291 		SSLerror(ssl, ERR_R_SYS_LIB);
292 		goto end;
293 	}
294 	if (type == SSL_FILETYPE_PEM) {
295 		j = ERR_R_PEM_LIB;
296 		pkey = PEM_read_bio_PrivateKey(in, NULL,
297 		    ssl->ctx->default_passwd_callback,
298 		    ssl->ctx->default_passwd_callback_userdata);
299 	} else if (type == SSL_FILETYPE_ASN1) {
300 		j = ERR_R_ASN1_LIB;
301 		pkey = d2i_PrivateKey_bio(in, NULL);
302 	} else {
303 		SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
304 		goto end;
305 	}
306 	if (pkey == NULL) {
307 		SSLerror(ssl, j);
308 		goto end;
309 	}
310 	ret = SSL_use_PrivateKey(ssl, pkey);
311 	EVP_PKEY_free(pkey);
312 end:
313 	BIO_free(in);
314 	return (ret);
315 }
316 
317 int
318 SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
319 {
320 	int ret;
321 	EVP_PKEY *pkey;
322 
323 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
324 		SSLerror(ssl, ERR_R_ASN1_LIB);
325 		return (0);
326 	}
327 
328 	ret = SSL_use_PrivateKey(ssl, pkey);
329 	EVP_PKEY_free(pkey);
330 	return (ret);
331 }
332 
333 int
334 SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
335 {
336 	if (x == NULL) {
337 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
338 		return (0);
339 	}
340 	return (ssl_set_cert(ctx->internal->cert, x));
341 }
342 
343 static int
344 ssl_set_cert(CERT *c, X509 *x)
345 {
346 	EVP_PKEY *pkey;
347 	int i;
348 
349 	pkey = X509_get_pubkey(x);
350 	if (pkey == NULL) {
351 		SSLerrorx(SSL_R_X509_LIB);
352 		return (0);
353 	}
354 
355 	i = ssl_cert_type(x, pkey);
356 	if (i < 0) {
357 		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
358 		EVP_PKEY_free(pkey);
359 		return (0);
360 	}
361 
362 	if (c->pkeys[i].privatekey != NULL) {
363 		EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
364 		ERR_clear_error();
365 
366 		/*
367 		 * Don't check the public/private key, this is mostly
368 		 * for smart cards.
369 		 */
370 		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
371 			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
372 		RSA_METHOD_FLAG_NO_CHECK))
373 ;
374 		else
375 		if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
376 			/*
377 			 * don't fail for a cert/key mismatch, just free
378 			 * current private key (when switching to a different
379 			 * cert & key, first this function should be used,
380 			 * then ssl_set_pkey
381 			 */
382 			EVP_PKEY_free(c->pkeys[i].privatekey);
383 			c->pkeys[i].privatekey = NULL;
384 			/* clear error queue */
385 			ERR_clear_error();
386 		}
387 	}
388 
389 	EVP_PKEY_free(pkey);
390 
391 	X509_free(c->pkeys[i].x509);
392 	CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
393 	c->pkeys[i].x509 = x;
394 	c->key = &(c->pkeys[i]);
395 
396 	c->valid = 0;
397 	return (1);
398 }
399 
400 int
401 SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
402 {
403 	int j;
404 	BIO *in;
405 	int ret = 0;
406 	X509 *x = NULL;
407 
408 	in = BIO_new(BIO_s_file_internal());
409 	if (in == NULL) {
410 		SSLerrorx(ERR_R_BUF_LIB);
411 		goto end;
412 	}
413 
414 	if (BIO_read_filename(in, file) <= 0) {
415 		SSLerrorx(ERR_R_SYS_LIB);
416 		goto end;
417 	}
418 	if (type == SSL_FILETYPE_ASN1) {
419 		j = ERR_R_ASN1_LIB;
420 		x = d2i_X509_bio(in, NULL);
421 	} else if (type == SSL_FILETYPE_PEM) {
422 		j = ERR_R_PEM_LIB;
423 		x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
424 		    ctx->default_passwd_callback_userdata);
425 	} else {
426 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
427 		goto end;
428 	}
429 
430 	if (x == NULL) {
431 		SSLerrorx(j);
432 		goto end;
433 	}
434 
435 	ret = SSL_CTX_use_certificate(ctx, x);
436 end:
437 	X509_free(x);
438 	BIO_free(in);
439 	return (ret);
440 }
441 
442 int
443 SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
444 {
445 	X509 *x;
446 	int ret;
447 
448 	x = d2i_X509(NULL, &d, (long)len);
449 	if (x == NULL) {
450 		SSLerrorx(ERR_R_ASN1_LIB);
451 		return (0);
452 	}
453 
454 	ret = SSL_CTX_use_certificate(ctx, x);
455 	X509_free(x);
456 	return (ret);
457 }
458 
459 int
460 SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
461 {
462 	int ret;
463 	EVP_PKEY *pkey;
464 
465 	if (rsa == NULL) {
466 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
467 		return (0);
468 	}
469 	if ((pkey = EVP_PKEY_new()) == NULL) {
470 		SSLerrorx(ERR_R_EVP_LIB);
471 		return (0);
472 	}
473 
474 	RSA_up_ref(rsa);
475 	EVP_PKEY_assign_RSA(pkey, rsa);
476 
477 	ret = ssl_set_pkey(ctx->internal->cert, pkey);
478 	EVP_PKEY_free(pkey);
479 	return (ret);
480 }
481 
482 int
483 SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
484 {
485 	int j, ret = 0;
486 	BIO *in;
487 	RSA *rsa = NULL;
488 
489 	in = BIO_new(BIO_s_file_internal());
490 	if (in == NULL) {
491 		SSLerrorx(ERR_R_BUF_LIB);
492 		goto end;
493 	}
494 
495 	if (BIO_read_filename(in, file) <= 0) {
496 		SSLerrorx(ERR_R_SYS_LIB);
497 		goto end;
498 	}
499 	if (type == SSL_FILETYPE_ASN1) {
500 		j = ERR_R_ASN1_LIB;
501 		rsa = d2i_RSAPrivateKey_bio(in, NULL);
502 	} else if (type == SSL_FILETYPE_PEM) {
503 		j = ERR_R_PEM_LIB;
504 		rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
505 		    ctx->default_passwd_callback,
506 		    ctx->default_passwd_callback_userdata);
507 	} else {
508 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
509 		goto end;
510 	}
511 	if (rsa == NULL) {
512 		SSLerrorx(j);
513 		goto end;
514 	}
515 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
516 	RSA_free(rsa);
517 end:
518 	BIO_free(in);
519 	return (ret);
520 }
521 
522 int
523 SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
524 {
525 	int ret;
526 	RSA *rsa;
527 
528 	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
529 		SSLerrorx(ERR_R_ASN1_LIB);
530 		return (0);
531 	}
532 
533 	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
534 	RSA_free(rsa);
535 	return (ret);
536 }
537 
538 int
539 SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
540 {
541 	if (pkey == NULL) {
542 		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
543 		return (0);
544 	}
545 	return (ssl_set_pkey(ctx->internal->cert, pkey));
546 }
547 
548 int
549 SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
550 {
551 	int j, ret = 0;
552 	BIO *in;
553 	EVP_PKEY *pkey = NULL;
554 
555 	in = BIO_new(BIO_s_file_internal());
556 	if (in == NULL) {
557 		SSLerrorx(ERR_R_BUF_LIB);
558 		goto end;
559 	}
560 
561 	if (BIO_read_filename(in, file) <= 0) {
562 		SSLerrorx(ERR_R_SYS_LIB);
563 		goto end;
564 	}
565 	if (type == SSL_FILETYPE_PEM) {
566 		j = ERR_R_PEM_LIB;
567 		pkey = PEM_read_bio_PrivateKey(in, NULL,
568 		    ctx->default_passwd_callback,
569 		    ctx->default_passwd_callback_userdata);
570 	} else if (type == SSL_FILETYPE_ASN1) {
571 		j = ERR_R_ASN1_LIB;
572 		pkey = d2i_PrivateKey_bio(in, NULL);
573 	} else {
574 		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
575 		goto end;
576 	}
577 	if (pkey == NULL) {
578 		SSLerrorx(j);
579 		goto end;
580 	}
581 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
582 	EVP_PKEY_free(pkey);
583 end:
584 	BIO_free(in);
585 	return (ret);
586 }
587 
588 int
589 SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
590     long len)
591 {
592 	int ret;
593 	EVP_PKEY *pkey;
594 
595 	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
596 		SSLerrorx(ERR_R_ASN1_LIB);
597 		return (0);
598 	}
599 
600 	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
601 	EVP_PKEY_free(pkey);
602 	return (ret);
603 }
604 
605 
606 /*
607  * Read a bio that contains our certificate in "PEM" format,
608  * possibly followed by a sequence of CA certificates that should be
609  * sent to the peer in the Certificate message.
610  */
611 static int
612 ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
613 {
614 	X509 *ca, *x = NULL;
615 	unsigned long err;
616 	int ret = 0;
617 
618 	if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
619 	    ctx->default_passwd_callback_userdata)) == NULL) {
620 		SSLerrorx(ERR_R_PEM_LIB);
621 		goto err;
622 	}
623 
624 	if (!SSL_CTX_use_certificate(ctx, x))
625 		goto err;
626 
627 	if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
628 		goto err;
629 
630 	/* Process any additional CA certificates. */
631 	while ((ca = PEM_read_bio_X509(in, NULL,
632 	    ctx->default_passwd_callback,
633 	    ctx->default_passwd_callback_userdata)) != NULL) {
634 		if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
635 			X509_free(ca);
636 			goto err;
637 		}
638 	}
639 
640 	/* When the while loop ends, it's usually just EOF. */
641 	err = ERR_peek_last_error();
642 	if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
643 	    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
644 		ERR_clear_error();
645 		ret = 1;
646 	}
647 
648  err:
649 	X509_free(x);
650 
651 	return (ret);
652 }
653 
654 int
655 SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
656 {
657 	BIO *in;
658 	int ret = 0;
659 
660 	in = BIO_new(BIO_s_file_internal());
661 	if (in == NULL) {
662 		SSLerrorx(ERR_R_BUF_LIB);
663 		goto end;
664 	}
665 
666 	if (BIO_read_filename(in, file) <= 0) {
667 		SSLerrorx(ERR_R_SYS_LIB);
668 		goto end;
669 	}
670 
671 	ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
672 
673 end:
674 	BIO_free(in);
675 	return (ret);
676 }
677 
678 int
679 SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
680 {
681 	BIO *in;
682 	int ret = 0;
683 
684 	in = BIO_new_mem_buf(buf, len);
685 	if (in == NULL) {
686 		SSLerrorx(ERR_R_BUF_LIB);
687 		goto end;
688 	}
689 
690 	ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
691 
692 end:
693 	BIO_free(in);
694 	return (ret);
695 }
696