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