os/ossrv/ssl/libssl/src/ssl_cert.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*! \file ssl/ssl_cert.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
/* ====================================================================
sl@0
    59
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
sl@0
    60
 *
sl@0
    61
 * Redistribution and use in source and binary forms, with or without
sl@0
    62
 * modification, are permitted provided that the following conditions
sl@0
    63
 * are met:
sl@0
    64
 *
sl@0
    65
 * 1. Redistributions of source code must retain the above copyright
sl@0
    66
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    67
 *
sl@0
    68
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    69
 *    notice, this list of conditions and the following disclaimer in
sl@0
    70
 *    the documentation and/or other materials provided with the
sl@0
    71
 *    distribution.
sl@0
    72
 *
sl@0
    73
 * 3. All advertising materials mentioning features or use of this
sl@0
    74
 *    software must display the following acknowledgment:
sl@0
    75
 *    "This product includes software developed by the OpenSSL Project
sl@0
    76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
sl@0
    77
 *
sl@0
    78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    79
 *    endorse or promote products derived from this software without
sl@0
    80
 *    prior written permission. For written permission, please contact
sl@0
    81
 *    openssl-core@openssl.org.
sl@0
    82
 *
sl@0
    83
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    84
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    85
 *    permission of the OpenSSL Project.
sl@0
    86
 *
sl@0
    87
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    88
 *    acknowledgment:
sl@0
    89
 *    "This product includes software developed by the OpenSSL Project
sl@0
    90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
sl@0
    91
 *
sl@0
    92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
   100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
   101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
   102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
   103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
   104
 * ====================================================================
sl@0
   105
  *
sl@0
   106
 * This product includes cryptographic software written by Eric Young
sl@0
   107
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
   108
 * Hudson (tjh@cryptsoft.com).
sl@0
   109
 *
sl@0
   110
 */
sl@0
   111
/* ====================================================================
sl@0
   112
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
sl@0
   113
 * ECC cipher suite support in OpenSSL originally developed by 
sl@0
   114
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
sl@0
   115
 */
sl@0
   116
/*
sl@0
   117
 © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
sl@0
   118
 */
sl@0
   119
 
sl@0
   120
#include <stdio.h>
sl@0
   121
sl@0
   122
#include "e_os.h"
sl@0
   123
#ifndef NO_SYS_TYPES_H
sl@0
   124
# include <sys/types.h>
sl@0
   125
#endif
sl@0
   126
sl@0
   127
#include "o_dir.h"
sl@0
   128
#include <openssl/objects.h>
sl@0
   129
#include <openssl/bio.h>
sl@0
   130
#include <openssl/pem.h>
sl@0
   131
#include <openssl/x509v3.h>
sl@0
   132
#ifndef OPENSSL_NO_DH
sl@0
   133
#include <openssl/dh.h>
sl@0
   134
#endif
sl@0
   135
#include <openssl/bn.h>
sl@0
   136
#include "ssl_locl.h"
sl@0
   137
sl@0
   138
#ifdef EMULATOR
sl@0
   139
sl@0
   140
	GET_STATIC_VAR_FROM_TLS(ssl_x509_store_ctx_idx,ssl_cert,volatile int)
sl@0
   141
	
sl@0
   142
	#define ssl_x509_store_ctx_idx (*GET_WSD_VAR_NAME(ssl_x509_store_ctx_idx,ssl_cert,s)())
sl@0
   143
sl@0
   144
#endif
sl@0
   145
sl@0
   146
sl@0
   147
EXPORT_C int SSL_get_ex_data_X509_STORE_CTX_idx(void)
sl@0
   148
	{
sl@0
   149
#ifndef EMULATOR
sl@0
   150
	static volatile int ssl_x509_store_ctx_idx= -1;
sl@0
   151
#endif
sl@0
   152
	int got_write_lock = 0;
sl@0
   153
sl@0
   154
	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
sl@0
   155
sl@0
   156
sl@0
   157
	if (ssl_x509_store_ctx_idx < 0)
sl@0
   158
		{
sl@0
   159
		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
sl@0
   160
		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
sl@0
   161
		got_write_lock = 1;
sl@0
   162
		
sl@0
   163
		if (ssl_x509_store_ctx_idx < 0)
sl@0
   164
			{
sl@0
   165
			ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
sl@0
   166
				0,"SSL for verify callback",NULL,NULL,NULL);
sl@0
   167
			}
sl@0
   168
		}
