ssl_cert.c revision 215697
155714Skris/*! \file ssl/ssl_cert.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/* ====================================================================
59162911Ssimon * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
6055714Skris *
6155714Skris * Redistribution and use in source and binary forms, with or without
6255714Skris * modification, are permitted provided that the following conditions
6355714Skris * are met:
6455714Skris *
6555714Skris * 1. Redistributions of source code must retain the above copyright
6655714Skris *    notice, this list of conditions and the following disclaimer.
6755714Skris *
6855714Skris * 2. Redistributions in binary form must reproduce the above copyright
6955714Skris *    notice, this list of conditions and the following disclaimer in
7055714Skris *    the documentation and/or other materials provided with the
7155714Skris *    distribution.
7255714Skris *
7355714Skris * 3. All advertising materials mentioning features or use of this
7455714Skris *    software must display the following acknowledgment:
7555714Skris *    "This product includes software developed by the OpenSSL Project
76162911Ssimon *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7755714Skris *
7855714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
7955714Skris *    endorse or promote products derived from this software without
8055714Skris *    prior written permission. For written permission, please contact
81162911Ssimon *    openssl-core@openssl.org.
8255714Skris *
8355714Skris * 5. Products derived from this software may not be called "OpenSSL"
8455714Skris *    nor may "OpenSSL" appear in their names without prior written
8555714Skris *    permission of the OpenSSL Project.
8655714Skris *
8755714Skris * 6. Redistributions of any form whatsoever must retain the following
8855714Skris *    acknowledgment:
8955714Skris *    "This product includes software developed by the OpenSSL Project
90162911Ssimon *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9155714Skris *
9255714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9355714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9455714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9555714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9655714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9755714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9855714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9955714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10055714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10155714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10255714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10355714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
10455714Skris * ====================================================================
105162911Ssimon *
106162911Ssimon * This product includes cryptographic software written by Eric Young
107162911Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
108162911Ssimon * Hudson (tjh@cryptsoft.com).
109162911Ssimon *
11055714Skris */
111160814Ssimon/* ====================================================================
112160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113160814Ssimon * ECC cipher suite support in OpenSSL originally developed by
114160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115160814Ssimon */
11655714Skris
11755714Skris#include <stdio.h>
11859191Skris
119109998Smarkm#include "e_os.h"
12059191Skris#ifndef NO_SYS_TYPES_H
12159191Skris# include <sys/types.h>
12259191Skris#endif
12359191Skris
124160814Ssimon#include "o_dir.h"
12555714Skris#include <openssl/objects.h>
12655714Skris#include <openssl/bio.h>
12755714Skris#include <openssl/pem.h>
12859191Skris#include <openssl/x509v3.h>
129160814Ssimon#ifndef OPENSSL_NO_DH
130160814Ssimon#include <openssl/dh.h>
131160814Ssimon#endif
132160814Ssimon#include <openssl/bn.h>
13355714Skris#include "ssl_locl.h"
13455714Skris
13555714Skrisint SSL_get_ex_data_X509_STORE_CTX_idx(void)
13655714Skris	{
137109998Smarkm	static volatile int ssl_x509_store_ctx_idx= -1;
138162911Ssimon	int got_write_lock = 0;
13955714Skris
140162911Ssimon	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
141162911Ssimon
14255714Skris	if (ssl_x509_store_ctx_idx < 0)
14355714Skris		{
144162911Ssimon		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
145109998Smarkm		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
146162911Ssimon		got_write_lock = 1;
147109998Smarkm
148109998Smarkm		if (ssl_x509_store_ctx_idx < 0)
149109998Smarkm			{
150109998Smarkm			ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
151109998Smarkm				0,"SSL for verify callback",NULL,NULL,NULL);
152109998Smarkm			}
153162911Ssimon		}
154162911Ssimon
155162911Ssimon	if (got_write_lock)
156109998Smarkm		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
157162911Ssimon	else
158162911Ssimon		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
159162911Ssimon
160109998Smarkm	return ssl_x509_store_ctx_idx;
16155714Skris	}
16255714Skris
16355714SkrisCERT *ssl_cert_new(void)
16455714Skris	{
16555714Skris	CERT *ret;
16655714Skris
16768651Skris	ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
16855714Skris	if (ret == NULL)
16955714Skris		{
17055714Skris		SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
17155714Skris		return(NULL);
17255714Skris		}
17355714Skris	memset(ret,0,sizeof(CERT));
17455714Skris
17555714Skris	ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
17655714Skris	ret->references=1;
17755714Skris
17855714Skris	return(ret);
17955714Skris	}
18055714Skris
18155714SkrisCERT *ssl_cert_dup(CERT *cert)
18255714Skris	{
18355714Skris	CERT *ret;
18455714Skris	int i;
18555714Skris
18668651Skris	ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
18755714Skris	if (ret == NULL)
18855714Skris		{
18955714Skris		SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
19055714Skris		return(NULL);
19155714Skris		}
19255714Skris
19355714Skris	memset(ret, 0, sizeof(CERT));
19455714Skris
19555714Skris	ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
19655714Skris	/* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
19755714Skris	 * if you find that more readable */
19855714Skris
19955714Skris	ret->valid = cert->valid;
20055714Skris	ret->mask = cert->mask;
20155714Skris	ret->export_mask = cert->export_mask;
20255714Skris
203109998Smarkm#ifndef OPENSSL_NO_RSA
20455714Skris	if (cert->rsa_tmp != NULL)
20555714Skris		{
206109998Smarkm		RSA_up_ref(cert->rsa_tmp);
20755714Skris		ret->rsa_tmp = cert->rsa_tmp;
20855714Skris		}
20955714Skris	ret->rsa_tmp_cb = cert->rsa_tmp_cb;
21055714Skris#endif
21155714Skris
212109998Smarkm#ifndef OPENSSL_NO_DH
21355714Skris	if (cert->dh_tmp != NULL)
21455714Skris		{
21555714Skris		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
21655714Skris		if (ret->dh_tmp == NULL)
21755714Skris			{
21859191Skris			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
21955714Skris			goto err;
22055714Skris			}
22159191Skris		if (cert->dh_tmp->priv_key)
22259191Skris			{
22359191Skris			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
22459191Skris			if (!b)
22559191Skris				{
22659191Skris				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
22759191Skris				goto err;
22859191Skris				}
22959191Skris			ret->dh_tmp->priv_key = b;
23059191Skris			}
23159191Skris		if (cert->dh_tmp->pub_key)
23259191Skris			{
23359191Skris			BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
23459191Skris			if (!b)
23559191Skris				{
23659191Skris				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
23759191Skris				goto err;
23859191Skris				}
23959191Skris			ret->dh_tmp->pub_key = b;
24059191Skris			}
24155714Skris		}
24255714Skris	ret->dh_tmp_cb = cert->dh_tmp_cb;
24355714Skris#endif
24455714Skris
245160814Ssimon#ifndef OPENSSL_NO_ECDH
246160814Ssimon	if (cert->ecdh_tmp)
247160814Ssimon		{
248160814Ssimon		ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
249160814Ssimon		if (ret->ecdh_tmp == NULL)
250160814Ssimon			{
251160814Ssimon			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
252160814Ssimon			goto err;
253160814Ssimon			}
254160814Ssimon		}
255160814Ssimon	ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
256160814Ssimon#endif
257160814Ssimon
25855714Skris	for (i = 0; i < SSL_PKEY_NUM; i++)
25955714Skris		{
26055714Skris		if (cert->pkeys[i].x509 != NULL)
26155714Skris			{
26255714Skris			ret->pkeys[i].x509 = cert->pkeys[i].x509;
26355714Skris			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
26455714Skris				CRYPTO_LOCK_X509);
26555714Skris			}
26655714Skris
26755714Skris		if (cert->pkeys[i].privatekey != NULL)
26855714Skris			{
26955714Skris			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
27055714Skris			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
27155714Skris				CRYPTO_LOCK_EVP_PKEY);
27255714Skris
27355714Skris			switch(i)
27455714Skris				{
27555714Skris				/* If there was anything special to do for
27655714Skris				 * certain types of keys, we'd do it here.
27755714Skris				 * (Nothing at the moment, I think.) */
27855714Skris
27955714Skris			case SSL_PKEY_RSA_ENC:
28055714Skris			case SSL_PKEY_RSA_SIGN:
28155714Skris				/* We have an RSA key. */
28255714Skris				break;
28355714Skris
28455714Skris			case SSL_PKEY_DSA_SIGN:
28555714Skris				/* We have a DSA key. */
28655714Skris				break;
28755714Skris
28855714Skris			case SSL_PKEY_DH_RSA:
28955714Skris			case SSL_PKEY_DH_DSA:
29055714Skris				/* We have a DH key. */
29155714Skris				break;
292160814Ssimon
293160814Ssimon			case SSL_PKEY_ECC:
294160814Ssimon				/* We have an ECC key */
295160814Ssimon				break;
296160814Ssimon
29755714Skris			default:
29855714Skris				/* Can't happen. */
29955714Skris				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
30055714Skris				}
30155714Skris			}
30255714Skris		}
30355714Skris
30455714Skris	/* ret->extra_certs *should* exist, but currently the own certificate
30555714Skris	 * chain is held inside SSL_CTX */
30655714Skris
30755714Skris	ret->references=1;
30855714Skris
30955714Skris	return(ret);
31055714Skris
311160814Ssimon#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
31255714Skriserr:
31376866Skris#endif
314109998Smarkm#ifndef OPENSSL_NO_RSA
31555714Skris	if (ret->rsa_tmp != NULL)
31655714Skris		RSA_free(ret->rsa_tmp);
31755714Skris#endif
318109998Smarkm#ifndef OPENSSL_NO_DH
31955714Skris	if (ret->dh_tmp != NULL)
32055714Skris		DH_free(ret->dh_tmp);
32155714Skris#endif
322160814Ssimon#ifndef OPENSSL_NO_ECDH
323160814Ssimon	if (ret->ecdh_tmp != NULL)
324160814Ssimon		EC_KEY_free(ret->ecdh_tmp);
325160814Ssimon#endif
32655714Skris
32755714Skris	for (i = 0; i < SSL_PKEY_NUM; i++)
32855714Skris		{
32955714Skris		if (ret->pkeys[i].x509 != NULL)
33055714Skris			X509_free(ret->pkeys[i].x509);
33155714Skris		if (ret->pkeys[i].privatekey != NULL)
33255714Skris			EVP_PKEY_free(ret->pkeys[i].privatekey);
33355714Skris		}
33455714Skris
33555714Skris	return NULL;
33655714Skris	}
33755714Skris
33855714Skris
33955714Skrisvoid ssl_cert_free(CERT *c)
34055714Skris	{
34155714Skris	int i;
34255714Skris
34355714Skris	if(c == NULL)
34455714Skris	    return;
34555714Skris
34655714Skris	i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
34755714Skris#ifdef REF_PRINT
34855714Skris	REF_PRINT("CERT",c);
34955714Skris#endif
35055714Skris	if (i > 0) return;
35155714Skris#ifdef REF_CHECK
35255714Skris	if (i < 0)
35355714Skris		{
35455714Skris		fprintf(stderr,"ssl_cert_free, bad reference count\n");
35555714Skris		abort(); /* ok */
35655714Skris		}
35755714Skris#endif
35855714Skris
359109998Smarkm#ifndef OPENSSL_NO_RSA
36055714Skris	if (c->rsa_tmp) RSA_free(c->rsa_tmp);
36155714Skris#endif
362109998Smarkm#ifndef OPENSSL_NO_DH
36355714Skris	if (c->dh_tmp) DH_free(c->dh_tmp);
36455714Skris#endif
365160814Ssimon#ifndef OPENSSL_NO_ECDH
366160814Ssimon	if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
367160814Ssimon#endif
36855714Skris
36955714Skris	for (i=0; i<SSL_PKEY_NUM; i++)
37055714Skris		{
37155714Skris		if (c->pkeys[i].x509 != NULL)
37255714Skris			X509_free(c->pkeys[i].x509);
37355714Skris		if (c->pkeys[i].privatekey != NULL)
37455714Skris			EVP_PKEY_free(c->pkeys[i].privatekey);
37555714Skris#if 0
37655714Skris		if (c->pkeys[i].publickey != NULL)
37755714Skris			EVP_PKEY_free(c->pkeys[i].publickey);
37855714Skris#endif
37955714Skris		}
38068651Skris	OPENSSL_free(c);
38155714Skris	}
38255714Skris
38355714Skrisint ssl_cert_inst(CERT **o)
38455714Skris	{
38555714Skris	/* Create a CERT if there isn't already one
38655714Skris	 * (which cannot really happen, as it is initially created in
38755714Skris	 * SSL_CTX_new; but the earlier code usually allows for that one
38855714Skris	 * being non-existant, so we follow that behaviour, as it might
38955714Skris	 * turn out that there actually is a reason for it -- but I'm
39055714Skris	 * not sure that *all* of the existing code could cope with
39155714Skris	 * s->cert being NULL, otherwise we could do without the
39255714Skris	 * initialization in SSL_CTX_new).
39355714Skris	 */
39455714Skris
39555714Skris	if (o == NULL)
39655714Skris		{
39755714Skris		SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
39855714Skris		return(0);
39955714Skris		}
40055714Skris	if (*o == NULL)
40155714Skris		{
40255714Skris		if ((*o = ssl_cert_new()) == NULL)
40355714Skris			{
40455714Skris			SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
40555714Skris			return(0);
40655714Skris			}
40755714Skris		}
40855714Skris	return(1);
40955714Skris	}
41055714Skris
41155714Skris
41255714SkrisSESS_CERT *ssl_sess_cert_new(void)
41355714Skris	{
41455714Skris	SESS_CERT *ret;
41555714Skris
41668651Skris	ret = OPENSSL_malloc(sizeof *ret);
41755714Skris	if (ret == NULL)
41855714Skris		{
41955714Skris		SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
42055714Skris		return NULL;
42155714Skris		}
42255714Skris
42355714Skris	memset(ret, 0 ,sizeof *ret);
42455714Skris	ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
42555714Skris	ret->references = 1;
42655714Skris
42755714Skris	return ret;
42855714Skris	}
42955714Skris
43055714Skrisvoid ssl_sess_cert_free(SESS_CERT *sc)
43155714Skris	{
43255714Skris	int i;
43355714Skris
43455714Skris	if (sc == NULL)
43555714Skris		return;
43655714Skris
43755714Skris	i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
43855714Skris#ifdef REF_PRINT
43955714Skris	REF_PRINT("SESS_CERT", sc);
44055714Skris#endif
44155714Skris	if (i > 0)
44255714Skris		return;
44355714Skris#ifdef REF_CHECK
44455714Skris	if (i < 0)
44555714Skris		{
44655714Skris		fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
44755714Skris		abort(); /* ok */
44855714Skris		}
44955714Skris#endif
45055714Skris
45155714Skris	/* i == 0 */
45255714Skris	if (sc->cert_chain != NULL)
45355714Skris		sk_X509_pop_free(sc->cert_chain, X509_free);
45455714Skris	for (i = 0; i < SSL_PKEY_NUM; i++)
45555714Skris		{
45655714Skris		if (sc->peer_pkeys[i].x509 != NULL)
45755714Skris			X509_free(sc->peer_pkeys[i].x509);
45855714Skris#if 0 /* We don't have the peer's private key.  These lines are just
45955714Skris	   * here as a reminder that we're still using a not-quite-appropriate
46055714Skris	   * data structure. */
46155714Skris		if (sc->peer_pkeys[i].privatekey != NULL)
46255714Skris			EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
46355714Skris#endif
46455714Skris		}
46555714Skris
466109998Smarkm#ifndef OPENSSL_NO_RSA
46755714Skris	if (sc->peer_rsa_tmp != NULL)
46855714Skris		RSA_free(sc->peer_rsa_tmp);
46955714Skris#endif
470109998Smarkm#ifndef OPENSSL_NO_DH
47155714Skris	if (sc->peer_dh_tmp != NULL)
47255714Skris		DH_free(sc->peer_dh_tmp);
47355714Skris#endif
474160814Ssimon#ifndef OPENSSL_NO_ECDH
475160814Ssimon	if (sc->peer_ecdh_tmp != NULL)
476160814Ssimon		EC_KEY_free(sc->peer_ecdh_tmp);
477160814Ssimon#endif
47855714Skris
47968651Skris	OPENSSL_free(sc);
48055714Skris	}
48155714Skris
48255714Skrisint ssl_set_peer_cert_type(SESS_CERT *sc,int type)
48355714Skris	{
48455714Skris	sc->peer_cert_type = type;
48555714Skris	return(1);
48655714Skris	}
48755714Skris
48855714Skrisint ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
48955714Skris	{
49055714Skris	X509 *x;
49155714Skris	int i;
49255714Skris	X509_STORE_CTX ctx;
49355714Skris
49455714Skris	if ((sk == NULL) || (sk_X509_num(sk) == 0))
49555714Skris		return(0);
49655714Skris
49755714Skris	x=sk_X509_value(sk,0);
498109998Smarkm	if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
499109998Smarkm		{
500109998Smarkm		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
501109998Smarkm		return(0);
502109998Smarkm		}
503160814Ssimon#if 0
50455714Skris	if (SSL_get_verify_depth(s) >= 0)
50555714Skris		X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
506160814Ssimon#endif
50759191Skris	X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
508109998Smarkm
509160814Ssimon	/* We need to inherit the verify parameters. These can be determined by
51059191Skris	 * the context: if its a server it will verify SSL client certificates
51159191Skris	 * or vice versa.
512109998Smarkm	 */
51355714Skris
514160814Ssimon	X509_STORE_CTX_set_default(&ctx,
515160814Ssimon				s->server ? "ssl_client" : "ssl_server");
516205128Ssimon	/* Anything non-default in "param" should overwrite anything in the
517205128Ssimon	 * ctx.
518205128Ssimon	 */
519205128Ssimon	X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
52059191Skris
52189837Skris	if (s->verify_callback)
52289837Skris		X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
52389837Skris
52455714Skris	if (s->ctx->app_verify_callback != NULL)
525109998Smarkm#if 1 /* new with OpenSSL 0.9.7 */
526109998Smarkm		i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
527109998Smarkm#else
52855714Skris		i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
529109998Smarkm#endif
53055714Skris	else
53155714Skris		{
532109998Smarkm#ifndef OPENSSL_NO_X509_VERIFY
53355714Skris		i=X509_verify_cert(&ctx);
53455714Skris#else
53555714Skris		i=0;
53655714Skris		ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
53755714Skris		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
53855714Skris#endif
53955714Skris		}
54055714Skris
54155714Skris	s->verify_result=ctx.error;
54255714Skris	X509_STORE_CTX_cleanup(&ctx);
54355714Skris
54455714Skris	return(i);
54555714Skris	}
54655714Skris
547127128Snectarstatic void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
54855714Skris	{
54955714Skris	if (*ca_list != NULL)
55055714Skris		sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
55155714Skris
552127128Snectar	*ca_list=name_list;
55355714Skris	}
55455714Skris
55555714SkrisSTACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
55655714Skris	{
55755714Skris	int i;
55855714Skris	STACK_OF(X509_NAME) *ret;
55955714Skris	X509_NAME *name;
56055714Skris
56155714Skris	ret=sk_X509_NAME_new_null();
56255714Skris	for (i=0; i<sk_X509_NAME_num(sk); i++)
56355714Skris		{
56455714Skris		name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
56555714Skris		if ((name == NULL) || !sk_X509_NAME_push(ret,name))
56655714Skris			{
56755714Skris			sk_X509_NAME_pop_free(ret,X509_NAME_free);
56855714Skris			return(NULL);
56955714Skris			}
57055714Skris		}
57155714Skris	return(ret);
57255714Skris	}
57355714Skris
574127128Snectarvoid SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
57555714Skris	{
576127128Snectar	set_client_CA_list(&(s->client_CA),name_list);
57755714Skris	}
57855714Skris
579127128Snectarvoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
58055714Skris	{
581127128Snectar	set_client_CA_list(&(ctx->client_CA),name_list);
58255714Skris	}
58355714Skris
584160814SsimonSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
58555714Skris	{
58655714Skris	return(ctx->client_CA);
58755714Skris	}
58855714Skris
589160814SsimonSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
59055714Skris	{
59155714Skris	if (s->type == SSL_ST_CONNECT)
59255714Skris		{ /* we are in the client */
59355714Skris		if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
59455714Skris			(s->s3 != NULL))
59555714Skris			return(s->s3->tmp.ca_names);
59655714Skris		else
59755714Skris			return(NULL);
59855714Skris		}
59955714Skris	else
60055714Skris		{
60155714Skris		if (s->client_CA != NULL)
60255714Skris			return(s->client_CA);
60355714Skris		else
60455714Skris			return(s->ctx->client_CA);
60555714Skris		}
60655714Skris	}
60755714Skris
60855714Skrisstatic int add_client_CA(STACK_OF(X509_NAME) **sk,X509 *x)
60955714Skris	{
61055714Skris	X509_NAME *name;
61155714Skris
61255714Skris	if (x == NULL) return(0);
61355714Skris	if ((*sk == NULL) && ((*sk=sk_X509_NAME_new_null()) == NULL))
61455714Skris		return(0);
61555714Skris
61655714Skris	if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
61755714Skris		return(0);
61855714Skris
61955714Skris	if (!sk_X509_NAME_push(*sk,name))
62055714Skris		{
62155714Skris		X509_NAME_free(name);
62255714Skris		return(0);
62355714Skris		}
62455714Skris	return(1);
62555714Skris	}
62655714Skris
62755714Skrisint SSL_add_client_CA(SSL *ssl,X509 *x)
62855714Skris	{
62955714Skris	return(add_client_CA(&(ssl->client_CA),x));
63055714Skris	}
63155714Skris
63255714Skrisint SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
63355714Skris	{
63455714Skris	return(add_client_CA(&(ctx->client_CA),x));
63555714Skris	}
63655714Skris
63768651Skrisstatic int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
63855714Skris	{
63955714Skris	return(X509_NAME_cmp(*a,*b));
64055714Skris	}
64155714Skris
642109998Smarkm#ifndef OPENSSL_NO_STDIO
64355714Skris/*!
64455714Skris * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
64555714Skris * it doesn't really have anything to do with clients (except that a common use
64655714Skris * for a stack of CAs is to send it to the client). Actually, it doesn't have
64755714Skris * much to do with CAs, either, since it will load any old cert.
64855714Skris * \param file the file containing one or more certs.
64955714Skris * \return a ::STACK containing the certs.
65055714Skris */
65155714SkrisSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
65255714Skris	{
65355714Skris	BIO *in;
65455714Skris	X509 *x=NULL;
65555714Skris	X509_NAME *xn=NULL;
656160814Ssimon	STACK_OF(X509_NAME) *ret = NULL,*sk;
65755714Skris
65859191Skris	sk=sk_X509_NAME_new(xname_cmp);
65955714Skris
66055714Skris	in=BIO_new(BIO_s_file_internal());
66155714Skris
662160814Ssimon	if ((sk == NULL) || (in == NULL))
66355714Skris		{
66455714Skris		SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
66555714Skris		goto err;
66655714Skris		}
66755714Skris
66855714Skris	if (!BIO_read_filename(in,file))
66955714Skris		goto err;
67055714Skris
67155714Skris	for (;;)
67255714Skris		{
67355714Skris		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
67455714Skris			break;
675160814Ssimon		if (ret == NULL)
676160814Ssimon			{
677160814Ssimon			ret = sk_X509_NAME_new_null();
678160814Ssimon			if (ret == NULL)
679160814Ssimon				{
680160814Ssimon				SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
681160814Ssimon				goto err;
682160814Ssimon				}
683160814Ssimon			}
68455714Skris		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
68555714Skris		/* check for duplicates */
68655714Skris		xn=X509_NAME_dup(xn);
68755714Skris		if (xn == NULL) goto err;
68855714Skris		if (sk_X509_NAME_find(sk,xn) >= 0)
68955714Skris			X509_NAME_free(xn);
69055714Skris		else
69155714Skris			{
69255714Skris			sk_X509_NAME_push(sk,xn);
69355714Skris			sk_X509_NAME_push(ret,xn);
69455714Skris			}
69555714Skris		}
69655714Skris
69755714Skris	if (0)
69855714Skris		{
69955714Skriserr:
70055714Skris		if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
70155714Skris		ret=NULL;
70255714Skris		}
70355714Skris	if (sk != NULL) sk_X509_NAME_free(sk);
70455714Skris	if (in != NULL) BIO_free(in);
70555714Skris	if (x != NULL) X509_free(x);
706160814Ssimon	if (ret != NULL)
707160814Ssimon		ERR_clear_error();
70855714Skris	return(ret);
70955714Skris	}
71055714Skris#endif
71155714Skris
71255714Skris/*!
71355714Skris * Add a file of certs to a stack.
71455714Skris * \param stack the stack to add to.
71555714Skris * \param file the file to add from. All certs in this file that are not
71655714Skris * already in the stack will be added.
71755714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
71855714Skris * certs may have been added to \c stack.
71955714Skris */
72055714Skris
72155714Skrisint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
72255714Skris					const char *file)
72355714Skris	{
72468651Skris	BIO *in;
72568651Skris	X509 *x=NULL;
72668651Skris	X509_NAME *xn=NULL;
72768651Skris	int ret=1;
72868651Skris	int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
72955714Skris
73068651Skris	oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp);
73168651Skris
73268651Skris	in=BIO_new(BIO_s_file_internal());
73368651Skris
73468651Skris	if (in == NULL)
73568651Skris		{
73668651Skris		SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
73768651Skris		goto err;
73868651Skris		}
73968651Skris
74068651Skris	if (!BIO_read_filename(in,file))
74168651Skris		goto err;
74268651Skris
74368651Skris	for (;;)
74468651Skris		{
74568651Skris		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
74668651Skris			break;
74768651Skris		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
74868651Skris		xn=X509_NAME_dup(xn);
74968651Skris		if (xn == NULL) goto err;
75068651Skris		if (sk_X509_NAME_find(stack,xn) >= 0)
75168651Skris			X509_NAME_free(xn);
75268651Skris		else
75368651Skris			sk_X509_NAME_push(stack,xn);
75468651Skris		}
75555714Skris
756215697Ssimon	ERR_clear_error();
757215697Ssimon
75868651Skris	if (0)
75968651Skris		{
76068651Skriserr:
76168651Skris		ret=0;
76268651Skris		}
76368651Skris	if(in != NULL)
76468651Skris		BIO_free(in);
76568651Skris	if(x != NULL)
76668651Skris		X509_free(x);
76768651Skris
768194206Ssimon	(void)sk_X509_NAME_set_cmp_func(stack,oldcmp);
76955714Skris
77068651Skris	return ret;
77155714Skris	}
77255714Skris
77355714Skris/*!
77455714Skris * Add a directory of certs to a stack.
77555714Skris * \param stack the stack to append to.
77655714Skris * \param dir the directory to append from. All files in this directory will be
77755714Skris * examined as potential certs. Any that are acceptable to
77855714Skris * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
77955714Skris * included.
78055714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
78155714Skris * certs may have been added to \c stack.
78255714Skris */
78355714Skris
78455714Skrisint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
78555714Skris				       const char *dir)
78655714Skris	{
787160814Ssimon	OPENSSL_DIR_CTX *d = NULL;
788160814Ssimon	const char *filename;
78968651Skris	int ret = 0;
79055714Skris
79168651Skris	CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
79255714Skris
79368651Skris	/* Note that a side effect is that the CAs will be sorted by name */
794160814Ssimon
795160814Ssimon	while((filename = OPENSSL_DIR_read(&d, dir)))
79668651Skris		{
79768651Skris		char buf[1024];
79868651Skris		int r;
799160814Ssimon
800160814Ssimon		if(strlen(dir)+strlen(filename)+2 > sizeof buf)
80168651Skris			{
80268651Skris			SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
80368651Skris			goto err;
80468651Skris			}
805160814Ssimon
806160814Ssimon#ifdef OPENSSL_SYS_VMS
807160814Ssimon		r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename);
808160814Ssimon#else
809160814Ssimon		r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename);
810160814Ssimon#endif
811160814Ssimon		if (r <= 0 || r >= (int)sizeof(buf))
81268651Skris			goto err;
81368651Skris		if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
81468651Skris			goto err;
81568651Skris		}
81655714Skris
817160814Ssimon	if (errno)
818142425Snectar		{
819109998Smarkm		SYSerr(SYS_F_OPENDIR, get_last_sys_error());
820160814Ssimon		ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
821109998Smarkm		SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
822160814Ssimon		goto err;
823109998Smarkm		}
824142425Snectar
825109998Smarkm	ret = 1;
826109998Smarkm
827160814Ssimonerr:
828160814Ssimon	if (d) OPENSSL_DIR_end(&d);
829109998Smarkm	CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
830109998Smarkm	return ret;
831109998Smarkm	}
832109998Smarkm
833