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