sl@0
   169
sl@0
   170
	if (got_write_lock)
sl@0
   171
		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
sl@0
   172
	else
sl@0
   173
		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
sl@0
   174
	
sl@0
   175
	return ssl_x509_store_ctx_idx;
sl@0
   176
	}
sl@0
   177
sl@0
   178
CERT *ssl_cert_new(void)
sl@0
   179
	{
sl@0
   180
	CERT *ret;
sl@0
   181
sl@0
   182
	ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
sl@0
   183
	if (ret == NULL)
sl@0
   184
		{
sl@0
   185
		SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
sl@0
   186
		return(NULL);
sl@0
   187
		}
sl@0
   188
	memset(ret,0,sizeof(CERT));
sl@0
   189
sl@0
   190
	ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
sl@0
   191
	ret->references=1;
sl@0
   192
sl@0
   193
	return(ret);
sl@0
   194
	}
sl@0
   195
sl@0
   196
CERT *ssl_cert_dup(CERT *cert)
sl@0
   197
	{
sl@0
   198
	CERT *ret;
sl@0
   199
	int i;
sl@0
   200
sl@0
   201
	ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
sl@0
   202
	if (ret == NULL)
sl@0
   203
		{
sl@0
   204
		SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
sl@0
   205
		return(NULL);
sl@0
   206
		}
sl@0
   207
sl@0
   208
	memset(ret, 0, sizeof(CERT));
sl@0
   209
sl@0
   210
	ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
sl@0
   211
	/* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
sl@0
   212
	 * if you find that more readable */
sl@0
   213
sl@0
   214
	ret->valid = cert->valid;
sl@0
   215
	ret->mask = cert->mask;
sl@0
   216
	ret->export_mask = cert->export_mask;
sl@0
   217
sl@0
   218
#ifndef OPENSSL_NO_RSA
sl@0
   219
	if (cert->rsa_tmp != NULL)
sl@0
   220
		{
sl@0
   221
		RSA_up_ref(cert->rsa_tmp);
sl@0
   222
		ret->rsa_tmp = cert->rsa_tmp;
sl@0
   223
		}
sl@0
   224
	ret->rsa_tmp_cb = cert->rsa_tmp_cb;
sl@0
   225
#endif
sl@0
   226
sl@0
   227
#ifndef OPENSSL_NO_DH
sl@0
   228
	if (cert->dh_tmp != NULL)
sl@0
   229
		{
sl@0
   230
		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
sl@0
   231
		if (ret->dh_tmp == NULL)
sl@0
   232
			{
sl@0
   233
			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
sl@0
   234
			goto err;
sl@0
   235
			}
sl@0
   236
		if (cert->dh_tmp->priv_key)
sl@0
   237
			{
sl@0
   238
			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
sl@0
   239
			if (!b)
sl@0
   240
				{
sl@0
   241
				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
sl@0
   242
				goto err;
sl@0
   243
				}
sl@0
   244
			ret->dh_tmp->priv_key = b;
sl@0
   245
			}
sl@0
   246
		if (cert->dh_tmp->pub_key)
sl@0
   247
			{
sl@0
   248
			BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
sl@0
   249
			if (!b)
sl@0
   250
				{
sl@0
   251
				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
sl@0
   252
				goto err;
sl@0
   253
				}
sl@0
   254
			ret->dh_tmp->pub_key = b;
sl@0
   255
			}
sl@0
   256
		}
sl@0
   257
	ret->dh_tmp_cb = cert->dh_tmp_cb;
sl@0
   258
#endif
sl@0
   259
sl@0
   260
#ifndef OPENSSL_NO_ECDH
sl@0
   261
	if (cert->ecdh_tmp)
sl@0
   262
		{
sl@0
   263
		ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
sl@0
   264
		if (ret->ecdh_tmp == NULL)
sl@0
   265
			{
sl@0
   266
			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
sl@0
   267
			goto err;
sl@0
   268
			}
sl@0
   269
		}
sl@0
   270
	ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
sl@0
   271
#endif
sl@0
   272
sl@0
   273
	for (i = 0; i < SSL_PKEY_NUM; i++)
sl@0
   274
		{
sl@0
   275
		if (cert->pkeys[i].x509 != NULL)
sl@0
   276
			{
sl@0
   277
			ret->pkeys[i].x509 = cert->pkeys[i].x509;
sl@0
   278
			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
sl@0
   279
				CRYPTO_LOCK_X509);
sl@0
   280
			}
sl@0
   281
		
sl@0
   282
		if (cert->pkeys[i].privatekey != NULL)
sl@0
   283
			{
sl@0
   284
			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
sl@0
   285
			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
sl@0
   286
				CRYPTO_LOCK_EVP_PKEY);
sl@0
   287
sl@0
   288
			switch(i) 
sl@0
   289
				{
sl@0
   290
				/* If there was anything special to do for
sl@0
   291
				 * certain types of keys, we'd do it here.
sl@0
   292
				 * (Nothing at the moment, I think.) */
sl@0
   293
sl@0
   294
			case SSL_PKEY_RSA_ENC:
sl@0
   295
			case SSL_PKEY_RSA_SIGN:
sl@0
   296
				/* We have an RSA key. */
sl@0
   297
				break;
sl@0
   298
				
sl@0
   299
			case SSL_PKEY_DSA_SIGN:
sl@0
   300
				/* We have a DSA key. */
sl@0
   301
				break;
sl@0
   302
				
sl@0
   303
			case SSL_PKEY_DH_RSA:
sl@0
   304
			case SSL_PKEY_DH_DSA:
sl@0
   305
				/* We have a DH key. */
sl@0
   306
				break;
sl@0
   307
sl@0
   308
			case SSL_PKEY_ECC:
sl@0
   309
				/* We have an ECC key */
sl@0
   310
				break;
sl@0
   311
sl@0
   312
			default:
sl@0
   313
				/* Can't happen. */
sl@0
   314
				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
sl@0
   315
				}
sl@0
   316
			}
