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