155714Skris/* ssl/ssl_rsa.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
60109998Smarkm#include "ssl_locl.h"
6155714Skris#include <openssl/bio.h>
6255714Skris#include <openssl/objects.h>
6355714Skris#include <openssl/evp.h>
6455714Skris#include <openssl/x509.h>
6555714Skris#include <openssl/pem.h>
6655714Skris
6755714Skrisstatic int ssl_set_cert(CERT *c, X509 *x509);
6855714Skrisstatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
6955714Skrisint SSL_use_certificate(SSL *ssl, X509 *x)
7055714Skris	{
7155714Skris	if (x == NULL)
7255714Skris		{
7355714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
7455714Skris		return(0);
7555714Skris		}
7655714Skris	if (!ssl_cert_inst(&ssl->cert))
7755714Skris		{
7855714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
7955714Skris		return(0);
8055714Skris		}
8155714Skris	return(ssl_set_cert(ssl->cert,x));
8255714Skris	}
8355714Skris
84109998Smarkm#ifndef OPENSSL_NO_STDIO
8555714Skrisint SSL_use_certificate_file(SSL *ssl, const char *file, int type)
8655714Skris	{
8755714Skris	int j;
8855714Skris	BIO *in;
8955714Skris	int ret=0;
9055714Skris	X509 *x=NULL;
9155714Skris
9255714Skris	in=BIO_new(BIO_s_file_internal());
9355714Skris	if (in == NULL)
9455714Skris		{
9555714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
9655714Skris		goto end;
9755714Skris		}
9855714Skris
9955714Skris	if (BIO_read_filename(in,file) <= 0)
10055714Skris		{
10155714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
10255714Skris		goto end;
10355714Skris		}
10455714Skris	if (type == SSL_FILETYPE_ASN1)
10555714Skris		{
10655714Skris		j=ERR_R_ASN1_LIB;
10755714Skris		x=d2i_X509_bio(in,NULL);
10855714Skris		}
10955714Skris	else if (type == SSL_FILETYPE_PEM)
11055714Skris		{
11155714Skris		j=ERR_R_PEM_LIB;
11255714Skris		x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
11355714Skris		}
11455714Skris	else
11555714Skris		{
11655714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
11755714Skris		goto end;
11855714Skris		}
11955714Skris
12055714Skris	if (x == NULL)
12155714Skris		{
12255714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,j);
12355714Skris		goto end;
12455714Skris		}
12555714Skris
12655714Skris	ret=SSL_use_certificate(ssl,x);
12755714Skrisend:
12855714Skris	if (x != NULL) X509_free(x);
12955714Skris	if (in != NULL) BIO_free(in);
13055714Skris	return(ret);
13155714Skris	}
13255714Skris#endif
13355714Skris
134160814Ssimonint SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
13555714Skris	{
13655714Skris	X509 *x;
13755714Skris	int ret;
13855714Skris
13955714Skris	x=d2i_X509(NULL,&d,(long)len);
14055714Skris	if (x == NULL)
14155714Skris		{
14255714Skris		SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
14355714Skris		return(0);
14455714Skris		}
14555714Skris
14655714Skris	ret=SSL_use_certificate(ssl,x);
14755714Skris	X509_free(x);
14855714Skris	return(ret);
14955714Skris	}
15055714Skris
151109998Smarkm#ifndef OPENSSL_NO_RSA
15255714Skrisint SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
15355714Skris	{
15455714Skris	EVP_PKEY *pkey;
15555714Skris	int ret;
15655714Skris
15755714Skris	if (rsa == NULL)
15855714Skris		{
15955714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
16055714Skris		return(0);
16155714Skris		}
16255714Skris	if (!ssl_cert_inst(&ssl->cert))
16355714Skris		{
16455714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
16555714Skris		return(0);
16655714Skris		}
16755714Skris	if ((pkey=EVP_PKEY_new()) == NULL)
16855714Skris		{
16955714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
17055714Skris		return(0);
17155714Skris		}
17255714Skris
173109998Smarkm	RSA_up_ref(rsa);
17455714Skris	EVP_PKEY_assign_RSA(pkey,rsa);
17555714Skris
17655714Skris	ret=ssl_set_pkey(ssl->cert,pkey);
17755714Skris	EVP_PKEY_free(pkey);
17855714Skris	return(ret);
17955714Skris	}
18055714Skris#endif
18155714Skris
18255714Skrisstatic int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
18355714Skris	{
184160814Ssimon	int i;
18555714Skris
18655714Skris	i=ssl_cert_type(NULL,pkey);
18755714Skris	if (i < 0)
18855714Skris		{
18955714Skris		SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
19055714Skris		return(0);
19155714Skris		}
19255714Skris
19355714Skris	if (c->pkeys[i].x509 != NULL)
19455714Skris		{
19555714Skris		EVP_PKEY *pktmp;
19655714Skris		pktmp =	X509_get_pubkey(c->pkeys[i].x509);
19755714Skris		EVP_PKEY_copy_parameters(pktmp,pkey);
19855714Skris		EVP_PKEY_free(pktmp);
19955714Skris		ERR_clear_error();
20055714Skris
201109998Smarkm#ifndef OPENSSL_NO_RSA
20255714Skris		/* Don't check the public/private key, this is mostly
20355714Skris		 * for smart cards. */
20455714Skris		if ((pkey->type == EVP_PKEY_RSA) &&
205160814Ssimon			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
206160814Ssimon			;
20755714Skris		else
20855714Skris#endif
209160814Ssimon		if (!X509_check_private_key(c->pkeys[i].x509,pkey))
21055714Skris			{
211160814Ssimon			X509_free(c->pkeys[i].x509);
212160814Ssimon			c->pkeys[i].x509 = NULL;
213160814Ssimon			return 0;
21455714Skris			}
21555714Skris		}
21655714Skris
21755714Skris	if (c->pkeys[i].privatekey != NULL)
21855714Skris		EVP_PKEY_free(c->pkeys[i].privatekey);
21955714Skris	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
22055714Skris	c->pkeys[i].privatekey=pkey;
22155714Skris	c->key= &(c->pkeys[i]);
22255714Skris
22355714Skris	c->valid=0;
22455714Skris	return(1);
22555714Skris	}
22655714Skris
227109998Smarkm#ifndef OPENSSL_NO_RSA
228109998Smarkm#ifndef OPENSSL_NO_STDIO
22955714Skrisint SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
23055714Skris	{
23155714Skris	int j,ret=0;
23255714Skris	BIO *in;
23355714Skris	RSA *rsa=NULL;
23455714Skris
23555714Skris	in=BIO_new(BIO_s_file_internal());
23655714Skris	if (in == NULL)
23755714Skris		{
23855714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
23955714Skris		goto end;
24055714Skris		}
24155714Skris
24255714Skris	if (BIO_read_filename(in,file) <= 0)
24355714Skris		{
24455714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
24555714Skris		goto end;
24655714Skris		}
24755714Skris	if	(type == SSL_FILETYPE_ASN1)
24855714Skris		{
24955714Skris		j=ERR_R_ASN1_LIB;
25055714Skris		rsa=d2i_RSAPrivateKey_bio(in,NULL);
25155714Skris		}
25255714Skris	else if (type == SSL_FILETYPE_PEM)
25355714Skris		{
25455714Skris		j=ERR_R_PEM_LIB;
25555714Skris		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
25655714Skris			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
25755714Skris		}
25855714Skris	else
25955714Skris		{
26055714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
26155714Skris		goto end;
26255714Skris		}
26355714Skris	if (rsa == NULL)
26455714Skris		{
26555714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,j);
26655714Skris		goto end;
26755714Skris		}
26855714Skris	ret=SSL_use_RSAPrivateKey(ssl,rsa);
26955714Skris	RSA_free(rsa);
27055714Skrisend:
27155714Skris	if (in != NULL) BIO_free(in);
27255714Skris	return(ret);
27355714Skris	}
27455714Skris#endif
27555714Skris
27655714Skrisint SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len)
27755714Skris	{
27855714Skris	int ret;
279109998Smarkm	const unsigned char *p;
28055714Skris	RSA *rsa;
28155714Skris
28255714Skris	p=d;
28355714Skris	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
28455714Skris		{
28555714Skris		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
28655714Skris		return(0);
28755714Skris		}
28855714Skris
28955714Skris	ret=SSL_use_RSAPrivateKey(ssl,rsa);
29055714Skris	RSA_free(rsa);
29155714Skris	return(ret);
29255714Skris	}
293109998Smarkm#endif /* !OPENSSL_NO_RSA */
29455714Skris
29555714Skrisint SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
29655714Skris	{
29755714Skris	int ret;
29855714Skris
29955714Skris	if (pkey == NULL)
30055714Skris		{
30155714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
30255714Skris		return(0);
30355714Skris		}
30455714Skris	if (!ssl_cert_inst(&ssl->cert))
30555714Skris		{
30655714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
30755714Skris		return(0);
30855714Skris		}
30955714Skris	ret=ssl_set_pkey(ssl->cert,pkey);
31055714Skris	return(ret);
31155714Skris	}
31255714Skris
313109998Smarkm#ifndef OPENSSL_NO_STDIO
31455714Skrisint SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
31555714Skris	{
31655714Skris	int j,ret=0;
31755714Skris	BIO *in;
31855714Skris	EVP_PKEY *pkey=NULL;
31955714Skris
32055714Skris	in=BIO_new(BIO_s_file_internal());
32155714Skris	if (in == NULL)
32255714Skris		{
32355714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
32455714Skris		goto end;
32555714Skris		}
32655714Skris
32755714Skris	if (BIO_read_filename(in,file) <= 0)
32855714Skris		{
32955714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
33055714Skris		goto end;
33155714Skris		}
33255714Skris	if (type == SSL_FILETYPE_PEM)
33355714Skris		{
33455714Skris		j=ERR_R_PEM_LIB;
33555714Skris		pkey=PEM_read_bio_PrivateKey(in,NULL,
33655714Skris			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
33755714Skris		}
338160814Ssimon	else if (type == SSL_FILETYPE_ASN1)
339160814Ssimon		{
340160814Ssimon		j = ERR_R_ASN1_LIB;
341160814Ssimon		pkey = d2i_PrivateKey_bio(in,NULL);
342160814Ssimon		}
34355714Skris	else
34455714Skris		{
34555714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
34655714Skris		goto end;
34755714Skris		}
34855714Skris	if (pkey == NULL)
34955714Skris		{
35055714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,j);
35155714Skris		goto end;
35255714Skris		}
35355714Skris	ret=SSL_use_PrivateKey(ssl,pkey);
35455714Skris	EVP_PKEY_free(pkey);
35555714Skrisend:
35655714Skris	if (in != NULL) BIO_free(in);
35755714Skris	return(ret);
35855714Skris	}
35955714Skris#endif
36055714Skris
361160814Ssimonint SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
36255714Skris	{
36355714Skris	int ret;
364160814Ssimon	const unsigned char *p;
36555714Skris	EVP_PKEY *pkey;
36655714Skris
36755714Skris	p=d;
36855714Skris	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
36955714Skris		{
37055714Skris		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
37155714Skris		return(0);
37255714Skris		}
37355714Skris
37455714Skris	ret=SSL_use_PrivateKey(ssl,pkey);
37555714Skris	EVP_PKEY_free(pkey);
37655714Skris	return(ret);
37755714Skris	}
37855714Skris
37955714Skrisint SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
38055714Skris	{
38155714Skris	if (x == NULL)
38255714Skris		{
38355714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
38455714Skris		return(0);
38555714Skris		}
38655714Skris	if (!ssl_cert_inst(&ctx->cert))
38755714Skris		{
38855714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
38955714Skris		return(0);
39055714Skris		}
39155714Skris	return(ssl_set_cert(ctx->cert, x));
39255714Skris	}
39355714Skris
39455714Skrisstatic int ssl_set_cert(CERT *c, X509 *x)
39555714Skris	{
39655714Skris	EVP_PKEY *pkey;
397160814Ssimon	int i;
39855714Skris
39955714Skris	pkey=X509_get_pubkey(x);
40055714Skris	if (pkey == NULL)
40155714Skris		{
40255714Skris		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB);
40355714Skris		return(0);
40455714Skris		}
40555714Skris
40655714Skris	i=ssl_cert_type(x,pkey);
40755714Skris	if (i < 0)
40855714Skris		{
40955714Skris		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
41055714Skris		EVP_PKEY_free(pkey);
41155714Skris		return(0);
41255714Skris		}
41355714Skris
41455714Skris	if (c->pkeys[i].privatekey != NULL)
41555714Skris		{
41655714Skris		EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey);
41755714Skris		ERR_clear_error();
41855714Skris
419109998Smarkm#ifndef OPENSSL_NO_RSA
42055714Skris		/* Don't check the public/private key, this is mostly
42155714Skris		 * for smart cards. */
42255714Skris		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
42355714Skris			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
42455714Skris			 RSA_METHOD_FLAG_NO_CHECK))
425160814Ssimon			 ;
42655714Skris		else
427160814Ssimon#endif /* OPENSSL_NO_RSA */
42855714Skris		if (!X509_check_private_key(x,c->pkeys[i].privatekey))
42955714Skris			{
430160814Ssimon			/* don't fail for a cert/key mismatch, just free
431160814Ssimon			 * current private key (when switching to a different
432160814Ssimon			 * cert & key, first this function should be used,
433160814Ssimon			 * then ssl_set_pkey */
434160814Ssimon			EVP_PKEY_free(c->pkeys[i].privatekey);
435160814Ssimon			c->pkeys[i].privatekey=NULL;
436160814Ssimon			/* clear error queue */
437160814Ssimon			ERR_clear_error();
43855714Skris			}
43955714Skris		}
44055714Skris
44155714Skris	EVP_PKEY_free(pkey);
44255714Skris
44355714Skris	if (c->pkeys[i].x509 != NULL)
44455714Skris		X509_free(c->pkeys[i].x509);
44555714Skris	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
44655714Skris	c->pkeys[i].x509=x;
44755714Skris	c->key= &(c->pkeys[i]);
44855714Skris
44955714Skris	c->valid=0;
45055714Skris	return(1);
45155714Skris	}
45255714Skris
453109998Smarkm#ifndef OPENSSL_NO_STDIO
45455714Skrisint SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
45555714Skris	{
45655714Skris	int j;
45755714Skris	BIO *in;
45855714Skris	int ret=0;
45955714Skris	X509 *x=NULL;
46055714Skris
46155714Skris	in=BIO_new(BIO_s_file_internal());
46255714Skris	if (in == NULL)
46355714Skris		{
46455714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
46555714Skris		goto end;
46655714Skris		}
46755714Skris
46855714Skris	if (BIO_read_filename(in,file) <= 0)
46955714Skris		{
47055714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
47155714Skris		goto end;
47255714Skris		}
47355714Skris	if (type == SSL_FILETYPE_ASN1)
47455714Skris		{
47555714Skris		j=ERR_R_ASN1_LIB;
47655714Skris		x=d2i_X509_bio(in,NULL);
47755714Skris		}
47855714Skris	else if (type == SSL_FILETYPE_PEM)
47955714Skris		{
48055714Skris		j=ERR_R_PEM_LIB;
48155714Skris		x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
48255714Skris		}
48355714Skris	else
48455714Skris		{
48555714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
48655714Skris		goto end;
48755714Skris		}
48855714Skris
48955714Skris	if (x == NULL)
49055714Skris		{
49155714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j);
49255714Skris		goto end;
49355714Skris		}
49455714Skris
49555714Skris	ret=SSL_CTX_use_certificate(ctx,x);
49655714Skrisend:
49755714Skris	if (x != NULL) X509_free(x);
49855714Skris	if (in != NULL) BIO_free(in);
49955714Skris	return(ret);
50055714Skris	}
50155714Skris#endif
50255714Skris
503160814Ssimonint SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
50455714Skris	{
50555714Skris	X509 *x;
50655714Skris	int ret;
50755714Skris
50855714Skris	x=d2i_X509(NULL,&d,(long)len);
50955714Skris	if (x == NULL)
51055714Skris		{
51155714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
51255714Skris		return(0);
51355714Skris		}
51455714Skris
51555714Skris	ret=SSL_CTX_use_certificate(ctx,x);
51655714Skris	X509_free(x);
51755714Skris	return(ret);
51855714Skris	}
51955714Skris
520109998Smarkm#ifndef OPENSSL_NO_RSA
52155714Skrisint SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
52255714Skris	{
52355714Skris	int ret;
52455714Skris	EVP_PKEY *pkey;
52555714Skris
52655714Skris	if (rsa == NULL)
52755714Skris		{
52855714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
52955714Skris		return(0);
53055714Skris		}
53155714Skris	if (!ssl_cert_inst(&ctx->cert))
53255714Skris		{
53355714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
53455714Skris		return(0);
53555714Skris		}
53655714Skris	if ((pkey=EVP_PKEY_new()) == NULL)
53755714Skris		{
53855714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
53955714Skris		return(0);
54055714Skris		}
54155714Skris
542109998Smarkm	RSA_up_ref(rsa);
54355714Skris	EVP_PKEY_assign_RSA(pkey,rsa);
54455714Skris
54555714Skris	ret=ssl_set_pkey(ctx->cert, pkey);
54655714Skris	EVP_PKEY_free(pkey);
54755714Skris	return(ret);
54855714Skris	}
54955714Skris
550109998Smarkm#ifndef OPENSSL_NO_STDIO
55155714Skrisint SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
55255714Skris	{
55355714Skris	int j,ret=0;
55455714Skris	BIO *in;
55555714Skris	RSA *rsa=NULL;
55655714Skris
55755714Skris	in=BIO_new(BIO_s_file_internal());
55855714Skris	if (in == NULL)
55955714Skris		{
56055714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
56155714Skris		goto end;
56255714Skris		}
56355714Skris
56455714Skris	if (BIO_read_filename(in,file) <= 0)
56555714Skris		{
56655714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
56755714Skris		goto end;
56855714Skris		}
56955714Skris	if	(type == SSL_FILETYPE_ASN1)
57055714Skris		{
57155714Skris		j=ERR_R_ASN1_LIB;
57255714Skris		rsa=d2i_RSAPrivateKey_bio(in,NULL);
57355714Skris		}
57455714Skris	else if (type == SSL_FILETYPE_PEM)
57555714Skris		{
57655714Skris		j=ERR_R_PEM_LIB;
57755714Skris		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
57855714Skris			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
57955714Skris		}
58055714Skris	else
58155714Skris		{
58255714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
58355714Skris		goto end;
58455714Skris		}
58555714Skris	if (rsa == NULL)
58655714Skris		{
58755714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,j);
58855714Skris		goto end;
58955714Skris		}
59055714Skris	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
59155714Skris	RSA_free(rsa);
59255714Skrisend:
59355714Skris	if (in != NULL) BIO_free(in);
59455714Skris	return(ret);
59555714Skris	}
59655714Skris#endif
59755714Skris
598160814Ssimonint SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
59955714Skris	{
60055714Skris	int ret;
601109998Smarkm	const unsigned char *p;
60255714Skris	RSA *rsa;
60355714Skris
60455714Skris	p=d;
60555714Skris	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
60655714Skris		{
60755714Skris		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
60855714Skris		return(0);
60955714Skris		}
61055714Skris
61155714Skris	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
61255714Skris	RSA_free(rsa);
61355714Skris	return(ret);
61455714Skris	}
615109998Smarkm#endif /* !OPENSSL_NO_RSA */
61655714Skris
61755714Skrisint SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
61855714Skris	{
61955714Skris	if (pkey == NULL)
62055714Skris		{
62155714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
62255714Skris		return(0);
62355714Skris		}
62455714Skris	if (!ssl_cert_inst(&ctx->cert))
62555714Skris		{
62655714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
62755714Skris		return(0);
62855714Skris		}
62955714Skris	return(ssl_set_pkey(ctx->cert,pkey));
63055714Skris	}
63155714Skris
632109998Smarkm#ifndef OPENSSL_NO_STDIO
63355714Skrisint SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
63455714Skris	{
63555714Skris	int j,ret=0;
63655714Skris	BIO *in;
63755714Skris	EVP_PKEY *pkey=NULL;
63855714Skris
63955714Skris	in=BIO_new(BIO_s_file_internal());
64055714Skris	if (in == NULL)
64155714Skris		{
64255714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
64355714Skris		goto end;
64455714Skris		}
64555714Skris
64655714Skris	if (BIO_read_filename(in,file) <= 0)
64755714Skris		{
64855714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
64955714Skris		goto end;
65055714Skris		}
65155714Skris	if (type == SSL_FILETYPE_PEM)
65255714Skris		{
65355714Skris		j=ERR_R_PEM_LIB;
65455714Skris		pkey=PEM_read_bio_PrivateKey(in,NULL,
65555714Skris			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
65655714Skris		}
657160814Ssimon	else if (type == SSL_FILETYPE_ASN1)
658160814Ssimon		{
659160814Ssimon		j = ERR_R_ASN1_LIB;
660160814Ssimon		pkey = d2i_PrivateKey_bio(in,NULL);
661160814Ssimon		}
66255714Skris	else
66355714Skris		{
66455714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
66555714Skris		goto end;
66655714Skris		}
66755714Skris	if (pkey == NULL)
66855714Skris		{
66955714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,j);
67055714Skris		goto end;
67155714Skris		}
67255714Skris	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
67355714Skris	EVP_PKEY_free(pkey);
67455714Skrisend:
67555714Skris	if (in != NULL) BIO_free(in);
67655714Skris	return(ret);
67755714Skris	}
67855714Skris#endif
67955714Skris
680160814Ssimonint SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
68155714Skris	     long len)
68255714Skris	{
68355714Skris	int ret;
684160814Ssimon	const unsigned char *p;
68555714Skris	EVP_PKEY *pkey;
68655714Skris
68755714Skris	p=d;
68855714Skris	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
68955714Skris		{
69055714Skris		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
69155714Skris		return(0);
69255714Skris		}
69355714Skris
69455714Skris	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
69555714Skris	EVP_PKEY_free(pkey);
69655714Skris	return(ret);
69755714Skris	}
69855714Skris
69955714Skris
700109998Smarkm#ifndef OPENSSL_NO_STDIO
70155714Skris/* Read a file that contains our certificate in "PEM" format,
70255714Skris * possibly followed by a sequence of CA certificates that should be
70355714Skris * sent to the peer in the Certificate message.
70455714Skris */
70555714Skrisint SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
70655714Skris	{
70755714Skris	BIO *in;
70855714Skris	int ret=0;
70955714Skris	X509 *x=NULL;
71055714Skris
711194206Ssimon	ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
712194206Ssimon
713246772Sjkim	in = BIO_new(BIO_s_file_internal());
71455714Skris	if (in == NULL)
71555714Skris		{
71655714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
71755714Skris		goto end;
71855714Skris		}
71955714Skris
72055714Skris	if (BIO_read_filename(in,file) <= 0)
72155714Skris		{
72255714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB);
72355714Skris		goto end;
72455714Skris		}
72555714Skris
726246772Sjkim	x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
727246772Sjkim				ctx->default_passwd_callback_userdata);
72855714Skris	if (x == NULL)
72955714Skris		{
73055714Skris		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
73155714Skris		goto end;
73255714Skris		}
73355714Skris
734246772Sjkim	ret = SSL_CTX_use_certificate(ctx, x);
735246772Sjkim
73655714Skris	if (ERR_peek_error() != 0)
73755714Skris		ret = 0;  /* Key/certificate mismatch doesn't imply ret==0 ... */
73855714Skris	if (ret)
73955714Skris		{
74055714Skris		/* If we could set up our certificate, now proceed to
74155714Skris		 * the CA certificates.
74255714Skris		 */
74355714Skris		X509 *ca;
74455714Skris		int r;
74555714Skris		unsigned long err;
74655714Skris
747246772Sjkim		if (ctx->extra_certs != NULL)
74855714Skris			{
74955714Skris			sk_X509_pop_free(ctx->extra_certs, X509_free);
75055714Skris			ctx->extra_certs = NULL;
75155714Skris			}
75255714Skris
753246772Sjkim		while ((ca = PEM_read_bio_X509(in, NULL,
754246772Sjkim					ctx->default_passwd_callback,
755246772Sjkim					ctx->default_passwd_callback_userdata))
75655714Skris			!= NULL)
75755714Skris			{
75855714Skris			r = SSL_CTX_add_extra_chain_cert(ctx, ca);
75955714Skris			if (!r)
76055714Skris				{
76155714Skris				X509_free(ca);
76255714Skris				ret = 0;
76355714Skris				goto end;
76455714Skris				}
76555714Skris			/* Note that we must not free r if it was successfully
76655714Skris			 * added to the chain (while we must free the main
76755714Skris			 * certificate, since its reference count is increased
76855714Skris			 * by SSL_CTX_use_certificate). */
76955714Skris			}
77055714Skris		/* When the while loop ends, it's usually just EOF. */
771109998Smarkm		err = ERR_peek_last_error();
77255714Skris		if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
773160814Ssimon			ERR_clear_error();
77455714Skris		else
77555714Skris			ret = 0; /* some real error */
77655714Skris		}
77755714Skris
77855714Skrisend:
77955714Skris	if (x != NULL) X509_free(x);
78055714Skris	if (in != NULL) BIO_free(in);
78155714Skris	return(ret);
78255714Skris	}
78355714Skris#endif
784