sl@0
   317
		}
sl@0
   318
	
sl@0
   319
	/* ret->extra_certs *should* exist, but currently the own certificate
sl@0
   320
	 * chain is held inside SSL_CTX */
sl@0
   321
sl@0
   322
	ret->references=1;
sl@0
   323
sl@0
   324
	return(ret);
sl@0
   325
	
sl@0
   326
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
sl@0
   327
err:
sl@0
   328
#endif
sl@0
   329
#ifndef OPENSSL_NO_RSA
sl@0
   330
	if (ret->rsa_tmp != NULL)
sl@0
   331
		RSA_free(ret->rsa_tmp);
sl@0
   332
#endif
sl@0
   333
#ifndef OPENSSL_NO_DH
sl@0
   334
	if (ret->dh_tmp != NULL)
sl@0
   335
		DH_free(ret->dh_tmp);
sl@0
   336
#endif
sl@0
   337
#ifndef OPENSSL_NO_ECDH
sl@0
   338
	if (ret->ecdh_tmp != NULL)
sl@0
   339
		EC_KEY_free(ret->ecdh_tmp);
sl@0
   340
#endif
sl@0
   341
sl@0
   342
	for (i = 0; i < SSL_PKEY_NUM; i++)
sl@0
   343
		{
sl@0
   344
		if (ret->pkeys[i].x509 != NULL)
sl@0
   345
			X509_free(ret->pkeys[i].x509);
sl@0
   346
		if (ret->pkeys[i].privatekey != NULL)
sl@0
   347
			EVP_PKEY_free(ret->pkeys[i].privatekey);
sl@0
   348
		}
sl@0
   349
sl@0
   350
	return NULL;
sl@0
   351
	}
sl@0
   352
sl@0
   353
sl@0
   354
