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