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