void ssl_cert_free(CERT *c)
sl@0
   355
	{
sl@0
   356
	int i;
sl@0
   357
sl@0
   358
	if(c == NULL)
sl@0
   359
	    return;
sl@0
   360
sl@0
   361
	i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
sl@0
   362
#ifdef REF_PRINT
sl@0
   363
	REF_PRINT("CERT",c);
sl@0
   364
#endif
sl@0
   365
	if (i > 0) return;
sl@0
   366
#ifdef REF_CHECK
sl@0
   367
	if (i < 0)
sl@0
   368
		{
sl@0
   369
		fprintf(stderr,"ssl_cert_free, bad reference count\n");
sl@0
   370
		abort(); /* ok */
sl@0
   371
		}
sl@0
   372
#endif
sl@0
   373
sl@0
   374
#ifndef OPENSSL_NO_RSA
sl@0
   375
	if (c->rsa_tmp) RSA_free(c->rsa_tmp);
sl@0
   376
#endif
sl@0
   377
#ifndef OPENSSL_NO_DH
sl@0
   378
	if (c->dh_tmp) DH_free(c->dh_tmp);
sl@0
   379
#endif
sl@0
   380
#ifndef OPENSSL_NO_ECDH
sl@0
   381
	if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
sl@0
   382
#endif
sl@0
   383
sl@0
   384
	for (i=0; i<SSL_PKEY_NUM; i++)
sl@0
   385
		{
sl@0
   386
		if (c->pkeys[i].x509 != NULL)
sl@0
   387
			X509_free(c->pkeys[i].x509);
sl@0
   388
		if (c->pkeys[i].privatekey != NULL)
sl@0
   389
			EVP_PKEY_free(c->pkeys[i].privatekey);
sl@0
   390
#if 0
sl@0
   391
		if (c->pkeys[i].publickey != NULL)
sl@0
   392
			EVP_PKEY_free(c->pkeys[i].publickey);
sl@0
   393
#endif
sl@0
   394
		}
sl@0
   395
	OPENSSL_free(c);
sl@0
   396
	}
sl@0
   397
sl@0
   398
int ssl_cert_inst(CERT **o)
sl@0
   399
	{
sl@0
   400
	/* Create a CERT if there isn't already one
sl@0
   401
	 * (which cannot really happen, as it is initially created in
sl@0
   402
	 * SSL_CTX_new; but the earlier code usually allows for that one
sl@0
   403
	 * being non-existant, so we follow that behaviour, as it might
sl@0
   404
	 * turn out that there actually is a reason for it -- but I'm
sl@0
   405
	 * not sure that *all* of the existing code could cope with
sl@0
   406
	 * s->cert being NULL, otherwise we could do without the
sl@0
   407
	 * initialization in SSL_CTX_new).
sl@0
   408
	 */
sl@0
   409
	
sl@0
   410
	if (o == NULL) 
sl@0
   411
		{
sl@0
   412
		SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
sl@0
   413
		return(0);
sl@0
   414
		}
sl@0
   415
	if (*o == NULL)
sl@0
   416
		{
sl@0
   417
		if ((*o = ssl_cert_new()) == NULL)
sl@0
   418
			{
sl@0
   419
			SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
sl@0
   420
			return(0);
sl@0
   421
			}
sl@0
   422
		}
sl@0
   423
	return(1);
sl@0
   424
	}
sl@0
   425
sl@0
   426
sl@0
   427
SESS_CERT *ssl_sess_cert_new(void)
sl@0
   428
	{
sl@0
   429
	SESS_CERT *ret;
sl@0
   430
sl@0
   431
	ret = OPENSSL_malloc(sizeof *ret);
sl@0
   432
	if (ret == NULL)
sl@0
   433
		{
sl@0
   434
		SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
sl@0
   435
		return NULL;
sl@0
   436
		}
sl@0
   437
sl@0
   438
	memset(ret, 0 ,sizeof *ret);
sl@0
   439
	ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
sl@0
   440
	ret->references = 1;
sl@0
   441
sl@0
   442
	return ret;
sl@0
   443
	}
sl@0
   444
sl@0
   445
