xref: /onnv-gate/usr/src/common/openssl/ssl/ssl_lib.c (revision 5211:18119b64ca57)
10Sstevel@tonic-gate /*! \file ssl/ssl_lib.c
20Sstevel@tonic-gate  *  \brief Version independent SSL functions.
30Sstevel@tonic-gate  */
40Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
50Sstevel@tonic-gate  * All rights reserved.
60Sstevel@tonic-gate  *
70Sstevel@tonic-gate  * This package is an SSL implementation written
80Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
90Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
100Sstevel@tonic-gate  *
110Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
120Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
130Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
140Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
150Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
160Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
170Sstevel@tonic-gate  *
180Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
190Sstevel@tonic-gate  * the code are not to be removed.
200Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
210Sstevel@tonic-gate  * as the author of the parts of the library used.
220Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
230Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
260Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
270Sstevel@tonic-gate  * are met:
280Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
300Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
310Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
320Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
330Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
340Sstevel@tonic-gate  *    must display the following acknowledgement:
350Sstevel@tonic-gate  *    "This product includes cryptographic software written by
360Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
370Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
380Sstevel@tonic-gate  *    being used are not cryptographic related :-).
390Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
400Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
410Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
420Sstevel@tonic-gate  *
430Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
440Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
450Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
460Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
470Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
480Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
490Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
500Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
510Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
520Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
530Sstevel@tonic-gate  * SUCH DAMAGE.
540Sstevel@tonic-gate  *
550Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
560Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
570Sstevel@tonic-gate  * copied and put under another distribution licence
580Sstevel@tonic-gate  * [including the GNU Public Licence.]
590Sstevel@tonic-gate  */
600Sstevel@tonic-gate /* ====================================================================
610Sstevel@tonic-gate  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
620Sstevel@tonic-gate  *
630Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
640Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
650Sstevel@tonic-gate  * are met:
660Sstevel@tonic-gate  *
670Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
680Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
690Sstevel@tonic-gate  *
700Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
710Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
720Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
730Sstevel@tonic-gate  *    distribution.
740Sstevel@tonic-gate  *
750Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
760Sstevel@tonic-gate  *    software must display the following acknowledgment:
770Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
780Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
790Sstevel@tonic-gate  *
800Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
810Sstevel@tonic-gate  *    endorse or promote products derived from this software without
820Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
830Sstevel@tonic-gate  *    openssl-core@openssl.org.
840Sstevel@tonic-gate  *
850Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
860Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
870Sstevel@tonic-gate  *    permission of the OpenSSL Project.
880Sstevel@tonic-gate  *
890Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
900Sstevel@tonic-gate  *    acknowledgment:
910Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
920Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
930Sstevel@tonic-gate  *
940Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
950Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
960Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
970Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
980Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
990Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1000Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1010Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1020Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1030Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1040Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1050Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
1060Sstevel@tonic-gate  * ====================================================================
1070Sstevel@tonic-gate  *
1080Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
1090Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
1100Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
1110Sstevel@tonic-gate  *
1120Sstevel@tonic-gate  */
1132139Sjp161948 /* ====================================================================
1142139Sjp161948  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1152139Sjp161948  * ECC cipher suite support in OpenSSL originally developed by
1162139Sjp161948  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1172139Sjp161948  */
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate #ifdef REF_CHECK
1200Sstevel@tonic-gate #  include <assert.h>
1210Sstevel@tonic-gate #endif
1220Sstevel@tonic-gate #include <stdio.h>
1230Sstevel@tonic-gate #include "ssl_locl.h"
1240Sstevel@tonic-gate #include "kssl_lcl.h"
1250Sstevel@tonic-gate #include <openssl/objects.h>
1260Sstevel@tonic-gate #include <openssl/lhash.h>
1270Sstevel@tonic-gate #include <openssl/x509v3.h>
1282139Sjp161948 #ifndef OPENSSL_NO_DH
1292139Sjp161948 #include <openssl/dh.h>
1302139Sjp161948 #endif
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate const char *SSL_version_str=OPENSSL_VERSION_TEXT;
1330Sstevel@tonic-gate 
1342139Sjp161948 SSL3_ENC_METHOD ssl3_undef_enc_method={
1350Sstevel@tonic-gate 	/* evil casts, but these functions are only called if there's a library bug */
1360Sstevel@tonic-gate 	(int (*)(SSL *,int))ssl_undefined_function,
1370Sstevel@tonic-gate 	(int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
1380Sstevel@tonic-gate 	ssl_undefined_function,
1390Sstevel@tonic-gate 	(int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
1400Sstevel@tonic-gate 	(int (*)(SSL*, int))ssl_undefined_function,
1412139Sjp161948 	(int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function,
1422139Sjp161948 	0,	/* finish_mac_length */
1432139Sjp161948 	(int (*)(SSL *, EVP_MD_CTX *, unsigned char *))ssl_undefined_function,
1442139Sjp161948 	NULL,	/* client_finished_label */
1452139Sjp161948 	0,	/* client_finished_label_len */
1462139Sjp161948 	NULL,	/* server_finished_label */
1472139Sjp161948 	0,	/* server_finished_label_len */
1482139Sjp161948 	(int (*)(int))ssl_undefined_function
1490Sstevel@tonic-gate 	};
1500Sstevel@tonic-gate 
SSL_clear(SSL * s)1510Sstevel@tonic-gate int SSL_clear(SSL *s)
1520Sstevel@tonic-gate 	{
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (s->method == NULL)
1550Sstevel@tonic-gate 		{
1560Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CLEAR,SSL_R_NO_METHOD_SPECIFIED);
1570Sstevel@tonic-gate 		return(0);
1580Sstevel@tonic-gate 		}
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	if (ssl_clear_bad_session(s))
1610Sstevel@tonic-gate 		{
1620Sstevel@tonic-gate 		SSL_SESSION_free(s->session);
1630Sstevel@tonic-gate 		s->session=NULL;
1640Sstevel@tonic-gate 		}
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	s->error=0;
1670Sstevel@tonic-gate 	s->hit=0;
1680Sstevel@tonic-gate 	s->shutdown=0;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate #if 0 /* Disabled since version 1.10 of this file (early return not
1710Sstevel@tonic-gate        * needed because SSL_clear is not called when doing renegotiation) */
1720Sstevel@tonic-gate 	/* This is set if we are doing dynamic renegotiation so keep
1730Sstevel@tonic-gate 	 * the old cipher.  It is sort of a SSL_clear_lite :-) */
1740Sstevel@tonic-gate 	if (s->new_session) return(1);
1750Sstevel@tonic-gate #else
1760Sstevel@tonic-gate 	if (s->new_session)
1770Sstevel@tonic-gate 		{
1780Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
1790Sstevel@tonic-gate 		return 0;
1800Sstevel@tonic-gate 		}
1810Sstevel@tonic-gate #endif
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	s->type=0;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	s->state=SSL_ST_BEFORE|((s->server)?SSL_ST_ACCEPT:SSL_ST_CONNECT);
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	s->version=s->method->version;
1880Sstevel@tonic-gate 	s->client_version=s->version;
1890Sstevel@tonic-gate 	s->rwstate=SSL_NOTHING;
1900Sstevel@tonic-gate 	s->rstate=SSL_ST_READ_HEADER;
1910Sstevel@tonic-gate #if 0
1920Sstevel@tonic-gate 	s->read_ahead=s->ctx->read_ahead;
1930Sstevel@tonic-gate #endif
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	if (s->init_buf != NULL)
1960Sstevel@tonic-gate 		{
1970Sstevel@tonic-gate 		BUF_MEM_free(s->init_buf);
1980Sstevel@tonic-gate 		s->init_buf=NULL;
1990Sstevel@tonic-gate 		}
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	ssl_clear_cipher_ctx(s);
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	s->first_packet=0;
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate #if 1
2060Sstevel@tonic-gate 	/* Check to see if we were changed into a different method, if
2070Sstevel@tonic-gate 	 * so, revert back if we are not doing session-id reuse. */
2080Sstevel@tonic-gate 	if (!s->in_handshake && (s->session == NULL) && (s->method != s->ctx->method))
2090Sstevel@tonic-gate 		{
2100Sstevel@tonic-gate 		s->method->ssl_free(s);
2110Sstevel@tonic-gate 		s->method=s->ctx->method;
2120Sstevel@tonic-gate 		if (!s->method->ssl_new(s))
2130Sstevel@tonic-gate 			return(0);
2140Sstevel@tonic-gate 		}
2150Sstevel@tonic-gate 	else
2160Sstevel@tonic-gate #endif
2170Sstevel@tonic-gate 		s->method->ssl_clear(s);
2180Sstevel@tonic-gate 	return(1);
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate /** Used to change an SSL_CTXs default SSL method type */
SSL_CTX_set_ssl_version(SSL_CTX * ctx,SSL_METHOD * meth)2220Sstevel@tonic-gate int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth)
2230Sstevel@tonic-gate 	{
2240Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	ctx->method=meth;
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list),
2290Sstevel@tonic-gate 		&(ctx->cipher_list_by_id),SSL_DEFAULT_CIPHER_LIST);
2300Sstevel@tonic-gate 	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0))
2310Sstevel@tonic-gate 		{
2320Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
2330Sstevel@tonic-gate 		return(0);
2340Sstevel@tonic-gate 		}
2350Sstevel@tonic-gate 	return(1);
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 
SSL_new(SSL_CTX * ctx)2380Sstevel@tonic-gate SSL *SSL_new(SSL_CTX *ctx)
2390Sstevel@tonic-gate 	{
2400Sstevel@tonic-gate 	SSL *s;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	if (ctx == NULL)
2430Sstevel@tonic-gate 		{
2440Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_NEW,SSL_R_NULL_SSL_CTX);
2450Sstevel@tonic-gate 		return(NULL);
2460Sstevel@tonic-gate 		}
2470Sstevel@tonic-gate 	if (ctx->method == NULL)
2480Sstevel@tonic-gate 		{
2490Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_NEW,SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
2500Sstevel@tonic-gate 		return(NULL);
2510Sstevel@tonic-gate 		}
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	s=(SSL *)OPENSSL_malloc(sizeof(SSL));
2540Sstevel@tonic-gate 	if (s == NULL) goto err;
2550Sstevel@tonic-gate 	memset(s,0,sizeof(SSL));
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate #ifndef	OPENSSL_NO_KRB5
2580Sstevel@tonic-gate 	s->kssl_ctx = kssl_ctx_new();
2590Sstevel@tonic-gate #endif	/* OPENSSL_NO_KRB5 */
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 	s->options=ctx->options;
2620Sstevel@tonic-gate 	s->mode=ctx->mode;
2630Sstevel@tonic-gate 	s->max_cert_list=ctx->max_cert_list;
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	if (ctx->cert != NULL)
2660Sstevel@tonic-gate 		{
2670Sstevel@tonic-gate 		/* Earlier library versions used to copy the pointer to
2680Sstevel@tonic-gate 		 * the CERT, not its contents; only when setting new
2690Sstevel@tonic-gate 		 * parameters for the per-SSL copy, ssl_cert_new would be
2700Sstevel@tonic-gate 		 * called (and the direct reference to the per-SSL_CTX
2710Sstevel@tonic-gate 		 * settings would be lost, but those still were indirectly
2720Sstevel@tonic-gate 		 * accessed for various purposes, and for that reason they
2730Sstevel@tonic-gate 		 * used to be known as s->ctx->default_cert).
2740Sstevel@tonic-gate 		 * Now we don't look at the SSL_CTX's CERT after having
2750Sstevel@tonic-gate 		 * duplicated it once. */
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 		s->cert = ssl_cert_dup(ctx->cert);
2780Sstevel@tonic-gate 		if (s->cert == NULL)
2790Sstevel@tonic-gate 			goto err;
2800Sstevel@tonic-gate 		}
2810Sstevel@tonic-gate 	else
2820Sstevel@tonic-gate 		s->cert=NULL; /* Cannot really happen (see SSL_CTX_new) */
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	s->read_ahead=ctx->read_ahead;
2850Sstevel@tonic-gate 	s->msg_callback=ctx->msg_callback;
2860Sstevel@tonic-gate 	s->msg_callback_arg=ctx->msg_callback_arg;
2870Sstevel@tonic-gate 	s->verify_mode=ctx->verify_mode;
2882139Sjp161948 #if 0
2890Sstevel@tonic-gate 	s->verify_depth=ctx->verify_depth;
2902139Sjp161948 #endif
2910Sstevel@tonic-gate 	s->sid_ctx_length=ctx->sid_ctx_length;
2920Sstevel@tonic-gate 	OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
2930Sstevel@tonic-gate 	memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
2940Sstevel@tonic-gate 	s->verify_callback=ctx->default_verify_callback;
2950Sstevel@tonic-gate 	s->generate_session_id=ctx->generate_session_id;
2962139Sjp161948 
2972139Sjp161948 	s->param = X509_VERIFY_PARAM_new();
2982139Sjp161948 	if (!s->param)
2992139Sjp161948 		goto err;
3002139Sjp161948 	X509_VERIFY_PARAM_inherit(s->param, ctx->param);
3012139Sjp161948 #if 0
3020Sstevel@tonic-gate 	s->purpose = ctx->purpose;
3030Sstevel@tonic-gate 	s->trust = ctx->trust;
3042139Sjp161948 #endif
3050Sstevel@tonic-gate 	s->quiet_shutdown=ctx->quiet_shutdown;
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
3080Sstevel@tonic-gate 	s->ctx=ctx;
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	s->verify_result=X509_V_OK;
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	s->method=ctx->method;
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	if (!s->method->ssl_new(s))
3150Sstevel@tonic-gate 		goto err;
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate 	s->references=1;
3180Sstevel@tonic-gate 	s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	SSL_clear(s);
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	return(s);
3250Sstevel@tonic-gate err:
3260Sstevel@tonic-gate 	if (s != NULL)
3270Sstevel@tonic-gate 		{
3280Sstevel@tonic-gate 		if (s->cert != NULL)
3290Sstevel@tonic-gate 			ssl_cert_free(s->cert);
3300Sstevel@tonic-gate 		if (s->ctx != NULL)
3310Sstevel@tonic-gate 			SSL_CTX_free(s->ctx); /* decrement reference count */
3320Sstevel@tonic-gate 		OPENSSL_free(s);
3330Sstevel@tonic-gate 		}
3340Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
3350Sstevel@tonic-gate 	return(NULL);
3360Sstevel@tonic-gate 	}
3370Sstevel@tonic-gate 
SSL_CTX_set_session_id_context(SSL_CTX * ctx,const unsigned char * sid_ctx,unsigned int sid_ctx_len)3380Sstevel@tonic-gate int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
3390Sstevel@tonic-gate 				   unsigned int sid_ctx_len)
3400Sstevel@tonic-gate     {
3410Sstevel@tonic-gate     if(sid_ctx_len > sizeof ctx->sid_ctx)
3420Sstevel@tonic-gate 	{
3430Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
3440Sstevel@tonic-gate 	return 0;
3450Sstevel@tonic-gate 	}
3460Sstevel@tonic-gate     ctx->sid_ctx_length=sid_ctx_len;
3470Sstevel@tonic-gate     memcpy(ctx->sid_ctx,sid_ctx,sid_ctx_len);
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate     return 1;
3500Sstevel@tonic-gate     }
3510Sstevel@tonic-gate 
SSL_set_session_id_context(SSL * ssl,const unsigned char * sid_ctx,unsigned int sid_ctx_len)3520Sstevel@tonic-gate int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
3530Sstevel@tonic-gate 			       unsigned int sid_ctx_len)
3540Sstevel@tonic-gate     {
3550Sstevel@tonic-gate     if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
3560Sstevel@tonic-gate 	{
3570Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
3580Sstevel@tonic-gate 	return 0;
3590Sstevel@tonic-gate 	}
3600Sstevel@tonic-gate     ssl->sid_ctx_length=sid_ctx_len;
3610Sstevel@tonic-gate     memcpy(ssl->sid_ctx,sid_ctx,sid_ctx_len);
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate     return 1;
3640Sstevel@tonic-gate     }
3650Sstevel@tonic-gate 
SSL_CTX_set_generate_session_id(SSL_CTX * ctx,GEN_SESSION_CB cb)3660Sstevel@tonic-gate int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
3670Sstevel@tonic-gate 	{
3680Sstevel@tonic-gate 	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
3690Sstevel@tonic-gate 	ctx->generate_session_id = cb;
3700Sstevel@tonic-gate 	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
3710Sstevel@tonic-gate 	return 1;
3720Sstevel@tonic-gate 	}
3730Sstevel@tonic-gate 
SSL_set_generate_session_id(SSL * ssl,GEN_SESSION_CB cb)3740Sstevel@tonic-gate int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
3750Sstevel@tonic-gate 	{
3760Sstevel@tonic-gate 	CRYPTO_w_lock(CRYPTO_LOCK_SSL);
3770Sstevel@tonic-gate 	ssl->generate_session_id = cb;
3780Sstevel@tonic-gate 	CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
3790Sstevel@tonic-gate 	return 1;
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate 
SSL_has_matching_session_id(const SSL * ssl,const unsigned char * id,unsigned int id_len)3820Sstevel@tonic-gate int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
3830Sstevel@tonic-gate 				unsigned int id_len)
3840Sstevel@tonic-gate 	{
3850Sstevel@tonic-gate 	/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
3860Sstevel@tonic-gate 	 * we can "construct" a session to give us the desired check - ie. to
3870Sstevel@tonic-gate 	 * find if there's a session in the hash table that would conflict with
3880Sstevel@tonic-gate 	 * any new session built out of this id/id_len and the ssl_version in
3890Sstevel@tonic-gate 	 * use by this SSL. */
3900Sstevel@tonic-gate 	SSL_SESSION r, *p;
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	if(id_len > sizeof r.session_id)
3930Sstevel@tonic-gate 		return 0;
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 	r.ssl_version = ssl->version;
3960Sstevel@tonic-gate 	r.session_id_length = id_len;
3970Sstevel@tonic-gate 	memcpy(r.session_id, id, id_len);
3980Sstevel@tonic-gate 	/* NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
3990Sstevel@tonic-gate 	 * callback is calling us to check the uniqueness of a shorter ID, it
4000Sstevel@tonic-gate 	 * must be compared as a padded-out ID because that is what it will be
4010Sstevel@tonic-gate 	 * converted to when the callback has finished choosing it. */
4020Sstevel@tonic-gate 	if((r.ssl_version == SSL2_VERSION) &&
4030Sstevel@tonic-gate 			(id_len < SSL2_SSL_SESSION_ID_LENGTH))
4040Sstevel@tonic-gate 		{
4050Sstevel@tonic-gate 		memset(r.session_id + id_len, 0,
4060Sstevel@tonic-gate 			SSL2_SSL_SESSION_ID_LENGTH - id_len);
4070Sstevel@tonic-gate 		r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
4080Sstevel@tonic-gate 		}
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
4110Sstevel@tonic-gate 	p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r);
4120Sstevel@tonic-gate 	CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
4130Sstevel@tonic-gate 	return (p != NULL);
4140Sstevel@tonic-gate 	}
4150Sstevel@tonic-gate 
SSL_CTX_set_purpose(SSL_CTX * s,int purpose)4160Sstevel@tonic-gate int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
4170Sstevel@tonic-gate 	{
4182139Sjp161948 	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 
SSL_set_purpose(SSL * s,int purpose)4210Sstevel@tonic-gate int SSL_set_purpose(SSL *s, int purpose)
4220Sstevel@tonic-gate 	{
4232139Sjp161948 	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
4240Sstevel@tonic-gate 	}
4250Sstevel@tonic-gate 
SSL_CTX_set_trust(SSL_CTX * s,int trust)4260Sstevel@tonic-gate int SSL_CTX_set_trust(SSL_CTX *s, int trust)
4270Sstevel@tonic-gate 	{
4282139Sjp161948 	return X509_VERIFY_PARAM_set_trust(s->param, trust);
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 
SSL_set_trust(SSL * s,int trust)4310Sstevel@tonic-gate int SSL_set_trust(SSL *s, int trust)
4320Sstevel@tonic-gate 	{
4332139Sjp161948 	return X509_VERIFY_PARAM_set_trust(s->param, trust);
4340Sstevel@tonic-gate 	}
4350Sstevel@tonic-gate 
SSL_free(SSL * s)4360Sstevel@tonic-gate void SSL_free(SSL *s)
4370Sstevel@tonic-gate 	{
4380Sstevel@tonic-gate 	int i;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	if(s == NULL)
4410Sstevel@tonic-gate 	    return;
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	i=CRYPTO_add(&s->references,-1,CRYPTO_LOCK_SSL);
4440Sstevel@tonic-gate #ifdef REF_PRINT
4450Sstevel@tonic-gate 	REF_PRINT("SSL",s);
4460Sstevel@tonic-gate #endif
4470Sstevel@tonic-gate 	if (i > 0) return;
4480Sstevel@tonic-gate #ifdef REF_CHECK
4490Sstevel@tonic-gate 	if (i < 0)
4500Sstevel@tonic-gate 		{
4510Sstevel@tonic-gate 		fprintf(stderr,"SSL_free, bad reference count\n");
4520Sstevel@tonic-gate 		abort(); /* ok */
4530Sstevel@tonic-gate 		}
4540Sstevel@tonic-gate #endif
4550Sstevel@tonic-gate 
4562139Sjp161948 	if (s->param)
4572139Sjp161948 		X509_VERIFY_PARAM_free(s->param);
4582139Sjp161948 
4590Sstevel@tonic-gate 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	if (s->bbio != NULL)
4620Sstevel@tonic-gate 		{
4630Sstevel@tonic-gate 		/* If the buffering BIO is in place, pop it off */
4640Sstevel@tonic-gate 		if (s->bbio == s->wbio)
4650Sstevel@tonic-gate 			{
4660Sstevel@tonic-gate 			s->wbio=BIO_pop(s->wbio);
4670Sstevel@tonic-gate 			}
4680Sstevel@tonic-gate 		BIO_free(s->bbio);
4690Sstevel@tonic-gate 		s->bbio=NULL;
4700Sstevel@tonic-gate 		}
4710Sstevel@tonic-gate 	if (s->rbio != NULL)
4720Sstevel@tonic-gate 		BIO_free_all(s->rbio);
4730Sstevel@tonic-gate 	if ((s->wbio != NULL) && (s->wbio != s->rbio))
4740Sstevel@tonic-gate 		BIO_free_all(s->wbio);
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	if (s->init_buf != NULL) BUF_MEM_free(s->init_buf);
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	/* add extra stuff */
4790Sstevel@tonic-gate 	if (s->cipher_list != NULL) sk_SSL_CIPHER_free(s->cipher_list);
4800Sstevel@tonic-gate 	if (s->cipher_list_by_id != NULL) sk_SSL_CIPHER_free(s->cipher_list_by_id);
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 	/* Make the next call work :-) */
4830Sstevel@tonic-gate 	if (s->session != NULL)
4840Sstevel@tonic-gate 		{
4850Sstevel@tonic-gate 		ssl_clear_bad_session(s);
4860Sstevel@tonic-gate 		SSL_SESSION_free(s->session);
4870Sstevel@tonic-gate 		}
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 	ssl_clear_cipher_ctx(s);
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	if (s->cert != NULL) ssl_cert_free(s->cert);
4920Sstevel@tonic-gate 	/* Free up if allocated */
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 	if (s->ctx) SSL_CTX_free(s->ctx);
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	if (s->client_CA != NULL)
4970Sstevel@tonic-gate 		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate 	if (s->method != NULL) s->method->ssl_free(s);
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate #ifndef	OPENSSL_NO_KRB5
5020Sstevel@tonic-gate 	if (s->kssl_ctx != NULL)
5030Sstevel@tonic-gate 		kssl_ctx_free(s->kssl_ctx);
5040Sstevel@tonic-gate #endif	/* OPENSSL_NO_KRB5 */
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate 	OPENSSL_free(s);
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 
SSL_set_bio(SSL * s,BIO * rbio,BIO * wbio)5090Sstevel@tonic-gate void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
5100Sstevel@tonic-gate 	{
5110Sstevel@tonic-gate 	/* If the output buffering BIO is still in place, remove it
5120Sstevel@tonic-gate 	 */
5130Sstevel@tonic-gate 	if (s->bbio != NULL)
5140Sstevel@tonic-gate 		{
5150Sstevel@tonic-gate 		if (s->wbio == s->bbio)
5160Sstevel@tonic-gate 			{
5170Sstevel@tonic-gate 			s->wbio=s->wbio->next_bio;
5180Sstevel@tonic-gate 			s->bbio->next_bio=NULL;
5190Sstevel@tonic-gate 			}
5200Sstevel@tonic-gate 		}
5210Sstevel@tonic-gate 	if ((s->rbio != NULL) && (s->rbio != rbio))
5220Sstevel@tonic-gate 		BIO_free_all(s->rbio);
5230Sstevel@tonic-gate 	if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
5240Sstevel@tonic-gate 		BIO_free_all(s->wbio);
5250Sstevel@tonic-gate 	s->rbio=rbio;
5260Sstevel@tonic-gate 	s->wbio=wbio;
5270Sstevel@tonic-gate 	}
5280Sstevel@tonic-gate 
SSL_get_rbio(const SSL * s)5292139Sjp161948 BIO *SSL_get_rbio(const SSL *s)
5300Sstevel@tonic-gate 	{ return(s->rbio); }
5310Sstevel@tonic-gate 
SSL_get_wbio(const SSL * s)5322139Sjp161948 BIO *SSL_get_wbio(const SSL *s)
5330Sstevel@tonic-gate 	{ return(s->wbio); }
5340Sstevel@tonic-gate 
SSL_get_fd(const SSL * s)5352139Sjp161948 int SSL_get_fd(const SSL *s)
5360Sstevel@tonic-gate 	{
5370Sstevel@tonic-gate 	return(SSL_get_rfd(s));
5380Sstevel@tonic-gate 	}
5390Sstevel@tonic-gate 
SSL_get_rfd(const SSL * s)5402139Sjp161948 int SSL_get_rfd(const SSL *s)
5410Sstevel@tonic-gate 	{
5420Sstevel@tonic-gate 	int ret= -1;
5430Sstevel@tonic-gate 	BIO *b,*r;
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	b=SSL_get_rbio(s);
5460Sstevel@tonic-gate 	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
5470Sstevel@tonic-gate 	if (r != NULL)
5480Sstevel@tonic-gate 		BIO_get_fd(r,&ret);
5490Sstevel@tonic-gate 	return(ret);
5500Sstevel@tonic-gate 	}
5510Sstevel@tonic-gate 
SSL_get_wfd(const SSL * s)5522139Sjp161948 int SSL_get_wfd(const SSL *s)
5530Sstevel@tonic-gate 	{
5540Sstevel@tonic-gate 	int ret= -1;
5550Sstevel@tonic-gate 	BIO *b,*r;
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	b=SSL_get_wbio(s);
5580Sstevel@tonic-gate 	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
5590Sstevel@tonic-gate 	if (r != NULL)
5600Sstevel@tonic-gate 		BIO_get_fd(r,&ret);
5610Sstevel@tonic-gate 	return(ret);
5620Sstevel@tonic-gate 	}
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK
SSL_set_fd(SSL * s,int fd)5650Sstevel@tonic-gate int SSL_set_fd(SSL *s,int fd)
5660Sstevel@tonic-gate 	{
5670Sstevel@tonic-gate 	int ret=0;
5680Sstevel@tonic-gate 	BIO *bio=NULL;
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	bio=BIO_new(BIO_s_socket());
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	if (bio == NULL)
5730Sstevel@tonic-gate 		{
5740Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB);
5750Sstevel@tonic-gate 		goto err;
5760Sstevel@tonic-gate 		}
5770Sstevel@tonic-gate 	BIO_set_fd(bio,fd,BIO_NOCLOSE);
5780Sstevel@tonic-gate 	SSL_set_bio(s,bio,bio);
5790Sstevel@tonic-gate 	ret=1;
5800Sstevel@tonic-gate err:
5810Sstevel@tonic-gate 	return(ret);
5820Sstevel@tonic-gate 	}
5830Sstevel@tonic-gate 
SSL_set_wfd(SSL * s,int fd)5840Sstevel@tonic-gate int SSL_set_wfd(SSL *s,int fd)
5850Sstevel@tonic-gate 	{
5860Sstevel@tonic-gate 	int ret=0;
5870Sstevel@tonic-gate 	BIO *bio=NULL;
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 	if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET)
5900Sstevel@tonic-gate 		|| ((int)BIO_get_fd(s->rbio,NULL) != fd))
5910Sstevel@tonic-gate 		{
5920Sstevel@tonic-gate 		bio=BIO_new(BIO_s_socket());
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate 		if (bio == NULL)
5950Sstevel@tonic-gate 			{ SSLerr(SSL_F_SSL_SET_WFD,ERR_R_BUF_LIB); goto err; }
5960Sstevel@tonic-gate 		BIO_set_fd(bio,fd,BIO_NOCLOSE);
5970Sstevel@tonic-gate 		SSL_set_bio(s,SSL_get_rbio(s),bio);
5980Sstevel@tonic-gate 		}
5990Sstevel@tonic-gate 	else
6000Sstevel@tonic-gate 		SSL_set_bio(s,SSL_get_rbio(s),SSL_get_rbio(s));
6010Sstevel@tonic-gate 	ret=1;
6020Sstevel@tonic-gate err:
6030Sstevel@tonic-gate 	return(ret);
6040Sstevel@tonic-gate 	}
6050Sstevel@tonic-gate 
SSL_set_rfd(SSL * s,int fd)6060Sstevel@tonic-gate int SSL_set_rfd(SSL *s,int fd)
6070Sstevel@tonic-gate 	{
6080Sstevel@tonic-gate 	int ret=0;
6090Sstevel@tonic-gate 	BIO *bio=NULL;
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET)
6120Sstevel@tonic-gate 		|| ((int)BIO_get_fd(s->wbio,NULL) != fd))
6130Sstevel@tonic-gate 		{
6140Sstevel@tonic-gate 		bio=BIO_new(BIO_s_socket());
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate 		if (bio == NULL)
6170Sstevel@tonic-gate 			{
6180Sstevel@tonic-gate 			SSLerr(SSL_F_SSL_SET_RFD,ERR_R_BUF_LIB);
6190Sstevel@tonic-gate 			goto err;
6200Sstevel@tonic-gate 			}
6210Sstevel@tonic-gate 		BIO_set_fd(bio,fd,BIO_NOCLOSE);
6220Sstevel@tonic-gate 		SSL_set_bio(s,bio,SSL_get_wbio(s));
6230Sstevel@tonic-gate 		}
6240Sstevel@tonic-gate 	else
6250Sstevel@tonic-gate 		SSL_set_bio(s,SSL_get_wbio(s),SSL_get_wbio(s));
6260Sstevel@tonic-gate 	ret=1;
6270Sstevel@tonic-gate err:
6280Sstevel@tonic-gate 	return(ret);
6290Sstevel@tonic-gate 	}
6300Sstevel@tonic-gate #endif
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate /* return length of latest Finished message we sent, copy to 'buf' */
SSL_get_finished(const SSL * s,void * buf,size_t count)6342139Sjp161948 size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
6350Sstevel@tonic-gate 	{
6360Sstevel@tonic-gate 	size_t ret = 0;
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate 	if (s->s3 != NULL)
6390Sstevel@tonic-gate 		{
6400Sstevel@tonic-gate 		ret = s->s3->tmp.finish_md_len;
6410Sstevel@tonic-gate 		if (count > ret)
6420Sstevel@tonic-gate 			count = ret;
6430Sstevel@tonic-gate 		memcpy(buf, s->s3->tmp.finish_md, count);
6440Sstevel@tonic-gate 		}
6450Sstevel@tonic-gate 	return ret;
6460Sstevel@tonic-gate 	}
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate /* return length of latest Finished message we expected, copy to 'buf' */
SSL_get_peer_finished(const SSL * s,void * buf,size_t count)6492139Sjp161948 size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
6500Sstevel@tonic-gate 	{
6510Sstevel@tonic-gate 	size_t ret = 0;
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	if (s->s3 != NULL)
6540Sstevel@tonic-gate 		{
6550Sstevel@tonic-gate 		ret = s->s3->tmp.peer_finish_md_len;
6560Sstevel@tonic-gate 		if (count > ret)
6570Sstevel@tonic-gate 			count = ret;
6580Sstevel@tonic-gate 		memcpy(buf, s->s3->tmp.peer_finish_md, count);
6590Sstevel@tonic-gate 		}
6600Sstevel@tonic-gate 	return ret;
6610Sstevel@tonic-gate 	}
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 
SSL_get_verify_mode(const SSL * s)6642139Sjp161948 int SSL_get_verify_mode(const SSL *s)
6650Sstevel@tonic-gate 	{
6660Sstevel@tonic-gate 	return(s->verify_mode);
6670Sstevel@tonic-gate 	}
6680Sstevel@tonic-gate 
SSL_get_verify_depth(const SSL * s)6692139Sjp161948 int SSL_get_verify_depth(const SSL *s)
6700Sstevel@tonic-gate 	{
6712139Sjp161948 	return X509_VERIFY_PARAM_get_depth(s->param);
6720Sstevel@tonic-gate 	}
6730Sstevel@tonic-gate 
SSL_get_verify_callback(const SSL * s)6742139Sjp161948 int (*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *)
6750Sstevel@tonic-gate 	{
6760Sstevel@tonic-gate 	return(s->verify_callback);
6770Sstevel@tonic-gate 	}
6780Sstevel@tonic-gate 
SSL_CTX_get_verify_mode(const SSL_CTX * ctx)6792139Sjp161948 int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
6800Sstevel@tonic-gate 	{
6810Sstevel@tonic-gate 	return(ctx->verify_mode);
6820Sstevel@tonic-gate 	}
6830Sstevel@tonic-gate 
SSL_CTX_get_verify_depth(const SSL_CTX * ctx)6842139Sjp161948 int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
6850Sstevel@tonic-gate 	{
6862139Sjp161948 	return X509_VERIFY_PARAM_get_depth(ctx->param);
6870Sstevel@tonic-gate 	}
6880Sstevel@tonic-gate 
SSL_CTX_get_verify_callback(const SSL_CTX * ctx)6892139Sjp161948 int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *)
6900Sstevel@tonic-gate 	{
6910Sstevel@tonic-gate 	return(ctx->default_verify_callback);
6920Sstevel@tonic-gate 	}
6930Sstevel@tonic-gate 
SSL_set_verify(SSL * s,int mode,int (* callback)(int ok,X509_STORE_CTX * ctx))6940Sstevel@tonic-gate void SSL_set_verify(SSL *s,int mode,
6950Sstevel@tonic-gate 		    int (*callback)(int ok,X509_STORE_CTX *ctx))
6960Sstevel@tonic-gate 	{
6970Sstevel@tonic-gate 	s->verify_mode=mode;
6980Sstevel@tonic-gate 	if (callback != NULL)
6990Sstevel@tonic-gate 		s->verify_callback=callback;
7000Sstevel@tonic-gate 	}
7010Sstevel@tonic-gate 
SSL_set_verify_depth(SSL * s,int depth)7020Sstevel@tonic-gate void SSL_set_verify_depth(SSL *s,int depth)
7030Sstevel@tonic-gate 	{
7042139Sjp161948 	X509_VERIFY_PARAM_set_depth(s->param, depth);
7050Sstevel@tonic-gate 	}
7060Sstevel@tonic-gate 
SSL_set_read_ahead(SSL * s,int yes)7070Sstevel@tonic-gate void SSL_set_read_ahead(SSL *s,int yes)
7080Sstevel@tonic-gate 	{
7090Sstevel@tonic-gate 	s->read_ahead=yes;
7100Sstevel@tonic-gate 	}
7110Sstevel@tonic-gate 
SSL_get_read_ahead(const SSL * s)7122139Sjp161948 int SSL_get_read_ahead(const SSL *s)
7130Sstevel@tonic-gate 	{
7140Sstevel@tonic-gate 	return(s->read_ahead);
7150Sstevel@tonic-gate 	}
7160Sstevel@tonic-gate 
SSL_pending(const SSL * s)7172139Sjp161948 int SSL_pending(const SSL *s)
7180Sstevel@tonic-gate 	{
7190Sstevel@tonic-gate 	/* SSL_pending cannot work properly if read-ahead is enabled
7200Sstevel@tonic-gate 	 * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)),
7210Sstevel@tonic-gate 	 * and it is impossible to fix since SSL_pending cannot report
7220Sstevel@tonic-gate 	 * errors that may be observed while scanning the new data.
7230Sstevel@tonic-gate 	 * (Note that SSL_pending() is often used as a boolean value,
7240Sstevel@tonic-gate 	 * so we'd better not return -1.)
7250Sstevel@tonic-gate 	 */
7260Sstevel@tonic-gate 	return(s->method->ssl_pending(s));
7270Sstevel@tonic-gate 	}
7280Sstevel@tonic-gate 
SSL_get_peer_certificate(const SSL * s)7292139Sjp161948 X509 *SSL_get_peer_certificate(const SSL *s)
7300Sstevel@tonic-gate 	{
7310Sstevel@tonic-gate 	X509 *r;
7320Sstevel@tonic-gate 
7330Sstevel@tonic-gate 	if ((s == NULL) || (s->session == NULL))
7340Sstevel@tonic-gate 		r=NULL;
7350Sstevel@tonic-gate 	else
7360Sstevel@tonic-gate 		r=s->session->peer;
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate 	if (r == NULL) return(r);
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 	CRYPTO_add(&r->references,1,CRYPTO_LOCK_X509);
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 	return(r);
7430Sstevel@tonic-gate 	}
7440Sstevel@tonic-gate 
STACK_OF(X509)7452139Sjp161948 STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
7460Sstevel@tonic-gate 	{
7470Sstevel@tonic-gate 	STACK_OF(X509) *r;
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	if ((s == NULL) || (s->session == NULL) || (s->session->sess_cert == NULL))
7500Sstevel@tonic-gate 		r=NULL;
7510Sstevel@tonic-gate 	else
7520Sstevel@tonic-gate 		r=s->session->sess_cert->cert_chain;
7530Sstevel@tonic-gate 
7540Sstevel@tonic-gate 	/* If we are a client, cert_chain includes the peer's own
7550Sstevel@tonic-gate 	 * certificate; if we are a server, it does not. */
7560Sstevel@tonic-gate 
7570Sstevel@tonic-gate 	return(r);
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate /* Now in theory, since the calling process own 't' it should be safe to
7610Sstevel@tonic-gate  * modify.  We need to be able to read f without being hassled */
SSL_copy_session_id(SSL * t,const SSL * f)7622139Sjp161948 void SSL_copy_session_id(SSL *t,const SSL *f)
7630Sstevel@tonic-gate 	{
7640Sstevel@tonic-gate 	CERT *tmp;
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate 	/* Do we need to to SSL locking? */
7670Sstevel@tonic-gate 	SSL_set_session(t,SSL_get_session(f));
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate 	/* what if we are setup as SSLv2 but want to talk SSLv3 or
7700Sstevel@tonic-gate 	 * vice-versa */
7710Sstevel@tonic-gate 	if (t->method != f->method)
7720Sstevel@tonic-gate 		{
7730Sstevel@tonic-gate 		t->method->ssl_free(t);	/* cleanup current */
7740Sstevel@tonic-gate 		t->method=f->method;	/* change method */
7750Sstevel@tonic-gate 		t->method->ssl_new(t);	/* setup new */
7760Sstevel@tonic-gate 		}
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 	tmp=t->cert;
7790Sstevel@tonic-gate 	if (f->cert != NULL)
7800Sstevel@tonic-gate 		{
7810Sstevel@tonic-gate 		CRYPTO_add(&f->cert->references,1,CRYPTO_LOCK_SSL_CERT);
7820Sstevel@tonic-gate 		t->cert=f->cert;
7830Sstevel@tonic-gate 		}
7840Sstevel@tonic-gate 	else
7850Sstevel@tonic-gate 		t->cert=NULL;
7860Sstevel@tonic-gate 	if (tmp != NULL) ssl_cert_free(tmp);
7870Sstevel@tonic-gate 	SSL_set_session_id_context(t,f->sid_ctx,f->sid_ctx_length);
7880Sstevel@tonic-gate 	}
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate /* Fix this so it checks all the valid key/cert options */
SSL_CTX_check_private_key(const SSL_CTX * ctx)7912139Sjp161948 int SSL_CTX_check_private_key(const SSL_CTX *ctx)
7920Sstevel@tonic-gate 	{
7930Sstevel@tonic-gate 	if (	(ctx == NULL) ||
7940Sstevel@tonic-gate 		(ctx->cert == NULL) ||
7950Sstevel@tonic-gate 		(ctx->cert->key->x509 == NULL))
7960Sstevel@tonic-gate 		{
7970Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
7980Sstevel@tonic-gate 		return(0);
7990Sstevel@tonic-gate 		}
8000Sstevel@tonic-gate 	if 	(ctx->cert->key->privatekey == NULL)
8010Sstevel@tonic-gate 		{
8020Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
8030Sstevel@tonic-gate 		return(0);
8040Sstevel@tonic-gate 		}
8050Sstevel@tonic-gate 	return(X509_check_private_key(ctx->cert->key->x509, ctx->cert->key->privatekey));
8060Sstevel@tonic-gate 	}
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate /* Fix this function so that it takes an optional type parameter */
SSL_check_private_key(const SSL * ssl)8092139Sjp161948 int SSL_check_private_key(const SSL *ssl)
8100Sstevel@tonic-gate 	{
8110Sstevel@tonic-gate 	if (ssl == NULL)
8120Sstevel@tonic-gate 		{
8130Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,ERR_R_PASSED_NULL_PARAMETER);
8140Sstevel@tonic-gate 		return(0);
8150Sstevel@tonic-gate 		}
8160Sstevel@tonic-gate 	if (ssl->cert == NULL)
8170Sstevel@tonic-gate 		{
8180Sstevel@tonic-gate                 SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
8190Sstevel@tonic-gate 		return 0;
8200Sstevel@tonic-gate 		}
8210Sstevel@tonic-gate 	if (ssl->cert->key->x509 == NULL)
8220Sstevel@tonic-gate 		{
8230Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
8240Sstevel@tonic-gate 		return(0);
8250Sstevel@tonic-gate 		}
8260Sstevel@tonic-gate 	if (ssl->cert->key->privatekey == NULL)
8270Sstevel@tonic-gate 		{
8280Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
8290Sstevel@tonic-gate 		return(0);
8300Sstevel@tonic-gate 		}
8310Sstevel@tonic-gate 	return(X509_check_private_key(ssl->cert->key->x509,
8320Sstevel@tonic-gate 		ssl->cert->key->privatekey));
8330Sstevel@tonic-gate 	}
8340Sstevel@tonic-gate 
SSL_accept(SSL * s)8350Sstevel@tonic-gate int SSL_accept(SSL *s)
8360Sstevel@tonic-gate 	{
8370Sstevel@tonic-gate 	if (s->handshake_func == 0)
8380Sstevel@tonic-gate 		/* Not properly initialized yet */
8390Sstevel@tonic-gate 		SSL_set_accept_state(s);
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 	return(s->method->ssl_accept(s));
8420Sstevel@tonic-gate 	}
8430Sstevel@tonic-gate 
SSL_connect(SSL * s)8440Sstevel@tonic-gate int SSL_connect(SSL *s)
8450Sstevel@tonic-gate 	{
8460Sstevel@tonic-gate 	if (s->handshake_func == 0)
8470Sstevel@tonic-gate 		/* Not properly initialized yet */
8480Sstevel@tonic-gate 		SSL_set_connect_state(s);
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 	return(s->method->ssl_connect(s));
8510Sstevel@tonic-gate 	}
8520Sstevel@tonic-gate 
SSL_get_default_timeout(const SSL * s)8532139Sjp161948 long SSL_get_default_timeout(const SSL *s)
8540Sstevel@tonic-gate 	{
8550Sstevel@tonic-gate 	return(s->method->get_timeout());
8560Sstevel@tonic-gate 	}
8570Sstevel@tonic-gate 
SSL_read(SSL * s,void * buf,int num)8580Sstevel@tonic-gate int SSL_read(SSL *s,void *buf,int num)
8590Sstevel@tonic-gate 	{
8600Sstevel@tonic-gate 	if (s->handshake_func == 0)
8610Sstevel@tonic-gate 		{
8620Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
8630Sstevel@tonic-gate 		return -1;
8640Sstevel@tonic-gate 		}
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
8670Sstevel@tonic-gate 		{
8680Sstevel@tonic-gate 		s->rwstate=SSL_NOTHING;
8690Sstevel@tonic-gate 		return(0);
8700Sstevel@tonic-gate 		}
8710Sstevel@tonic-gate 	return(s->method->ssl_read(s,buf,num));
8720Sstevel@tonic-gate 	}
8730Sstevel@tonic-gate 
SSL_peek(SSL * s,void * buf,int num)8740Sstevel@tonic-gate int SSL_peek(SSL *s,void *buf,int num)
8750Sstevel@tonic-gate 	{
8760Sstevel@tonic-gate 	if (s->handshake_func == 0)
8770Sstevel@tonic-gate 		{
8782139Sjp161948 		SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
8790Sstevel@tonic-gate 		return -1;
8800Sstevel@tonic-gate 		}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
8830Sstevel@tonic-gate 		{
8840Sstevel@tonic-gate 		return(0);
8850Sstevel@tonic-gate 		}
8860Sstevel@tonic-gate 	return(s->method->ssl_peek(s,buf,num));
8870Sstevel@tonic-gate 	}
8880Sstevel@tonic-gate 
SSL_write(SSL * s,const void * buf,int num)8890Sstevel@tonic-gate int SSL_write(SSL *s,const void *buf,int num)
8900Sstevel@tonic-gate 	{
8910Sstevel@tonic-gate 	if (s->handshake_func == 0)
8920Sstevel@tonic-gate 		{
8930Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
8940Sstevel@tonic-gate 		return -1;
8950Sstevel@tonic-gate 		}
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 	if (s->shutdown & SSL_SENT_SHUTDOWN)
8980Sstevel@tonic-gate 		{
8990Sstevel@tonic-gate 		s->rwstate=SSL_NOTHING;
9000Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_WRITE,SSL_R_PROTOCOL_IS_SHUTDOWN);
9010Sstevel@tonic-gate 		return(-1);
9020Sstevel@tonic-gate 		}
9030Sstevel@tonic-gate 	return(s->method->ssl_write(s,buf,num));
9040Sstevel@tonic-gate 	}
9050Sstevel@tonic-gate 
SSL_shutdown(SSL * s)9060Sstevel@tonic-gate int SSL_shutdown(SSL *s)
9070Sstevel@tonic-gate 	{
9080Sstevel@tonic-gate 	/* Note that this function behaves differently from what one might
9090Sstevel@tonic-gate 	 * expect.  Return values are 0 for no success (yet),
9100Sstevel@tonic-gate 	 * 1 for success; but calling it once is usually not enough,
9110Sstevel@tonic-gate 	 * even if blocking I/O is used (see ssl3_shutdown).
9120Sstevel@tonic-gate 	 */
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 	if (s->handshake_func == 0)
9150Sstevel@tonic-gate 		{
9160Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
9170Sstevel@tonic-gate 		return -1;
9180Sstevel@tonic-gate 		}
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 	if ((s != NULL) && !SSL_in_init(s))
9210Sstevel@tonic-gate 		return(s->method->ssl_shutdown(s));
9220Sstevel@tonic-gate 	else
9230Sstevel@tonic-gate 		return(1);
9240Sstevel@tonic-gate 	}
9250Sstevel@tonic-gate 
SSL_renegotiate(SSL * s)9260Sstevel@tonic-gate int SSL_renegotiate(SSL *s)
9270Sstevel@tonic-gate 	{
9280Sstevel@tonic-gate 	if (s->new_session == 0)
9290Sstevel@tonic-gate 		{
9300Sstevel@tonic-gate 		s->new_session=1;
9310Sstevel@tonic-gate 		}
9320Sstevel@tonic-gate 	return(s->method->ssl_renegotiate(s));
9330Sstevel@tonic-gate 	}
9340Sstevel@tonic-gate 
SSL_renegotiate_pending(SSL * s)9350Sstevel@tonic-gate int SSL_renegotiate_pending(SSL *s)
9360Sstevel@tonic-gate 	{
9370Sstevel@tonic-gate 	/* becomes true when negotiation is requested;
9380Sstevel@tonic-gate 	 * false again once a handshake has finished */
9390Sstevel@tonic-gate 	return (s->new_session != 0);
9400Sstevel@tonic-gate 	}
9410Sstevel@tonic-gate 
SSL_ctrl(SSL * s,int cmd,long larg,void * parg)9420Sstevel@tonic-gate long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
9430Sstevel@tonic-gate 	{
9440Sstevel@tonic-gate 	long l;
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	switch (cmd)
9470Sstevel@tonic-gate 		{
9480Sstevel@tonic-gate 	case SSL_CTRL_GET_READ_AHEAD:
9490Sstevel@tonic-gate 		return(s->read_ahead);
9500Sstevel@tonic-gate 	case SSL_CTRL_SET_READ_AHEAD:
9510Sstevel@tonic-gate 		l=s->read_ahead;
9520Sstevel@tonic-gate 		s->read_ahead=larg;
9530Sstevel@tonic-gate 		return(l);
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
9560Sstevel@tonic-gate 		s->msg_callback_arg = parg;
9570Sstevel@tonic-gate 		return 1;
9580Sstevel@tonic-gate 
9590Sstevel@tonic-gate 	case SSL_CTRL_OPTIONS:
9600Sstevel@tonic-gate 		return(s->options|=larg);
9610Sstevel@tonic-gate 	case SSL_CTRL_MODE:
9620Sstevel@tonic-gate 		return(s->mode|=larg);
9630Sstevel@tonic-gate 	case SSL_CTRL_GET_MAX_CERT_LIST:
9640Sstevel@tonic-gate 		return(s->max_cert_list);
9650Sstevel@tonic-gate 	case SSL_CTRL_SET_MAX_CERT_LIST:
9660Sstevel@tonic-gate 		l=s->max_cert_list;
9670Sstevel@tonic-gate 		s->max_cert_list=larg;
9680Sstevel@tonic-gate 		return(l);
9692139Sjp161948 	case SSL_CTRL_SET_MTU:
9702139Sjp161948 		if (SSL_version(s) == DTLS1_VERSION)
9712139Sjp161948 			{
9722139Sjp161948 			s->d1->mtu = larg;
9732139Sjp161948 			return larg;
9742139Sjp161948 			}
9752139Sjp161948 		return 0;
9760Sstevel@tonic-gate 	default:
9770Sstevel@tonic-gate 		return(s->method->ssl_ctrl(s,cmd,larg,parg));
9780Sstevel@tonic-gate 		}
9790Sstevel@tonic-gate 	}
9800Sstevel@tonic-gate 
SSL_callback_ctrl(SSL * s,int cmd,void (* fp)(void))9812139Sjp161948 long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
9820Sstevel@tonic-gate 	{
9830Sstevel@tonic-gate 	switch(cmd)
9840Sstevel@tonic-gate 		{
9850Sstevel@tonic-gate 	case SSL_CTRL_SET_MSG_CALLBACK:
9860Sstevel@tonic-gate 		s->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
9870Sstevel@tonic-gate 		return 1;
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	default:
9900Sstevel@tonic-gate 		return(s->method->ssl_callback_ctrl(s,cmd,fp));
9910Sstevel@tonic-gate 		}
9920Sstevel@tonic-gate 	}
9930Sstevel@tonic-gate 
SSL_CTX_sessions(SSL_CTX * ctx)9940Sstevel@tonic-gate struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx)
9950Sstevel@tonic-gate 	{
9960Sstevel@tonic-gate 	return ctx->sessions;
9970Sstevel@tonic-gate 	}
9980Sstevel@tonic-gate 
SSL_CTX_ctrl(SSL_CTX * ctx,int cmd,long larg,void * parg)9990Sstevel@tonic-gate long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg)
10000Sstevel@tonic-gate 	{
10010Sstevel@tonic-gate 	long l;
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 	switch (cmd)
10040Sstevel@tonic-gate 		{
10050Sstevel@tonic-gate 	case SSL_CTRL_GET_READ_AHEAD:
10060Sstevel@tonic-gate 		return(ctx->read_ahead);
10070Sstevel@tonic-gate 	case SSL_CTRL_SET_READ_AHEAD:
10080Sstevel@tonic-gate 		l=ctx->read_ahead;
10090Sstevel@tonic-gate 		ctx->read_ahead=larg;
10100Sstevel@tonic-gate 		return(l);
10110Sstevel@tonic-gate 
10120Sstevel@tonic-gate 	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
10130Sstevel@tonic-gate 		ctx->msg_callback_arg = parg;
10140Sstevel@tonic-gate 		return 1;
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	case SSL_CTRL_GET_MAX_CERT_LIST:
10170Sstevel@tonic-gate 		return(ctx->max_cert_list);
10180Sstevel@tonic-gate 	case SSL_CTRL_SET_MAX_CERT_LIST:
10190Sstevel@tonic-gate 		l=ctx->max_cert_list;
10200Sstevel@tonic-gate 		ctx->max_cert_list=larg;
10210Sstevel@tonic-gate 		return(l);
10220Sstevel@tonic-gate 
10230Sstevel@tonic-gate 	case SSL_CTRL_SET_SESS_CACHE_SIZE:
10240Sstevel@tonic-gate 		l=ctx->session_cache_size;
10250Sstevel@tonic-gate 		ctx->session_cache_size=larg;
10260Sstevel@tonic-gate 		return(l);
10270Sstevel@tonic-gate 	case SSL_CTRL_GET_SESS_CACHE_SIZE:
10280Sstevel@tonic-gate 		return(ctx->session_cache_size);
10290Sstevel@tonic-gate 	case SSL_CTRL_SET_SESS_CACHE_MODE:
10300Sstevel@tonic-gate 		l=ctx->session_cache_mode;
10310Sstevel@tonic-gate 		ctx->session_cache_mode=larg;
10320Sstevel@tonic-gate 		return(l);
10330Sstevel@tonic-gate 	case SSL_CTRL_GET_SESS_CACHE_MODE:
10340Sstevel@tonic-gate 		return(ctx->session_cache_mode);
10350Sstevel@tonic-gate 
10360Sstevel@tonic-gate 	case SSL_CTRL_SESS_NUMBER:
10370Sstevel@tonic-gate 		return(ctx->sessions->num_items);
10380Sstevel@tonic-gate 	case SSL_CTRL_SESS_CONNECT:
10390Sstevel@tonic-gate 		return(ctx->stats.sess_connect);
10400Sstevel@tonic-gate 	case SSL_CTRL_SESS_CONNECT_GOOD:
10410Sstevel@tonic-gate 		return(ctx->stats.sess_connect_good);
10420Sstevel@tonic-gate 	case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
10430Sstevel@tonic-gate 		return(ctx->stats.sess_connect_renegotiate);
10440Sstevel@tonic-gate 	case SSL_CTRL_SESS_ACCEPT:
10450Sstevel@tonic-gate 		return(ctx->stats.sess_accept);
10460Sstevel@tonic-gate 	case SSL_CTRL_SESS_ACCEPT_GOOD:
10470Sstevel@tonic-gate 		return(ctx->stats.sess_accept_good);
10480Sstevel@tonic-gate 	case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
10490Sstevel@tonic-gate 		return(ctx->stats.sess_accept_renegotiate);
10500Sstevel@tonic-gate 	case SSL_CTRL_SESS_HIT:
10510Sstevel@tonic-gate 		return(ctx->stats.sess_hit);
10520Sstevel@tonic-gate 	case SSL_CTRL_SESS_CB_HIT:
10530Sstevel@tonic-gate 		return(ctx->stats.sess_cb_hit);
10540Sstevel@tonic-gate 	case SSL_CTRL_SESS_MISSES:
10550Sstevel@tonic-gate 		return(ctx->stats.sess_miss);
10560Sstevel@tonic-gate 	case SSL_CTRL_SESS_TIMEOUTS:
10570Sstevel@tonic-gate 		return(ctx->stats.sess_timeout);
10580Sstevel@tonic-gate 	case SSL_CTRL_SESS_CACHE_FULL:
10590Sstevel@tonic-gate 		return(ctx->stats.sess_cache_full);
10600Sstevel@tonic-gate 	case SSL_CTRL_OPTIONS:
10610Sstevel@tonic-gate 		return(ctx->options|=larg);
10620Sstevel@tonic-gate 	case SSL_CTRL_MODE:
10630Sstevel@tonic-gate 		return(ctx->mode|=larg);
10640Sstevel@tonic-gate 	default:
10650Sstevel@tonic-gate 		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
10660Sstevel@tonic-gate 		}
10670Sstevel@tonic-gate 	}
10680Sstevel@tonic-gate 
SSL_CTX_callback_ctrl(SSL_CTX * ctx,int cmd,void (* fp)(void))10692139Sjp161948 long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
10700Sstevel@tonic-gate 	{
10710Sstevel@tonic-gate 	switch(cmd)
10720Sstevel@tonic-gate 		{
10730Sstevel@tonic-gate 	case SSL_CTRL_SET_MSG_CALLBACK:
10740Sstevel@tonic-gate 		ctx->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
10750Sstevel@tonic-gate 		return 1;
10760Sstevel@tonic-gate 
10770Sstevel@tonic-gate 	default:
10780Sstevel@tonic-gate 		return(ctx->method->ssl_ctx_callback_ctrl(ctx,cmd,fp));
10790Sstevel@tonic-gate 		}
10800Sstevel@tonic-gate 	}
10810Sstevel@tonic-gate 
ssl_cipher_id_cmp(const SSL_CIPHER * a,const SSL_CIPHER * b)10820Sstevel@tonic-gate int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
10830Sstevel@tonic-gate 	{
10840Sstevel@tonic-gate 	long l;
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate 	l=a->id-b->id;
10870Sstevel@tonic-gate 	if (l == 0L)
10880Sstevel@tonic-gate 		return(0);
10890Sstevel@tonic-gate 	else
10900Sstevel@tonic-gate 		return((l > 0)?1:-1);
10910Sstevel@tonic-gate 	}
10920Sstevel@tonic-gate 
ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const * ap,const SSL_CIPHER * const * bp)10930Sstevel@tonic-gate int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
10940Sstevel@tonic-gate 			const SSL_CIPHER * const *bp)
10950Sstevel@tonic-gate 	{
10960Sstevel@tonic-gate 	long l;
10970Sstevel@tonic-gate 
10980Sstevel@tonic-gate 	l=(*ap)->id-(*bp)->id;
10990Sstevel@tonic-gate 	if (l == 0L)
11000Sstevel@tonic-gate 		return(0);
11010Sstevel@tonic-gate 	else
11020Sstevel@tonic-gate 		return((l > 0)?1:-1);
11030Sstevel@tonic-gate 	}
11040Sstevel@tonic-gate 
11050Sstevel@tonic-gate /** return a STACK of the ciphers available for the SSL and in order of
11060Sstevel@tonic-gate  * preference */
STACK_OF(SSL_CIPHER)11072139Sjp161948 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
11080Sstevel@tonic-gate 	{
11090Sstevel@tonic-gate 	if (s != NULL)
11100Sstevel@tonic-gate 		{
11110Sstevel@tonic-gate 		if (s->cipher_list != NULL)
11120Sstevel@tonic-gate 			{
11130Sstevel@tonic-gate 			return(s->cipher_list);
11140Sstevel@tonic-gate 			}
11150Sstevel@tonic-gate 		else if ((s->ctx != NULL) &&
11160Sstevel@tonic-gate 			(s->ctx->cipher_list != NULL))
11170Sstevel@tonic-gate 			{
11180Sstevel@tonic-gate 			return(s->ctx->cipher_list);
11190Sstevel@tonic-gate 			}
11200Sstevel@tonic-gate 		}
11210Sstevel@tonic-gate 	return(NULL);
11220Sstevel@tonic-gate 	}
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate /** return a STACK of the ciphers available for the SSL and in order of
11250Sstevel@tonic-gate  * algorithm id */
STACK_OF(SSL_CIPHER)11260Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
11270Sstevel@tonic-gate 	{
11280Sstevel@tonic-gate 	if (s != NULL)
11290Sstevel@tonic-gate 		{
11300Sstevel@tonic-gate 		if (s->cipher_list_by_id != NULL)
11310Sstevel@tonic-gate 			{
11320Sstevel@tonic-gate 			return(s->cipher_list_by_id);
11330Sstevel@tonic-gate 			}
11340Sstevel@tonic-gate 		else if ((s->ctx != NULL) &&
11350Sstevel@tonic-gate 			(s->ctx->cipher_list_by_id != NULL))
11360Sstevel@tonic-gate 			{
11370Sstevel@tonic-gate 			return(s->ctx->cipher_list_by_id);
11380Sstevel@tonic-gate 			}
11390Sstevel@tonic-gate 		}
11400Sstevel@tonic-gate 	return(NULL);
11410Sstevel@tonic-gate 	}
11420Sstevel@tonic-gate 
11430Sstevel@tonic-gate /** The old interface to get the same thing as SSL_get_ciphers() */
SSL_get_cipher_list(const SSL * s,int n)11442139Sjp161948 const char *SSL_get_cipher_list(const SSL *s,int n)
11450Sstevel@tonic-gate 	{
11460Sstevel@tonic-gate 	SSL_CIPHER *c;
11470Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
11480Sstevel@tonic-gate 
11490Sstevel@tonic-gate 	if (s == NULL) return(NULL);
11500Sstevel@tonic-gate 	sk=SSL_get_ciphers(s);
11510Sstevel@tonic-gate 	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
11520Sstevel@tonic-gate 		return(NULL);
11530Sstevel@tonic-gate 	c=sk_SSL_CIPHER_value(sk,n);
11540Sstevel@tonic-gate 	if (c == NULL) return(NULL);
11550Sstevel@tonic-gate 	return(c->name);
11560Sstevel@tonic-gate 	}
11570Sstevel@tonic-gate 
11580Sstevel@tonic-gate /** specify the ciphers to be used by default by the SSL_CTX */
SSL_CTX_set_cipher_list(SSL_CTX * ctx,const char * str)11590Sstevel@tonic-gate int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
11600Sstevel@tonic-gate 	{
11610Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
11620Sstevel@tonic-gate 
11630Sstevel@tonic-gate 	sk=ssl_create_cipher_list(ctx->method,&ctx->cipher_list,
11640Sstevel@tonic-gate 		&ctx->cipher_list_by_id,str);
11652139Sjp161948 	/* ssl_create_cipher_list may return an empty stack if it
11662139Sjp161948 	 * was unable to find a cipher matching the given rule string
11672139Sjp161948 	 * (for example if the rule string specifies a cipher which
11682139Sjp161948 	 * has been disabled). This is not an error as far as
11692139Sjp161948 	 * ssl_create_cipher_list is concerned, and hence
11702139Sjp161948 	 * ctx->cipher_list and ctx->cipher_list_by_id has been
11712139Sjp161948 	 * updated. */
11722139Sjp161948 	if (sk == NULL)
11732139Sjp161948 		return 0;
11742139Sjp161948 	else if (sk_SSL_CIPHER_num(sk) == 0)
11752139Sjp161948 		{
11762139Sjp161948 		SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
11772139Sjp161948 		return 0;
11782139Sjp161948 		}
11792139Sjp161948 	return 1;
11800Sstevel@tonic-gate 	}
11810Sstevel@tonic-gate 
11820Sstevel@tonic-gate /** specify the ciphers to be used by the SSL */
SSL_set_cipher_list(SSL * s,const char * str)11830Sstevel@tonic-gate int SSL_set_cipher_list(SSL *s,const char *str)
11840Sstevel@tonic-gate 	{
11850Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
11860Sstevel@tonic-gate 
11870Sstevel@tonic-gate 	sk=ssl_create_cipher_list(s->ctx->method,&s->cipher_list,
11880Sstevel@tonic-gate 		&s->cipher_list_by_id,str);
11892139Sjp161948 	/* see comment in SSL_CTX_set_cipher_list */
11902139Sjp161948 	if (sk == NULL)
11912139Sjp161948 		return 0;
11922139Sjp161948 	else if (sk_SSL_CIPHER_num(sk) == 0)
11932139Sjp161948 		{
11942139Sjp161948 		SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
11952139Sjp161948 		return 0;
11962139Sjp161948 		}
11972139Sjp161948 	return 1;
11980Sstevel@tonic-gate 	}
11990Sstevel@tonic-gate 
12000Sstevel@tonic-gate /* works well for SSLv2, not so good for SSLv3 */
SSL_get_shared_ciphers(const SSL * s,char * buf,int len)12012139Sjp161948 char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
12020Sstevel@tonic-gate 	{
12030Sstevel@tonic-gate 	char *p;
12040Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
12050Sstevel@tonic-gate 	SSL_CIPHER *c;
12060Sstevel@tonic-gate 	int i;
12070Sstevel@tonic-gate 
12080Sstevel@tonic-gate 	if ((s->session == NULL) || (s->session->ciphers == NULL) ||
12090Sstevel@tonic-gate 		(len < 2))
12100Sstevel@tonic-gate 		return(NULL);
12110Sstevel@tonic-gate 
12120Sstevel@tonic-gate 	p=buf;
12130Sstevel@tonic-gate 	sk=s->session->ciphers;
12140Sstevel@tonic-gate 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
12150Sstevel@tonic-gate 		{
1216*5211Sjp161948 		int n;
1217*5211Sjp161948 
12180Sstevel@tonic-gate 		c=sk_SSL_CIPHER_value(sk,i);
1219*5211Sjp161948 		n=strlen(c->name);
1220*5211Sjp161948 		if (n+1 > len)
12210Sstevel@tonic-gate 			{
1222*5211Sjp161948 			if (p != buf)
1223*5211Sjp161948 				--p;
1224*5211Sjp161948 			*p='\0';
1225*5211Sjp161948 			return buf;
12260Sstevel@tonic-gate 			}
1227*5211Sjp161948 		strcpy(p,c->name);
1228*5211Sjp161948 		p+=n;
12290Sstevel@tonic-gate 		*(p++)=':';
1230*5211Sjp161948 		len-=n+1;
12310Sstevel@tonic-gate 		}
12320Sstevel@tonic-gate 	p[-1]='\0';
12330Sstevel@tonic-gate 	return(buf);
12340Sstevel@tonic-gate 	}
12350Sstevel@tonic-gate 
ssl_cipher_list_to_bytes(SSL * s,STACK_OF (SSL_CIPHER)* sk,unsigned char * p,int (* put_cb)(const SSL_CIPHER *,unsigned char *))12362139Sjp161948 int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
12372139Sjp161948                              int (*put_cb)(const SSL_CIPHER *, unsigned char *))
12380Sstevel@tonic-gate 	{
12390Sstevel@tonic-gate 	int i,j=0;
12400Sstevel@tonic-gate 	SSL_CIPHER *c;
12410Sstevel@tonic-gate 	unsigned char *q;
12420Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
12430Sstevel@tonic-gate         int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
12440Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
12450Sstevel@tonic-gate 
12460Sstevel@tonic-gate 	if (sk == NULL) return(0);
12470Sstevel@tonic-gate 	q=p;
12480Sstevel@tonic-gate 
12490Sstevel@tonic-gate 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
12500Sstevel@tonic-gate 		{
12510Sstevel@tonic-gate 		c=sk_SSL_CIPHER_value(sk,i);
12520Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
12530Sstevel@tonic-gate                 if ((c->algorithms & SSL_KRB5) && nokrb5)
12540Sstevel@tonic-gate                     continue;
12550Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
12562139Sjp161948 
12572139Sjp161948 		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
12580Sstevel@tonic-gate 		p+=j;
12590Sstevel@tonic-gate 		}
12600Sstevel@tonic-gate 	return(p-q);
12610Sstevel@tonic-gate 	}
12620Sstevel@tonic-gate 
STACK_OF(SSL_CIPHER)12630Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
12640Sstevel@tonic-gate 					       STACK_OF(SSL_CIPHER) **skp)
12650Sstevel@tonic-gate 	{
12660Sstevel@tonic-gate 	SSL_CIPHER *c;
12670Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *sk;
12680Sstevel@tonic-gate 	int i,n;
12690Sstevel@tonic-gate 
12700Sstevel@tonic-gate 	n=ssl_put_cipher_by_char(s,NULL,NULL);
12710Sstevel@tonic-gate 	if ((num%n) != 0)
12720Sstevel@tonic-gate 		{
12730Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
12740Sstevel@tonic-gate 		return(NULL);
12750Sstevel@tonic-gate 		}
12760Sstevel@tonic-gate 	if ((skp == NULL) || (*skp == NULL))
12770Sstevel@tonic-gate 		sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
12780Sstevel@tonic-gate 	else
12790Sstevel@tonic-gate 		{
12800Sstevel@tonic-gate 		sk= *skp;
12810Sstevel@tonic-gate 		sk_SSL_CIPHER_zero(sk);
12820Sstevel@tonic-gate 		}
12830Sstevel@tonic-gate 
12840Sstevel@tonic-gate 	for (i=0; i<num; i+=n)
12850Sstevel@tonic-gate 		{
12860Sstevel@tonic-gate 		c=ssl_get_cipher_by_char(s,p);
12870Sstevel@tonic-gate 		p+=n;
12880Sstevel@tonic-gate 		if (c != NULL)
12890Sstevel@tonic-gate 			{
12900Sstevel@tonic-gate 			if (!sk_SSL_CIPHER_push(sk,c))
12910Sstevel@tonic-gate 				{
12920Sstevel@tonic-gate 				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
12930Sstevel@tonic-gate 				goto err;
12940Sstevel@tonic-gate 				}
12950Sstevel@tonic-gate 			}
12960Sstevel@tonic-gate 		}
12970Sstevel@tonic-gate 
12980Sstevel@tonic-gate 	if (skp != NULL)
12990Sstevel@tonic-gate 		*skp=sk;
13000Sstevel@tonic-gate 	return(sk);
13010Sstevel@tonic-gate err:
13020Sstevel@tonic-gate 	if ((skp == NULL) || (*skp == NULL))
13030Sstevel@tonic-gate 		sk_SSL_CIPHER_free(sk);
13040Sstevel@tonic-gate 	return(NULL);
13050Sstevel@tonic-gate 	}
13060Sstevel@tonic-gate 
SSL_SESSION_hash(const SSL_SESSION * a)13072139Sjp161948 unsigned long SSL_SESSION_hash(const SSL_SESSION *a)
13080Sstevel@tonic-gate 	{
13090Sstevel@tonic-gate 	unsigned long l;
13100Sstevel@tonic-gate 
13110Sstevel@tonic-gate 	l=(unsigned long)
13120Sstevel@tonic-gate 		((unsigned int) a->session_id[0]     )|
13130Sstevel@tonic-gate 		((unsigned int) a->session_id[1]<< 8L)|
13140Sstevel@tonic-gate 		((unsigned long)a->session_id[2]<<16L)|
13150Sstevel@tonic-gate 		((unsigned long)a->session_id[3]<<24L);
13160Sstevel@tonic-gate 	return(l);
13170Sstevel@tonic-gate 	}
13180Sstevel@tonic-gate 
13190Sstevel@tonic-gate /* NB: If this function (or indeed the hash function which uses a sort of
13200Sstevel@tonic-gate  * coarser function than this one) is changed, ensure
13210Sstevel@tonic-gate  * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
13220Sstevel@tonic-gate  * able to construct an SSL_SESSION that will collide with any existing session
13230Sstevel@tonic-gate  * with a matching session ID. */
SSL_SESSION_cmp(const SSL_SESSION * a,const SSL_SESSION * b)13242139Sjp161948 int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
13250Sstevel@tonic-gate 	{
13260Sstevel@tonic-gate 	if (a->ssl_version != b->ssl_version)
13270Sstevel@tonic-gate 		return(1);
13280Sstevel@tonic-gate 	if (a->session_id_length != b->session_id_length)
13290Sstevel@tonic-gate 		return(1);
13300Sstevel@tonic-gate 	return(memcmp(a->session_id,b->session_id,a->session_id_length));
13310Sstevel@tonic-gate 	}
13320Sstevel@tonic-gate 
13330Sstevel@tonic-gate /* These wrapper functions should remain rather than redeclaring
13340Sstevel@tonic-gate  * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
13350Sstevel@tonic-gate  * variable. The reason is that the functions aren't static, they're exposed via
13360Sstevel@tonic-gate  * ssl.h. */
IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash,SSL_SESSION *)13370Sstevel@tonic-gate static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *)
13380Sstevel@tonic-gate static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
13390Sstevel@tonic-gate 
13400Sstevel@tonic-gate SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
13410Sstevel@tonic-gate 	{
13420Sstevel@tonic-gate 	SSL_CTX *ret=NULL;
13430Sstevel@tonic-gate 
13440Sstevel@tonic-gate 	if (meth == NULL)
13450Sstevel@tonic-gate 		{
13460Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
13470Sstevel@tonic-gate 		return(NULL);
13480Sstevel@tonic-gate 		}
13490Sstevel@tonic-gate 
13500Sstevel@tonic-gate 	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
13510Sstevel@tonic-gate 		{
13520Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
13530Sstevel@tonic-gate 		goto err;
13540Sstevel@tonic-gate 		}
13550Sstevel@tonic-gate 	ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
13560Sstevel@tonic-gate 	if (ret == NULL)
13570Sstevel@tonic-gate 		goto err;
13580Sstevel@tonic-gate 
13590Sstevel@tonic-gate 	memset(ret,0,sizeof(SSL_CTX));
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate 	ret->method=meth;
13620Sstevel@tonic-gate 
13630Sstevel@tonic-gate 	ret->cert_store=NULL;
13640Sstevel@tonic-gate 	ret->session_cache_mode=SSL_SESS_CACHE_SERVER;
13650Sstevel@tonic-gate 	ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
13660Sstevel@tonic-gate 	ret->session_cache_head=NULL;
13670Sstevel@tonic-gate 	ret->session_cache_tail=NULL;
13680Sstevel@tonic-gate 
13690Sstevel@tonic-gate 	/* We take the system default */
13700Sstevel@tonic-gate 	ret->session_timeout=meth->get_timeout();
13710Sstevel@tonic-gate 
13720Sstevel@tonic-gate 	ret->new_session_cb=0;
13730Sstevel@tonic-gate 	ret->remove_session_cb=0;
13740Sstevel@tonic-gate 	ret->get_session_cb=0;
13750Sstevel@tonic-gate 	ret->generate_session_id=0;
13760Sstevel@tonic-gate 
13770Sstevel@tonic-gate 	memset((char *)&ret->stats,0,sizeof(ret->stats));
13780Sstevel@tonic-gate 
13790Sstevel@tonic-gate 	ret->references=1;
13800Sstevel@tonic-gate 	ret->quiet_shutdown=0;
13810Sstevel@tonic-gate 
13820Sstevel@tonic-gate /*	ret->cipher=NULL;*/
13830Sstevel@tonic-gate /*	ret->s2->challenge=NULL;
13840Sstevel@tonic-gate 	ret->master_key=NULL;
13850Sstevel@tonic-gate 	ret->key_arg=NULL;
13860Sstevel@tonic-gate 	ret->s2->conn_id=NULL; */
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 	ret->info_callback=NULL;
13890Sstevel@tonic-gate 
13900Sstevel@tonic-gate 	ret->app_verify_callback=0;
13910Sstevel@tonic-gate 	ret->app_verify_arg=NULL;
13920Sstevel@tonic-gate 
13930Sstevel@tonic-gate 	ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;
13940Sstevel@tonic-gate 	ret->read_ahead=0;
13950Sstevel@tonic-gate 	ret->msg_callback=0;
13960Sstevel@tonic-gate 	ret->msg_callback_arg=NULL;
13970Sstevel@tonic-gate 	ret->verify_mode=SSL_VERIFY_NONE;
13982139Sjp161948 #if 0
13990Sstevel@tonic-gate 	ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
14002139Sjp161948 #endif
14010Sstevel@tonic-gate 	ret->sid_ctx_length=0;
14020Sstevel@tonic-gate 	ret->default_verify_callback=NULL;
14030Sstevel@tonic-gate 	if ((ret->cert=ssl_cert_new()) == NULL)
14040Sstevel@tonic-gate 		goto err;
14050Sstevel@tonic-gate 
14060Sstevel@tonic-gate 	ret->default_passwd_callback=0;
14070Sstevel@tonic-gate 	ret->default_passwd_callback_userdata=NULL;
14080Sstevel@tonic-gate 	ret->client_cert_cb=0;
14092139Sjp161948 	ret->app_gen_cookie_cb=0;
14102139Sjp161948 	ret->app_verify_cookie_cb=0;
14110Sstevel@tonic-gate 
14120Sstevel@tonic-gate 	ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
14130Sstevel@tonic-gate 			LHASH_COMP_FN(SSL_SESSION_cmp));
14140Sstevel@tonic-gate 	if (ret->sessions == NULL) goto err;
14150Sstevel@tonic-gate 	ret->cert_store=X509_STORE_new();
14160Sstevel@tonic-gate 	if (ret->cert_store == NULL) goto err;
14170Sstevel@tonic-gate 
14180Sstevel@tonic-gate 	ssl_create_cipher_list(ret->method,
14190Sstevel@tonic-gate 		&ret->cipher_list,&ret->cipher_list_by_id,
14200Sstevel@tonic-gate 		SSL_DEFAULT_CIPHER_LIST);
14210Sstevel@tonic-gate 	if (ret->cipher_list == NULL
14220Sstevel@tonic-gate 	    || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
14230Sstevel@tonic-gate 		{
14240Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_LIBRARY_HAS_NO_CIPHERS);
14250Sstevel@tonic-gate 		goto err2;
14260Sstevel@tonic-gate 		}
14270Sstevel@tonic-gate 
14282139Sjp161948 	ret->param = X509_VERIFY_PARAM_new();
14292139Sjp161948 	if (!ret->param)
14302139Sjp161948 		goto err;
14312139Sjp161948 
14320Sstevel@tonic-gate 	if ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL)
14330Sstevel@tonic-gate 		{
14340Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES);
14350Sstevel@tonic-gate 		goto err2;
14360Sstevel@tonic-gate 		}
14370Sstevel@tonic-gate 	if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL)
14380Sstevel@tonic-gate 		{
14390Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
14400Sstevel@tonic-gate 		goto err2;
14410Sstevel@tonic-gate 		}
14420Sstevel@tonic-gate 	if ((ret->sha1=EVP_get_digestbyname("ssl3-sha1")) == NULL)
14430Sstevel@tonic-gate 		{
14440Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
14450Sstevel@tonic-gate 		goto err2;
14460Sstevel@tonic-gate 		}
14470Sstevel@tonic-gate 
14480Sstevel@tonic-gate 	if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)
14490Sstevel@tonic-gate 		goto err;
14500Sstevel@tonic-gate 
14510Sstevel@tonic-gate 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
14520Sstevel@tonic-gate 
14530Sstevel@tonic-gate 	ret->extra_certs=NULL;
14540Sstevel@tonic-gate 	ret->comp_methods=SSL_COMP_get_compression_methods();
14550Sstevel@tonic-gate 
14560Sstevel@tonic-gate 	return(ret);
14570Sstevel@tonic-gate err:
14580Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
14590Sstevel@tonic-gate err2:
14600Sstevel@tonic-gate 	if (ret != NULL) SSL_CTX_free(ret);
14610Sstevel@tonic-gate 	return(NULL);
14620Sstevel@tonic-gate 	}
14630Sstevel@tonic-gate 
14640Sstevel@tonic-gate #if 0
14650Sstevel@tonic-gate static void SSL_COMP_free(SSL_COMP *comp)
14660Sstevel@tonic-gate     { OPENSSL_free(comp); }
14670Sstevel@tonic-gate #endif
14680Sstevel@tonic-gate 
SSL_CTX_free(SSL_CTX * a)14690Sstevel@tonic-gate void SSL_CTX_free(SSL_CTX *a)
14700Sstevel@tonic-gate 	{
14710Sstevel@tonic-gate 	int i;
14720Sstevel@tonic-gate 
14730Sstevel@tonic-gate 	if (a == NULL) return;
14740Sstevel@tonic-gate 
14750Sstevel@tonic-gate 	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_SSL_CTX);
14760Sstevel@tonic-gate #ifdef REF_PRINT
14770Sstevel@tonic-gate 	REF_PRINT("SSL_CTX",a);
14780Sstevel@tonic-gate #endif
14790Sstevel@tonic-gate 	if (i > 0) return;
14800Sstevel@tonic-gate #ifdef REF_CHECK
14810Sstevel@tonic-gate 	if (i < 0)
14820Sstevel@tonic-gate 		{
14830Sstevel@tonic-gate 		fprintf(stderr,"SSL_CTX_free, bad reference count\n");
14840Sstevel@tonic-gate 		abort(); /* ok */
14850Sstevel@tonic-gate 		}
14860Sstevel@tonic-gate #endif
14870Sstevel@tonic-gate 
14882139Sjp161948 	if (a->param)
14892139Sjp161948 		X509_VERIFY_PARAM_free(a->param);
14902139Sjp161948 
14910Sstevel@tonic-gate 	/*
14920Sstevel@tonic-gate 	 * Free internal session cache. However: the remove_cb() may reference
14930Sstevel@tonic-gate 	 * the ex_data of SSL_CTX, thus the ex_data store can only be removed
14940Sstevel@tonic-gate 	 * after the sessions were flushed.
14950Sstevel@tonic-gate 	 * As the ex_data handling routines might also touch the session cache,
14960Sstevel@tonic-gate 	 * the most secure solution seems to be: empty (flush) the cache, then
14970Sstevel@tonic-gate 	 * free ex_data, then finally free the cache.
14980Sstevel@tonic-gate 	 * (See ticket [openssl.org #212].)
14990Sstevel@tonic-gate 	 */
15000Sstevel@tonic-gate 	if (a->sessions != NULL)
15010Sstevel@tonic-gate 		SSL_CTX_flush_sessions(a,0);
15020Sstevel@tonic-gate 
15030Sstevel@tonic-gate 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
15040Sstevel@tonic-gate 
15050Sstevel@tonic-gate 	if (a->sessions != NULL)
15060Sstevel@tonic-gate 		lh_free(a->sessions);
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate 	if (a->cert_store != NULL)
15090Sstevel@tonic-gate 		X509_STORE_free(a->cert_store);
15100Sstevel@tonic-gate 	if (a->cipher_list != NULL)
15110Sstevel@tonic-gate 		sk_SSL_CIPHER_free(a->cipher_list);
15120Sstevel@tonic-gate 	if (a->cipher_list_by_id != NULL)
15130Sstevel@tonic-gate 		sk_SSL_CIPHER_free(a->cipher_list_by_id);
15140Sstevel@tonic-gate 	if (a->cert != NULL)
15150Sstevel@tonic-gate 		ssl_cert_free(a->cert);
15160Sstevel@tonic-gate 	if (a->client_CA != NULL)
15170Sstevel@tonic-gate 		sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
15180Sstevel@tonic-gate 	if (a->extra_certs != NULL)
15190Sstevel@tonic-gate 		sk_X509_pop_free(a->extra_certs,X509_free);
15200Sstevel@tonic-gate #if 0 /* This should never be done, since it removes a global database */
15210Sstevel@tonic-gate 	if (a->comp_methods != NULL)
15220Sstevel@tonic-gate 		sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
15230Sstevel@tonic-gate #else
15240Sstevel@tonic-gate 	a->comp_methods = NULL;
15250Sstevel@tonic-gate #endif
15260Sstevel@tonic-gate 	OPENSSL_free(a);
15270Sstevel@tonic-gate 	}
15280Sstevel@tonic-gate 
SSL_CTX_set_default_passwd_cb(SSL_CTX * ctx,pem_password_cb * cb)15290Sstevel@tonic-gate void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
15300Sstevel@tonic-gate 	{
15310Sstevel@tonic-gate 	ctx->default_passwd_callback=cb;
15320Sstevel@tonic-gate 	}
15330Sstevel@tonic-gate 
SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX * ctx,void * u)15340Sstevel@tonic-gate void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,void *u)
15350Sstevel@tonic-gate 	{
15360Sstevel@tonic-gate 	ctx->default_passwd_callback_userdata=u;
15370Sstevel@tonic-gate 	}
15380Sstevel@tonic-gate 
SSL_CTX_set_cert_verify_callback(SSL_CTX * ctx,int (* cb)(X509_STORE_CTX *,void *),void * arg)15390Sstevel@tonic-gate void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg)
15400Sstevel@tonic-gate 	{
15410Sstevel@tonic-gate 	ctx->app_verify_callback=cb;
15420Sstevel@tonic-gate 	ctx->app_verify_arg=arg;
15430Sstevel@tonic-gate 	}
15440Sstevel@tonic-gate 
SSL_CTX_set_verify(SSL_CTX * ctx,int mode,int (* cb)(int,X509_STORE_CTX *))15450Sstevel@tonic-gate void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
15460Sstevel@tonic-gate 	{
15470Sstevel@tonic-gate 	ctx->verify_mode=mode;
15480Sstevel@tonic-gate 	ctx->default_verify_callback=cb;
15490Sstevel@tonic-gate 	}
15500Sstevel@tonic-gate 
SSL_CTX_set_verify_depth(SSL_CTX * ctx,int depth)15510Sstevel@tonic-gate void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
15520Sstevel@tonic-gate 	{
15532139Sjp161948 	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
15540Sstevel@tonic-gate 	}
15550Sstevel@tonic-gate 
ssl_set_cert_masks(CERT * c,SSL_CIPHER * cipher)15560Sstevel@tonic-gate void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
15570Sstevel@tonic-gate 	{
15580Sstevel@tonic-gate 	CERT_PKEY *cpk;
15590Sstevel@tonic-gate 	int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
15600Sstevel@tonic-gate 	int rsa_enc_export,dh_rsa_export,dh_dsa_export;
15610Sstevel@tonic-gate 	int rsa_tmp_export,dh_tmp_export,kl;
15620Sstevel@tonic-gate 	unsigned long mask,emask;
15632139Sjp161948 	int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;
15642139Sjp161948 #ifndef OPENSSL_NO_ECDH
15652139Sjp161948 	int have_ecdh_tmp;
15662139Sjp161948 #endif
15672139Sjp161948 	X509 *x = NULL;
15682139Sjp161948 	EVP_PKEY *ecc_pkey = NULL;
15692139Sjp161948 	int signature_nid = 0;
15700Sstevel@tonic-gate 
15710Sstevel@tonic-gate 	if (c == NULL) return;
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 	kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
15740Sstevel@tonic-gate 
15750Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
15760Sstevel@tonic-gate 	rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
15770Sstevel@tonic-gate 	rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
15780Sstevel@tonic-gate 		(rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
15790Sstevel@tonic-gate #else
15800Sstevel@tonic-gate 	rsa_tmp=rsa_tmp_export=0;
15810Sstevel@tonic-gate #endif
15820Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
15830Sstevel@tonic-gate 	dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
15840Sstevel@tonic-gate 	dh_tmp_export=(c->dh_tmp_cb != NULL ||
15850Sstevel@tonic-gate 		(dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
15860Sstevel@tonic-gate #else
15870Sstevel@tonic-gate 	dh_tmp=dh_tmp_export=0;
15880Sstevel@tonic-gate #endif
15890Sstevel@tonic-gate 
15902139Sjp161948 #ifndef OPENSSL_NO_ECDH
15912139Sjp161948 	have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);
15922139Sjp161948 #endif
15930Sstevel@tonic-gate 	cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]);
15940Sstevel@tonic-gate 	rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL);
15950Sstevel@tonic-gate 	rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
15960Sstevel@tonic-gate 	cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);
15970Sstevel@tonic-gate 	rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
15980Sstevel@tonic-gate 	cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);
15990Sstevel@tonic-gate 	dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
16000Sstevel@tonic-gate 	cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);
16010Sstevel@tonic-gate 	dh_rsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
16020Sstevel@tonic-gate 	dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
16030Sstevel@tonic-gate 	cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);
16040Sstevel@tonic-gate /* FIX THIS EAY EAY EAY */
16050Sstevel@tonic-gate 	dh_dsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
16060Sstevel@tonic-gate 	dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
16072139Sjp161948 	cpk= &(c->pkeys[SSL_PKEY_ECC]);
16082139Sjp161948 	have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL);
16090Sstevel@tonic-gate 	mask=0;
16100Sstevel@tonic-gate 	emask=0;
16110Sstevel@tonic-gate 
16120Sstevel@tonic-gate #ifdef CIPHER_DEBUG
16130Sstevel@tonic-gate 	printf("rt=%d rte=%d dht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
16140Sstevel@tonic-gate 		rsa_tmp,rsa_tmp_export,dh_tmp,
16150Sstevel@tonic-gate 		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
16160Sstevel@tonic-gate #endif
16170Sstevel@tonic-gate 
16180Sstevel@tonic-gate 	if (rsa_enc || (rsa_tmp && rsa_sign))
16190Sstevel@tonic-gate 		mask|=SSL_kRSA;
16200Sstevel@tonic-gate 	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
16210Sstevel@tonic-gate 		emask|=SSL_kRSA;
16220Sstevel@tonic-gate 
16230Sstevel@tonic-gate #if 0
16240Sstevel@tonic-gate 	/* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
16250Sstevel@tonic-gate 	if (	(dh_tmp || dh_rsa || dh_dsa) &&
16260Sstevel@tonic-gate 		(rsa_enc || rsa_sign || dsa_sign))
16270Sstevel@tonic-gate 		mask|=SSL_kEDH;
16280Sstevel@tonic-gate 	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
16290Sstevel@tonic-gate 		(rsa_enc || rsa_sign || dsa_sign))
16300Sstevel@tonic-gate 		emask|=SSL_kEDH;
16310Sstevel@tonic-gate #endif
16320Sstevel@tonic-gate 
16330Sstevel@tonic-gate 	if (dh_tmp_export)
16340Sstevel@tonic-gate 		emask|=SSL_kEDH;
16350Sstevel@tonic-gate 
16360Sstevel@tonic-gate 	if (dh_tmp)
16370Sstevel@tonic-gate 		mask|=SSL_kEDH;
16380Sstevel@tonic-gate 
16390Sstevel@tonic-gate 	if (dh_rsa) mask|=SSL_kDHr;
16400Sstevel@tonic-gate 	if (dh_rsa_export) emask|=SSL_kDHr;
16410Sstevel@tonic-gate 
16420Sstevel@tonic-gate 	if (dh_dsa) mask|=SSL_kDHd;
16430Sstevel@tonic-gate 	if (dh_dsa_export) emask|=SSL_kDHd;
16440Sstevel@tonic-gate 
16450Sstevel@tonic-gate 	if (rsa_enc || rsa_sign)
16460Sstevel@tonic-gate 		{
16470Sstevel@tonic-gate 		mask|=SSL_aRSA;
16480Sstevel@tonic-gate 		emask|=SSL_aRSA;
16490Sstevel@tonic-gate 		}
16500Sstevel@tonic-gate 
16510Sstevel@tonic-gate 	if (dsa_sign)
16520Sstevel@tonic-gate 		{
16530Sstevel@tonic-gate 		mask|=SSL_aDSS;
16540Sstevel@tonic-gate 		emask|=SSL_aDSS;
16550Sstevel@tonic-gate 		}
16560Sstevel@tonic-gate 
16570Sstevel@tonic-gate 	mask|=SSL_aNULL;
16580Sstevel@tonic-gate 	emask|=SSL_aNULL;
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
16610Sstevel@tonic-gate 	mask|=SSL_kKRB5|SSL_aKRB5;
16620Sstevel@tonic-gate 	emask|=SSL_kKRB5|SSL_aKRB5;
16630Sstevel@tonic-gate #endif
16640Sstevel@tonic-gate 
16652139Sjp161948 	/* An ECC certificate may be usable for ECDH and/or
16662139Sjp161948 	 * ECDSA cipher suites depending on the key usage extension.
16672139Sjp161948 	 */
16682139Sjp161948 	if (have_ecc_cert)
16692139Sjp161948 		{
16702139Sjp161948                 /* This call populates extension flags (ex_flags) */
16712139Sjp161948 		x = (c->pkeys[SSL_PKEY_ECC]).x509;
16722139Sjp161948 		X509_check_purpose(x, -1, 0);
16732139Sjp161948 		ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
16742139Sjp161948 		    (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
16752139Sjp161948 		ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
16762139Sjp161948 		    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
16772139Sjp161948 		ecc_pkey = X509_get_pubkey(x);
16782139Sjp161948 		ecc_pkey_size = (ecc_pkey != NULL) ?
16792139Sjp161948 		    EVP_PKEY_bits(ecc_pkey) : 0;
16802139Sjp161948 		EVP_PKEY_free(ecc_pkey);
16812139Sjp161948 		if ((x->sig_alg) && (x->sig_alg->algorithm))
16822139Sjp161948 			signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
16832139Sjp161948 #ifndef OPENSSL_NO_ECDH
16842139Sjp161948 		if (ecdh_ok)
16852139Sjp161948 			{
16862139Sjp161948 			if ((signature_nid == NID_md5WithRSAEncryption) ||
16872139Sjp161948 			    (signature_nid == NID_md4WithRSAEncryption) ||
16882139Sjp161948 			    (signature_nid == NID_md2WithRSAEncryption))
16892139Sjp161948 				{
16902139Sjp161948 				mask|=SSL_kECDH|SSL_aRSA;
16912139Sjp161948 				if (ecc_pkey_size <= 163)
16922139Sjp161948 					emask|=SSL_kECDH|SSL_aRSA;
16932139Sjp161948 				}
16942139Sjp161948 			if (signature_nid == NID_ecdsa_with_SHA1)
16952139Sjp161948 				{
16962139Sjp161948 				mask|=SSL_kECDH|SSL_aECDSA;
16972139Sjp161948 				if (ecc_pkey_size <= 163)
16982139Sjp161948 					emask|=SSL_kECDH|SSL_aECDSA;
16992139Sjp161948 				}
17002139Sjp161948 			}
17012139Sjp161948 #endif
17022139Sjp161948 #ifndef OPENSSL_NO_ECDSA
17032139Sjp161948 		if (ecdsa_ok)
17042139Sjp161948 			{
17052139Sjp161948 			mask|=SSL_aECDSA;
17062139Sjp161948 			emask|=SSL_aECDSA;
17072139Sjp161948 			}
17082139Sjp161948 #endif
17092139Sjp161948 		}
17102139Sjp161948 
17112139Sjp161948 #ifndef OPENSSL_NO_ECDH
17122139Sjp161948 	if (have_ecdh_tmp)
17132139Sjp161948 		{
17142139Sjp161948 		mask|=SSL_kECDHE;
17152139Sjp161948 		emask|=SSL_kECDHE;
17162139Sjp161948 		}
17172139Sjp161948 #endif
17180Sstevel@tonic-gate 	c->mask=mask;
17190Sstevel@tonic-gate 	c->export_mask=emask;
17200Sstevel@tonic-gate 	c->valid=1;
17210Sstevel@tonic-gate 	}
17220Sstevel@tonic-gate 
17232139Sjp161948 /* This handy macro borrowed from crypto/x509v3/v3_purp.c */
17242139Sjp161948 #define ku_reject(x, usage) \
17252139Sjp161948 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
17262139Sjp161948 
check_srvr_ecc_cert_and_alg(X509 * x,SSL_CIPHER * cs)17272139Sjp161948 int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs)
17282139Sjp161948 	{
17292139Sjp161948 	unsigned long alg = cs->algorithms;
17302139Sjp161948 	EVP_PKEY *pkey = NULL;
17312139Sjp161948 	int keysize = 0;
17322139Sjp161948 	int signature_nid = 0;
17332139Sjp161948 
17342139Sjp161948 	if (SSL_C_IS_EXPORT(cs))
17352139Sjp161948 		{
17362139Sjp161948 		/* ECDH key length in export ciphers must be <= 163 bits */
17372139Sjp161948 		pkey = X509_get_pubkey(x);
17382139Sjp161948 		if (pkey == NULL) return 0;
17392139Sjp161948 		keysize = EVP_PKEY_bits(pkey);
17402139Sjp161948 		EVP_PKEY_free(pkey);
17412139Sjp161948 		if (keysize > 163) return 0;
17422139Sjp161948 		}
17432139Sjp161948 
17442139Sjp161948 	/* This call populates the ex_flags field correctly */
17452139Sjp161948 	X509_check_purpose(x, -1, 0);
17462139Sjp161948 	if ((x->sig_alg) && (x->sig_alg->algorithm))
17472139Sjp161948 		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
17482139Sjp161948 	if (alg & SSL_kECDH)
17492139Sjp161948 		{
17502139Sjp161948 		/* key usage, if present, must allow key agreement */
17512139Sjp161948 		if (ku_reject(x, X509v3_KU_KEY_AGREEMENT))
17522139Sjp161948 			{
17532139Sjp161948 			return 0;
17542139Sjp161948 			}
17552139Sjp161948 		if (alg & SSL_aECDSA)
17562139Sjp161948 			{
17572139Sjp161948 			/* signature alg must be ECDSA */
17582139Sjp161948 			if (signature_nid != NID_ecdsa_with_SHA1)
17592139Sjp161948 				{
17602139Sjp161948 				return 0;
17612139Sjp161948 				}
17622139Sjp161948 			}
17632139Sjp161948 		if (alg & SSL_aRSA)
17642139Sjp161948 			{
17652139Sjp161948 			/* signature alg must be RSA */
17662139Sjp161948 			if ((signature_nid != NID_md5WithRSAEncryption) &&
17672139Sjp161948 			    (signature_nid != NID_md4WithRSAEncryption) &&
17682139Sjp161948 			    (signature_nid != NID_md2WithRSAEncryption))
17692139Sjp161948 				{
17702139Sjp161948 				return 0;
17712139Sjp161948 				}
17722139Sjp161948 			}
17732139Sjp161948 		}
17742139Sjp161948 	else if (alg & SSL_aECDSA)
17752139Sjp161948 		{
17762139Sjp161948 		/* key usage, if present, must allow signing */
17772139Sjp161948 		if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
17782139Sjp161948 			{
17792139Sjp161948 			return 0;
17802139Sjp161948 			}
17812139Sjp161948 		}
17822139Sjp161948 
17832139Sjp161948 	return 1;  /* all checks are ok */
17842139Sjp161948 	}
17852139Sjp161948 
17860Sstevel@tonic-gate /* THIS NEEDS CLEANING UP */
ssl_get_server_send_cert(SSL * s)17870Sstevel@tonic-gate X509 *ssl_get_server_send_cert(SSL *s)
17880Sstevel@tonic-gate 	{
17890Sstevel@tonic-gate 	unsigned long alg,mask,kalg;
17900Sstevel@tonic-gate 	CERT *c;
17910Sstevel@tonic-gate 	int i,is_export;
17920Sstevel@tonic-gate 
17930Sstevel@tonic-gate 	c=s->cert;
17940Sstevel@tonic-gate 	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
17950Sstevel@tonic-gate 	alg=s->s3->tmp.new_cipher->algorithms;
17960Sstevel@tonic-gate 	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
17970Sstevel@tonic-gate 	mask=is_export?c->export_mask:c->mask;
17980Sstevel@tonic-gate 	kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);
17990Sstevel@tonic-gate 
18002139Sjp161948 	if (kalg & SSL_kECDH)
18012139Sjp161948 		{
18022139Sjp161948 		/* we don't need to look at SSL_kECDHE
18032139Sjp161948 		 * since no certificate is needed for
18042139Sjp161948 		 * anon ECDH and for authenticated
18052139Sjp161948 		 * ECDHE, the check for the auth
18062139Sjp161948 		 * algorithm will set i correctly
18072139Sjp161948 		 * NOTE: For ECDH-RSA, we need an ECC
18082139Sjp161948 		 * not an RSA cert but for ECDHE-RSA
18092139Sjp161948 		 * we need an RSA cert. Placing the
18102139Sjp161948 		 * checks for SSL_kECDH before RSA
18112139Sjp161948 		 * checks ensures the correct cert is chosen.
18122139Sjp161948 		 */
18132139Sjp161948 		i=SSL_PKEY_ECC;
18142139Sjp161948 		}
18152139Sjp161948 	else if (kalg & SSL_aECDSA)
18162139Sjp161948 		{
18172139Sjp161948 		i=SSL_PKEY_ECC;
18182139Sjp161948 		}
18192139Sjp161948 	else if (kalg & SSL_kDHr)
18200Sstevel@tonic-gate 		i=SSL_PKEY_DH_RSA;
18210Sstevel@tonic-gate 	else if (kalg & SSL_kDHd)
18220Sstevel@tonic-gate 		i=SSL_PKEY_DH_DSA;
18230Sstevel@tonic-gate 	else if (kalg & SSL_aDSS)
18240Sstevel@tonic-gate 		i=SSL_PKEY_DSA_SIGN;
18250Sstevel@tonic-gate 	else if (kalg & SSL_aRSA)
18260Sstevel@tonic-gate 		{
18270Sstevel@tonic-gate 		if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
18280Sstevel@tonic-gate 			i=SSL_PKEY_RSA_SIGN;
18290Sstevel@tonic-gate 		else
18300Sstevel@tonic-gate 			i=SSL_PKEY_RSA_ENC;
18310Sstevel@tonic-gate 		}
18320Sstevel@tonic-gate 	else if (kalg & SSL_aKRB5)
18330Sstevel@tonic-gate 		{
18340Sstevel@tonic-gate 		/* VRS something else here? */
18350Sstevel@tonic-gate 		return(NULL);
18360Sstevel@tonic-gate 		}
18370Sstevel@tonic-gate 	else /* if (kalg & SSL_aNULL) */
18380Sstevel@tonic-gate 		{
18390Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
18400Sstevel@tonic-gate 		return(NULL);
18410Sstevel@tonic-gate 		}
18420Sstevel@tonic-gate 	if (c->pkeys[i].x509 == NULL) return(NULL);
18432139Sjp161948 
18440Sstevel@tonic-gate 	return(c->pkeys[i].x509);
18450Sstevel@tonic-gate 	}
18460Sstevel@tonic-gate 
ssl_get_sign_pkey(SSL * s,SSL_CIPHER * cipher)18470Sstevel@tonic-gate EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)
18480Sstevel@tonic-gate 	{
18490Sstevel@tonic-gate 	unsigned long alg;
18500Sstevel@tonic-gate 	CERT *c;
18510Sstevel@tonic-gate 
18520Sstevel@tonic-gate 	alg=cipher->algorithms;
18530Sstevel@tonic-gate 	c=s->cert;
18540Sstevel@tonic-gate 
18550Sstevel@tonic-gate 	if ((alg & SSL_aDSS) &&
18560Sstevel@tonic-gate 		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
18570Sstevel@tonic-gate 		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
18580Sstevel@tonic-gate 	else if (alg & SSL_aRSA)
18590Sstevel@tonic-gate 		{
18600Sstevel@tonic-gate 		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
18610Sstevel@tonic-gate 			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
18620Sstevel@tonic-gate 		else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
18630Sstevel@tonic-gate 			return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey);
18640Sstevel@tonic-gate 		else
18650Sstevel@tonic-gate 			return(NULL);
18660Sstevel@tonic-gate 		}
18672139Sjp161948 	else if ((alg & SSL_aECDSA) &&
18682139Sjp161948 	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
18692139Sjp161948 		return(c->pkeys[SSL_PKEY_ECC].privatekey);
18700Sstevel@tonic-gate 	else /* if (alg & SSL_aNULL) */
18710Sstevel@tonic-gate 		{
18720Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
18730Sstevel@tonic-gate 		return(NULL);
18740Sstevel@tonic-gate 		}
18750Sstevel@tonic-gate 	}
18760Sstevel@tonic-gate 
ssl_update_cache(SSL * s,int mode)18770Sstevel@tonic-gate void ssl_update_cache(SSL *s,int mode)
18780Sstevel@tonic-gate 	{
18790Sstevel@tonic-gate 	int i;
18800Sstevel@tonic-gate 
18810Sstevel@tonic-gate 	/* If the session_id_length is 0, we are not supposed to cache it,
18820Sstevel@tonic-gate 	 * and it would be rather hard to do anyway :-) */
18830Sstevel@tonic-gate 	if (s->session->session_id_length == 0) return;
18840Sstevel@tonic-gate 
18850Sstevel@tonic-gate 	i=s->ctx->session_cache_mode;
18860Sstevel@tonic-gate 	if ((i & mode) && (!s->hit)
18870Sstevel@tonic-gate 		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
18880Sstevel@tonic-gate 		    || SSL_CTX_add_session(s->ctx,s->session))
18890Sstevel@tonic-gate 		&& (s->ctx->new_session_cb != NULL))
18900Sstevel@tonic-gate 		{
18910Sstevel@tonic-gate 		CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
18920Sstevel@tonic-gate 		if (!s->ctx->new_session_cb(s,s->session))
18930Sstevel@tonic-gate 			SSL_SESSION_free(s->session);
18940Sstevel@tonic-gate 		}
18950Sstevel@tonic-gate 
18960Sstevel@tonic-gate 	/* auto flush every 255 connections */
18970Sstevel@tonic-gate 	if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) &&
18980Sstevel@tonic-gate 		((i & mode) == mode))
18990Sstevel@tonic-gate 		{
19000Sstevel@tonic-gate 		if (  (((mode & SSL_SESS_CACHE_CLIENT)
19010Sstevel@tonic-gate 			?s->ctx->stats.sess_connect_good
19020Sstevel@tonic-gate 			:s->ctx->stats.sess_accept_good) & 0xff) == 0xff)
19030Sstevel@tonic-gate 			{
19040Sstevel@tonic-gate 			SSL_CTX_flush_sessions(s->ctx,time(NULL));
19050Sstevel@tonic-gate 			}
19060Sstevel@tonic-gate 		}
19070Sstevel@tonic-gate 	}
19080Sstevel@tonic-gate 
SSL_get_ssl_method(SSL * s)19090Sstevel@tonic-gate SSL_METHOD *SSL_get_ssl_method(SSL *s)
19100Sstevel@tonic-gate 	{
19110Sstevel@tonic-gate 	return(s->method);
19120Sstevel@tonic-gate 	}
19130Sstevel@tonic-gate 
SSL_set_ssl_method(SSL * s,SSL_METHOD * meth)19140Sstevel@tonic-gate int SSL_set_ssl_method(SSL *s,SSL_METHOD *meth)
19150Sstevel@tonic-gate 	{
19160Sstevel@tonic-gate 	int conn= -1;
19170Sstevel@tonic-gate 	int ret=1;
19180Sstevel@tonic-gate 
19190Sstevel@tonic-gate 	if (s->method != meth)
19200Sstevel@tonic-gate 		{
19210Sstevel@tonic-gate 		if (s->handshake_func != NULL)
19220Sstevel@tonic-gate 			conn=(s->handshake_func == s->method->ssl_connect);
19230Sstevel@tonic-gate 
19240Sstevel@tonic-gate 		if (s->method->version == meth->version)
19250Sstevel@tonic-gate 			s->method=meth;
19260Sstevel@tonic-gate 		else
19270Sstevel@tonic-gate 			{
19280Sstevel@tonic-gate 			s->method->ssl_free(s);
19290Sstevel@tonic-gate 			s->method=meth;
19300Sstevel@tonic-gate 			ret=s->method->ssl_new(s);
19310Sstevel@tonic-gate 			}
19320Sstevel@tonic-gate 
19330Sstevel@tonic-gate 		if (conn == 1)
19340Sstevel@tonic-gate 			s->handshake_func=meth->ssl_connect;
19350Sstevel@tonic-gate 		else if (conn == 0)
19360Sstevel@tonic-gate 			s->handshake_func=meth->ssl_accept;
19370Sstevel@tonic-gate 		}
19380Sstevel@tonic-gate 	return(ret);
19390Sstevel@tonic-gate 	}
19400Sstevel@tonic-gate 
SSL_get_error(const SSL * s,int i)19412139Sjp161948 int SSL_get_error(const SSL *s,int i)
19420Sstevel@tonic-gate 	{
19430Sstevel@tonic-gate 	int reason;
19440Sstevel@tonic-gate 	unsigned long l;
19450Sstevel@tonic-gate 	BIO *bio;
19460Sstevel@tonic-gate 
19470Sstevel@tonic-gate 	if (i > 0) return(SSL_ERROR_NONE);
19480Sstevel@tonic-gate 
19490Sstevel@tonic-gate 	/* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake
19500Sstevel@tonic-gate 	 * etc, where we do encode the error */
19510Sstevel@tonic-gate 	if ((l=ERR_peek_error()) != 0)
19520Sstevel@tonic-gate 		{
19530Sstevel@tonic-gate 		if (ERR_GET_LIB(l) == ERR_LIB_SYS)
19540Sstevel@tonic-gate 			return(SSL_ERROR_SYSCALL);
19550Sstevel@tonic-gate 		else
19560Sstevel@tonic-gate 			return(SSL_ERROR_SSL);
19570Sstevel@tonic-gate 		}
19580Sstevel@tonic-gate 
19590Sstevel@tonic-gate 	if ((i < 0) && SSL_want_read(s))
19600Sstevel@tonic-gate 		{
19610Sstevel@tonic-gate 		bio=SSL_get_rbio(s);
19620Sstevel@tonic-gate 		if (BIO_should_read(bio))
19630Sstevel@tonic-gate 			return(SSL_ERROR_WANT_READ);
19640Sstevel@tonic-gate 		else if (BIO_should_write(bio))
19650Sstevel@tonic-gate 			/* This one doesn't make too much sense ... We never try
19660Sstevel@tonic-gate 			 * to write to the rbio, and an application program where
19670Sstevel@tonic-gate 			 * rbio and wbio are separate couldn't even know what it
19680Sstevel@tonic-gate 			 * should wait for.
19690Sstevel@tonic-gate 			 * However if we ever set s->rwstate incorrectly
19700Sstevel@tonic-gate 			 * (so that we have SSL_want_read(s) instead of
19710Sstevel@tonic-gate 			 * SSL_want_write(s)) and rbio and wbio *are* the same,
19720Sstevel@tonic-gate 			 * this test works around that bug; so it might be safer
19730Sstevel@tonic-gate 			 * to keep it. */
19740Sstevel@tonic-gate 			return(SSL_ERROR_WANT_WRITE);
19750Sstevel@tonic-gate 		else if (BIO_should_io_special(bio))
19760Sstevel@tonic-gate 			{
19770Sstevel@tonic-gate 			reason=BIO_get_retry_reason(bio);
19780Sstevel@tonic-gate 			if (reason == BIO_RR_CONNECT)
19790Sstevel@tonic-gate 				return(SSL_ERROR_WANT_CONNECT);
19800Sstevel@tonic-gate 			else if (reason == BIO_RR_ACCEPT)
19810Sstevel@tonic-gate 				return(SSL_ERROR_WANT_ACCEPT);
19820Sstevel@tonic-gate 			else
19830Sstevel@tonic-gate 				return(SSL_ERROR_SYSCALL); /* unknown */
19840Sstevel@tonic-gate 			}
19850Sstevel@tonic-gate 		}
19860Sstevel@tonic-gate 
19870Sstevel@tonic-gate 	if ((i < 0) && SSL_want_write(s))
19880Sstevel@tonic-gate 		{
19890Sstevel@tonic-gate 		bio=SSL_get_wbio(s);
19900Sstevel@tonic-gate 		if (BIO_should_write(bio))
19910Sstevel@tonic-gate 			return(SSL_ERROR_WANT_WRITE);
19920Sstevel@tonic-gate 		else if (BIO_should_read(bio))
19930Sstevel@tonic-gate 			/* See above (SSL_want_read(s) with BIO_should_write(bio)) */
19940Sstevel@tonic-gate 			return(SSL_ERROR_WANT_READ);
19950Sstevel@tonic-gate 		else if (BIO_should_io_special(bio))
19960Sstevel@tonic-gate 			{
19970Sstevel@tonic-gate 			reason=BIO_get_retry_reason(bio);
19980Sstevel@tonic-gate 			if (reason == BIO_RR_CONNECT)
19990Sstevel@tonic-gate 				return(SSL_ERROR_WANT_CONNECT);
20000Sstevel@tonic-gate 			else if (reason == BIO_RR_ACCEPT)
20010Sstevel@tonic-gate 				return(SSL_ERROR_WANT_ACCEPT);
20020Sstevel@tonic-gate 			else
20030Sstevel@tonic-gate 				return(SSL_ERROR_SYSCALL);
20040Sstevel@tonic-gate 			}
20050Sstevel@tonic-gate 		}
20060Sstevel@tonic-gate 	if ((i < 0) && SSL_want_x509_lookup(s))
20070Sstevel@tonic-gate 		{
20080Sstevel@tonic-gate 		return(SSL_ERROR_WANT_X509_LOOKUP);
20090Sstevel@tonic-gate 		}
20100Sstevel@tonic-gate 
20110Sstevel@tonic-gate 	if (i == 0)
20120Sstevel@tonic-gate 		{
20130Sstevel@tonic-gate 		if (s->version == SSL2_VERSION)
20140Sstevel@tonic-gate 			{
20150Sstevel@tonic-gate 			/* assume it is the socket being closed */
20160Sstevel@tonic-gate 			return(SSL_ERROR_ZERO_RETURN);
20170Sstevel@tonic-gate 			}
20180Sstevel@tonic-gate 		else
20190Sstevel@tonic-gate 			{
20200Sstevel@tonic-gate 			if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
20210Sstevel@tonic-gate 				(s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
20220Sstevel@tonic-gate 				return(SSL_ERROR_ZERO_RETURN);
20230Sstevel@tonic-gate 			}
20240Sstevel@tonic-gate 		}
20250Sstevel@tonic-gate 	return(SSL_ERROR_SYSCALL);
20260Sstevel@tonic-gate 	}
20270Sstevel@tonic-gate 
SSL_do_handshake(SSL * s)20280Sstevel@tonic-gate int SSL_do_handshake(SSL *s)
20290Sstevel@tonic-gate 	{
20300Sstevel@tonic-gate 	int ret=1;
20310Sstevel@tonic-gate 
20320Sstevel@tonic-gate 	if (s->handshake_func == NULL)
20330Sstevel@tonic-gate 		{
20340Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_CONNECTION_TYPE_NOT_SET);
20350Sstevel@tonic-gate 		return(-1);
20360Sstevel@tonic-gate 		}
20370Sstevel@tonic-gate 
20380Sstevel@tonic-gate 	s->method->ssl_renegotiate_check(s);
20390Sstevel@tonic-gate 
20400Sstevel@tonic-gate 	if (SSL_in_init(s) || SSL_in_before(s))
20410Sstevel@tonic-gate 		{
20420Sstevel@tonic-gate 		ret=s->handshake_func(s);
20430Sstevel@tonic-gate 		}
20440Sstevel@tonic-gate 	return(ret);
20450Sstevel@tonic-gate 	}
20460Sstevel@tonic-gate 
20470Sstevel@tonic-gate /* For the next 2 functions, SSL_clear() sets shutdown and so
20480Sstevel@tonic-gate  * one of these calls will reset it */
SSL_set_accept_state(SSL * s)20490Sstevel@tonic-gate void SSL_set_accept_state(SSL *s)
20500Sstevel@tonic-gate 	{
20510Sstevel@tonic-gate 	s->server=1;
20520Sstevel@tonic-gate 	s->shutdown=0;
20530Sstevel@tonic-gate 	s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;
20540Sstevel@tonic-gate 	s->handshake_func=s->method->ssl_accept;
20550Sstevel@tonic-gate 	/* clear the current cipher */
20560Sstevel@tonic-gate 	ssl_clear_cipher_ctx(s);
20570Sstevel@tonic-gate 	}
20580Sstevel@tonic-gate 
SSL_set_connect_state(SSL * s)20590Sstevel@tonic-gate void SSL_set_connect_state(SSL *s)
20600Sstevel@tonic-gate 	{
20610Sstevel@tonic-gate 	s->server=0;
20620Sstevel@tonic-gate 	s->shutdown=0;
20630Sstevel@tonic-gate 	s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;
20640Sstevel@tonic-gate 	s->handshake_func=s->method->ssl_connect;
20650Sstevel@tonic-gate 	/* clear the current cipher */
20660Sstevel@tonic-gate 	ssl_clear_cipher_ctx(s);
20670Sstevel@tonic-gate 	}
20680Sstevel@tonic-gate 
ssl_undefined_function(SSL * s)20690Sstevel@tonic-gate int ssl_undefined_function(SSL *s)
20700Sstevel@tonic-gate 	{
20710Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
20720Sstevel@tonic-gate 	return(0);
20730Sstevel@tonic-gate 	}
20740Sstevel@tonic-gate 
ssl_undefined_void_function(void)20752139Sjp161948 int ssl_undefined_void_function(void)
20762139Sjp161948 	{
20772139Sjp161948 	SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
20782139Sjp161948 	return(0);
20792139Sjp161948 	}
20802139Sjp161948 
ssl_undefined_const_function(const SSL * s)20812139Sjp161948 int ssl_undefined_const_function(const SSL *s)
20822139Sjp161948 	{
20832139Sjp161948 	SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
20842139Sjp161948 	return(0);
20852139Sjp161948 	}
20862139Sjp161948 
ssl_bad_method(int ver)20870Sstevel@tonic-gate SSL_METHOD *ssl_bad_method(int ver)
20880Sstevel@tonic-gate 	{
20890Sstevel@tonic-gate 	SSLerr(SSL_F_SSL_BAD_METHOD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
20900Sstevel@tonic-gate 	return(NULL);
20910Sstevel@tonic-gate 	}
20920Sstevel@tonic-gate 
SSL_get_version(const SSL * s)20932139Sjp161948 const char *SSL_get_version(const SSL *s)
20940Sstevel@tonic-gate 	{
20950Sstevel@tonic-gate 	if (s->version == TLS1_VERSION)
20960Sstevel@tonic-gate 		return("TLSv1");
20970Sstevel@tonic-gate 	else if (s->version == SSL3_VERSION)
20980Sstevel@tonic-gate 		return("SSLv3");
20990Sstevel@tonic-gate 	else if (s->version == SSL2_VERSION)
21000Sstevel@tonic-gate 		return("SSLv2");
21010Sstevel@tonic-gate 	else
21020Sstevel@tonic-gate 		return("unknown");
21030Sstevel@tonic-gate 	}
21040Sstevel@tonic-gate 
SSL_dup(SSL * s)21050Sstevel@tonic-gate SSL *SSL_dup(SSL *s)
21060Sstevel@tonic-gate 	{
21070Sstevel@tonic-gate 	STACK_OF(X509_NAME) *sk;
21080Sstevel@tonic-gate 	X509_NAME *xn;
21090Sstevel@tonic-gate 	SSL *ret;
21100Sstevel@tonic-gate 	int i;
21110Sstevel@tonic-gate 
21120Sstevel@tonic-gate 	if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
21130Sstevel@tonic-gate 	    return(NULL);
21140Sstevel@tonic-gate 
21150Sstevel@tonic-gate 	ret->version = s->version;
21160Sstevel@tonic-gate 	ret->type = s->type;
21170Sstevel@tonic-gate 	ret->method = s->method;
21180Sstevel@tonic-gate 
21190Sstevel@tonic-gate 	if (s->session != NULL)
21200Sstevel@tonic-gate 		{
21210Sstevel@tonic-gate 		/* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
21220Sstevel@tonic-gate 		SSL_copy_session_id(ret,s);
21230Sstevel@tonic-gate 		}
21240Sstevel@tonic-gate 	else
21250Sstevel@tonic-gate 		{
21260Sstevel@tonic-gate 		/* No session has been established yet, so we have to expect
21270Sstevel@tonic-gate 		 * that s->cert or ret->cert will be changed later --
21280Sstevel@tonic-gate 		 * they should not both point to the same object,
21290Sstevel@tonic-gate 		 * and thus we can't use SSL_copy_session_id. */
21300Sstevel@tonic-gate 
21310Sstevel@tonic-gate 		ret->method->ssl_free(ret);
21320Sstevel@tonic-gate 		ret->method = s->method;
21330Sstevel@tonic-gate 		ret->method->ssl_new(ret);
21340Sstevel@tonic-gate 
21350Sstevel@tonic-gate 		if (s->cert != NULL)
21360Sstevel@tonic-gate 			{
21370Sstevel@tonic-gate 			if (ret->cert != NULL)
21380Sstevel@tonic-gate 				{
21390Sstevel@tonic-gate 				ssl_cert_free(ret->cert);
21400Sstevel@tonic-gate 				}
21410Sstevel@tonic-gate 			ret->cert = ssl_cert_dup(s->cert);
21420Sstevel@tonic-gate 			if (ret->cert == NULL)
21430Sstevel@tonic-gate 				goto err;
21440Sstevel@tonic-gate 			}
21450Sstevel@tonic-gate 
21460Sstevel@tonic-gate 		SSL_set_session_id_context(ret,
21470Sstevel@tonic-gate 			s->sid_ctx, s->sid_ctx_length);
21480Sstevel@tonic-gate 		}
21490Sstevel@tonic-gate 
21500Sstevel@tonic-gate 	ret->options=s->options;
21510Sstevel@tonic-gate 	ret->mode=s->mode;
21520Sstevel@tonic-gate 	SSL_set_max_cert_list(ret,SSL_get_max_cert_list(s));
21530Sstevel@tonic-gate 	SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
21540Sstevel@tonic-gate 	ret->msg_callback = s->msg_callback;
21550Sstevel@tonic-gate 	ret->msg_callback_arg = s->msg_callback_arg;
21560Sstevel@tonic-gate 	SSL_set_verify(ret,SSL_get_verify_mode(s),
21570Sstevel@tonic-gate 		SSL_get_verify_callback(s));
21580Sstevel@tonic-gate 	SSL_set_verify_depth(ret,SSL_get_verify_depth(s));
21590Sstevel@tonic-gate 	ret->generate_session_id = s->generate_session_id;
21600Sstevel@tonic-gate 
21610Sstevel@tonic-gate 	SSL_set_info_callback(ret,SSL_get_info_callback(s));
21620Sstevel@tonic-gate 
21630Sstevel@tonic-gate 	ret->debug=s->debug;
21640Sstevel@tonic-gate 
21650Sstevel@tonic-gate 	/* copy app data, a little dangerous perhaps */
21660Sstevel@tonic-gate 	if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
21670Sstevel@tonic-gate 		goto err;
21680Sstevel@tonic-gate 
21690Sstevel@tonic-gate 	/* setup rbio, and wbio */
21700Sstevel@tonic-gate 	if (s->rbio != NULL)
21710Sstevel@tonic-gate 		{
21720Sstevel@tonic-gate 		if (!BIO_dup_state(s->rbio,(char *)&ret->rbio))
21730Sstevel@tonic-gate 			goto err;
21740Sstevel@tonic-gate 		}
21750Sstevel@tonic-gate 	if (s->wbio != NULL)
21760Sstevel@tonic-gate 		{
21770Sstevel@tonic-gate 		if (s->wbio != s->rbio)
21780Sstevel@tonic-gate 			{
21790Sstevel@tonic-gate 			if (!BIO_dup_state(s->wbio,(char *)&ret->wbio))
21800Sstevel@tonic-gate 				goto err;
21810Sstevel@tonic-gate 			}
21820Sstevel@tonic-gate 		else
21830Sstevel@tonic-gate 			ret->wbio=ret->rbio;
21840Sstevel@tonic-gate 		}
21850Sstevel@tonic-gate 	ret->rwstate = s->rwstate;
21860Sstevel@tonic-gate 	ret->in_handshake = s->in_handshake;
21870Sstevel@tonic-gate 	ret->handshake_func = s->handshake_func;
21880Sstevel@tonic-gate 	ret->server = s->server;
21890Sstevel@tonic-gate 	ret->new_session = s->new_session;
21900Sstevel@tonic-gate 	ret->quiet_shutdown = s->quiet_shutdown;
21910Sstevel@tonic-gate 	ret->shutdown=s->shutdown;
21920Sstevel@tonic-gate 	ret->state=s->state; /* SSL_dup does not really work at any state, though */
21930Sstevel@tonic-gate 	ret->rstate=s->rstate;
21940Sstevel@tonic-gate 	ret->init_num = 0; /* would have to copy ret->init_buf, ret->init_msg, ret->init_num, ret->init_off */
21950Sstevel@tonic-gate 	ret->hit=s->hit;
21962139Sjp161948 
21972139Sjp161948 	X509_VERIFY_PARAM_inherit(ret->param, s->param);
21980Sstevel@tonic-gate 
21990Sstevel@tonic-gate 	/* dup the cipher_list and cipher_list_by_id stacks */
22000Sstevel@tonic-gate 	if (s->cipher_list != NULL)
22010Sstevel@tonic-gate 		{
22020Sstevel@tonic-gate 		if ((ret->cipher_list=sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
22030Sstevel@tonic-gate 			goto err;
22040Sstevel@tonic-gate 		}
22050Sstevel@tonic-gate 	if (s->cipher_list_by_id != NULL)
22060Sstevel@tonic-gate 		if ((ret->cipher_list_by_id=sk_SSL_CIPHER_dup(s->cipher_list_by_id))
22070Sstevel@tonic-gate 			== NULL)
22080Sstevel@tonic-gate 			goto err;
22090Sstevel@tonic-gate 
22100Sstevel@tonic-gate 	/* Dup the client_CA list */
22110Sstevel@tonic-gate 	if (s->client_CA != NULL)
22120Sstevel@tonic-gate 		{
22130Sstevel@tonic-gate 		if ((sk=sk_X509_NAME_dup(s->client_CA)) == NULL) goto err;
22140Sstevel@tonic-gate 		ret->client_CA=sk;
22150Sstevel@tonic-gate 		for (i=0; i<sk_X509_NAME_num(sk); i++)
22160Sstevel@tonic-gate 			{
22170Sstevel@tonic-gate 			xn=sk_X509_NAME_value(sk,i);
22180Sstevel@tonic-gate 			if (sk_X509_NAME_set(sk,i,X509_NAME_dup(xn)) == NULL)
22190Sstevel@tonic-gate 				{
22200Sstevel@tonic-gate 				X509_NAME_free(xn);
22210Sstevel@tonic-gate 				goto err;
22220Sstevel@tonic-gate 				}
22230Sstevel@tonic-gate 			}
22240Sstevel@tonic-gate 		}
22250Sstevel@tonic-gate 
22260Sstevel@tonic-gate 	if (0)
22270Sstevel@tonic-gate 		{
22280Sstevel@tonic-gate err:
22290Sstevel@tonic-gate 		if (ret != NULL) SSL_free(ret);
22300Sstevel@tonic-gate 		ret=NULL;
22310Sstevel@tonic-gate 		}
22320Sstevel@tonic-gate 	return(ret);
22330Sstevel@tonic-gate 	}
22340Sstevel@tonic-gate 
ssl_clear_cipher_ctx(SSL * s)22350Sstevel@tonic-gate void ssl_clear_cipher_ctx(SSL *s)
22360Sstevel@tonic-gate 	{
22370Sstevel@tonic-gate 	if (s->enc_read_ctx != NULL)
22380Sstevel@tonic-gate 		{
22390Sstevel@tonic-gate 		EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
22400Sstevel@tonic-gate 		OPENSSL_free(s->enc_read_ctx);
22410Sstevel@tonic-gate 		s->enc_read_ctx=NULL;
22420Sstevel@tonic-gate 		}
22430Sstevel@tonic-gate 	if (s->enc_write_ctx != NULL)
22440Sstevel@tonic-gate 		{
22450Sstevel@tonic-gate 		EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
22460Sstevel@tonic-gate 		OPENSSL_free(s->enc_write_ctx);
22470Sstevel@tonic-gate 		s->enc_write_ctx=NULL;
22480Sstevel@tonic-gate 		}
22492139Sjp161948 #ifndef OPENSSL_NO_COMP
22500Sstevel@tonic-gate 	if (s->expand != NULL)
22510Sstevel@tonic-gate 		{
22520Sstevel@tonic-gate 		COMP_CTX_free(s->expand);
22530Sstevel@tonic-gate 		s->expand=NULL;
22540Sstevel@tonic-gate 		}
22550Sstevel@tonic-gate 	if (s->compress != NULL)
22560Sstevel@tonic-gate 		{
22570Sstevel@tonic-gate 		COMP_CTX_free(s->compress);
22580Sstevel@tonic-gate 		s->compress=NULL;
22590Sstevel@tonic-gate 		}
22602139Sjp161948 #endif
22610Sstevel@tonic-gate 	}
22620Sstevel@tonic-gate 
22630Sstevel@tonic-gate /* Fix this function so that it takes an optional type parameter */
SSL_get_certificate(const SSL * s)22642139Sjp161948 X509 *SSL_get_certificate(const SSL *s)
22650Sstevel@tonic-gate 	{
22660Sstevel@tonic-gate 	if (s->cert != NULL)
22670Sstevel@tonic-gate 		return(s->cert->key->x509);
22680Sstevel@tonic-gate 	else
22690Sstevel@tonic-gate 		return(NULL);
22700Sstevel@tonic-gate 	}
22710Sstevel@tonic-gate 
22720Sstevel@tonic-gate /* Fix this function so that it takes an optional type parameter */
SSL_get_privatekey(SSL * s)22730Sstevel@tonic-gate EVP_PKEY *SSL_get_privatekey(SSL *s)
22740Sstevel@tonic-gate 	{
22750Sstevel@tonic-gate 	if (s->cert != NULL)
22760Sstevel@tonic-gate 		return(s->cert->key->privatekey);
22770Sstevel@tonic-gate 	else
22780Sstevel@tonic-gate 		return(NULL);
22790Sstevel@tonic-gate 	}
22800Sstevel@tonic-gate 
SSL_get_current_cipher(const SSL * s)22812139Sjp161948 SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
22820Sstevel@tonic-gate 	{
22830Sstevel@tonic-gate 	if ((s->session != NULL) && (s->session->cipher != NULL))
22840Sstevel@tonic-gate 		return(s->session->cipher);
22850Sstevel@tonic-gate 	return(NULL);
22860Sstevel@tonic-gate 	}
22872139Sjp161948 #ifdef OPENSSL_NO_COMP
SSL_get_current_compression(SSL * s)22882139Sjp161948 const void *SSL_get_current_compression(SSL *s)
22892139Sjp161948 	{
22902139Sjp161948 	return NULL;
22912139Sjp161948 	}
SSL_get_current_expansion(SSL * s)22922139Sjp161948 const void *SSL_get_current_expansion(SSL *s)
22932139Sjp161948 	{
22942139Sjp161948 	return NULL;
22952139Sjp161948 	}
22962139Sjp161948 #else
22972139Sjp161948 
SSL_get_current_compression(SSL * s)22982139Sjp161948 const COMP_METHOD *SSL_get_current_compression(SSL *s)
22992139Sjp161948 	{
23002139Sjp161948 	if (s->compress != NULL)
23012139Sjp161948 		return(s->compress->meth);
23022139Sjp161948 	return(NULL);
23032139Sjp161948 	}
23042139Sjp161948 
SSL_get_current_expansion(SSL * s)23052139Sjp161948 const COMP_METHOD *SSL_get_current_expansion(SSL *s)
23062139Sjp161948 	{
23072139Sjp161948 	if (s->expand != NULL)
23082139Sjp161948 		return(s->expand->meth);
23092139Sjp161948 	return(NULL);
23102139Sjp161948 	}
23112139Sjp161948 #endif
23120Sstevel@tonic-gate 
ssl_init_wbio_buffer(SSL * s,int push)23130Sstevel@tonic-gate int ssl_init_wbio_buffer(SSL *s,int push)
23140Sstevel@tonic-gate 	{
23150Sstevel@tonic-gate 	BIO *bbio;
23160Sstevel@tonic-gate 
23170Sstevel@tonic-gate 	if (s->bbio == NULL)
23180Sstevel@tonic-gate 		{
23190Sstevel@tonic-gate 		bbio=BIO_new(BIO_f_buffer());
23200Sstevel@tonic-gate 		if (bbio == NULL) return(0);
23210Sstevel@tonic-gate 		s->bbio=bbio;
23220Sstevel@tonic-gate 		}
23230Sstevel@tonic-gate 	else
23240Sstevel@tonic-gate 		{
23250Sstevel@tonic-gate 		bbio=s->bbio;
23260Sstevel@tonic-gate 		if (s->bbio == s->wbio)
23270Sstevel@tonic-gate 			s->wbio=BIO_pop(s->wbio);
23280Sstevel@tonic-gate 		}
23290Sstevel@tonic-gate 	(void)BIO_reset(bbio);
23300Sstevel@tonic-gate /*	if (!BIO_set_write_buffer_size(bbio,16*1024)) */
23310Sstevel@tonic-gate 	if (!BIO_set_read_buffer_size(bbio,1))
23320Sstevel@tonic-gate 		{
23330Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER,ERR_R_BUF_LIB);
23340Sstevel@tonic-gate 		return(0);
23350Sstevel@tonic-gate 		}
23360Sstevel@tonic-gate 	if (push)
23370Sstevel@tonic-gate 		{
23380Sstevel@tonic-gate 		if (s->wbio != bbio)
23390Sstevel@tonic-gate 			s->wbio=BIO_push(bbio,s->wbio);
23400Sstevel@tonic-gate 		}
23410Sstevel@tonic-gate 	else
23420Sstevel@tonic-gate 		{
23430Sstevel@tonic-gate 		if (s->wbio == bbio)
23440Sstevel@tonic-gate 			s->wbio=BIO_pop(bbio);
23450Sstevel@tonic-gate 		}
23460Sstevel@tonic-gate 	return(1);
23470Sstevel@tonic-gate 	}
23480Sstevel@tonic-gate 
ssl_free_wbio_buffer(SSL * s)23490Sstevel@tonic-gate void ssl_free_wbio_buffer(SSL *s)
23500Sstevel@tonic-gate 	{
23510Sstevel@tonic-gate 	if (s->bbio == NULL) return;
23520Sstevel@tonic-gate 
23530Sstevel@tonic-gate 	if (s->bbio == s->wbio)
23540Sstevel@tonic-gate 		{
23550Sstevel@tonic-gate 		/* remove buffering */
23560Sstevel@tonic-gate 		s->wbio=BIO_pop(s->wbio);
23570Sstevel@tonic-gate #ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
23580Sstevel@tonic-gate 		assert(s->wbio != NULL);
23590Sstevel@tonic-gate #endif
23600Sstevel@tonic-gate 	}
23610Sstevel@tonic-gate 	BIO_free(s->bbio);
23620Sstevel@tonic-gate 	s->bbio=NULL;
23630Sstevel@tonic-gate 	}
23640Sstevel@tonic-gate 
SSL_CTX_set_quiet_shutdown(SSL_CTX * ctx,int mode)23650Sstevel@tonic-gate void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode)
23660Sstevel@tonic-gate 	{
23670Sstevel@tonic-gate 	ctx->quiet_shutdown=mode;
23680Sstevel@tonic-gate 	}
23690Sstevel@tonic-gate 
SSL_CTX_get_quiet_shutdown(const SSL_CTX * ctx)23702139Sjp161948 int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
23710Sstevel@tonic-gate 	{
23720Sstevel@tonic-gate 	return(ctx->quiet_shutdown);
23730Sstevel@tonic-gate 	}
23740Sstevel@tonic-gate 
SSL_set_quiet_shutdown(SSL * s,int mode)23750Sstevel@tonic-gate void SSL_set_quiet_shutdown(SSL *s,int mode)
23760Sstevel@tonic-gate 	{
23770Sstevel@tonic-gate 	s->quiet_shutdown=mode;
23780Sstevel@tonic-gate 	}
23790Sstevel@tonic-gate 
SSL_get_quiet_shutdown(const SSL * s)23802139Sjp161948 int SSL_get_quiet_shutdown(const SSL *s)
23810Sstevel@tonic-gate 	{
23820Sstevel@tonic-gate 	return(s->quiet_shutdown);
23830Sstevel@tonic-gate 	}
23840Sstevel@tonic-gate 
SSL_set_shutdown(SSL * s,int mode)23850Sstevel@tonic-gate void SSL_set_shutdown(SSL *s,int mode)
23860Sstevel@tonic-gate 	{
23870Sstevel@tonic-gate 	s->shutdown=mode;
23880Sstevel@tonic-gate 	}
23890Sstevel@tonic-gate 
SSL_get_shutdown(const SSL * s)23902139Sjp161948 int SSL_get_shutdown(const SSL *s)
23910Sstevel@tonic-gate 	{
23920Sstevel@tonic-gate 	return(s->shutdown);
23930Sstevel@tonic-gate 	}
23940Sstevel@tonic-gate 
SSL_version(const SSL * s)23952139Sjp161948 int SSL_version(const SSL *s)
23960Sstevel@tonic-gate 	{
23970Sstevel@tonic-gate 	return(s->version);
23980Sstevel@tonic-gate 	}
23990Sstevel@tonic-gate 
SSL_get_SSL_CTX(const SSL * ssl)24002139Sjp161948 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
24010Sstevel@tonic-gate 	{
24020Sstevel@tonic-gate 	return(ssl->ctx);
24030Sstevel@tonic-gate 	}
24040Sstevel@tonic-gate 
24050Sstevel@tonic-gate #ifndef OPENSSL_NO_STDIO
SSL_CTX_set_default_verify_paths(SSL_CTX * ctx)24060Sstevel@tonic-gate int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
24070Sstevel@tonic-gate 	{
24080Sstevel@tonic-gate 	return(X509_STORE_set_default_paths(ctx->cert_store));
24090Sstevel@tonic-gate 	}
24100Sstevel@tonic-gate 
SSL_CTX_load_verify_locations(SSL_CTX * ctx,const char * CAfile,const char * CApath)24110Sstevel@tonic-gate int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
24120Sstevel@tonic-gate 		const char *CApath)
24130Sstevel@tonic-gate 	{
24140Sstevel@tonic-gate 	return(X509_STORE_load_locations(ctx->cert_store,CAfile,CApath));
24150Sstevel@tonic-gate 	}
24160Sstevel@tonic-gate #endif
24170Sstevel@tonic-gate 
SSL_set_info_callback(SSL * ssl,void (* cb)(const SSL * ssl,int type,int val))24180Sstevel@tonic-gate void SSL_set_info_callback(SSL *ssl,
24190Sstevel@tonic-gate 			   void (*cb)(const SSL *ssl,int type,int val))
24200Sstevel@tonic-gate 	{
24210Sstevel@tonic-gate 	ssl->info_callback=cb;
24220Sstevel@tonic-gate 	}
24230Sstevel@tonic-gate 
24242139Sjp161948 /* One compiler (Diab DCC) doesn't like argument names in returned
24252139Sjp161948    function pointer.  */
SSL_get_info_callback(const SSL * ssl)24262139Sjp161948 void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/)
24270Sstevel@tonic-gate 	{
24280Sstevel@tonic-gate 	return ssl->info_callback;
24290Sstevel@tonic-gate 	}
24300Sstevel@tonic-gate 
SSL_state(const SSL * ssl)24312139Sjp161948 int SSL_state(const SSL *ssl)
24320Sstevel@tonic-gate 	{
24330Sstevel@tonic-gate 	return(ssl->state);
24340Sstevel@tonic-gate 	}
24350Sstevel@tonic-gate 
SSL_set_verify_result(SSL * ssl,long arg)24360Sstevel@tonic-gate void SSL_set_verify_result(SSL *ssl,long arg)
24370Sstevel@tonic-gate 	{
24380Sstevel@tonic-gate 	ssl->verify_result=arg;
24390Sstevel@tonic-gate 	}
24400Sstevel@tonic-gate 
SSL_get_verify_result(const SSL * ssl)24412139Sjp161948 long SSL_get_verify_result(const SSL *ssl)
24420Sstevel@tonic-gate 	{
24430Sstevel@tonic-gate 	return(ssl->verify_result);
24440Sstevel@tonic-gate 	}
24450Sstevel@tonic-gate 
SSL_get_ex_new_index(long argl,void * argp,CRYPTO_EX_new * new_func,CRYPTO_EX_dup * dup_func,CRYPTO_EX_free * free_func)24460Sstevel@tonic-gate int SSL_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
24470Sstevel@tonic-gate 			 CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
24480Sstevel@tonic-gate 	{
24490Sstevel@tonic-gate 	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp,
24500Sstevel@tonic-gate 				new_func, dup_func, free_func);
24510Sstevel@tonic-gate 	}
24520Sstevel@tonic-gate 
SSL_set_ex_data(SSL * s,int idx,void * arg)24530Sstevel@tonic-gate int SSL_set_ex_data(SSL *s,int idx,void *arg)
24540Sstevel@tonic-gate 	{
24550Sstevel@tonic-gate 	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
24560Sstevel@tonic-gate 	}
24570Sstevel@tonic-gate 
SSL_get_ex_data(const SSL * s,int idx)24582139Sjp161948 void *SSL_get_ex_data(const SSL *s,int idx)
24590Sstevel@tonic-gate 	{
24600Sstevel@tonic-gate 	return(CRYPTO_get_ex_data(&s->ex_data,idx));
24610Sstevel@tonic-gate 	}
24620Sstevel@tonic-gate 
SSL_CTX_get_ex_new_index(long argl,void * argp,CRYPTO_EX_new * new_func,CRYPTO_EX_dup * dup_func,CRYPTO_EX_free * free_func)24630Sstevel@tonic-gate int SSL_CTX_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
24640Sstevel@tonic-gate 			     CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
24650Sstevel@tonic-gate 	{
24660Sstevel@tonic-gate 	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp,
24670Sstevel@tonic-gate 				new_func, dup_func, free_func);
24680Sstevel@tonic-gate 	}
24690Sstevel@tonic-gate 
SSL_CTX_set_ex_data(SSL_CTX * s,int idx,void * arg)24700Sstevel@tonic-gate int SSL_CTX_set_ex_data(SSL_CTX *s,int idx,void *arg)
24710Sstevel@tonic-gate 	{
24720Sstevel@tonic-gate 	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
24730Sstevel@tonic-gate 	}
24740Sstevel@tonic-gate 
SSL_CTX_get_ex_data(const SSL_CTX * s,int idx)24752139Sjp161948 void *SSL_CTX_get_ex_data(const SSL_CTX *s,int idx)
24760Sstevel@tonic-gate 	{
24770Sstevel@tonic-gate 	return(CRYPTO_get_ex_data(&s->ex_data,idx));
24780Sstevel@tonic-gate 	}
24790Sstevel@tonic-gate 
ssl_ok(SSL * s)24800Sstevel@tonic-gate int ssl_ok(SSL *s)
24810Sstevel@tonic-gate 	{
24820Sstevel@tonic-gate 	return(1);
24830Sstevel@tonic-gate 	}
24840Sstevel@tonic-gate 
SSL_CTX_get_cert_store(const SSL_CTX * ctx)24852139Sjp161948 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
24860Sstevel@tonic-gate 	{
24870Sstevel@tonic-gate 	return(ctx->cert_store);
24880Sstevel@tonic-gate 	}
24890Sstevel@tonic-gate 
SSL_CTX_set_cert_store(SSL_CTX * ctx,X509_STORE * store)24900Sstevel@tonic-gate void SSL_CTX_set_cert_store(SSL_CTX *ctx,X509_STORE *store)
24910Sstevel@tonic-gate 	{
24920Sstevel@tonic-gate 	if (ctx->cert_store != NULL)
24930Sstevel@tonic-gate 		X509_STORE_free(ctx->cert_store);
24940Sstevel@tonic-gate 	ctx->cert_store=store;
24950Sstevel@tonic-gate 	}
24960Sstevel@tonic-gate 
SSL_want(const SSL * s)24972139Sjp161948 int SSL_want(const SSL *s)
24980Sstevel@tonic-gate 	{
24990Sstevel@tonic-gate 	return(s->rwstate);
25000Sstevel@tonic-gate 	}
25010Sstevel@tonic-gate 
25020Sstevel@tonic-gate /*!
25030Sstevel@tonic-gate  * \brief Set the callback for generating temporary RSA keys.
25040Sstevel@tonic-gate  * \param ctx the SSL context.
25050Sstevel@tonic-gate  * \param cb the callback
25060Sstevel@tonic-gate  */
25070Sstevel@tonic-gate 
25080Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
SSL_CTX_set_tmp_rsa_callback(SSL_CTX * ctx,RSA * (* cb)(SSL * ssl,int is_export,int keylength))25090Sstevel@tonic-gate void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
25100Sstevel@tonic-gate 							  int is_export,
25110Sstevel@tonic-gate 							  int keylength))
25120Sstevel@tonic-gate     {
25132139Sjp161948     SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
25140Sstevel@tonic-gate     }
25150Sstevel@tonic-gate 
SSL_set_tmp_rsa_callback(SSL * ssl,RSA * (* cb)(SSL * ssl,int is_export,int keylength))25160Sstevel@tonic-gate void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,
25170Sstevel@tonic-gate 						  int is_export,
25180Sstevel@tonic-gate 						  int keylength))
25190Sstevel@tonic-gate     {
25202139Sjp161948     SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
25210Sstevel@tonic-gate     }
25220Sstevel@tonic-gate #endif
25230Sstevel@tonic-gate 
25240Sstevel@tonic-gate #ifdef DOXYGEN
25250Sstevel@tonic-gate /*!
25260Sstevel@tonic-gate  * \brief The RSA temporary key callback function.
25270Sstevel@tonic-gate  * \param ssl the SSL session.
25280Sstevel@tonic-gate  * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite.
25290Sstevel@tonic-gate  * \param keylength if \c is_export is \c TRUE, then \c keylength is the size
25300Sstevel@tonic-gate  * of the required key in bits.
25310Sstevel@tonic-gate  * \return the temporary RSA key.
25320Sstevel@tonic-gate  * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback
25330Sstevel@tonic-gate  */
25340Sstevel@tonic-gate 
cb(SSL * ssl,int is_export,int keylength)25350Sstevel@tonic-gate RSA *cb(SSL *ssl,int is_export,int keylength)
25360Sstevel@tonic-gate     {}
25370Sstevel@tonic-gate #endif
25380Sstevel@tonic-gate 
25390Sstevel@tonic-gate /*!
25400Sstevel@tonic-gate  * \brief Set the callback for generating temporary DH keys.
25410Sstevel@tonic-gate  * \param ctx the SSL context.
25420Sstevel@tonic-gate  * \param dh the callback
25430Sstevel@tonic-gate  */
25440Sstevel@tonic-gate 
25450Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
SSL_CTX_set_tmp_dh_callback(SSL_CTX * ctx,DH * (* dh)(SSL * ssl,int is_export,int keylength))25460Sstevel@tonic-gate void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
25470Sstevel@tonic-gate 							int keylength))
25480Sstevel@tonic-gate 	{
25492139Sjp161948 	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
25500Sstevel@tonic-gate 	}
25510Sstevel@tonic-gate 
SSL_set_tmp_dh_callback(SSL * ssl,DH * (* dh)(SSL * ssl,int is_export,int keylength))25520Sstevel@tonic-gate void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
25530Sstevel@tonic-gate 						int keylength))
25540Sstevel@tonic-gate 	{
25552139Sjp161948 	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
25562139Sjp161948 	}
25572139Sjp161948 #endif
25582139Sjp161948 
25592139Sjp161948 #ifndef OPENSSL_NO_ECDH
SSL_CTX_set_tmp_ecdh_callback(SSL_CTX * ctx,EC_KEY * (* ecdh)(SSL * ssl,int is_export,int keylength))25602139Sjp161948 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
25612139Sjp161948 							int keylength))
25622139Sjp161948 	{
25632139Sjp161948 	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
25642139Sjp161948 	}
25652139Sjp161948 
SSL_set_tmp_ecdh_callback(SSL * ssl,EC_KEY * (* ecdh)(SSL * ssl,int is_export,int keylength))25662139Sjp161948 void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
25672139Sjp161948 						int keylength))
25682139Sjp161948 	{
25692139Sjp161948 	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
25700Sstevel@tonic-gate 	}
25710Sstevel@tonic-gate #endif
25720Sstevel@tonic-gate 
25730Sstevel@tonic-gate 
SSL_CTX_set_msg_callback(SSL_CTX * ctx,void (* cb)(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg))25740Sstevel@tonic-gate void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
25750Sstevel@tonic-gate 	{
25762139Sjp161948 	SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
25770Sstevel@tonic-gate 	}
SSL_set_msg_callback(SSL * ssl,void (* cb)(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg))25780Sstevel@tonic-gate void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
25790Sstevel@tonic-gate 	{
25802139Sjp161948 	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
25810Sstevel@tonic-gate 	}
25820Sstevel@tonic-gate 
25830Sstevel@tonic-gate 
25840Sstevel@tonic-gate 
25850Sstevel@tonic-gate #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
25860Sstevel@tonic-gate #include "../crypto/bio/bss_file.c"
25870Sstevel@tonic-gate #endif
25880Sstevel@tonic-gate 
25890Sstevel@tonic-gate IMPLEMENT_STACK_OF(SSL_CIPHER)
25900Sstevel@tonic-gate IMPLEMENT_STACK_OF(SSL_COMP)
2591