os/ossrv/ssl/libssl/src/s2_srvr.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libssl/src/s2_srvr.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1157 @@
     1.4 +/* ssl/s2_srvr.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +/* ====================================================================
    1.62 + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
    1.63 + *
    1.64 + * Redistribution and use in source and binary forms, with or without
    1.65 + * modification, are permitted provided that the following conditions
    1.66 + * are met:
    1.67 + *
    1.68 + * 1. Redistributions of source code must retain the above copyright
    1.69 + *    notice, this list of conditions and the following disclaimer. 
    1.70 + *
    1.71 + * 2. Redistributions in binary form must reproduce the above copyright
    1.72 + *    notice, this list of conditions and the following disclaimer in
    1.73 + *    the documentation and/or other materials provided with the
    1.74 + *    distribution.
    1.75 + *
    1.76 + * 3. All advertising materials mentioning features or use of this
    1.77 + *    software must display the following acknowledgment:
    1.78 + *    "This product includes software developed by the OpenSSL Project
    1.79 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.80 + *
    1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.82 + *    endorse or promote products derived from this software without
    1.83 + *    prior written permission. For written permission, please contact
    1.84 + *    openssl-core@openssl.org.
    1.85 + *
    1.86 + * 5. Products derived from this software may not be called "OpenSSL"
    1.87 + *    nor may "OpenSSL" appear in their names without prior written
    1.88 + *    permission of the OpenSSL Project.
    1.89 + *
    1.90 + * 6. Redistributions of any form whatsoever must retain the following
    1.91 + *    acknowledgment:
    1.92 + *    "This product includes software developed by the OpenSSL Project
    1.93 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.94 + *
    1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.98 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
   1.107 + * ====================================================================
   1.108 + *
   1.109 + * This product includes cryptographic software written by Eric Young
   1.110 + * (eay@cryptsoft.com).  This product includes software written by Tim
   1.111 + * Hudson (tjh@cryptsoft.com).
   1.112 + *
   1.113 + */
   1.114 +/*
   1.115 + © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
   1.116 + */
   1.117 + 
   1.118 +#include "ssl_locl.h"
   1.119 +#ifndef OPENSSL_NO_SSL2
   1.120 +#include <stdio.h>
   1.121 +#include <openssl/bio.h>
   1.122 +#include <openssl/rand.h>
   1.123 +#include <openssl/objects.h>
   1.124 +#include <openssl/evp.h>
   1.125 +
   1.126 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
   1.127 +#include "libssl_wsd.h"
   1.128 +#endif
   1.129 +
   1.130 +#ifdef EMULATOR
   1.131 +
   1.132 +	GET_STATIC_VAR_FROM_TLS(SSLv2_server_method_data,s2_srvr,SSL_METHOD)
   1.133 +	
   1.134 +	#define SSLv2_server_method_data (*GET_WSD_VAR_NAME(SSLv2_server_method_data,s2_srvr,s)())
   1.135 +	
   1.136 +#endif
   1.137 +static SSL_METHOD *ssl2_get_server_method(int ver);
   1.138 +static int get_client_master_key(SSL *s);
   1.139 +static int get_client_hello(SSL *s);
   1.140 +static int server_hello(SSL *s); 
   1.141 +static int get_client_finished(SSL *s);
   1.142 +static int server_verify(SSL *s);
   1.143 +static int server_finish(SSL *s);
   1.144 +static int request_certificate(SSL *s);
   1.145 +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
   1.146 +	unsigned char *to,int padding);
   1.147 +#define BREAK	break
   1.148 +
   1.149 +static SSL_METHOD *ssl2_get_server_method(int ver)
   1.150 +	{
   1.151 +	if (ver == SSL2_VERSION)
   1.152 +		return(SSLv2_server_method());
   1.153 +	else
   1.154 +		return(NULL);
   1.155 +	}
   1.156 +
   1.157 +EXPORT_C IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
   1.158 +			ssl2_accept,
   1.159 +			ssl_undefined_function,
   1.160 +			ssl2_get_server_method)
   1.161 +
   1.162 +int ssl2_accept(SSL *s)
   1.163 +	{
   1.164 +	unsigned long l=(unsigned long)time(NULL);
   1.165 +	BUF_MEM *buf=NULL;
   1.166 +	int ret= -1;
   1.167 +	long num1;
   1.168 +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
   1.169 +	int new_state,state;
   1.170 +
   1.171 +	RAND_add(&l,sizeof(l),0);
   1.172 +	ERR_clear_error();
   1.173 +	clear_sys_error();
   1.174 +
   1.175 +	if (s->info_callback != NULL)
   1.176 +		cb=s->info_callback;
   1.177 +	else if (s->ctx->info_callback != NULL)
   1.178 +		cb=s->ctx->info_callback;
   1.179 +
   1.180 +	/* init things to blank */
   1.181 +	s->in_handshake++;
   1.182 +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
   1.183 +
   1.184 +	if (s->cert == NULL)
   1.185 +		{
   1.186 +		SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
   1.187 +		return(-1);
   1.188 +		}
   1.189 +
   1.190 +	clear_sys_error();
   1.191 +	for (;;)
   1.192 +		{
   1.193 +		state=s->state;
   1.194 +
   1.195 +		switch (s->state)
   1.196 +			{
   1.197 +		case SSL_ST_BEFORE:
   1.198 +		case SSL_ST_ACCEPT:
   1.199 +		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
   1.200 +		case SSL_ST_OK|SSL_ST_ACCEPT:
   1.201 +
   1.202 +			s->server=1;
   1.203 +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
   1.204 +
   1.205 +			s->version=SSL2_VERSION;
   1.206 +			s->type=SSL_ST_ACCEPT;
   1.207 +
   1.208 +			buf=s->init_buf;
   1.209 +			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
   1.210 +				{ ret= -1; goto end; }
   1.211 +			if (!BUF_MEM_grow(buf,(int)
   1.212 +				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
   1.213 +				{ ret= -1; goto end; }
   1.214 +			s->init_buf=buf;
   1.215 +			s->init_num=0;
   1.216 +			s->ctx->stats.sess_accept++;
   1.217 +			s->handshake_func=ssl2_accept;
   1.218 +			s->state=SSL2_ST_GET_CLIENT_HELLO_A;
   1.219 +			BREAK;
   1.220 +
   1.221 +		case SSL2_ST_GET_CLIENT_HELLO_A:
   1.222 +		case SSL2_ST_GET_CLIENT_HELLO_B:
   1.223 +		case SSL2_ST_GET_CLIENT_HELLO_C:
   1.224 +			s->shutdown=0;
   1.225 +			ret=get_client_hello(s);
   1.226 +			if (ret <= 0) goto end;
   1.227 +			s->init_num=0;
   1.228 +			s->state=SSL2_ST_SEND_SERVER_HELLO_A;
   1.229 +			BREAK;
   1.230 +
   1.231 +		case SSL2_ST_SEND_SERVER_HELLO_A:
   1.232 +		case SSL2_ST_SEND_SERVER_HELLO_B:
   1.233 +			ret=server_hello(s);
   1.234 +			if (ret <= 0) goto end;
   1.235 +			s->init_num=0;
   1.236 +			if (!s->hit)
   1.237 +				{
   1.238 +				s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
   1.239 +				BREAK;
   1.240 +				}
   1.241 +			else
   1.242 +				{
   1.243 +				s->state=SSL2_ST_SERVER_START_ENCRYPTION;
   1.244 +				BREAK;
   1.245 +				}
   1.246 +		case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
   1.247 +		case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
   1.248 +			ret=get_client_master_key(s);
   1.249 +			if (ret <= 0) goto end;
   1.250 +			s->init_num=0;
   1.251 +			s->state=SSL2_ST_SERVER_START_ENCRYPTION;
   1.252 +			BREAK;
   1.253 +
   1.254 +		case SSL2_ST_SERVER_START_ENCRYPTION:
   1.255 +			/* Ok we how have sent all the stuff needed to
   1.256 +			 * start encrypting, the next packet back will
   1.257 +			 * be encrypted. */
   1.258 +			if (!ssl2_enc_init(s,0))
   1.259 +				{ ret= -1; goto end; }
   1.260 +			s->s2->clear_text=0;
   1.261 +			s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
   1.262 +			BREAK;
   1.263 +
   1.264 +		case SSL2_ST_SEND_SERVER_VERIFY_A:
   1.265 +		case SSL2_ST_SEND_SERVER_VERIFY_B:
   1.266 +			ret=server_verify(s);
   1.267 +			if (ret <= 0) goto end;
   1.268 +			s->init_num=0;
   1.269 +			if (s->hit)
   1.270 +				{
   1.271 +				/* If we are in here, we have been
   1.272 +				 * buffering the output, so we need to
   1.273 +				 * flush it and remove buffering from
   1.274 +				 * future traffic */
   1.275 +				s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
   1.276 +				BREAK;
   1.277 +				}
   1.278 +			else
   1.279 +				{
   1.280 +				s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
   1.281 +				break;
   1.282 +				}
   1.283 +
   1.284 + 		case SSL2_ST_SEND_SERVER_VERIFY_C:
   1.285 + 			/* get the number of bytes to write */
   1.286 + 			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
   1.287 + 			if (num1 != 0)
   1.288 + 				{
   1.289 +				s->rwstate=SSL_WRITING;
   1.290 + 				num1=BIO_flush(s->wbio);
   1.291 + 				if (num1 <= 0) { ret= -1; goto end; }
   1.292 +				s->rwstate=SSL_NOTHING;
   1.293 +				}
   1.294 +
   1.295 + 			/* flushed and now remove buffering */
   1.296 + 			s->wbio=BIO_pop(s->wbio);
   1.297 +
   1.298 + 			s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
   1.299 +  			BREAK;
   1.300 +
   1.301 +		case SSL2_ST_GET_CLIENT_FINISHED_A:
   1.302 +		case SSL2_ST_GET_CLIENT_FINISHED_B:
   1.303 +			ret=get_client_finished(s);
   1.304 +			if (ret <= 0)
   1.305 +				goto end;
   1.306 +			s->init_num=0;
   1.307 +			s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
   1.308 +			BREAK;
   1.309 +
   1.310 +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
   1.311 +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
   1.312 +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
   1.313 +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
   1.314 +			/* don't do a 'request certificate' if we
   1.315 +			 * don't want to, or we already have one, and
   1.316 +			 * we only want to do it once. */
   1.317 +			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
   1.318 +				((s->session->peer != NULL) &&
   1.319 +				(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
   1.320 +				{
   1.321 +				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
   1.322 +				break;
   1.323 +				}
   1.324 +			else
   1.325 +				{
   1.326 +				ret=request_certificate(s);
   1.327 +				if (ret <= 0) goto end;
   1.328 +				s->init_num=0;
   1.329 +				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
   1.330 +				}
   1.331 +			BREAK;
   1.332 +
   1.333 +		case SSL2_ST_SEND_SERVER_FINISHED_A:
   1.334 +		case SSL2_ST_SEND_SERVER_FINISHED_B:
   1.335 +			ret=server_finish(s);
   1.336 +			if (ret <= 0) goto end;
   1.337 +			s->init_num=0;
   1.338 +			s->state=SSL_ST_OK;
   1.339 +			break;
   1.340 +
   1.341 +		case SSL_ST_OK:
   1.342 +			BUF_MEM_free(s->init_buf);
   1.343 +			ssl_free_wbio_buffer(s);
   1.344 +			s->init_buf=NULL;
   1.345 +			s->init_num=0;
   1.346 +		/*	ERR_clear_error();*/
   1.347 +
   1.348 +			ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
   1.349 +
   1.350 +			s->ctx->stats.sess_accept_good++;
   1.351 +			/* s->server=1; */
   1.352 +			ret=1;
   1.353 +
   1.354 +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
   1.355 +
   1.356 +			goto end;
   1.357 +			/* BREAK; */
   1.358 +
   1.359 +		default:
   1.360 +			SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
   1.361 +			ret= -1;
   1.362 +			goto end;
   1.363 +			/* BREAK; */
   1.364 +			}
   1.365 +		
   1.366 +		if ((cb != NULL) && (s->state != state))
   1.367 +			{
   1.368 +			new_state=s->state;
   1.369 +			s->state=state;
   1.370 +			cb(s,SSL_CB_ACCEPT_LOOP,1);
   1.371 +			s->state=new_state;
   1.372 +			}
   1.373 +		}
   1.374 +end:
   1.375 +	s->in_handshake--;
   1.376 +	if (cb != NULL)
   1.377 +		cb(s,SSL_CB_ACCEPT_EXIT,ret);
   1.378 +	return(ret);
   1.379 +	}
   1.380 +
   1.381 +static int get_client_master_key(SSL *s)
   1.382 +	{
   1.383 +	int is_export,i,n,keya,ek;
   1.384 +	unsigned long len;
   1.385 +	unsigned char *p;
   1.386 +	SSL_CIPHER *cp;
   1.387 +	const EVP_CIPHER *c;
   1.388 +	const EVP_MD *md;
   1.389 +
   1.390 +	p=(unsigned char *)s->init_buf->data;
   1.391 +	if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
   1.392 +		{
   1.393 +		i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
   1.394 +
   1.395 +		if (i < (10-s->init_num))
   1.396 +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
   1.397 +		s->init_num = 10;
   1.398 +
   1.399 +		if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
   1.400 +			{
   1.401 +			if (p[-1] != SSL2_MT_ERROR)
   1.402 +				{
   1.403 +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.404 +				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
   1.405 +				}
   1.406 +			else
   1.407 +				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
   1.408 +			return(-1);
   1.409 +			}
   1.410 +
   1.411 +		cp=ssl2_get_cipher_by_char(p);
   1.412 +		if (cp == NULL)
   1.413 +			{
   1.414 +			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
   1.415 +			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
   1.416 +			return(-1);
   1.417 +			}
   1.418 +		s->session->cipher= cp;
   1.419 +
   1.420 +		p+=3;
   1.421 +		n2s(p,i); s->s2->tmp.clear=i;
   1.422 +		n2s(p,i); s->s2->tmp.enc=i;
   1.423 +		n2s(p,i); s->session->key_arg_length=i;
   1.424 +		if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH)
   1.425 +			{
   1.426 +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.427 +			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
   1.428 +			return -1;
   1.429 +			}
   1.430 +		s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
   1.431 +		}
   1.432 +
   1.433 +	/* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
   1.434 +	p=(unsigned char *)s->init_buf->data;
   1.435 +	if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
   1.436 +		{
   1.437 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.438 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
   1.439 +		return -1;
   1.440 +		}
   1.441 +	keya=s->session->key_arg_length;
   1.442 +	len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
   1.443 +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
   1.444 +		{
   1.445 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.446 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
   1.447 +		return -1;
   1.448 +		}
   1.449 +	n = (int)len - s->init_num;
   1.450 +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
   1.451 +	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
   1.452 +	if (s->msg_callback)
   1.453 +		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
   1.454 +	p += 10;
   1.455 +
   1.456 +	memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
   1.457 +		(unsigned int)keya);
   1.458 +
   1.459 +	if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
   1.460 +		{
   1.461 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.462 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
   1.463 +		return(-1);
   1.464 +		}
   1.465 +	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
   1.466 +		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
   1.467 +		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
   1.468 +
   1.469 +	is_export=SSL_C_IS_EXPORT(s->session->cipher);
   1.470 +	
   1.471 +	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
   1.472 +		{
   1.473 +		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
   1.474 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
   1.475 +		return(0);
   1.476 +		}
   1.477 +
   1.478 +	if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
   1.479 +		{
   1.480 +		is_export=1;
   1.481 +		ek=8;
   1.482 +		}
   1.483 +	else
   1.484 +		ek=5;
   1.485 +
   1.486 +	/* bad decrypt */
   1.487 +#if 1
   1.488 +	/* If a bad decrypt, continue with protocol but with a
   1.489 +	 * random master secret (Bleichenbacher attack) */
   1.490 +	if ((i < 0) ||
   1.491 +		((!is_export && (i != EVP_CIPHER_key_length(c)))
   1.492 +		|| (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
   1.493 +			(unsigned int)EVP_CIPHER_key_length(c))))))
   1.494 +		{
   1.495 +		ERR_clear_error();
   1.496 +		if (is_export)
   1.497 +			i=ek;
   1.498 +		else
   1.499 +			i=EVP_CIPHER_key_length(c);
   1.500 +		if (RAND_pseudo_bytes(p,i) <= 0)
   1.501 +			return 0;
   1.502 +		}
   1.503 +#else
   1.504 +	if (i < 0)
   1.505 +		{
   1.506 +		error=1;
   1.507 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
   1.508 +		}
   1.509 +	/* incorrect number of key bytes for non export cipher */
   1.510 +	else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
   1.511 +		|| (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
   1.512 +			EVP_CIPHER_key_length(c)))))
   1.513 +		{
   1.514 +		error=1;
   1.515 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
   1.516 +		}
   1.517 +	if (error)
   1.518 +		{
   1.519 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.520 +		return(-1);
   1.521 +		}
   1.522 +#endif
   1.523 +
   1.524 +	if (is_export) i+=s->s2->tmp.clear;
   1.525 +
   1.526 +	if (i > SSL_MAX_MASTER_KEY_LENGTH)
   1.527 +		{
   1.528 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.529 +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
   1.530 +		return -1;
   1.531 +		}
   1.532 +	s->session->master_key_length=i;
   1.533 +	memcpy(s->session->master_key,p,(unsigned int)i);
   1.534 +	return(1);
   1.535 +	}
   1.536 +
   1.537 +static int get_client_hello(SSL *s)
   1.538 +	{
   1.539 +	int i,n;
   1.540 +	unsigned long len;
   1.541 +	unsigned char *p;
   1.542 +	STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
   1.543 +	STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
   1.544 +	STACK_OF(SSL_CIPHER) *prio, *allow;
   1.545 +	int z;
   1.546 +
   1.547 +	/* This is a bit of a hack to check for the correct packet
   1.548 +	 * type the first time round. */
   1.549 +	if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
   1.550 +		{
   1.551 +		s->first_packet=1;
   1.552 +		s->state=SSL2_ST_GET_CLIENT_HELLO_B;
   1.553 +		}
   1.554 +
   1.555 +	p=(unsigned char *)s->init_buf->data;
   1.556 +	if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
   1.557 +		{
   1.558 +		i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
   1.559 +		if (i < (9-s->init_num)) 
   1.560 +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
   1.561 +		s->init_num = 9;
   1.562 +	
   1.563 +		if (*(p++) != SSL2_MT_CLIENT_HELLO)
   1.564 +			{
   1.565 +			if (p[-1] != SSL2_MT_ERROR)
   1.566 +				{
   1.567 +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.568 +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
   1.569 +				}
   1.570 +			else
   1.571 +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
   1.572 +			return(-1);
   1.573 +			}
   1.574 +		n2s(p,i);
   1.575 +		if (i < s->version) s->version=i;
   1.576 +		n2s(p,i); s->s2->tmp.cipher_spec_length=i;
   1.577 +		n2s(p,i); s->s2->tmp.session_id_length=i;
   1.578 +		n2s(p,i); s->s2->challenge_length=i;
   1.579 +		if (	(i < SSL2_MIN_CHALLENGE_LENGTH) ||
   1.580 +			(i > SSL2_MAX_CHALLENGE_LENGTH))
   1.581 +			{
   1.582 +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.583 +			SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
   1.584 +			return(-1);
   1.585 +			}
   1.586 +		s->state=SSL2_ST_GET_CLIENT_HELLO_C;
   1.587 +		}
   1.588 +
   1.589 +	/* SSL2_ST_GET_CLIENT_HELLO_C */
   1.590 +	p=(unsigned char *)s->init_buf->data;
   1.591 +	len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
   1.592 +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
   1.593 +		{
   1.594 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.595 +		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
   1.596 +		return -1;
   1.597 +		}
   1.598 +	n = (int)len - s->init_num;
   1.599 +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
   1.600 +	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
   1.601 +	if (s->msg_callback)
   1.602 +		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
   1.603 +	p += 9;
   1.604 +
   1.605 +	/* get session-id before cipher stuff so we can get out session
   1.606 +	 * structure if it is cached */
   1.607 +	/* session-id */
   1.608 +	if ((s->s2->tmp.session_id_length != 0) && 
   1.609 +		(s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
   1.610 +		{
   1.611 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.612 +		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
   1.613 +		return(-1);
   1.614 +		}
   1.615 +
   1.616 +	if (s->s2->tmp.session_id_length == 0)
   1.617 +		{
   1.618 +		if (!ssl_get_new_session(s,1))
   1.619 +			{
   1.620 +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.621 +			return(-1);
   1.622 +			}
   1.623 +		}
   1.624 +	else
   1.625 +		{
   1.626 +		i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
   1.627 +			s->s2->tmp.session_id_length, NULL);
   1.628 +		if (i == 1)
   1.629 +			{ /* previous session */
   1.630 +			s->hit=1;
   1.631 +			}
   1.632 +		else if (i == -1)
   1.633 +			{
   1.634 +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.635 +			return(-1);
   1.636 +			}
   1.637 +		else
   1.638 +			{
   1.639 +			if (s->cert == NULL)
   1.640 +				{
   1.641 +				ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
   1.642 +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
   1.643 +				return(-1);
   1.644 +				}
   1.645 +
   1.646 +			if (!ssl_get_new_session(s,1))
   1.647 +				{
   1.648 +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.649 +				return(-1);
   1.650 +				}
   1.651 +			}
   1.652 +		}
   1.653 +
   1.654 +	if (!s->hit)
   1.655 +		{
   1.656 +		cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
   1.657 +			&s->session->ciphers);
   1.658 +		if (cs == NULL) goto mem_err;
   1.659 +
   1.660 +		cl=SSL_get_ciphers(s);
   1.661 +
   1.662 +		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
   1.663 +		    {
   1.664 +		    prio=sk_SSL_CIPHER_dup(cl);
   1.665 +		    if (prio == NULL) goto mem_err;
   1.666 +		    allow = cs;
   1.667 +		    }
   1.668 +		else
   1.669 +		    {
   1.670 +		    prio = cs;
   1.671 +		    allow = cl;
   1.672 +		    }
   1.673 +		for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
   1.674 +			{
   1.675 +			if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
   1.676 +				{
   1.677 +				(void)sk_SSL_CIPHER_delete(prio,z);
   1.678 +				z--;
   1.679 +				}
   1.680 +			}
   1.681 +		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
   1.682 +		    {
   1.683 +		    sk_SSL_CIPHER_free(s->session->ciphers);
   1.684 +		    s->session->ciphers = prio;
   1.685 +		    }
   1.686 +		/* s->session->ciphers should now have a list of
   1.687 +		 * ciphers that are on both the client and server.
   1.688 +		 * This list is ordered by the order the client sent
   1.689 +		 * the ciphers or in the order of the server's preference
   1.690 +		 * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
   1.691 +		 */
   1.692 +		}
   1.693 +	p+=s->s2->tmp.cipher_spec_length;
   1.694 +	/* done cipher selection */
   1.695 +
   1.696 +	/* session id extracted already */
   1.697 +	p+=s->s2->tmp.session_id_length;
   1.698 +
   1.699 +	/* challenge */
   1.700 +	if (s->s2->challenge_length > sizeof s->s2->challenge)
   1.701 +		{
   1.702 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.703 +		SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
   1.704 +		return -1;
   1.705 +		}
   1.706 +	memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
   1.707 +	return(1);
   1.708 +mem_err:
   1.709 +	SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
   1.710 +	return(0);
   1.711 +	}
   1.712 +
   1.713 +static int server_hello(SSL *s)
   1.714 +	{
   1.715 +	unsigned char *p,*d;
   1.716 +	int n,hit;
   1.717 +	STACK_OF(SSL_CIPHER) *sk;
   1.718 +
   1.719 +	p=(unsigned char *)s->init_buf->data;
   1.720 +	if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
   1.721 +		{
   1.722 +		d=p+11;
   1.723 +		*(p++)=SSL2_MT_SERVER_HELLO;		/* type */
   1.724 +		hit=s->hit;
   1.725 +		*(p++)=(unsigned char)hit;
   1.726 +#if 1
   1.727 +		if (!hit)
   1.728 +			{
   1.729 +			if (s->session->sess_cert != NULL)
   1.730 +				/* This can't really happen because get_client_hello
   1.731 +				 * has called ssl_get_new_session, which does not set
   1.732 +				 * sess_cert. */
   1.733 +				ssl_sess_cert_free(s->session->sess_cert);
   1.734 +			s->session->sess_cert = ssl_sess_cert_new();
   1.735 +			if (s->session->sess_cert == NULL)
   1.736 +				{
   1.737 +				SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
   1.738 +				return(-1);
   1.739 +				}
   1.740 +			}
   1.741 +		/* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
   1.742 +		 * depending on whether it survived in the internal cache
   1.743 +		 * or was retrieved from an external cache.
   1.744 +		 * If it is NULL, we cannot put any useful data in it anyway,
   1.745 +		 * so we don't touch it.
   1.746 +		 */
   1.747 +
   1.748 +#else /* That's what used to be done when cert_st and sess_cert_st were
   1.749 +	   * the same. */
   1.750 +		if (!hit)
   1.751 +			{			/* else add cert to session */
   1.752 +			CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
   1.753 +			if (s->session->sess_cert != NULL)
   1.754 +				ssl_cert_free(s->session->sess_cert);
   1.755 +			s->session->sess_cert=s->cert;		
   1.756 +			}
   1.757 +		else	/* We have a session id-cache hit, if the
   1.758 +			 * session-id has no certificate listed against
   1.759 +			 * the 'cert' structure, grab the 'old' one
   1.760 +			 * listed against the SSL connection */
   1.761 +			{
   1.762 +			if (s->session->sess_cert == NULL)
   1.763 +				{
   1.764 +				CRYPTO_add(&s->cert->references,1,
   1.765 +					CRYPTO_LOCK_SSL_CERT);
   1.766 +				s->session->sess_cert=s->cert;
   1.767 +				}
   1.768 +			}
   1.769 +#endif
   1.770 +
   1.771 +		if (s->cert == NULL)
   1.772 +			{
   1.773 +			ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
   1.774 +			SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
   1.775 +			return(-1);
   1.776 +			}
   1.777 +
   1.778 +		if (hit)
   1.779 +			{
   1.780 +			*(p++)=0;		/* no certificate type */
   1.781 +			s2n(s->version,p);	/* version */
   1.782 +			s2n(0,p);		/* cert len */
   1.783 +			s2n(0,p);		/* ciphers len */
   1.784 +			}
   1.785 +		else
   1.786 +			{
   1.787 +			/* EAY EAY */
   1.788 +			/* put certificate type */
   1.789 +			*(p++)=SSL2_CT_X509_CERTIFICATE;
   1.790 +			s2n(s->version,p);	/* version */
   1.791 +			n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
   1.792 +			s2n(n,p);		/* certificate length */
   1.793 +			i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
   1.794 +			n=0;
   1.795 +			
   1.796 +			/* lets send out the ciphers we like in the
   1.797 +			 * prefered order */
   1.798 +			sk= s->session->ciphers;
   1.799 +			n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
   1.800 +			d+=n;
   1.801 +			s2n(n,p);		/* add cipher length */
   1.802 +			}
   1.803 +
   1.804 +		/* make and send conn_id */
   1.805 +		s2n(SSL2_CONNECTION_ID_LENGTH,p);	/* add conn_id length */
   1.806 +		s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
   1.807 +		if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
   1.808 +			return -1;
   1.809 +		memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
   1.810 +		d+=SSL2_CONNECTION_ID_LENGTH;
   1.811 +
   1.812 +		s->state=SSL2_ST_SEND_SERVER_HELLO_B;
   1.813 +		s->init_num=d-(unsigned char *)s->init_buf->data;
   1.814 +		s->init_off=0;
   1.815 +		}
   1.816 +	/* SSL2_ST_SEND_SERVER_HELLO_B */
   1.817 + 	/* If we are using TCP/IP, the performance is bad if we do 2
   1.818 + 	 * writes without a read between them.  This occurs when
   1.819 + 	 * Session-id reuse is used, so I will put in a buffering module
   1.820 + 	 */
   1.821 + 	if (s->hit)
   1.822 + 		{
   1.823 +		if (!ssl_init_wbio_buffer(s,1)) return(-1);
   1.824 + 		}
   1.825 + 
   1.826 +	return(ssl2_do_write(s));
   1.827 +	}
   1.828 +
   1.829 +static int get_client_finished(SSL *s)
   1.830 +	{
   1.831 +	unsigned char *p;
   1.832 +	int i, n;
   1.833 +	unsigned long len;
   1.834 +
   1.835 +	p=(unsigned char *)s->init_buf->data;
   1.836 +	if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
   1.837 +		{
   1.838 +		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
   1.839 +		if (i < 1-s->init_num)
   1.840 +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
   1.841 +		s->init_num += i;
   1.842 +
   1.843 +		if (*p != SSL2_MT_CLIENT_FINISHED)
   1.844 +			{
   1.845 +			if (*p != SSL2_MT_ERROR)
   1.846 +				{
   1.847 +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.848 +				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
   1.849 +				}
   1.850 +			else
   1.851 +				{
   1.852 +				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
   1.853 +				/* try to read the error message */
   1.854 +				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
   1.855 +				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
   1.856 +				}
   1.857 +			return(-1);
   1.858 +			}
   1.859 +		s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
   1.860 +		}
   1.861 +
   1.862 +	/* SSL2_ST_GET_CLIENT_FINISHED_B */
   1.863 +	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
   1.864 +		{
   1.865 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.866 +		SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
   1.867 +		return -1;
   1.868 +		}
   1.869 +	len = 1 + (unsigned long)s->s2->conn_id_length;
   1.870 +	n = (int)len - s->init_num;
   1.871 +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
   1.872 +	if (i < n)
   1.873 +		{
   1.874 +		return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
   1.875 +		}
   1.876 +	if (s->msg_callback)
   1.877 +		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
   1.878 +	p += 1;
   1.879 +	if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
   1.880 +		{
   1.881 +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
   1.882 +		SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
   1.883 +		return(-1);
   1.884 +		}
   1.885 +	return(1);
   1.886 +	}
   1.887 +
   1.888 +static int server_verify(SSL *s)
   1.889 +	{
   1.890 +	unsigned char *p;
   1.891 +
   1.892 +	if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
   1.893 +		{
   1.894 +		p=(unsigned char *)s->init_buf->data;
   1.895 +		*(p++)=SSL2_MT_SERVER_VERIFY;
   1.896 +		if (s->s2->challenge_length > sizeof s->s2->challenge)
   1.897 +			{
   1.898 +			SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
   1.899 +			return -1;
   1.900 +			}
   1.901 +		memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
   1.902 +		/* p+=s->s2->challenge_length; */
   1.903 +
   1.904 +		s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
   1.905 +		s->init_num=s->s2->challenge_length+1;
   1.906 +		s->init_off=0;
   1.907 +		}
   1.908 +	return(ssl2_do_write(s));
   1.909 +	}
   1.910 +
   1.911 +static int server_finish(SSL *s)
   1.912 +	{
   1.913 +	unsigned char *p;
   1.914 +
   1.915 +	if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
   1.916 +		{
   1.917 +		p=(unsigned char *)s->init_buf->data;
   1.918 +		*(p++)=SSL2_MT_SERVER_FINISHED;
   1.919 +
   1.920 +		if (s->session->session_id_length > sizeof s->session->session_id)
   1.921 +			{
   1.922 +			SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
   1.923 +			return -1;
   1.924 +			}
   1.925 +		memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
   1.926 +		/* p+=s->session->session_id_length; */
   1.927 +
   1.928 +		s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
   1.929 +		s->init_num=s->session->session_id_length+1;
   1.930 +		s->init_off=0;
   1.931 +		}
   1.932 +
   1.933 +	/* SSL2_ST_SEND_SERVER_FINISHED_B */
   1.934 +	return(ssl2_do_write(s));
   1.935 +	}
   1.936 +
   1.937 +/* send the request and check the response */
   1.938 +static int request_certificate(SSL *s)
   1.939 +	{
   1.940 +	const unsigned char *cp;
   1.941 +	unsigned char *p,*p2,*buf2;
   1.942 +	unsigned char *ccd;
   1.943 +	int i,j,ctype,ret= -1;
   1.944 +	unsigned long len;
   1.945 +	X509 *x509=NULL;
   1.946 +	STACK_OF(X509) *sk=NULL;
   1.947 +
   1.948 +	ccd=s->s2->tmp.ccl;
   1.949 +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
   1.950 +		{
   1.951 +		p=(unsigned char *)s->init_buf->data;
   1.952 +		*(p++)=SSL2_MT_REQUEST_CERTIFICATE;
   1.953 +		*(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
   1.954 +		if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
   1.955 +			return -1;
   1.956 +		memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
   1.957 +
   1.958 +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
   1.959 +		s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
   1.960 +		s->init_off=0;
   1.961 +		}
   1.962 +
   1.963 +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
   1.964 +		{
   1.965 +		i=ssl2_do_write(s);
   1.966 +		if (i <= 0)
   1.967 +			{
   1.968 +			ret=i;
   1.969 +			goto end;
   1.970 +			}
   1.971 +
   1.972 +		s->init_num=0;
   1.973 +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
   1.974 +		}
   1.975 +
   1.976 +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
   1.977 +		{
   1.978 +		p=(unsigned char *)s->init_buf->data;
   1.979 +		i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
   1.980 +		if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
   1.981 +		                        * (probably NO-CERTIFICATE-ERROR) */
   1.982 +			{
   1.983 +			ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
   1.984 +			goto end;
   1.985 +			}
   1.986 +		s->init_num += i;
   1.987 +
   1.988 +		if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
   1.989 +			{
   1.990 +			n2s(p,i);
   1.991 +			if (i != SSL2_PE_NO_CERTIFICATE)
   1.992 +				{
   1.993 +				/* not the error message we expected -- let ssl2_part_read handle it */
   1.994 +				s->init_num -= 3;
   1.995 +				ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
   1.996 +				goto end;
   1.997 +				}
   1.998 +
   1.999 +			if (s->msg_callback)
  1.1000 +				s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
  1.1001 +
  1.1002 +			/* this is the one place where we can recover from an SSL 2.0 error */
  1.1003 +
  1.1004 +			if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  1.1005 +				{
  1.1006 +				ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
  1.1007 +				SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
  1.1008 +				goto end;
  1.1009 +				}
  1.1010 +			ret=1;
  1.1011 +			goto end;
  1.1012 +			}
  1.1013 +		if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
  1.1014 +			{
  1.1015 +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
  1.1016 +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
  1.1017 +			goto end;
  1.1018 +			}
  1.1019 +		if (s->init_num != 6)
  1.1020 +			{
  1.1021 +			SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
  1.1022 +			goto end;
  1.1023 +			}
  1.1024 +		
  1.1025 +		/* ok we have a response */
  1.1026 +		/* certificate type, there is only one right now. */
  1.1027 +		ctype= *(p++);
  1.1028 +		if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
  1.1029 +			{
  1.1030 +			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
  1.1031 +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
  1.1032 +			goto end;
  1.1033 +			}
  1.1034 +		n2s(p,i); s->s2->tmp.clen=i;
  1.1035 +		n2s(p,i); s->s2->tmp.rlen=i;
  1.1036 +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
  1.1037 +		}
  1.1038 +
  1.1039 +	/* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
  1.1040 +	p=(unsigned char *)s->init_buf->data;
  1.1041 +	len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
  1.1042 +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
  1.1043 +		{
  1.1044 +		SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
  1.1045 +		goto end;
  1.1046 +		}
  1.1047 +	j = (int)len - s->init_num;
  1.1048 +	i = ssl2_read(s,(char *)&(p[s->init_num]),j);
  1.1049 +	if (i < j) 
  1.1050 +		{
  1.1051 +		ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
  1.1052 +		goto end;
  1.1053 +		}
  1.1054 +	if (s->msg_callback)
  1.1055 +		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
  1.1056 +	p += 6;
  1.1057 +
  1.1058 +	cp = p;
  1.1059 +	x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
  1.1060 +	if (x509 == NULL)
  1.1061 +		{
  1.1062 +		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
  1.1063 +		goto msg_end;
  1.1064 +		}
  1.1065 +
  1.1066 +	if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
  1.1067 +		{
  1.1068 +		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
  1.1069 +		goto msg_end;
  1.1070 +		}
  1.1071 +
  1.1072 +	i=ssl_verify_cert_chain(s,sk);
  1.1073 +
  1.1074 +	if (i)	/* we like the packet, now check the chksum */
  1.1075 +		{
  1.1076 +		EVP_MD_CTX ctx;
  1.1077 +		EVP_PKEY *pkey=NULL;
  1.1078 +
  1.1079 +		EVP_MD_CTX_init(&ctx);
  1.1080 +		EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
  1.1081 +		EVP_VerifyUpdate(&ctx,s->s2->key_material,
  1.1082 +				 s->s2->key_material_length);
  1.1083 +		EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
  1.1084 +
  1.1085 +		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
  1.1086 +		buf2=OPENSSL_malloc((unsigned int)i);
  1.1087 +		if (buf2 == NULL)
  1.1088 +			{
  1.1089 +			SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
  1.1090 +			goto msg_end;
  1.1091 +			}
  1.1092 +		p2=buf2;
  1.1093 +		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
  1.1094 +		EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
  1.1095 +		OPENSSL_free(buf2);
  1.1096 +
  1.1097 +		pkey=X509_get_pubkey(x509);
  1.1098 +		if (pkey == NULL) goto end;
  1.1099 +		i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
  1.1100 +		EVP_PKEY_free(pkey);
  1.1101 +		EVP_MD_CTX_cleanup(&ctx);
  1.1102 +
  1.1103 +		if (i) 
  1.1104 +			{
  1.1105 +			if (s->session->peer != NULL)
  1.1106 +				X509_free(s->session->peer);
  1.1107 +			s->session->peer=x509;
  1.1108 +			CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
  1.1109 +			s->session->verify_result = s->verify_result;
  1.1110 +			ret=1;
  1.1111 +			goto end;
  1.1112 +			}
  1.1113 +		else
  1.1114 +			{
  1.1115 +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
  1.1116 +			goto msg_end;
  1.1117 +			}
  1.1118 +		}
  1.1119 +	else
  1.1120 +		{
  1.1121 +msg_end:
  1.1122 +		ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
  1.1123 +		}
  1.1124 +end:
  1.1125 +	sk_X509_free(sk);
  1.1126 +	X509_free(x509);
  1.1127 +	return(ret);
  1.1128 +	}
  1.1129 +
  1.1130 +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
  1.1131 +	     unsigned char *to, int padding)
  1.1132 +	{
  1.1133 +	RSA *rsa;
  1.1134 +	int i;
  1.1135 +
  1.1136 +	if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
  1.1137 +		{
  1.1138 +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
  1.1139 +		return(-1);
  1.1140 +		}
  1.1141 +	if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
  1.1142 +		{
  1.1143 +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
  1.1144 +		return(-1);
  1.1145 +		}
  1.1146 +	rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
  1.1147 +
  1.1148 +	/* we have the public key */
  1.1149 +	i=RSA_private_decrypt(len,from,to,rsa,padding);
  1.1150 +	if (i < 0)
  1.1151 +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
  1.1152 +	return(i);
  1.1153 +	}
  1.1154 +#else /* !OPENSSL_NO_SSL2 */
  1.1155 +
  1.1156 +# if PEDANTIC
  1.1157 +static void *dummy=&dummy;
  1.1158 +# endif
  1.1159 +
  1.1160 +#endif