void ssl_sess_cert_free(SESS_CERT *sc)
sl@0
   446
	{
sl@0
   447
	int i;
sl@0
   448
sl@0
   449
	if (sc == NULL)
sl@0
   450
		return;
sl@0
   451
sl@0
   452
	i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
sl@0
   453
#ifdef REF_PRINT
sl@0
   454
	REF_PRINT("SESS_CERT", sc);
sl@0
   455
#endif
sl@0
   456
	if (i > 0)
sl@0
   457
		return;
sl@0
   458
#ifdef REF_CHECK
sl@0
   459
	if (i < 0)
sl@0
   460
		{
sl@0
   461
		fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
sl@0
   462
		abort(); /* ok */
sl@0
   463
		}
sl@0
   464
#endif
sl@0
   465
sl@0
   466
	/* i == 0 */
sl@0
   467
	if (sc->cert_chain != NULL)
sl@0
   468
		sk_X509_pop_free(sc->cert_chain, X509_free);
sl@0
   469
	for (i = 0; i < SSL_PKEY_NUM; i++)
sl@0
   470
		{
sl@0
   471
		if (sc->peer_pkeys[i].x509 != NULL)
sl@0
   472
			X509_free(sc->peer_pkeys[i].x509);
sl@0
   473
#if 0 /* We don't have the peer's private key.  These lines are just
sl@0
   474
	   * here as a reminder that we're still using a not-quite-appropriate
sl@0
   475
	   * data structure. */
sl@0
   476
		if (sc->peer_pkeys[i].privatekey != NULL)
sl@0
   477
			EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
sl@0
   478
#endif
sl@0
   479
		}
sl@0
   480
sl@0
   481
#ifndef OPENSSL_NO_RSA
sl@0
   482
	if (sc->peer_rsa_tmp != NULL)
sl@0
   483
		RSA_free(sc->peer_rsa_tmp);
sl@0
   484
#endif
sl@0
   485
#ifndef OPENSSL_NO_DH
sl@0
   486
	if (sc->peer_dh_tmp != NULL)
sl@0
   487
		DH_free(sc->peer_dh_tmp);
sl@0
   488
#endif
sl@0
   489
#ifndef OPENSSL_NO_ECDH
sl@0
   490
	if (sc->peer_ecdh_tmp != NULL)
sl@0
   491
		EC_KEY_free(sc->peer_ecdh_tmp);
sl@0
   492
#endif
sl@0
   493
sl@0
   494
	OPENSSL_free(sc);
sl@0
   495
	}
sl@0
   496
sl@0
   497
int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
sl@0
   498
	{
sl@0
   499
	sc->peer_cert_type = type;
sl@0
   500
	return(1);
sl@0
   501
	}
sl@0
   502
sl@0
   503
int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
sl@0
   504
	{
sl@0
   505
	X509 *x;
sl@0
   506
	int i;
sl@0
   507
	X509_STORE_CTX ctx;
sl@0
   508
sl@0
   509
	if ((sk == NULL) || (sk_X509_num(sk) == 0))
sl@0
   510
		return(0);
sl@0
   511
sl@0
   512
	x=sk_X509_value(sk,0);
sl@0
   513
	if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
sl@0
   514
		{
sl@0
   515
		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
sl@0
   516
		return(0);
sl@0
   517
		}
sl@0
   518
	if (s->param)
sl@0
   519
		X509_VERIFY_PARAM_inherit(X509_STORE_CTX_get0_param(&ctx),
sl@0
   520
						s->param);
sl@0
   521
#if 0
sl@0
   522
	if (SSL_get_verify_depth(s) >= 0)
sl@0
   523
		X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
sl@0
   524
#endif
sl@0
   525
	X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
sl@0
   526
sl@0
   527
	/* We need to inherit the verify parameters. These can be determined by
sl@0
   528
	 * the context: if its a server it will verify SSL client certificates
sl@0
   529
	 * or vice versa.
sl@0
   530
	 */
sl@0
   531
sl@0
   532
	X509_STORE_CTX_set_default(&ctx,
sl@0
   533
				s->server ? "ssl_client" : "ssl_server");
sl@0
   534
sl@0
   535
	if (s->verify_callback)
sl@0
   536
		X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
sl@0
   537
sl@0
   538
	if (s->ctx->app_verify_callback != NULL)
sl@0
   539
#if 1 /* new with OpenSSL 0.9.7 */
sl@0
   540
		i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
sl@0
   541
#else
sl@0
   542
		i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
sl@0
   543
#endif
sl@0
   544
	else
sl@0
   545
		{
sl@0
   546
#ifndef OPENSSL_NO_X509_VERIFY
sl@0
   547
		i=X509_verify_cert(&ctx);
sl@0
   548
#else
sl@0
   549
		i=0;
sl@0
   550
		ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
sl@0
   551
		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
sl@0
   552
#endif
sl@0
   553
		}
sl@0
   554
sl@0
   555
	s->verify_result=ctx.error;
sl@0
   556
	X509_STORE_CTX_cleanup(&ctx);
sl@0
   557
sl@0
   558
	return(i);
sl@0
   559
	}
sl@0
   560
sl@0
   561
static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
sl@0
   562
	{
sl@0
   563
	if (*ca_list != NULL)
sl@0
   564
		sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
sl@0
   565
sl@0
   566
	*ca_list=name_list;
sl@0
   567
	}
sl@0
   568
sl@0
   569
EXPORT_C STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
sl@0
   570
	{
sl@0
   571
	int i;
sl@0
   572
	STACK_OF(X509_NAME) *ret;
sl@0
   573
	X509_NAME *name;
sl@0
   574
sl@0
   575
	ret=sk_X509_NAME_new_null();
sl@0
   576
	for (i=0; i<sk_X509_NAME_num(sk); i++)
sl@0
   577
		{
sl@0
   578
		name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
sl@0
   579
		if ((name == NULL) || !sk_X509_NAME_push(ret,name))
sl@0
   580
			{
sl@0
   581
			sk_X509_NAME_pop_free(ret,X509_NAME_free);
sl@0
   582
			return(NULL);
sl@0
   583
			}
sl@0
   584
		}
sl@0
   585
	return(ret);
sl@0
   586
	}
sl@0
   587
sl@0
   588
EXPORT_C void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
sl@0
   589
	{
sl@0
   590
	set_client_CA_list(&(s->client_CA),name_list);
sl@0
   591
	}
sl@0
   592
sl@0
   593
EXPORT_C void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
sl@0
   594
	{
sl@0
   595
	set_client_CA_list(&(ctx->client_CA),name_list);
sl@0
   596
	}
sl@0
   597
sl@0
   598
EXPORT_C STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
sl@0
   599
	{
sl@0
   600
	return(ctx->client_CA);
sl@0
   601
	}
sl@0
   602
sl@0
   603
EXPORT_C STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
sl@0
   604
	{
sl@0
   605
	if (s->type == SSL_ST_CONNECT)
sl@0
   606
		{ /* we are in the client */
sl@0
   607
		if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
sl@0
   608
			(s->s3 != NULL))
sl@0
   609
			return(s->s3->tmp.ca_names);
sl@0
   610
		else
sl@0
   611
			return(NULL);
sl@0
   612
		}
sl@0
   613
	else
sl@0
   614
		{
sl@0
   615
		if (s->client_CA != NULL)
sl@0
   616
			return(s->client_CA);
sl@0
   617
		else
sl@0
   618
			return(s->ctx->client_CA);
sl@0
   619
		}
sl@0
   620
	}
sl@0
   621
sl@0
   622
static int add_client_CA(STACK_OF(X509_NAME) **sk,X509 *x)
sl@0
   623
	{
sl@0
   624
	X509_NAME *name;
sl@0
   625
sl@0
   626
	if (x == NULL) return(0);
sl@0
   627
	if ((*sk == NULL) && ((*sk=sk_X509_NAME_new_null()) == NULL))
sl@0
   628
		return(0);
sl@0
   629
		
sl@0
   630
	if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
sl@0
   631
		return(0);
sl@0
   632
sl@0
   633
	if (!sk_X509_NAME_push(*sk,name))
sl@0
   634
		{
sl@0
   635
		X509_NAME_free(name);
sl@0
   636
		return(0);
sl@0
   637
		}
sl@0
   638
	return(1);
sl@0
   639
	}
sl@0
   640
sl@0
   641
EXPORT_C int SSL_add_client_CA(SSL *ssl,X509 *x)
sl@0
   642
	{
sl@0
   643
	return(add_client_CA(&(ssl->client_CA),x));
sl@0
   644
	}
sl@0
   645
sl@0
   646
EXPORT_C int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
sl@0
   647
	{
sl@0
   648
	return(add_client_CA(&(ctx->client_CA),x));
sl@0
   649
	}
sl@0
   650
sl@0
   651
static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
sl@0
   652
	{
sl@0
   653
	return(X509_NAME_cmp(*a,*b));
sl@0
   654
	}
sl@0
   655
sl@0
   656
#ifndef OPENSSL_NO_STDIO
sl@0
   657
/*!
sl@0
   658
 * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
sl@0
   659
 * it doesn't really have anything to do with clients (except that a common use
sl@0
   660
 * for a stack of CAs is to send it to the client). Actually, it doesn't have
sl@0
   661
 * much to do with CAs, either, since it will load any old cert.
sl@0
   662
 * \param file the file containing one or more certs.
sl@0
   663
 * \return a ::STACK containing the certs.
sl@0
   664
 */
sl@0
   665
EXPORT_C STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
sl@0
   666
	{
sl@0
   667
	BIO *in;
sl@0
   668
	X509 *x=NULL;
sl@0
   669
	X509_NAME *xn=NULL;
sl@0
   670
	STACK_OF(X509_NAME) *ret = NULL,*sk;
sl@0
   671
sl@0
   672
	sk=sk_X509_NAME_new(xname_cmp);
sl@0
   673
sl@0
   674
	in=BIO_new(BIO_s_file_internal());
sl@0
   675
sl@0
   676
	if ((sk == NULL) || (in == NULL))
sl@0
   677
		{
sl@0
   678
		SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
sl@0
   679
		goto err;
sl@0
   680
		}
sl@0
   681
	
sl@0
   682
	if (!BIO_read_filename(in,file))
sl@0
   683
		goto err;
sl@0
   684
sl@0
   685
	for (;;)
sl@0
   686
		{
sl@0
   687
		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
sl@0
   688
			break;
sl@0
   689
		if (ret == NULL)
sl@0
   690
			{
sl@0
   691
			ret = sk_X509_NAME_new_null();
sl@0
   692
			if (ret == NULL)
sl@0
   693
				{
sl@0
   694
				SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
sl@0
   695
				goto err;
sl@0
   696
				}
sl@0
   697
			}
sl@0
   698
		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
sl@0
   699
		/* check for duplicates */
sl@0
   700
		xn=X509_NAME_dup(xn);
sl@0
   701
		if (xn == NULL) goto err;
sl@0
   702
		if (sk_X509_NAME_find(sk,xn) >= 0)
sl@0
   703
			X509_NAME_free(xn);
sl@0
   704
		else
sl@0
   705
			{
sl@0
   706
			sk_X509_NAME_push(sk,xn);
sl@0
   707
			sk_X509_NAME_push(ret,xn);
sl@0
   708
			}
sl@0
   709
		}
sl@0
   710
sl@0
   711
	if (0)
sl@0
   712
		{
sl@0
   713
err:
sl@0
   714
		if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
sl@0
   715
		ret=NULL;
sl@0
   716
		}
sl@0
   717
	if (sk != NULL) sk_X509_NAME_free(sk);
sl@0
   718
	if (in != NULL) BIO_free(in);
sl@0
   719
	if (x != NULL) X509_free(x);
sl@0
   720
	if (ret != NULL)
sl@0
   721
		ERR_clear_error();
sl@0
   722
	return(ret);
sl@0
   723
	}
sl@0
   724
#endif
sl@0
   725
sl@0
   726
/*!
sl@0
   727
 * Add a file of certs to a stack.
sl@0
   728
 * \param stack the stack to add to.
sl@0
   729
 * \param file the file to add from. All certs in this file that are not
sl@0
   730
 * already in the stack will be added.
sl@0
   731
 * \return 1 for success, 0 for failure. Note that in the case of failure some
sl@0
   732
 * certs may have been added to \c stack.
sl@0
   733
 */
sl@0
   734
sl@0
   735
EXPORT_C int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
sl@0
   736
					const char *file)
sl@0
   737
	{
sl@0
   738
	BIO *in;
sl@0
   739
	X509 *x=NULL;
sl@0
   740
	X509_NAME *xn=NULL;
sl@0
   741
	int ret=1;
sl@0
   742
	int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
sl@0
   743
	
sl@0
   744
	oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp);
sl@0
   745
	
sl@0
   746
	in=BIO_new(BIO_s_file_internal());
sl@0
   747
	
sl@0
   748
	if (in == NULL)
sl@0
   749
		{
sl@0
   750
		SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
sl@0
   751
		goto err;
sl@0
   752
		}
sl@0
   753
	
sl@0
   754
	if (!BIO_read_filename(in,file))
sl@0
   755
		goto err;
sl@0
   756
	
sl@0
   757
	for (;;)
sl@0
   758
		{
sl@0
   759
		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
sl@0
   760
			break;
sl@0
   761
		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
sl@0
   762
		xn=X509_NAME_dup(xn);
sl@0
   763
		if (xn == NULL) goto err;
sl@0
   764
		if (sk_X509_NAME_find(stack,xn) >= 0)
sl@0
   765
			X509_NAME_free(xn);
sl@0
   766
		else
sl@0
   767
			sk_X509_NAME_push(stack,xn);
sl@0
   768
		}
sl@0
   769
sl@0
   770
	if (0)
sl@0
   771
		{
sl@0
   772
err:
sl@0
   773
		ret=0;
sl@0
   774
		}
sl@0
   775
	if(in != NULL)
sl@0
   776
		BIO_free(in);
sl@0
   777
	if(x != NULL)
sl@0
   778
		X509_free(x);
sl@0
   779
	
sl@0
   780
	(void)sk_X509_NAME_set_cmp_func(stack,oldcmp);
sl@0
   781
sl@0
   782
	return ret;
sl@0
   783
	}
sl@0
   784
sl@0
   785
/*!
sl@0
   786
 * Add a directory of certs to a stack.
sl@0
   787
 * \param stack the stack to append to.
sl@0
   788
 * \param dir the directory to append from. All files in this directory will be
sl@0
   789
 * examined as potential certs. Any that are acceptable to
sl@0
   790
 * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
sl@0
   791
 * included.
sl@0
   792
 * \return 1 for success, 0 for failure. Note that in the case of failure some
sl@0
   793
 * certs may have been added to \c stack.
sl@0
   794
 */
sl@0
   795
sl@0
   796
EXPORT_C int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
sl@0
   797
				       const char *dir)
sl@0
   798
	{
sl@0
   799
	OPENSSL_DIR_CTX *d = NULL;
sl@0
   800
	const char *filename;
sl@0
   801
	int ret = 0;
sl@0
   802
sl@0
   803
	CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
sl@0
   804
sl@0
   805
	/* Note that a side effect is that the CAs will be sorted by name */
sl@0
   806
sl@0
   807
	while((filename = OPENSSL_DIR_read(&d, dir)))
sl@0
   808
		{
sl@0
   809
		char buf[1024];
sl@0
   810
		int r;
sl@0
   811
sl@0
   812
		if(strlen(dir)+strlen(filename)+2 > sizeof buf)
sl@0
   813
			{
sl@0
   814
			SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
sl@0
   815
			goto err;
sl@0
   816
			}
sl@0
   817
sl@0
   818
#ifdef OPENSSL_SYS_VMS
sl@0
   819
		r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename);
sl@0
   820
#else
sl@0
   821
		r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename);
sl@0
   822
#endif
sl@0
   823
		if (r <= 0 || r >= (int)sizeof(buf))
sl@0
   824
			goto err;
sl@0
   825
		if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
sl@0
   826
			goto err;
sl@0
   827
		}
sl@0
   828
sl@0
   829
	if (errno)
sl@0
   830
		{
sl@0
   831
		SYSerr(SYS_F_OPENDIR, get_last_sys_error());
sl@0
   832
		ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
sl@0
   833
		SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
sl@0
   834
		goto err;
sl@0
   835
		}
sl@0
   836
sl@0
   837
	ret = 1;
sl@0
   838
sl@0
   839
err:
sl@0
   840
	if (d) OPENSSL_DIR_end(&d);
sl@0
   841
	CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
sl@0
   842
	return ret;
sl@0
   843
	}
sl@0
   844