xref: /onnv-gate/usr/src/common/openssl/ssl/s3_srvr.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* ssl/s3_srvr.c */
2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3*0Sstevel@tonic-gate  * All rights reserved.
4*0Sstevel@tonic-gate  *
5*0Sstevel@tonic-gate  * This package is an SSL implementation written
6*0Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
7*0Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
10*0Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
11*0Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
12*0Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13*0Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
14*0Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15*0Sstevel@tonic-gate  *
16*0Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
17*0Sstevel@tonic-gate  * the code are not to be removed.
18*0Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
19*0Sstevel@tonic-gate  * as the author of the parts of the library used.
20*0Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
21*0Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
24*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
25*0Sstevel@tonic-gate  * are met:
26*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
27*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
28*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
29*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
30*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
31*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
32*0Sstevel@tonic-gate  *    must display the following acknowledgement:
33*0Sstevel@tonic-gate  *    "This product includes cryptographic software written by
34*0Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
35*0Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
36*0Sstevel@tonic-gate  *    being used are not cryptographic related :-).
37*0Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
38*0Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
39*0Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40*0Sstevel@tonic-gate  *
41*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42*0Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44*0Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45*0Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46*0Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47*0Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49*0Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50*0Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51*0Sstevel@tonic-gate  * SUCH DAMAGE.
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
54*0Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55*0Sstevel@tonic-gate  * copied and put under another distribution licence
56*0Sstevel@tonic-gate  * [including the GNU Public Licence.]
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate /* ====================================================================
59*0Sstevel@tonic-gate  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
60*0Sstevel@tonic-gate  *
61*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
62*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
63*0Sstevel@tonic-gate  * are met:
64*0Sstevel@tonic-gate  *
65*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
66*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
67*0Sstevel@tonic-gate  *
68*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
69*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
70*0Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
71*0Sstevel@tonic-gate  *    distribution.
72*0Sstevel@tonic-gate  *
73*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
74*0Sstevel@tonic-gate  *    software must display the following acknowledgment:
75*0Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
76*0Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77*0Sstevel@tonic-gate  *
78*0Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79*0Sstevel@tonic-gate  *    endorse or promote products derived from this software without
80*0Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
81*0Sstevel@tonic-gate  *    openssl-core@openssl.org.
82*0Sstevel@tonic-gate  *
83*0Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
84*0Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
85*0Sstevel@tonic-gate  *    permission of the OpenSSL Project.
86*0Sstevel@tonic-gate  *
87*0Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
88*0Sstevel@tonic-gate  *    acknowledgment:
89*0Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
90*0Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91*0Sstevel@tonic-gate  *
92*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93*0Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95*0Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96*0Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97*0Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98*0Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99*0Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101*0Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102*0Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103*0Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
104*0Sstevel@tonic-gate  * ====================================================================
105*0Sstevel@tonic-gate  *
106*0Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
107*0Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
108*0Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
109*0Sstevel@tonic-gate  *
110*0Sstevel@tonic-gate  */
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate #define REUSE_CIPHER_BUG
113*0Sstevel@tonic-gate #define NETSCAPE_HANG_BUG
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate #include <stdio.h>
117*0Sstevel@tonic-gate #include "ssl_locl.h"
118*0Sstevel@tonic-gate #include "kssl_lcl.h"
119*0Sstevel@tonic-gate #include <openssl/buffer.h>
120*0Sstevel@tonic-gate #include <openssl/rand.h>
121*0Sstevel@tonic-gate #include <openssl/objects.h>
122*0Sstevel@tonic-gate #include <openssl/evp.h>
123*0Sstevel@tonic-gate #include <openssl/x509.h>
124*0Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
125*0Sstevel@tonic-gate #include <openssl/krb5_asn.h>
126*0Sstevel@tonic-gate #endif
127*0Sstevel@tonic-gate #include <openssl/md5.h>
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate static SSL_METHOD *ssl3_get_server_method(int ver);
130*0Sstevel@tonic-gate static int ssl3_get_client_hello(SSL *s);
131*0Sstevel@tonic-gate static int ssl3_check_client_hello(SSL *s);
132*0Sstevel@tonic-gate static int ssl3_send_server_hello(SSL *s);
133*0Sstevel@tonic-gate static int ssl3_send_server_key_exchange(SSL *s);
134*0Sstevel@tonic-gate static int ssl3_send_certificate_request(SSL *s);
135*0Sstevel@tonic-gate static int ssl3_send_server_done(SSL *s);
136*0Sstevel@tonic-gate static int ssl3_get_client_key_exchange(SSL *s);
137*0Sstevel@tonic-gate static int ssl3_get_client_certificate(SSL *s);
138*0Sstevel@tonic-gate static int ssl3_get_cert_verify(SSL *s);
139*0Sstevel@tonic-gate static int ssl3_send_hello_request(SSL *s);
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate static SSL_METHOD *ssl3_get_server_method(int ver)
142*0Sstevel@tonic-gate 	{
143*0Sstevel@tonic-gate 	if (ver == SSL3_VERSION)
144*0Sstevel@tonic-gate 		return(SSLv3_server_method());
145*0Sstevel@tonic-gate 	else
146*0Sstevel@tonic-gate 		return(NULL);
147*0Sstevel@tonic-gate 	}
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate SSL_METHOD *SSLv3_server_method(void)
150*0Sstevel@tonic-gate 	{
151*0Sstevel@tonic-gate 	static int init=1;
152*0Sstevel@tonic-gate 	static SSL_METHOD SSLv3_server_data;
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 	if (init)
155*0Sstevel@tonic-gate 		{
156*0Sstevel@tonic-gate 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 		if (init)
159*0Sstevel@tonic-gate 			{
160*0Sstevel@tonic-gate 			memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
161*0Sstevel@tonic-gate 				sizeof(SSL_METHOD));
162*0Sstevel@tonic-gate 			SSLv3_server_data.ssl_accept=ssl3_accept;
163*0Sstevel@tonic-gate 			SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
164*0Sstevel@tonic-gate 			init=0;
165*0Sstevel@tonic-gate 			}
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
168*0Sstevel@tonic-gate 		}
169*0Sstevel@tonic-gate 	return(&SSLv3_server_data);
170*0Sstevel@tonic-gate 	}
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate int ssl3_accept(SSL *s)
173*0Sstevel@tonic-gate 	{
174*0Sstevel@tonic-gate 	BUF_MEM *buf;
175*0Sstevel@tonic-gate 	unsigned long l,Time=time(NULL);
176*0Sstevel@tonic-gate 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
177*0Sstevel@tonic-gate 	long num1;
178*0Sstevel@tonic-gate 	int ret= -1;
179*0Sstevel@tonic-gate 	int new_state,state,skip=0;
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	RAND_add(&Time,sizeof(Time),0);
182*0Sstevel@tonic-gate 	ERR_clear_error();
183*0Sstevel@tonic-gate 	clear_sys_error();
184*0Sstevel@tonic-gate 
185*0Sstevel@tonic-gate 	if (s->info_callback != NULL)
186*0Sstevel@tonic-gate 		cb=s->info_callback;
187*0Sstevel@tonic-gate 	else if (s->ctx->info_callback != NULL)
188*0Sstevel@tonic-gate 		cb=s->ctx->info_callback;
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	/* init things to blank */
191*0Sstevel@tonic-gate 	s->in_handshake++;
192*0Sstevel@tonic-gate 	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 	if (s->cert == NULL)
195*0Sstevel@tonic-gate 		{
196*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
197*0Sstevel@tonic-gate 		return(-1);
198*0Sstevel@tonic-gate 		}
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate 	for (;;)
201*0Sstevel@tonic-gate 		{
202*0Sstevel@tonic-gate 		state=s->state;
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 		switch (s->state)
205*0Sstevel@tonic-gate 			{
206*0Sstevel@tonic-gate 		case SSL_ST_RENEGOTIATE:
207*0Sstevel@tonic-gate 			s->new_session=1;
208*0Sstevel@tonic-gate 			/* s->state=SSL_ST_ACCEPT; */
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 		case SSL_ST_BEFORE:
211*0Sstevel@tonic-gate 		case SSL_ST_ACCEPT:
212*0Sstevel@tonic-gate 		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
213*0Sstevel@tonic-gate 		case SSL_ST_OK|SSL_ST_ACCEPT:
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 			s->server=1;
216*0Sstevel@tonic-gate 			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 			if ((s->version>>8) != 3)
219*0Sstevel@tonic-gate 				{
220*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
221*0Sstevel@tonic-gate 				return -1;
222*0Sstevel@tonic-gate 				}
223*0Sstevel@tonic-gate 			s->type=SSL_ST_ACCEPT;
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 			if (s->init_buf == NULL)
226*0Sstevel@tonic-gate 				{
227*0Sstevel@tonic-gate 				if ((buf=BUF_MEM_new()) == NULL)
228*0Sstevel@tonic-gate 					{
229*0Sstevel@tonic-gate 					ret= -1;
230*0Sstevel@tonic-gate 					goto end;
231*0Sstevel@tonic-gate 					}
232*0Sstevel@tonic-gate 				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
233*0Sstevel@tonic-gate 					{
234*0Sstevel@tonic-gate 					ret= -1;
235*0Sstevel@tonic-gate 					goto end;
236*0Sstevel@tonic-gate 					}
237*0Sstevel@tonic-gate 				s->init_buf=buf;
238*0Sstevel@tonic-gate 				}
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 			if (!ssl3_setup_buffers(s))
241*0Sstevel@tonic-gate 				{
242*0Sstevel@tonic-gate 				ret= -1;
243*0Sstevel@tonic-gate 				goto end;
244*0Sstevel@tonic-gate 				}
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 			s->init_num=0;
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate 			if (s->state != SSL_ST_RENEGOTIATE)
249*0Sstevel@tonic-gate 				{
250*0Sstevel@tonic-gate 				/* Ok, we now need to push on a buffering BIO so that
251*0Sstevel@tonic-gate 				 * the output is sent in a way that TCP likes :-)
252*0Sstevel@tonic-gate 				 */
253*0Sstevel@tonic-gate 				if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate 				ssl3_init_finished_mac(s);
256*0Sstevel@tonic-gate 				s->state=SSL3_ST_SR_CLNT_HELLO_A;
257*0Sstevel@tonic-gate 				s->ctx->stats.sess_accept++;
258*0Sstevel@tonic-gate 				}
259*0Sstevel@tonic-gate 			else
260*0Sstevel@tonic-gate 				{
261*0Sstevel@tonic-gate 				/* s->state == SSL_ST_RENEGOTIATE,
262*0Sstevel@tonic-gate 				 * we will just send a HelloRequest */
263*0Sstevel@tonic-gate 				s->ctx->stats.sess_accept_renegotiate++;
264*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_HELLO_REQ_A;
265*0Sstevel@tonic-gate 				}
266*0Sstevel@tonic-gate 			break;
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate 		case SSL3_ST_SW_HELLO_REQ_A:
269*0Sstevel@tonic-gate 		case SSL3_ST_SW_HELLO_REQ_B:
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 			s->shutdown=0;
272*0Sstevel@tonic-gate 			ret=ssl3_send_hello_request(s);
273*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
274*0Sstevel@tonic-gate 			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
275*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_FLUSH;
276*0Sstevel@tonic-gate 			s->init_num=0;
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate 			ssl3_init_finished_mac(s);
279*0Sstevel@tonic-gate 			break;
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate 		case SSL3_ST_SW_HELLO_REQ_C:
282*0Sstevel@tonic-gate 			s->state=SSL_ST_OK;
283*0Sstevel@tonic-gate 			break;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 		case SSL3_ST_SR_CLNT_HELLO_A:
286*0Sstevel@tonic-gate 		case SSL3_ST_SR_CLNT_HELLO_B:
287*0Sstevel@tonic-gate 		case SSL3_ST_SR_CLNT_HELLO_C:
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 			s->shutdown=0;
290*0Sstevel@tonic-gate 			ret=ssl3_get_client_hello(s);
291*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
292*0Sstevel@tonic-gate 			s->new_session = 2;
293*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_SRVR_HELLO_A;
294*0Sstevel@tonic-gate 			s->init_num=0;
295*0Sstevel@tonic-gate 			break;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 		case SSL3_ST_SW_SRVR_HELLO_A:
298*0Sstevel@tonic-gate 		case SSL3_ST_SW_SRVR_HELLO_B:
299*0Sstevel@tonic-gate 			ret=ssl3_send_server_hello(s);
300*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
301*0Sstevel@tonic-gate 
302*0Sstevel@tonic-gate 			if (s->hit)
303*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_CHANGE_A;
304*0Sstevel@tonic-gate 			else
305*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_CERT_A;
306*0Sstevel@tonic-gate 			s->init_num=0;
307*0Sstevel@tonic-gate 			break;
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate 		case SSL3_ST_SW_CERT_A:
310*0Sstevel@tonic-gate 		case SSL3_ST_SW_CERT_B:
311*0Sstevel@tonic-gate 			/* Check if it is anon DH */
312*0Sstevel@tonic-gate 			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
313*0Sstevel@tonic-gate 				{
314*0Sstevel@tonic-gate 				ret=ssl3_send_server_certificate(s);
315*0Sstevel@tonic-gate 				if (ret <= 0) goto end;
316*0Sstevel@tonic-gate 				}
317*0Sstevel@tonic-gate 			else
318*0Sstevel@tonic-gate 				skip=1;
319*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_KEY_EXCH_A;
320*0Sstevel@tonic-gate 			s->init_num=0;
321*0Sstevel@tonic-gate 			break;
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 		case SSL3_ST_SW_KEY_EXCH_A:
324*0Sstevel@tonic-gate 		case SSL3_ST_SW_KEY_EXCH_B:
325*0Sstevel@tonic-gate 			l=s->s3->tmp.new_cipher->algorithms;
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 			/* clear this, it may get reset by
328*0Sstevel@tonic-gate 			 * send_server_key_exchange */
329*0Sstevel@tonic-gate 			if ((s->options & SSL_OP_EPHEMERAL_RSA)
330*0Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
331*0Sstevel@tonic-gate 				&& !(l & SSL_KRB5)
332*0Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
333*0Sstevel@tonic-gate 				)
334*0Sstevel@tonic-gate 				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
335*0Sstevel@tonic-gate 				 * even when forbidden by protocol specs
336*0Sstevel@tonic-gate 				 * (handshake may fail as clients are not required to
337*0Sstevel@tonic-gate 				 * be able to handle this) */
338*0Sstevel@tonic-gate 				s->s3->tmp.use_rsa_tmp=1;
339*0Sstevel@tonic-gate 			else
340*0Sstevel@tonic-gate 				s->s3->tmp.use_rsa_tmp=0;
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 			/* only send if a DH key exchange, fortezza or
343*0Sstevel@tonic-gate 			 * RSA but we have a sign only certificate */
344*0Sstevel@tonic-gate 			if (s->s3->tmp.use_rsa_tmp
345*0Sstevel@tonic-gate 			    || (l & (SSL_DH|SSL_kFZA))
346*0Sstevel@tonic-gate 			    || ((l & SSL_kRSA)
347*0Sstevel@tonic-gate 				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
348*0Sstevel@tonic-gate 				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
349*0Sstevel@tonic-gate 					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
350*0Sstevel@tonic-gate 					)
351*0Sstevel@tonic-gate 				    )
352*0Sstevel@tonic-gate 				)
353*0Sstevel@tonic-gate 			    )
354*0Sstevel@tonic-gate 				{
355*0Sstevel@tonic-gate 				ret=ssl3_send_server_key_exchange(s);
356*0Sstevel@tonic-gate 				if (ret <= 0) goto end;
357*0Sstevel@tonic-gate 				}
358*0Sstevel@tonic-gate 			else
359*0Sstevel@tonic-gate 				skip=1;
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_CERT_REQ_A;
362*0Sstevel@tonic-gate 			s->init_num=0;
363*0Sstevel@tonic-gate 			break;
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 		case SSL3_ST_SW_CERT_REQ_A:
366*0Sstevel@tonic-gate 		case SSL3_ST_SW_CERT_REQ_B:
367*0Sstevel@tonic-gate 			if (/* don't request cert unless asked for it: */
368*0Sstevel@tonic-gate 				!(s->verify_mode & SSL_VERIFY_PEER) ||
369*0Sstevel@tonic-gate 				/* if SSL_VERIFY_CLIENT_ONCE is set,
370*0Sstevel@tonic-gate 				 * don't request cert during re-negotiation: */
371*0Sstevel@tonic-gate 				((s->session->peer != NULL) &&
372*0Sstevel@tonic-gate 				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
373*0Sstevel@tonic-gate 				/* never request cert in anonymous ciphersuites
374*0Sstevel@tonic-gate 				 * (see section "Certificate request" in SSL 3 drafts
375*0Sstevel@tonic-gate 				 * and in RFC 2246): */
376*0Sstevel@tonic-gate 				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
377*0Sstevel@tonic-gate 				 /* ... except when the application insists on verification
378*0Sstevel@tonic-gate 				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
379*0Sstevel@tonic-gate 				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
380*0Sstevel@tonic-gate                                  /* never request cert in Kerberos ciphersuites */
381*0Sstevel@tonic-gate                                 (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
382*0Sstevel@tonic-gate 				{
383*0Sstevel@tonic-gate 				/* no cert request */
384*0Sstevel@tonic-gate 				skip=1;
385*0Sstevel@tonic-gate 				s->s3->tmp.cert_request=0;
386*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_SRVR_DONE_A;
387*0Sstevel@tonic-gate 				}
388*0Sstevel@tonic-gate 			else
389*0Sstevel@tonic-gate 				{
390*0Sstevel@tonic-gate 				s->s3->tmp.cert_request=1;
391*0Sstevel@tonic-gate 				ret=ssl3_send_certificate_request(s);
392*0Sstevel@tonic-gate 				if (ret <= 0) goto end;
393*0Sstevel@tonic-gate #ifndef NETSCAPE_HANG_BUG
394*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_SRVR_DONE_A;
395*0Sstevel@tonic-gate #else
396*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_FLUSH;
397*0Sstevel@tonic-gate 				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
398*0Sstevel@tonic-gate #endif
399*0Sstevel@tonic-gate 				s->init_num=0;
400*0Sstevel@tonic-gate 				}
401*0Sstevel@tonic-gate 			break;
402*0Sstevel@tonic-gate 
403*0Sstevel@tonic-gate 		case SSL3_ST_SW_SRVR_DONE_A:
404*0Sstevel@tonic-gate 		case SSL3_ST_SW_SRVR_DONE_B:
405*0Sstevel@tonic-gate 			ret=ssl3_send_server_done(s);
406*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
407*0Sstevel@tonic-gate 			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
408*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_FLUSH;
409*0Sstevel@tonic-gate 			s->init_num=0;
410*0Sstevel@tonic-gate 			break;
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 		case SSL3_ST_SW_FLUSH:
413*0Sstevel@tonic-gate 			/* number of bytes to be flushed */
414*0Sstevel@tonic-gate 			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
415*0Sstevel@tonic-gate 			if (num1 > 0)
416*0Sstevel@tonic-gate 				{
417*0Sstevel@tonic-gate 				s->rwstate=SSL_WRITING;
418*0Sstevel@tonic-gate 				num1=BIO_flush(s->wbio);
419*0Sstevel@tonic-gate 				if (num1 <= 0) { ret= -1; goto end; }
420*0Sstevel@tonic-gate 				s->rwstate=SSL_NOTHING;
421*0Sstevel@tonic-gate 				}
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate 			s->state=s->s3->tmp.next_state;
424*0Sstevel@tonic-gate 			break;
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 		case SSL3_ST_SR_CERT_A:
427*0Sstevel@tonic-gate 		case SSL3_ST_SR_CERT_B:
428*0Sstevel@tonic-gate 			/* Check for second client hello (MS SGC) */
429*0Sstevel@tonic-gate 			ret = ssl3_check_client_hello(s);
430*0Sstevel@tonic-gate 			if (ret <= 0)
431*0Sstevel@tonic-gate 				goto end;
432*0Sstevel@tonic-gate 			if (ret == 2)
433*0Sstevel@tonic-gate 				s->state = SSL3_ST_SR_CLNT_HELLO_C;
434*0Sstevel@tonic-gate 			else {
435*0Sstevel@tonic-gate 				if (s->s3->tmp.cert_request)
436*0Sstevel@tonic-gate 					{
437*0Sstevel@tonic-gate 					ret=ssl3_get_client_certificate(s);
438*0Sstevel@tonic-gate 					if (ret <= 0) goto end;
439*0Sstevel@tonic-gate 					}
440*0Sstevel@tonic-gate 				s->init_num=0;
441*0Sstevel@tonic-gate 				s->state=SSL3_ST_SR_KEY_EXCH_A;
442*0Sstevel@tonic-gate 			}
443*0Sstevel@tonic-gate 			break;
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate 		case SSL3_ST_SR_KEY_EXCH_A:
446*0Sstevel@tonic-gate 		case SSL3_ST_SR_KEY_EXCH_B:
447*0Sstevel@tonic-gate 			ret=ssl3_get_client_key_exchange(s);
448*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
449*0Sstevel@tonic-gate 			s->state=SSL3_ST_SR_CERT_VRFY_A;
450*0Sstevel@tonic-gate 			s->init_num=0;
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate 			/* We need to get hashes here so if there is
453*0Sstevel@tonic-gate 			 * a client cert, it can be verified */
454*0Sstevel@tonic-gate 			s->method->ssl3_enc->cert_verify_mac(s,
455*0Sstevel@tonic-gate 				&(s->s3->finish_dgst1),
456*0Sstevel@tonic-gate 				&(s->s3->tmp.cert_verify_md[0]));
457*0Sstevel@tonic-gate 			s->method->ssl3_enc->cert_verify_mac(s,
458*0Sstevel@tonic-gate 				&(s->s3->finish_dgst2),
459*0Sstevel@tonic-gate 				&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate 			break;
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 		case SSL3_ST_SR_CERT_VRFY_A:
464*0Sstevel@tonic-gate 		case SSL3_ST_SR_CERT_VRFY_B:
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate 			/* we should decide if we expected this one */
467*0Sstevel@tonic-gate 			ret=ssl3_get_cert_verify(s);
468*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
469*0Sstevel@tonic-gate 
470*0Sstevel@tonic-gate 			s->state=SSL3_ST_SR_FINISHED_A;
471*0Sstevel@tonic-gate 			s->init_num=0;
472*0Sstevel@tonic-gate 			break;
473*0Sstevel@tonic-gate 
474*0Sstevel@tonic-gate 		case SSL3_ST_SR_FINISHED_A:
475*0Sstevel@tonic-gate 		case SSL3_ST_SR_FINISHED_B:
476*0Sstevel@tonic-gate 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
477*0Sstevel@tonic-gate 				SSL3_ST_SR_FINISHED_B);
478*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
479*0Sstevel@tonic-gate 			if (s->hit)
480*0Sstevel@tonic-gate 				s->state=SSL_ST_OK;
481*0Sstevel@tonic-gate 			else
482*0Sstevel@tonic-gate 				s->state=SSL3_ST_SW_CHANGE_A;
483*0Sstevel@tonic-gate 			s->init_num=0;
484*0Sstevel@tonic-gate 			break;
485*0Sstevel@tonic-gate 
486*0Sstevel@tonic-gate 		case SSL3_ST_SW_CHANGE_A:
487*0Sstevel@tonic-gate 		case SSL3_ST_SW_CHANGE_B:
488*0Sstevel@tonic-gate 
489*0Sstevel@tonic-gate 			s->session->cipher=s->s3->tmp.new_cipher;
490*0Sstevel@tonic-gate 			if (!s->method->ssl3_enc->setup_key_block(s))
491*0Sstevel@tonic-gate 				{ ret= -1; goto end; }
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 			ret=ssl3_send_change_cipher_spec(s,
494*0Sstevel@tonic-gate 				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
495*0Sstevel@tonic-gate 
496*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
497*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_FINISHED_A;
498*0Sstevel@tonic-gate 			s->init_num=0;
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate 			if (!s->method->ssl3_enc->change_cipher_state(s,
501*0Sstevel@tonic-gate 				SSL3_CHANGE_CIPHER_SERVER_WRITE))
502*0Sstevel@tonic-gate 				{
503*0Sstevel@tonic-gate 				ret= -1;
504*0Sstevel@tonic-gate 				goto end;
505*0Sstevel@tonic-gate 				}
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate 			break;
508*0Sstevel@tonic-gate 
509*0Sstevel@tonic-gate 		case SSL3_ST_SW_FINISHED_A:
510*0Sstevel@tonic-gate 		case SSL3_ST_SW_FINISHED_B:
511*0Sstevel@tonic-gate 			ret=ssl3_send_finished(s,
512*0Sstevel@tonic-gate 				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
513*0Sstevel@tonic-gate 				s->method->ssl3_enc->server_finished_label,
514*0Sstevel@tonic-gate 				s->method->ssl3_enc->server_finished_label_len);
515*0Sstevel@tonic-gate 			if (ret <= 0) goto end;
516*0Sstevel@tonic-gate 			s->state=SSL3_ST_SW_FLUSH;
517*0Sstevel@tonic-gate 			if (s->hit)
518*0Sstevel@tonic-gate 				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
519*0Sstevel@tonic-gate 			else
520*0Sstevel@tonic-gate 				s->s3->tmp.next_state=SSL_ST_OK;
521*0Sstevel@tonic-gate 			s->init_num=0;
522*0Sstevel@tonic-gate 			break;
523*0Sstevel@tonic-gate 
524*0Sstevel@tonic-gate 		case SSL_ST_OK:
525*0Sstevel@tonic-gate 			/* clean a few things up */
526*0Sstevel@tonic-gate 			ssl3_cleanup_key_block(s);
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 			BUF_MEM_free(s->init_buf);
529*0Sstevel@tonic-gate 			s->init_buf=NULL;
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 			/* remove buffering on output */
532*0Sstevel@tonic-gate 			ssl_free_wbio_buffer(s);
533*0Sstevel@tonic-gate 
534*0Sstevel@tonic-gate 			s->init_num=0;
535*0Sstevel@tonic-gate 
536*0Sstevel@tonic-gate 			if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
537*0Sstevel@tonic-gate 				{
538*0Sstevel@tonic-gate 				/* actually not necessarily a 'new' session unless
539*0Sstevel@tonic-gate 				 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
540*0Sstevel@tonic-gate 
541*0Sstevel@tonic-gate 				s->new_session=0;
542*0Sstevel@tonic-gate 
543*0Sstevel@tonic-gate 				ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate 				s->ctx->stats.sess_accept_good++;
546*0Sstevel@tonic-gate 				/* s->server=1; */
547*0Sstevel@tonic-gate 				s->handshake_func=ssl3_accept;
548*0Sstevel@tonic-gate 
549*0Sstevel@tonic-gate 				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
550*0Sstevel@tonic-gate 				}
551*0Sstevel@tonic-gate 
552*0Sstevel@tonic-gate 			ret = 1;
553*0Sstevel@tonic-gate 			goto end;
554*0Sstevel@tonic-gate 			/* break; */
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate 		default:
557*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE);
558*0Sstevel@tonic-gate 			ret= -1;
559*0Sstevel@tonic-gate 			goto end;
560*0Sstevel@tonic-gate 			/* break; */
561*0Sstevel@tonic-gate 			}
562*0Sstevel@tonic-gate 
563*0Sstevel@tonic-gate 		if (!s->s3->tmp.reuse_message && !skip)
564*0Sstevel@tonic-gate 			{
565*0Sstevel@tonic-gate 			if (s->debug)
566*0Sstevel@tonic-gate 				{
567*0Sstevel@tonic-gate 				if ((ret=BIO_flush(s->wbio)) <= 0)
568*0Sstevel@tonic-gate 					goto end;
569*0Sstevel@tonic-gate 				}
570*0Sstevel@tonic-gate 
571*0Sstevel@tonic-gate 
572*0Sstevel@tonic-gate 			if ((cb != NULL) && (s->state != state))
573*0Sstevel@tonic-gate 				{
574*0Sstevel@tonic-gate 				new_state=s->state;
575*0Sstevel@tonic-gate 				s->state=state;
576*0Sstevel@tonic-gate 				cb(s,SSL_CB_ACCEPT_LOOP,1);
577*0Sstevel@tonic-gate 				s->state=new_state;
578*0Sstevel@tonic-gate 				}
579*0Sstevel@tonic-gate 			}
580*0Sstevel@tonic-gate 		skip=0;
581*0Sstevel@tonic-gate 		}
582*0Sstevel@tonic-gate end:
583*0Sstevel@tonic-gate 	/* BIO_flush(s->wbio); */
584*0Sstevel@tonic-gate 
585*0Sstevel@tonic-gate 	s->in_handshake--;
586*0Sstevel@tonic-gate 	if (cb != NULL)
587*0Sstevel@tonic-gate 		cb(s,SSL_CB_ACCEPT_EXIT,ret);
588*0Sstevel@tonic-gate 	return(ret);
589*0Sstevel@tonic-gate 	}
590*0Sstevel@tonic-gate 
591*0Sstevel@tonic-gate static int ssl3_send_hello_request(SSL *s)
592*0Sstevel@tonic-gate 	{
593*0Sstevel@tonic-gate 	unsigned char *p;
594*0Sstevel@tonic-gate 
595*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_HELLO_REQ_A)
596*0Sstevel@tonic-gate 		{
597*0Sstevel@tonic-gate 		p=(unsigned char *)s->init_buf->data;
598*0Sstevel@tonic-gate 		*(p++)=SSL3_MT_HELLO_REQUEST;
599*0Sstevel@tonic-gate 		*(p++)=0;
600*0Sstevel@tonic-gate 		*(p++)=0;
601*0Sstevel@tonic-gate 		*(p++)=0;
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate 		s->state=SSL3_ST_SW_HELLO_REQ_B;
604*0Sstevel@tonic-gate 		/* number of bytes to write */
605*0Sstevel@tonic-gate 		s->init_num=4;
606*0Sstevel@tonic-gate 		s->init_off=0;
607*0Sstevel@tonic-gate 		}
608*0Sstevel@tonic-gate 
609*0Sstevel@tonic-gate 	/* SSL3_ST_SW_HELLO_REQ_B */
610*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
611*0Sstevel@tonic-gate 	}
612*0Sstevel@tonic-gate 
613*0Sstevel@tonic-gate static int ssl3_check_client_hello(SSL *s)
614*0Sstevel@tonic-gate 	{
615*0Sstevel@tonic-gate 	int ok;
616*0Sstevel@tonic-gate 	long n;
617*0Sstevel@tonic-gate 
618*0Sstevel@tonic-gate 	/* this function is called when we really expect a Certificate message,
619*0Sstevel@tonic-gate 	 * so permit appropriate message length */
620*0Sstevel@tonic-gate 	n=ssl3_get_message(s,
621*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_A,
622*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_B,
623*0Sstevel@tonic-gate 		-1,
624*0Sstevel@tonic-gate 		s->max_cert_list,
625*0Sstevel@tonic-gate 		&ok);
626*0Sstevel@tonic-gate 	if (!ok) return((int)n);
627*0Sstevel@tonic-gate 	s->s3->tmp.reuse_message = 1;
628*0Sstevel@tonic-gate 	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
629*0Sstevel@tonic-gate 		{
630*0Sstevel@tonic-gate 		/* Throw away what we have done so far in the current handshake,
631*0Sstevel@tonic-gate 		 * which will now be aborted. (A full SSL_clear would be too much.)
632*0Sstevel@tonic-gate 		 * I hope that tmp.dh is the only thing that may need to be cleared
633*0Sstevel@tonic-gate 		 * when a handshake is not completed ... */
634*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
635*0Sstevel@tonic-gate 		if (s->s3->tmp.dh != NULL)
636*0Sstevel@tonic-gate 			{
637*0Sstevel@tonic-gate 			DH_free(s->s3->tmp.dh);
638*0Sstevel@tonic-gate 			s->s3->tmp.dh = NULL;
639*0Sstevel@tonic-gate 			}
640*0Sstevel@tonic-gate #endif
641*0Sstevel@tonic-gate 		return 2;
642*0Sstevel@tonic-gate 		}
643*0Sstevel@tonic-gate 	return 1;
644*0Sstevel@tonic-gate }
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate static int ssl3_get_client_hello(SSL *s)
647*0Sstevel@tonic-gate 	{
648*0Sstevel@tonic-gate 	int i,j,ok,al,ret= -1;
649*0Sstevel@tonic-gate 	long n;
650*0Sstevel@tonic-gate 	unsigned long id;
651*0Sstevel@tonic-gate 	unsigned char *p,*d,*q;
652*0Sstevel@tonic-gate 	SSL_CIPHER *c;
653*0Sstevel@tonic-gate 	SSL_COMP *comp=NULL;
654*0Sstevel@tonic-gate 	STACK_OF(SSL_CIPHER) *ciphers=NULL;
655*0Sstevel@tonic-gate 
656*0Sstevel@tonic-gate 	/* We do this so that we will respond with our native type.
657*0Sstevel@tonic-gate 	 * If we are TLSv1 and we get SSLv3, we will respond with TLSv1,
658*0Sstevel@tonic-gate 	 * This down switching should be handled by a different method.
659*0Sstevel@tonic-gate 	 * If we are SSLv3, we will respond with SSLv3, even if prompted with
660*0Sstevel@tonic-gate 	 * TLSv1.
661*0Sstevel@tonic-gate 	 */
662*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
663*0Sstevel@tonic-gate 		{
664*0Sstevel@tonic-gate 		s->first_packet=1;
665*0Sstevel@tonic-gate 		s->state=SSL3_ST_SR_CLNT_HELLO_B;
666*0Sstevel@tonic-gate 		}
667*0Sstevel@tonic-gate 	n=ssl3_get_message(s,
668*0Sstevel@tonic-gate 		SSL3_ST_SR_CLNT_HELLO_B,
669*0Sstevel@tonic-gate 		SSL3_ST_SR_CLNT_HELLO_C,
670*0Sstevel@tonic-gate 		SSL3_MT_CLIENT_HELLO,
671*0Sstevel@tonic-gate 		SSL3_RT_MAX_PLAIN_LENGTH,
672*0Sstevel@tonic-gate 		&ok);
673*0Sstevel@tonic-gate 
674*0Sstevel@tonic-gate 	if (!ok) return((int)n);
675*0Sstevel@tonic-gate 	d=p=(unsigned char *)s->init_msg;
676*0Sstevel@tonic-gate 
677*0Sstevel@tonic-gate 	/* use version from inside client hello, not from record header
678*0Sstevel@tonic-gate 	 * (may differ: see RFC 2246, Appendix E, second paragraph) */
679*0Sstevel@tonic-gate 	s->client_version=(((int)p[0])<<8)|(int)p[1];
680*0Sstevel@tonic-gate 	p+=2;
681*0Sstevel@tonic-gate 
682*0Sstevel@tonic-gate 	if (s->client_version < s->version)
683*0Sstevel@tonic-gate 		{
684*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
685*0Sstevel@tonic-gate 		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
686*0Sstevel@tonic-gate 			{
687*0Sstevel@tonic-gate 			/* similar to ssl3_get_record, send alert using remote version number */
688*0Sstevel@tonic-gate 			s->version = s->client_version;
689*0Sstevel@tonic-gate 			}
690*0Sstevel@tonic-gate 		al = SSL_AD_PROTOCOL_VERSION;
691*0Sstevel@tonic-gate 		goto f_err;
692*0Sstevel@tonic-gate 		}
693*0Sstevel@tonic-gate 
694*0Sstevel@tonic-gate 	/* load the client random */
695*0Sstevel@tonic-gate 	memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);
696*0Sstevel@tonic-gate 	p+=SSL3_RANDOM_SIZE;
697*0Sstevel@tonic-gate 
698*0Sstevel@tonic-gate 	/* get the session-id */
699*0Sstevel@tonic-gate 	j= *(p++);
700*0Sstevel@tonic-gate 
701*0Sstevel@tonic-gate 	s->hit=0;
702*0Sstevel@tonic-gate 	/* Versions before 0.9.7 always allow session reuse during renegotiation
703*0Sstevel@tonic-gate 	 * (i.e. when s->new_session is true), option
704*0Sstevel@tonic-gate 	 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is new with 0.9.7.
705*0Sstevel@tonic-gate 	 * Maybe this optional behaviour should always have been the default,
706*0Sstevel@tonic-gate 	 * but we cannot safely change the default behaviour (or new applications
707*0Sstevel@tonic-gate 	 * might be written that become totally unsecure when compiled with
708*0Sstevel@tonic-gate 	 * an earlier library version)
709*0Sstevel@tonic-gate 	 */
710*0Sstevel@tonic-gate 	if (j == 0 || (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
711*0Sstevel@tonic-gate 		{
712*0Sstevel@tonic-gate 		if (!ssl_get_new_session(s,1))
713*0Sstevel@tonic-gate 			goto err;
714*0Sstevel@tonic-gate 		}
715*0Sstevel@tonic-gate 	else
716*0Sstevel@tonic-gate 		{
717*0Sstevel@tonic-gate 		i=ssl_get_prev_session(s,p,j);
718*0Sstevel@tonic-gate 		if (i == 1)
719*0Sstevel@tonic-gate 			{ /* previous session */
720*0Sstevel@tonic-gate 			s->hit=1;
721*0Sstevel@tonic-gate 			}
722*0Sstevel@tonic-gate 		else if (i == -1)
723*0Sstevel@tonic-gate 			goto err;
724*0Sstevel@tonic-gate 		else /* i == 0 */
725*0Sstevel@tonic-gate 			{
726*0Sstevel@tonic-gate 			if (!ssl_get_new_session(s,1))
727*0Sstevel@tonic-gate 				goto err;
728*0Sstevel@tonic-gate 			}
729*0Sstevel@tonic-gate 		}
730*0Sstevel@tonic-gate 
731*0Sstevel@tonic-gate 	p+=j;
732*0Sstevel@tonic-gate 	n2s(p,i);
733*0Sstevel@tonic-gate 	if ((i == 0) && (j != 0))
734*0Sstevel@tonic-gate 		{
735*0Sstevel@tonic-gate 		/* we need a cipher if we are not resuming a session */
736*0Sstevel@tonic-gate 		al=SSL_AD_ILLEGAL_PARAMETER;
737*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);
738*0Sstevel@tonic-gate 		goto f_err;
739*0Sstevel@tonic-gate 		}
740*0Sstevel@tonic-gate 	if ((p+i) >= (d+n))
741*0Sstevel@tonic-gate 		{
742*0Sstevel@tonic-gate 		/* not enough data */
743*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
744*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
745*0Sstevel@tonic-gate 		goto f_err;
746*0Sstevel@tonic-gate 		}
747*0Sstevel@tonic-gate 	if ((i > 0) && (ssl_bytes_to_cipher_list(s,p,i,&(ciphers))
748*0Sstevel@tonic-gate 		== NULL))
749*0Sstevel@tonic-gate 		{
750*0Sstevel@tonic-gate 		goto err;
751*0Sstevel@tonic-gate 		}
752*0Sstevel@tonic-gate 	p+=i;
753*0Sstevel@tonic-gate 
754*0Sstevel@tonic-gate 	/* If it is a hit, check that the cipher is in the list */
755*0Sstevel@tonic-gate 	if ((s->hit) && (i > 0))
756*0Sstevel@tonic-gate 		{
757*0Sstevel@tonic-gate 		j=0;
758*0Sstevel@tonic-gate 		id=s->session->cipher->id;
759*0Sstevel@tonic-gate 
760*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG
761*0Sstevel@tonic-gate 		printf("client sent %d ciphers\n",sk_num(ciphers));
762*0Sstevel@tonic-gate #endif
763*0Sstevel@tonic-gate 		for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
764*0Sstevel@tonic-gate 			{
765*0Sstevel@tonic-gate 			c=sk_SSL_CIPHER_value(ciphers,i);
766*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG
767*0Sstevel@tonic-gate 			printf("client [%2d of %2d]:%s\n",
768*0Sstevel@tonic-gate 				i,sk_num(ciphers),SSL_CIPHER_get_name(c));
769*0Sstevel@tonic-gate #endif
770*0Sstevel@tonic-gate 			if (c->id == id)
771*0Sstevel@tonic-gate 				{
772*0Sstevel@tonic-gate 				j=1;
773*0Sstevel@tonic-gate 				break;
774*0Sstevel@tonic-gate 				}
775*0Sstevel@tonic-gate 			}
776*0Sstevel@tonic-gate 		if (j == 0)
777*0Sstevel@tonic-gate 			{
778*0Sstevel@tonic-gate 			if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
779*0Sstevel@tonic-gate 				{
780*0Sstevel@tonic-gate 				/* Very bad for multi-threading.... */
781*0Sstevel@tonic-gate 				s->session->cipher=sk_SSL_CIPHER_value(ciphers,
782*0Sstevel@tonic-gate 								       0);
783*0Sstevel@tonic-gate 				}
784*0Sstevel@tonic-gate 			else
785*0Sstevel@tonic-gate 				{
786*0Sstevel@tonic-gate 				/* we need to have the cipher in the cipher
787*0Sstevel@tonic-gate 				 * list if we are asked to reuse it */
788*0Sstevel@tonic-gate 				al=SSL_AD_ILLEGAL_PARAMETER;
789*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
790*0Sstevel@tonic-gate 				goto f_err;
791*0Sstevel@tonic-gate 				}
792*0Sstevel@tonic-gate 			}
793*0Sstevel@tonic-gate 		}
794*0Sstevel@tonic-gate 
795*0Sstevel@tonic-gate 	/* compression */
796*0Sstevel@tonic-gate 	i= *(p++);
797*0Sstevel@tonic-gate 	if ((p+i) > (d+n))
798*0Sstevel@tonic-gate 		{
799*0Sstevel@tonic-gate 		/* not enough data */
800*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
801*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
802*0Sstevel@tonic-gate 		goto f_err;
803*0Sstevel@tonic-gate 		}
804*0Sstevel@tonic-gate 	q=p;
805*0Sstevel@tonic-gate 	for (j=0; j<i; j++)
806*0Sstevel@tonic-gate 		{
807*0Sstevel@tonic-gate 		if (p[j] == 0) break;
808*0Sstevel@tonic-gate 		}
809*0Sstevel@tonic-gate 
810*0Sstevel@tonic-gate 	p+=i;
811*0Sstevel@tonic-gate 	if (j >= i)
812*0Sstevel@tonic-gate 		{
813*0Sstevel@tonic-gate 		/* no compress */
814*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
815*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_COMPRESSION_SPECIFIED);
816*0Sstevel@tonic-gate 		goto f_err;
817*0Sstevel@tonic-gate 		}
818*0Sstevel@tonic-gate 
819*0Sstevel@tonic-gate 	/* Worst case, we will use the NULL compression, but if we have other
820*0Sstevel@tonic-gate 	 * options, we will now look for them.  We have i-1 compression
821*0Sstevel@tonic-gate 	 * algorithms from the client, starting at q. */
822*0Sstevel@tonic-gate 	s->s3->tmp.new_compression=NULL;
823*0Sstevel@tonic-gate 	if (s->ctx->comp_methods != NULL)
824*0Sstevel@tonic-gate 		{ /* See if we have a match */
825*0Sstevel@tonic-gate 		int m,nn,o,v,done=0;
826*0Sstevel@tonic-gate 
827*0Sstevel@tonic-gate 		nn=sk_SSL_COMP_num(s->ctx->comp_methods);
828*0Sstevel@tonic-gate 		for (m=0; m<nn; m++)
829*0Sstevel@tonic-gate 			{
830*0Sstevel@tonic-gate 			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
831*0Sstevel@tonic-gate 			v=comp->id;
832*0Sstevel@tonic-gate 			for (o=0; o<i; o++)
833*0Sstevel@tonic-gate 				{
834*0Sstevel@tonic-gate 				if (v == q[o])
835*0Sstevel@tonic-gate 					{
836*0Sstevel@tonic-gate 					done=1;
837*0Sstevel@tonic-gate 					break;
838*0Sstevel@tonic-gate 					}
839*0Sstevel@tonic-gate 				}
840*0Sstevel@tonic-gate 			if (done) break;
841*0Sstevel@tonic-gate 			}
842*0Sstevel@tonic-gate 		if (done)
843*0Sstevel@tonic-gate 			s->s3->tmp.new_compression=comp;
844*0Sstevel@tonic-gate 		else
845*0Sstevel@tonic-gate 			comp=NULL;
846*0Sstevel@tonic-gate 		}
847*0Sstevel@tonic-gate 
848*0Sstevel@tonic-gate 	/* TLS does not mind if there is extra stuff */
849*0Sstevel@tonic-gate #if 0   /* SSL 3.0 does not mind either, so we should disable this test
850*0Sstevel@tonic-gate          * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b,
851*0Sstevel@tonic-gate          * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */
852*0Sstevel@tonic-gate 	if (s->version == SSL3_VERSION)
853*0Sstevel@tonic-gate 		{
854*0Sstevel@tonic-gate 		if (p < (d+n))
855*0Sstevel@tonic-gate 			{
856*0Sstevel@tonic-gate 			/* wrong number of bytes,
857*0Sstevel@tonic-gate 			 * there could be more to follow */
858*0Sstevel@tonic-gate 			al=SSL_AD_DECODE_ERROR;
859*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
860*0Sstevel@tonic-gate 			goto f_err;
861*0Sstevel@tonic-gate 			}
862*0Sstevel@tonic-gate 		}
863*0Sstevel@tonic-gate #endif
864*0Sstevel@tonic-gate 
865*0Sstevel@tonic-gate 	/* Given s->session->ciphers and SSL_get_ciphers, we must
866*0Sstevel@tonic-gate 	 * pick a cipher */
867*0Sstevel@tonic-gate 
868*0Sstevel@tonic-gate 	if (!s->hit)
869*0Sstevel@tonic-gate 		{
870*0Sstevel@tonic-gate 		s->session->compress_meth=(comp == NULL)?0:comp->id;
871*0Sstevel@tonic-gate 		if (s->session->ciphers != NULL)
872*0Sstevel@tonic-gate 			sk_SSL_CIPHER_free(s->session->ciphers);
873*0Sstevel@tonic-gate 		s->session->ciphers=ciphers;
874*0Sstevel@tonic-gate 		if (ciphers == NULL)
875*0Sstevel@tonic-gate 			{
876*0Sstevel@tonic-gate 			al=SSL_AD_ILLEGAL_PARAMETER;
877*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
878*0Sstevel@tonic-gate 			goto f_err;
879*0Sstevel@tonic-gate 			}
880*0Sstevel@tonic-gate 		ciphers=NULL;
881*0Sstevel@tonic-gate 		c=ssl3_choose_cipher(s,s->session->ciphers,
882*0Sstevel@tonic-gate 				     SSL_get_ciphers(s));
883*0Sstevel@tonic-gate 
884*0Sstevel@tonic-gate 		if (c == NULL)
885*0Sstevel@tonic-gate 			{
886*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
887*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
888*0Sstevel@tonic-gate 			goto f_err;
889*0Sstevel@tonic-gate 			}
890*0Sstevel@tonic-gate 		s->s3->tmp.new_cipher=c;
891*0Sstevel@tonic-gate 		}
892*0Sstevel@tonic-gate 	else
893*0Sstevel@tonic-gate 		{
894*0Sstevel@tonic-gate 		/* Session-id reuse */
895*0Sstevel@tonic-gate #ifdef REUSE_CIPHER_BUG
896*0Sstevel@tonic-gate 		STACK_OF(SSL_CIPHER) *sk;
897*0Sstevel@tonic-gate 		SSL_CIPHER *nc=NULL;
898*0Sstevel@tonic-gate 		SSL_CIPHER *ec=NULL;
899*0Sstevel@tonic-gate 
900*0Sstevel@tonic-gate 		if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
901*0Sstevel@tonic-gate 			{
902*0Sstevel@tonic-gate 			sk=s->session->ciphers;
903*0Sstevel@tonic-gate 			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
904*0Sstevel@tonic-gate 				{
905*0Sstevel@tonic-gate 				c=sk_SSL_CIPHER_value(sk,i);
906*0Sstevel@tonic-gate 				if (c->algorithms & SSL_eNULL)
907*0Sstevel@tonic-gate 					nc=c;
908*0Sstevel@tonic-gate 				if (SSL_C_IS_EXPORT(c))
909*0Sstevel@tonic-gate 					ec=c;
910*0Sstevel@tonic-gate 				}
911*0Sstevel@tonic-gate 			if (nc != NULL)
912*0Sstevel@tonic-gate 				s->s3->tmp.new_cipher=nc;
913*0Sstevel@tonic-gate 			else if (ec != NULL)
914*0Sstevel@tonic-gate 				s->s3->tmp.new_cipher=ec;
915*0Sstevel@tonic-gate 			else
916*0Sstevel@tonic-gate 				s->s3->tmp.new_cipher=s->session->cipher;
917*0Sstevel@tonic-gate 			}
918*0Sstevel@tonic-gate 		else
919*0Sstevel@tonic-gate #endif
920*0Sstevel@tonic-gate 		s->s3->tmp.new_cipher=s->session->cipher;
921*0Sstevel@tonic-gate 		}
922*0Sstevel@tonic-gate 
923*0Sstevel@tonic-gate 	/* we now have the following setup.
924*0Sstevel@tonic-gate 	 * client_random
925*0Sstevel@tonic-gate 	 * cipher_list 		- our prefered list of ciphers
926*0Sstevel@tonic-gate 	 * ciphers 		- the clients prefered list of ciphers
927*0Sstevel@tonic-gate 	 * compression		- basically ignored right now
928*0Sstevel@tonic-gate 	 * ssl version is set	- sslv3
929*0Sstevel@tonic-gate 	 * s->session		- The ssl session has been setup.
930*0Sstevel@tonic-gate 	 * s->hit		- session reuse flag
931*0Sstevel@tonic-gate 	 * s->tmp.new_cipher	- the new cipher to use.
932*0Sstevel@tonic-gate 	 */
933*0Sstevel@tonic-gate 
934*0Sstevel@tonic-gate 	ret=1;
935*0Sstevel@tonic-gate 	if (0)
936*0Sstevel@tonic-gate 		{
937*0Sstevel@tonic-gate f_err:
938*0Sstevel@tonic-gate 		ssl3_send_alert(s,SSL3_AL_FATAL,al);
939*0Sstevel@tonic-gate 		}
940*0Sstevel@tonic-gate err:
941*0Sstevel@tonic-gate 	if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers);
942*0Sstevel@tonic-gate 	return(ret);
943*0Sstevel@tonic-gate 	}
944*0Sstevel@tonic-gate 
945*0Sstevel@tonic-gate static int ssl3_send_server_hello(SSL *s)
946*0Sstevel@tonic-gate 	{
947*0Sstevel@tonic-gate 	unsigned char *buf;
948*0Sstevel@tonic-gate 	unsigned char *p,*d;
949*0Sstevel@tonic-gate 	int i,sl;
950*0Sstevel@tonic-gate 	unsigned long l,Time;
951*0Sstevel@tonic-gate 
952*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
953*0Sstevel@tonic-gate 		{
954*0Sstevel@tonic-gate 		buf=(unsigned char *)s->init_buf->data;
955*0Sstevel@tonic-gate 		p=s->s3->server_random;
956*0Sstevel@tonic-gate 		Time=time(NULL);			/* Time */
957*0Sstevel@tonic-gate 		l2n(Time,p);
958*0Sstevel@tonic-gate 		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
959*0Sstevel@tonic-gate 		/* Do the message type and length last */
960*0Sstevel@tonic-gate 		d=p= &(buf[4]);
961*0Sstevel@tonic-gate 
962*0Sstevel@tonic-gate 		*(p++)=s->version>>8;
963*0Sstevel@tonic-gate 		*(p++)=s->version&0xff;
964*0Sstevel@tonic-gate 
965*0Sstevel@tonic-gate 		/* Random stuff */
966*0Sstevel@tonic-gate 		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
967*0Sstevel@tonic-gate 		p+=SSL3_RANDOM_SIZE;
968*0Sstevel@tonic-gate 
969*0Sstevel@tonic-gate 		/* now in theory we have 3 options to sending back the
970*0Sstevel@tonic-gate 		 * session id.  If it is a re-use, we send back the
971*0Sstevel@tonic-gate 		 * old session-id, if it is a new session, we send
972*0Sstevel@tonic-gate 		 * back the new session-id or we send back a 0 length
973*0Sstevel@tonic-gate 		 * session-id if we want it to be single use.
974*0Sstevel@tonic-gate 		 * Currently I will not implement the '0' length session-id
975*0Sstevel@tonic-gate 		 * 12-Jan-98 - I'll now support the '0' length stuff.
976*0Sstevel@tonic-gate 		 */
977*0Sstevel@tonic-gate 		if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER))
978*0Sstevel@tonic-gate 			s->session->session_id_length=0;
979*0Sstevel@tonic-gate 
980*0Sstevel@tonic-gate 		sl=s->session->session_id_length;
981*0Sstevel@tonic-gate 		if (sl > sizeof s->session->session_id)
982*0Sstevel@tonic-gate 			{
983*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
984*0Sstevel@tonic-gate 			return -1;
985*0Sstevel@tonic-gate 			}
986*0Sstevel@tonic-gate 		*(p++)=sl;
987*0Sstevel@tonic-gate 		memcpy(p,s->session->session_id,sl);
988*0Sstevel@tonic-gate 		p+=sl;
989*0Sstevel@tonic-gate 
990*0Sstevel@tonic-gate 		/* put the cipher */
991*0Sstevel@tonic-gate 		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
992*0Sstevel@tonic-gate 		p+=i;
993*0Sstevel@tonic-gate 
994*0Sstevel@tonic-gate 		/* put the compression method */
995*0Sstevel@tonic-gate 		if (s->s3->tmp.new_compression == NULL)
996*0Sstevel@tonic-gate 			*(p++)=0;
997*0Sstevel@tonic-gate 		else
998*0Sstevel@tonic-gate 			*(p++)=s->s3->tmp.new_compression->id;
999*0Sstevel@tonic-gate 
1000*0Sstevel@tonic-gate 		/* do the header */
1001*0Sstevel@tonic-gate 		l=(p-d);
1002*0Sstevel@tonic-gate 		d=buf;
1003*0Sstevel@tonic-gate 		*(d++)=SSL3_MT_SERVER_HELLO;
1004*0Sstevel@tonic-gate 		l2n3(l,d);
1005*0Sstevel@tonic-gate 
1006*0Sstevel@tonic-gate 		s->state=SSL3_ST_CW_CLNT_HELLO_B;
1007*0Sstevel@tonic-gate 		/* number of bytes to write */
1008*0Sstevel@tonic-gate 		s->init_num=p-buf;
1009*0Sstevel@tonic-gate 		s->init_off=0;
1010*0Sstevel@tonic-gate 		}
1011*0Sstevel@tonic-gate 
1012*0Sstevel@tonic-gate 	/* SSL3_ST_CW_CLNT_HELLO_B */
1013*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
1014*0Sstevel@tonic-gate 	}
1015*0Sstevel@tonic-gate 
1016*0Sstevel@tonic-gate static int ssl3_send_server_done(SSL *s)
1017*0Sstevel@tonic-gate 	{
1018*0Sstevel@tonic-gate 	unsigned char *p;
1019*0Sstevel@tonic-gate 
1020*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_SRVR_DONE_A)
1021*0Sstevel@tonic-gate 		{
1022*0Sstevel@tonic-gate 		p=(unsigned char *)s->init_buf->data;
1023*0Sstevel@tonic-gate 
1024*0Sstevel@tonic-gate 		/* do the header */
1025*0Sstevel@tonic-gate 		*(p++)=SSL3_MT_SERVER_DONE;
1026*0Sstevel@tonic-gate 		*(p++)=0;
1027*0Sstevel@tonic-gate 		*(p++)=0;
1028*0Sstevel@tonic-gate 		*(p++)=0;
1029*0Sstevel@tonic-gate 
1030*0Sstevel@tonic-gate 		s->state=SSL3_ST_SW_SRVR_DONE_B;
1031*0Sstevel@tonic-gate 		/* number of bytes to write */
1032*0Sstevel@tonic-gate 		s->init_num=4;
1033*0Sstevel@tonic-gate 		s->init_off=0;
1034*0Sstevel@tonic-gate 		}
1035*0Sstevel@tonic-gate 
1036*0Sstevel@tonic-gate 	/* SSL3_ST_CW_CLNT_HELLO_B */
1037*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
1038*0Sstevel@tonic-gate 	}
1039*0Sstevel@tonic-gate 
1040*0Sstevel@tonic-gate static int ssl3_send_server_key_exchange(SSL *s)
1041*0Sstevel@tonic-gate 	{
1042*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1043*0Sstevel@tonic-gate 	unsigned char *q;
1044*0Sstevel@tonic-gate 	int j,num;
1045*0Sstevel@tonic-gate 	RSA *rsa;
1046*0Sstevel@tonic-gate 	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
1047*0Sstevel@tonic-gate 	unsigned int u;
1048*0Sstevel@tonic-gate #endif
1049*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
1050*0Sstevel@tonic-gate 	DH *dh=NULL,*dhp;
1051*0Sstevel@tonic-gate #endif
1052*0Sstevel@tonic-gate 	EVP_PKEY *pkey;
1053*0Sstevel@tonic-gate 	unsigned char *p,*d;
1054*0Sstevel@tonic-gate 	int al,i;
1055*0Sstevel@tonic-gate 	unsigned long type;
1056*0Sstevel@tonic-gate 	int n;
1057*0Sstevel@tonic-gate 	CERT *cert;
1058*0Sstevel@tonic-gate 	BIGNUM *r[4];
1059*0Sstevel@tonic-gate 	int nr[4],kn;
1060*0Sstevel@tonic-gate 	BUF_MEM *buf;
1061*0Sstevel@tonic-gate 	EVP_MD_CTX md_ctx;
1062*0Sstevel@tonic-gate 
1063*0Sstevel@tonic-gate 	EVP_MD_CTX_init(&md_ctx);
1064*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
1065*0Sstevel@tonic-gate 		{
1066*0Sstevel@tonic-gate 		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
1067*0Sstevel@tonic-gate 		cert=s->cert;
1068*0Sstevel@tonic-gate 
1069*0Sstevel@tonic-gate 		buf=s->init_buf;
1070*0Sstevel@tonic-gate 
1071*0Sstevel@tonic-gate 		r[0]=r[1]=r[2]=r[3]=NULL;
1072*0Sstevel@tonic-gate 		n=0;
1073*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1074*0Sstevel@tonic-gate 		if (type & SSL_kRSA)
1075*0Sstevel@tonic-gate 			{
1076*0Sstevel@tonic-gate 			rsa=cert->rsa_tmp;
1077*0Sstevel@tonic-gate 			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
1078*0Sstevel@tonic-gate 				{
1079*0Sstevel@tonic-gate 				rsa=s->cert->rsa_tmp_cb(s,
1080*0Sstevel@tonic-gate 				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
1081*0Sstevel@tonic-gate 				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
1082*0Sstevel@tonic-gate 				if(rsa == NULL)
1083*0Sstevel@tonic-gate 				{
1084*0Sstevel@tonic-gate 					al=SSL_AD_HANDSHAKE_FAILURE;
1085*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
1086*0Sstevel@tonic-gate 					goto f_err;
1087*0Sstevel@tonic-gate 				}
1088*0Sstevel@tonic-gate 				RSA_up_ref(rsa);
1089*0Sstevel@tonic-gate 				cert->rsa_tmp=rsa;
1090*0Sstevel@tonic-gate 				}
1091*0Sstevel@tonic-gate 			if (rsa == NULL)
1092*0Sstevel@tonic-gate 				{
1093*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1094*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
1095*0Sstevel@tonic-gate 				goto f_err;
1096*0Sstevel@tonic-gate 				}
1097*0Sstevel@tonic-gate 			r[0]=rsa->n;
1098*0Sstevel@tonic-gate 			r[1]=rsa->e;
1099*0Sstevel@tonic-gate 			s->s3->tmp.use_rsa_tmp=1;
1100*0Sstevel@tonic-gate 			}
1101*0Sstevel@tonic-gate 		else
1102*0Sstevel@tonic-gate #endif
1103*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
1104*0Sstevel@tonic-gate 			if (type & SSL_kEDH)
1105*0Sstevel@tonic-gate 			{
1106*0Sstevel@tonic-gate 			dhp=cert->dh_tmp;
1107*0Sstevel@tonic-gate 			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
1108*0Sstevel@tonic-gate 				dhp=s->cert->dh_tmp_cb(s,
1109*0Sstevel@tonic-gate 				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
1110*0Sstevel@tonic-gate 				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
1111*0Sstevel@tonic-gate 			if (dhp == NULL)
1112*0Sstevel@tonic-gate 				{
1113*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1114*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
1115*0Sstevel@tonic-gate 				goto f_err;
1116*0Sstevel@tonic-gate 				}
1117*0Sstevel@tonic-gate 
1118*0Sstevel@tonic-gate 			if (s->s3->tmp.dh != NULL)
1119*0Sstevel@tonic-gate 				{
1120*0Sstevel@tonic-gate 				DH_free(dh);
1121*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
1122*0Sstevel@tonic-gate 				goto err;
1123*0Sstevel@tonic-gate 				}
1124*0Sstevel@tonic-gate 
1125*0Sstevel@tonic-gate 			if ((dh=DHparams_dup(dhp)) == NULL)
1126*0Sstevel@tonic-gate 				{
1127*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
1128*0Sstevel@tonic-gate 				goto err;
1129*0Sstevel@tonic-gate 				}
1130*0Sstevel@tonic-gate 
1131*0Sstevel@tonic-gate 			s->s3->tmp.dh=dh;
1132*0Sstevel@tonic-gate 			if ((dhp->pub_key == NULL ||
1133*0Sstevel@tonic-gate 			     dhp->priv_key == NULL ||
1134*0Sstevel@tonic-gate 			     (s->options & SSL_OP_SINGLE_DH_USE)))
1135*0Sstevel@tonic-gate 				{
1136*0Sstevel@tonic-gate 				if(!DH_generate_key(dh))
1137*0Sstevel@tonic-gate 				    {
1138*0Sstevel@tonic-gate 				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
1139*0Sstevel@tonic-gate 					   ERR_R_DH_LIB);
1140*0Sstevel@tonic-gate 				    goto err;
1141*0Sstevel@tonic-gate 				    }
1142*0Sstevel@tonic-gate 				}
1143*0Sstevel@tonic-gate 			else
1144*0Sstevel@tonic-gate 				{
1145*0Sstevel@tonic-gate 				dh->pub_key=BN_dup(dhp->pub_key);
1146*0Sstevel@tonic-gate 				dh->priv_key=BN_dup(dhp->priv_key);
1147*0Sstevel@tonic-gate 				if ((dh->pub_key == NULL) ||
1148*0Sstevel@tonic-gate 					(dh->priv_key == NULL))
1149*0Sstevel@tonic-gate 					{
1150*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
1151*0Sstevel@tonic-gate 					goto err;
1152*0Sstevel@tonic-gate 					}
1153*0Sstevel@tonic-gate 				}
1154*0Sstevel@tonic-gate 			r[0]=dh->p;
1155*0Sstevel@tonic-gate 			r[1]=dh->g;
1156*0Sstevel@tonic-gate 			r[2]=dh->pub_key;
1157*0Sstevel@tonic-gate 			}
1158*0Sstevel@tonic-gate 		else
1159*0Sstevel@tonic-gate #endif
1160*0Sstevel@tonic-gate 			{
1161*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
1162*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
1163*0Sstevel@tonic-gate 			goto f_err;
1164*0Sstevel@tonic-gate 			}
1165*0Sstevel@tonic-gate 		for (i=0; r[i] != NULL; i++)
1166*0Sstevel@tonic-gate 			{
1167*0Sstevel@tonic-gate 			nr[i]=BN_num_bytes(r[i]);
1168*0Sstevel@tonic-gate 			n+=2+nr[i];
1169*0Sstevel@tonic-gate 			}
1170*0Sstevel@tonic-gate 
1171*0Sstevel@tonic-gate 		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
1172*0Sstevel@tonic-gate 			{
1173*0Sstevel@tonic-gate 			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
1174*0Sstevel@tonic-gate 				== NULL)
1175*0Sstevel@tonic-gate 				{
1176*0Sstevel@tonic-gate 				al=SSL_AD_DECODE_ERROR;
1177*0Sstevel@tonic-gate 				goto f_err;
1178*0Sstevel@tonic-gate 				}
1179*0Sstevel@tonic-gate 			kn=EVP_PKEY_size(pkey);
1180*0Sstevel@tonic-gate 			}
1181*0Sstevel@tonic-gate 		else
1182*0Sstevel@tonic-gate 			{
1183*0Sstevel@tonic-gate 			pkey=NULL;
1184*0Sstevel@tonic-gate 			kn=0;
1185*0Sstevel@tonic-gate 			}
1186*0Sstevel@tonic-gate 
1187*0Sstevel@tonic-gate 		if (!BUF_MEM_grow_clean(buf,n+4+kn))
1188*0Sstevel@tonic-gate 			{
1189*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
1190*0Sstevel@tonic-gate 			goto err;
1191*0Sstevel@tonic-gate 			}
1192*0Sstevel@tonic-gate 		d=(unsigned char *)s->init_buf->data;
1193*0Sstevel@tonic-gate 		p= &(d[4]);
1194*0Sstevel@tonic-gate 
1195*0Sstevel@tonic-gate 		for (i=0; r[i] != NULL; i++)
1196*0Sstevel@tonic-gate 			{
1197*0Sstevel@tonic-gate 			s2n(nr[i],p);
1198*0Sstevel@tonic-gate 			BN_bn2bin(r[i],p);
1199*0Sstevel@tonic-gate 			p+=nr[i];
1200*0Sstevel@tonic-gate 			}
1201*0Sstevel@tonic-gate 
1202*0Sstevel@tonic-gate 		/* not anonymous */
1203*0Sstevel@tonic-gate 		if (pkey != NULL)
1204*0Sstevel@tonic-gate 			{
1205*0Sstevel@tonic-gate 			/* n is the length of the params, they start at &(d[4])
1206*0Sstevel@tonic-gate 			 * and p points to the space at the end. */
1207*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1208*0Sstevel@tonic-gate 			if (pkey->type == EVP_PKEY_RSA)
1209*0Sstevel@tonic-gate 				{
1210*0Sstevel@tonic-gate 				q=md_buf;
1211*0Sstevel@tonic-gate 				j=0;
1212*0Sstevel@tonic-gate 				for (num=2; num > 0; num--)
1213*0Sstevel@tonic-gate 					{
1214*0Sstevel@tonic-gate 					EVP_DigestInit_ex(&md_ctx,(num == 2)
1215*0Sstevel@tonic-gate 						?s->ctx->md5:s->ctx->sha1, NULL);
1216*0Sstevel@tonic-gate 					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
1217*0Sstevel@tonic-gate 					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
1218*0Sstevel@tonic-gate 					EVP_DigestUpdate(&md_ctx,&(d[4]),n);
1219*0Sstevel@tonic-gate 					EVP_DigestFinal_ex(&md_ctx,q,
1220*0Sstevel@tonic-gate 						(unsigned int *)&i);
1221*0Sstevel@tonic-gate 					q+=i;
1222*0Sstevel@tonic-gate 					j+=i;
1223*0Sstevel@tonic-gate 					}
1224*0Sstevel@tonic-gate 				if (RSA_sign(NID_md5_sha1, md_buf, j,
1225*0Sstevel@tonic-gate 					&(p[2]), &u, pkey->pkey.rsa) <= 0)
1226*0Sstevel@tonic-gate 					{
1227*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
1228*0Sstevel@tonic-gate 					goto err;
1229*0Sstevel@tonic-gate 					}
1230*0Sstevel@tonic-gate 				s2n(u,p);
1231*0Sstevel@tonic-gate 				n+=u+2;
1232*0Sstevel@tonic-gate 				}
1233*0Sstevel@tonic-gate 			else
1234*0Sstevel@tonic-gate #endif
1235*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_DSA)
1236*0Sstevel@tonic-gate 				if (pkey->type == EVP_PKEY_DSA)
1237*0Sstevel@tonic-gate 				{
1238*0Sstevel@tonic-gate 				/* lets do DSS */
1239*0Sstevel@tonic-gate 				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
1240*0Sstevel@tonic-gate 				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
1241*0Sstevel@tonic-gate 				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
1242*0Sstevel@tonic-gate 				EVP_SignUpdate(&md_ctx,&(d[4]),n);
1243*0Sstevel@tonic-gate 				if (!EVP_SignFinal(&md_ctx,&(p[2]),
1244*0Sstevel@tonic-gate 					(unsigned int *)&i,pkey))
1245*0Sstevel@tonic-gate 					{
1246*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
1247*0Sstevel@tonic-gate 					goto err;
1248*0Sstevel@tonic-gate 					}
1249*0Sstevel@tonic-gate 				s2n(i,p);
1250*0Sstevel@tonic-gate 				n+=i+2;
1251*0Sstevel@tonic-gate 				}
1252*0Sstevel@tonic-gate 			else
1253*0Sstevel@tonic-gate #endif
1254*0Sstevel@tonic-gate 				{
1255*0Sstevel@tonic-gate 				/* Is this error check actually needed? */
1256*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1257*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
1258*0Sstevel@tonic-gate 				goto f_err;
1259*0Sstevel@tonic-gate 				}
1260*0Sstevel@tonic-gate 			}
1261*0Sstevel@tonic-gate 
1262*0Sstevel@tonic-gate 		*(d++)=SSL3_MT_SERVER_KEY_EXCHANGE;
1263*0Sstevel@tonic-gate 		l2n3(n,d);
1264*0Sstevel@tonic-gate 
1265*0Sstevel@tonic-gate 		/* we should now have things packed up, so lets send
1266*0Sstevel@tonic-gate 		 * it off */
1267*0Sstevel@tonic-gate 		s->init_num=n+4;
1268*0Sstevel@tonic-gate 		s->init_off=0;
1269*0Sstevel@tonic-gate 		}
1270*0Sstevel@tonic-gate 
1271*0Sstevel@tonic-gate 	s->state = SSL3_ST_SW_KEY_EXCH_B;
1272*0Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&md_ctx);
1273*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
1274*0Sstevel@tonic-gate f_err:
1275*0Sstevel@tonic-gate 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
1276*0Sstevel@tonic-gate err:
1277*0Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&md_ctx);
1278*0Sstevel@tonic-gate 	return(-1);
1279*0Sstevel@tonic-gate 	}
1280*0Sstevel@tonic-gate 
1281*0Sstevel@tonic-gate static int ssl3_send_certificate_request(SSL *s)
1282*0Sstevel@tonic-gate 	{
1283*0Sstevel@tonic-gate 	unsigned char *p,*d;
1284*0Sstevel@tonic-gate 	int i,j,nl,off,n;
1285*0Sstevel@tonic-gate 	STACK_OF(X509_NAME) *sk=NULL;
1286*0Sstevel@tonic-gate 	X509_NAME *name;
1287*0Sstevel@tonic-gate 	BUF_MEM *buf;
1288*0Sstevel@tonic-gate 
1289*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_CERT_REQ_A)
1290*0Sstevel@tonic-gate 		{
1291*0Sstevel@tonic-gate 		buf=s->init_buf;
1292*0Sstevel@tonic-gate 
1293*0Sstevel@tonic-gate 		d=p=(unsigned char *)&(buf->data[4]);
1294*0Sstevel@tonic-gate 
1295*0Sstevel@tonic-gate 		/* get the list of acceptable cert types */
1296*0Sstevel@tonic-gate 		p++;
1297*0Sstevel@tonic-gate 		n=ssl3_get_req_cert_type(s,p);
1298*0Sstevel@tonic-gate 		d[0]=n;
1299*0Sstevel@tonic-gate 		p+=n;
1300*0Sstevel@tonic-gate 		n++;
1301*0Sstevel@tonic-gate 
1302*0Sstevel@tonic-gate 		off=n;
1303*0Sstevel@tonic-gate 		p+=2;
1304*0Sstevel@tonic-gate 		n+=2;
1305*0Sstevel@tonic-gate 
1306*0Sstevel@tonic-gate 		sk=SSL_get_client_CA_list(s);
1307*0Sstevel@tonic-gate 		nl=0;
1308*0Sstevel@tonic-gate 		if (sk != NULL)
1309*0Sstevel@tonic-gate 			{
1310*0Sstevel@tonic-gate 			for (i=0; i<sk_X509_NAME_num(sk); i++)
1311*0Sstevel@tonic-gate 				{
1312*0Sstevel@tonic-gate 				name=sk_X509_NAME_value(sk,i);
1313*0Sstevel@tonic-gate 				j=i2d_X509_NAME(name,NULL);
1314*0Sstevel@tonic-gate 				if (!BUF_MEM_grow_clean(buf,4+n+j+2))
1315*0Sstevel@tonic-gate 					{
1316*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
1317*0Sstevel@tonic-gate 					goto err;
1318*0Sstevel@tonic-gate 					}
1319*0Sstevel@tonic-gate 				p=(unsigned char *)&(buf->data[4+n]);
1320*0Sstevel@tonic-gate 				if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
1321*0Sstevel@tonic-gate 					{
1322*0Sstevel@tonic-gate 					s2n(j,p);
1323*0Sstevel@tonic-gate 					i2d_X509_NAME(name,&p);
1324*0Sstevel@tonic-gate 					n+=2+j;
1325*0Sstevel@tonic-gate 					nl+=2+j;
1326*0Sstevel@tonic-gate 					}
1327*0Sstevel@tonic-gate 				else
1328*0Sstevel@tonic-gate 					{
1329*0Sstevel@tonic-gate 					d=p;
1330*0Sstevel@tonic-gate 					i2d_X509_NAME(name,&p);
1331*0Sstevel@tonic-gate 					j-=2; s2n(j,d); j+=2;
1332*0Sstevel@tonic-gate 					n+=j;
1333*0Sstevel@tonic-gate 					nl+=j;
1334*0Sstevel@tonic-gate 					}
1335*0Sstevel@tonic-gate 				}
1336*0Sstevel@tonic-gate 			}
1337*0Sstevel@tonic-gate 		/* else no CA names */
1338*0Sstevel@tonic-gate 		p=(unsigned char *)&(buf->data[4+off]);
1339*0Sstevel@tonic-gate 		s2n(nl,p);
1340*0Sstevel@tonic-gate 
1341*0Sstevel@tonic-gate 		d=(unsigned char *)buf->data;
1342*0Sstevel@tonic-gate 		*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
1343*0Sstevel@tonic-gate 		l2n3(n,d);
1344*0Sstevel@tonic-gate 
1345*0Sstevel@tonic-gate 		/* we should now have things packed up, so lets send
1346*0Sstevel@tonic-gate 		 * it off */
1347*0Sstevel@tonic-gate 
1348*0Sstevel@tonic-gate 		s->init_num=n+4;
1349*0Sstevel@tonic-gate 		s->init_off=0;
1350*0Sstevel@tonic-gate #ifdef NETSCAPE_HANG_BUG
1351*0Sstevel@tonic-gate 		p=(unsigned char *)s->init_buf->data + s->init_num;
1352*0Sstevel@tonic-gate 
1353*0Sstevel@tonic-gate 		/* do the header */
1354*0Sstevel@tonic-gate 		*(p++)=SSL3_MT_SERVER_DONE;
1355*0Sstevel@tonic-gate 		*(p++)=0;
1356*0Sstevel@tonic-gate 		*(p++)=0;
1357*0Sstevel@tonic-gate 		*(p++)=0;
1358*0Sstevel@tonic-gate 		s->init_num += 4;
1359*0Sstevel@tonic-gate #endif
1360*0Sstevel@tonic-gate 
1361*0Sstevel@tonic-gate 		s->state = SSL3_ST_SW_CERT_REQ_B;
1362*0Sstevel@tonic-gate 		}
1363*0Sstevel@tonic-gate 
1364*0Sstevel@tonic-gate 	/* SSL3_ST_SW_CERT_REQ_B */
1365*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
1366*0Sstevel@tonic-gate err:
1367*0Sstevel@tonic-gate 	return(-1);
1368*0Sstevel@tonic-gate 	}
1369*0Sstevel@tonic-gate 
1370*0Sstevel@tonic-gate static int ssl3_get_client_key_exchange(SSL *s)
1371*0Sstevel@tonic-gate 	{
1372*0Sstevel@tonic-gate 	int i,al,ok;
1373*0Sstevel@tonic-gate 	long n;
1374*0Sstevel@tonic-gate 	unsigned long l;
1375*0Sstevel@tonic-gate 	unsigned char *p;
1376*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1377*0Sstevel@tonic-gate 	RSA *rsa=NULL;
1378*0Sstevel@tonic-gate 	EVP_PKEY *pkey=NULL;
1379*0Sstevel@tonic-gate #endif
1380*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
1381*0Sstevel@tonic-gate 	BIGNUM *pub=NULL;
1382*0Sstevel@tonic-gate 	DH *dh_srvr;
1383*0Sstevel@tonic-gate #endif
1384*0Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
1385*0Sstevel@tonic-gate         KSSL_ERR kssl_err;
1386*0Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
1387*0Sstevel@tonic-gate 
1388*0Sstevel@tonic-gate 	n=ssl3_get_message(s,
1389*0Sstevel@tonic-gate 		SSL3_ST_SR_KEY_EXCH_A,
1390*0Sstevel@tonic-gate 		SSL3_ST_SR_KEY_EXCH_B,
1391*0Sstevel@tonic-gate 		SSL3_MT_CLIENT_KEY_EXCHANGE,
1392*0Sstevel@tonic-gate 		2048, /* ??? */
1393*0Sstevel@tonic-gate 		&ok);
1394*0Sstevel@tonic-gate 
1395*0Sstevel@tonic-gate 	if (!ok) return((int)n);
1396*0Sstevel@tonic-gate 	p=(unsigned char *)s->init_msg;
1397*0Sstevel@tonic-gate 
1398*0Sstevel@tonic-gate 	l=s->s3->tmp.new_cipher->algorithms;
1399*0Sstevel@tonic-gate 
1400*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1401*0Sstevel@tonic-gate 	if (l & SSL_kRSA)
1402*0Sstevel@tonic-gate 		{
1403*0Sstevel@tonic-gate 		/* FIX THIS UP EAY EAY EAY EAY */
1404*0Sstevel@tonic-gate 		if (s->s3->tmp.use_rsa_tmp)
1405*0Sstevel@tonic-gate 			{
1406*0Sstevel@tonic-gate 			if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
1407*0Sstevel@tonic-gate 				rsa=s->cert->rsa_tmp;
1408*0Sstevel@tonic-gate 			/* Don't do a callback because rsa_tmp should
1409*0Sstevel@tonic-gate 			 * be sent already */
1410*0Sstevel@tonic-gate 			if (rsa == NULL)
1411*0Sstevel@tonic-gate 				{
1412*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1413*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);
1414*0Sstevel@tonic-gate 				goto f_err;
1415*0Sstevel@tonic-gate 
1416*0Sstevel@tonic-gate 				}
1417*0Sstevel@tonic-gate 			}
1418*0Sstevel@tonic-gate 		else
1419*0Sstevel@tonic-gate 			{
1420*0Sstevel@tonic-gate 			pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
1421*0Sstevel@tonic-gate 			if (	(pkey == NULL) ||
1422*0Sstevel@tonic-gate 				(pkey->type != EVP_PKEY_RSA) ||
1423*0Sstevel@tonic-gate 				(pkey->pkey.rsa == NULL))
1424*0Sstevel@tonic-gate 				{
1425*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1426*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
1427*0Sstevel@tonic-gate 				goto f_err;
1428*0Sstevel@tonic-gate 				}
1429*0Sstevel@tonic-gate 			rsa=pkey->pkey.rsa;
1430*0Sstevel@tonic-gate 			}
1431*0Sstevel@tonic-gate 
1432*0Sstevel@tonic-gate 		/* TLS */
1433*0Sstevel@tonic-gate 		if (s->version > SSL3_VERSION)
1434*0Sstevel@tonic-gate 			{
1435*0Sstevel@tonic-gate 			n2s(p,i);
1436*0Sstevel@tonic-gate 			if (n != i+2)
1437*0Sstevel@tonic-gate 				{
1438*0Sstevel@tonic-gate 				if (!(s->options & SSL_OP_TLS_D5_BUG))
1439*0Sstevel@tonic-gate 					{
1440*0Sstevel@tonic-gate 					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
1441*0Sstevel@tonic-gate 					goto err;
1442*0Sstevel@tonic-gate 					}
1443*0Sstevel@tonic-gate 				else
1444*0Sstevel@tonic-gate 					p-=2;
1445*0Sstevel@tonic-gate 				}
1446*0Sstevel@tonic-gate 			else
1447*0Sstevel@tonic-gate 				n=i;
1448*0Sstevel@tonic-gate 			}
1449*0Sstevel@tonic-gate 
1450*0Sstevel@tonic-gate 		i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
1451*0Sstevel@tonic-gate 
1452*0Sstevel@tonic-gate 		al = -1;
1453*0Sstevel@tonic-gate 
1454*0Sstevel@tonic-gate 		if (i != SSL_MAX_MASTER_KEY_LENGTH)
1455*0Sstevel@tonic-gate 			{
1456*0Sstevel@tonic-gate 			al=SSL_AD_DECODE_ERROR;
1457*0Sstevel@tonic-gate 			/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
1458*0Sstevel@tonic-gate 			}
1459*0Sstevel@tonic-gate 
1460*0Sstevel@tonic-gate 		if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
1461*0Sstevel@tonic-gate 			{
1462*0Sstevel@tonic-gate 			/* The premaster secret must contain the same version number as the
1463*0Sstevel@tonic-gate 			 * ClientHello to detect version rollback attacks (strangely, the
1464*0Sstevel@tonic-gate 			 * protocol does not offer such protection for DH ciphersuites).
1465*0Sstevel@tonic-gate 			 * However, buggy clients exist that send the negotiated protocol
1466*0Sstevel@tonic-gate 			 * version instead if the server does not support the requested
1467*0Sstevel@tonic-gate 			 * protocol version.
1468*0Sstevel@tonic-gate 			 * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
1469*0Sstevel@tonic-gate 			if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
1470*0Sstevel@tonic-gate 				(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
1471*0Sstevel@tonic-gate 				{
1472*0Sstevel@tonic-gate 				al=SSL_AD_DECODE_ERROR;
1473*0Sstevel@tonic-gate 				/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
1474*0Sstevel@tonic-gate 
1475*0Sstevel@tonic-gate 				/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
1476*0Sstevel@tonic-gate 				 * (http://eprint.iacr.org/2003/052/) exploits the version
1477*0Sstevel@tonic-gate 				 * number check as a "bad version oracle" -- an alert would
1478*0Sstevel@tonic-gate 				 * reveal that the plaintext corresponding to some ciphertext
1479*0Sstevel@tonic-gate 				 * made up by the adversary is properly formatted except
1480*0Sstevel@tonic-gate 				 * that the version number is wrong.  To avoid such attacks,
1481*0Sstevel@tonic-gate 				 * we should treat this just like any other decryption error. */
1482*0Sstevel@tonic-gate 				}
1483*0Sstevel@tonic-gate 			}
1484*0Sstevel@tonic-gate 
1485*0Sstevel@tonic-gate 		if (al != -1)
1486*0Sstevel@tonic-gate 			{
1487*0Sstevel@tonic-gate 			/* Some decryption failure -- use random value instead as countermeasure
1488*0Sstevel@tonic-gate 			 * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
1489*0Sstevel@tonic-gate 			 * (see RFC 2246, section 7.4.7.1). */
1490*0Sstevel@tonic-gate 			ERR_clear_error();
1491*0Sstevel@tonic-gate 			i = SSL_MAX_MASTER_KEY_LENGTH;
1492*0Sstevel@tonic-gate 			p[0] = s->client_version >> 8;
1493*0Sstevel@tonic-gate 			p[1] = s->client_version & 0xff;
1494*0Sstevel@tonic-gate 			RAND_pseudo_bytes(p+2, i-2); /* should be RAND_bytes, but we cannot work around a failure */
1495*0Sstevel@tonic-gate 			}
1496*0Sstevel@tonic-gate 
1497*0Sstevel@tonic-gate 		s->session->master_key_length=
1498*0Sstevel@tonic-gate 			s->method->ssl3_enc->generate_master_secret(s,
1499*0Sstevel@tonic-gate 				s->session->master_key,
1500*0Sstevel@tonic-gate 				p,i);
1501*0Sstevel@tonic-gate 		OPENSSL_cleanse(p,i);
1502*0Sstevel@tonic-gate 		}
1503*0Sstevel@tonic-gate 	else
1504*0Sstevel@tonic-gate #endif
1505*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
1506*0Sstevel@tonic-gate 		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
1507*0Sstevel@tonic-gate 		{
1508*0Sstevel@tonic-gate 		n2s(p,i);
1509*0Sstevel@tonic-gate 		if (n != i+2)
1510*0Sstevel@tonic-gate 			{
1511*0Sstevel@tonic-gate 			if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))
1512*0Sstevel@tonic-gate 				{
1513*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
1514*0Sstevel@tonic-gate 				goto err;
1515*0Sstevel@tonic-gate 				}
1516*0Sstevel@tonic-gate 			else
1517*0Sstevel@tonic-gate 				{
1518*0Sstevel@tonic-gate 				p-=2;
1519*0Sstevel@tonic-gate 				i=(int)n;
1520*0Sstevel@tonic-gate 				}
1521*0Sstevel@tonic-gate 			}
1522*0Sstevel@tonic-gate 
1523*0Sstevel@tonic-gate 		if (n == 0L) /* the parameters are in the cert */
1524*0Sstevel@tonic-gate 			{
1525*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
1526*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS);
1527*0Sstevel@tonic-gate 			goto f_err;
1528*0Sstevel@tonic-gate 			}
1529*0Sstevel@tonic-gate 		else
1530*0Sstevel@tonic-gate 			{
1531*0Sstevel@tonic-gate 			if (s->s3->tmp.dh == NULL)
1532*0Sstevel@tonic-gate 				{
1533*0Sstevel@tonic-gate 				al=SSL_AD_HANDSHAKE_FAILURE;
1534*0Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
1535*0Sstevel@tonic-gate 				goto f_err;
1536*0Sstevel@tonic-gate 				}
1537*0Sstevel@tonic-gate 			else
1538*0Sstevel@tonic-gate 				dh_srvr=s->s3->tmp.dh;
1539*0Sstevel@tonic-gate 			}
1540*0Sstevel@tonic-gate 
1541*0Sstevel@tonic-gate 		pub=BN_bin2bn(p,i,NULL);
1542*0Sstevel@tonic-gate 		if (pub == NULL)
1543*0Sstevel@tonic-gate 			{
1544*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB);
1545*0Sstevel@tonic-gate 			goto err;
1546*0Sstevel@tonic-gate 			}
1547*0Sstevel@tonic-gate 
1548*0Sstevel@tonic-gate 		i=DH_compute_key(p,pub,dh_srvr);
1549*0Sstevel@tonic-gate 
1550*0Sstevel@tonic-gate 		if (i <= 0)
1551*0Sstevel@tonic-gate 			{
1552*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1553*0Sstevel@tonic-gate 			goto err;
1554*0Sstevel@tonic-gate 			}
1555*0Sstevel@tonic-gate 
1556*0Sstevel@tonic-gate 		DH_free(s->s3->tmp.dh);
1557*0Sstevel@tonic-gate 		s->s3->tmp.dh=NULL;
1558*0Sstevel@tonic-gate 
1559*0Sstevel@tonic-gate 		BN_clear_free(pub);
1560*0Sstevel@tonic-gate 		pub=NULL;
1561*0Sstevel@tonic-gate 		s->session->master_key_length=
1562*0Sstevel@tonic-gate 			s->method->ssl3_enc->generate_master_secret(s,
1563*0Sstevel@tonic-gate 				s->session->master_key,p,i);
1564*0Sstevel@tonic-gate 		OPENSSL_cleanse(p,i);
1565*0Sstevel@tonic-gate 		}
1566*0Sstevel@tonic-gate 	else
1567*0Sstevel@tonic-gate #endif
1568*0Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
1569*0Sstevel@tonic-gate         if (l & SSL_kKRB5)
1570*0Sstevel@tonic-gate                 {
1571*0Sstevel@tonic-gate                 krb5_error_code		krb5rc;
1572*0Sstevel@tonic-gate 		krb5_data		enc_ticket;
1573*0Sstevel@tonic-gate 		krb5_data		authenticator;
1574*0Sstevel@tonic-gate 		krb5_data		enc_pms;
1575*0Sstevel@tonic-gate                 KSSL_CTX		*kssl_ctx = s->kssl_ctx;
1576*0Sstevel@tonic-gate 		EVP_CIPHER_CTX		ciph_ctx;
1577*0Sstevel@tonic-gate 		EVP_CIPHER		*enc = NULL;
1578*0Sstevel@tonic-gate 		unsigned char		iv[EVP_MAX_IV_LENGTH];
1579*0Sstevel@tonic-gate 		unsigned char		pms[SSL_MAX_MASTER_KEY_LENGTH
1580*0Sstevel@tonic-gate                                                + EVP_MAX_BLOCK_LENGTH];
1581*0Sstevel@tonic-gate 		int                     padl, outl;
1582*0Sstevel@tonic-gate 		krb5_timestamp		authtime = 0;
1583*0Sstevel@tonic-gate 		krb5_ticket_times	ttimes;
1584*0Sstevel@tonic-gate 
1585*0Sstevel@tonic-gate 		EVP_CIPHER_CTX_init(&ciph_ctx);
1586*0Sstevel@tonic-gate 
1587*0Sstevel@tonic-gate                 if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
1588*0Sstevel@tonic-gate 
1589*0Sstevel@tonic-gate 		n2s(p,i);
1590*0Sstevel@tonic-gate 		enc_ticket.length = i;
1591*0Sstevel@tonic-gate 
1592*0Sstevel@tonic-gate 		if (n < enc_ticket.length + 6)
1593*0Sstevel@tonic-gate 			{
1594*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1595*0Sstevel@tonic-gate 				SSL_R_DATA_LENGTH_TOO_LONG);
1596*0Sstevel@tonic-gate 			goto err;
1597*0Sstevel@tonic-gate 			}
1598*0Sstevel@tonic-gate 
1599*0Sstevel@tonic-gate 		enc_ticket.data = (char *)p;
1600*0Sstevel@tonic-gate 		p+=enc_ticket.length;
1601*0Sstevel@tonic-gate 
1602*0Sstevel@tonic-gate 		n2s(p,i);
1603*0Sstevel@tonic-gate 		authenticator.length = i;
1604*0Sstevel@tonic-gate 
1605*0Sstevel@tonic-gate 		if (n < enc_ticket.length + authenticator.length + 6)
1606*0Sstevel@tonic-gate 			{
1607*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1608*0Sstevel@tonic-gate 				SSL_R_DATA_LENGTH_TOO_LONG);
1609*0Sstevel@tonic-gate 			goto err;
1610*0Sstevel@tonic-gate 			}
1611*0Sstevel@tonic-gate 
1612*0Sstevel@tonic-gate 		authenticator.data = (char *)p;
1613*0Sstevel@tonic-gate 		p+=authenticator.length;
1614*0Sstevel@tonic-gate 
1615*0Sstevel@tonic-gate 		n2s(p,i);
1616*0Sstevel@tonic-gate 		enc_pms.length = i;
1617*0Sstevel@tonic-gate 		enc_pms.data = (char *)p;
1618*0Sstevel@tonic-gate 		p+=enc_pms.length;
1619*0Sstevel@tonic-gate 
1620*0Sstevel@tonic-gate 		/* Note that the length is checked again below,
1621*0Sstevel@tonic-gate 		** after decryption
1622*0Sstevel@tonic-gate 		*/
1623*0Sstevel@tonic-gate 		if(enc_pms.length > sizeof pms)
1624*0Sstevel@tonic-gate 			{
1625*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1626*0Sstevel@tonic-gate 			       SSL_R_DATA_LENGTH_TOO_LONG);
1627*0Sstevel@tonic-gate 			goto err;
1628*0Sstevel@tonic-gate 			}
1629*0Sstevel@tonic-gate 
1630*0Sstevel@tonic-gate 		if (n != enc_ticket.length + authenticator.length +
1631*0Sstevel@tonic-gate 						enc_pms.length + 6)
1632*0Sstevel@tonic-gate 			{
1633*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1634*0Sstevel@tonic-gate 				SSL_R_DATA_LENGTH_TOO_LONG);
1635*0Sstevel@tonic-gate 			goto err;
1636*0Sstevel@tonic-gate 			}
1637*0Sstevel@tonic-gate 
1638*0Sstevel@tonic-gate                 if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
1639*0Sstevel@tonic-gate 					&kssl_err)) != 0)
1640*0Sstevel@tonic-gate                         {
1641*0Sstevel@tonic-gate #ifdef KSSL_DEBUG
1642*0Sstevel@tonic-gate                         printf("kssl_sget_tkt rtn %d [%d]\n",
1643*0Sstevel@tonic-gate                                 krb5rc, kssl_err.reason);
1644*0Sstevel@tonic-gate                         if (kssl_err.text)
1645*0Sstevel@tonic-gate                                 printf("kssl_err text= %s\n", kssl_err.text);
1646*0Sstevel@tonic-gate #endif	/* KSSL_DEBUG */
1647*0Sstevel@tonic-gate                         SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
1648*0Sstevel@tonic-gate                                 kssl_err.reason);
1649*0Sstevel@tonic-gate                         goto err;
1650*0Sstevel@tonic-gate                         }
1651*0Sstevel@tonic-gate 
1652*0Sstevel@tonic-gate 		/*  Note: no authenticator is not considered an error,
1653*0Sstevel@tonic-gate 		**  but will return authtime == 0.
1654*0Sstevel@tonic-gate 		*/
1655*0Sstevel@tonic-gate 		if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
1656*0Sstevel@tonic-gate 					&authtime, &kssl_err)) != 0)
1657*0Sstevel@tonic-gate 			{
1658*0Sstevel@tonic-gate #ifdef KSSL_DEBUG
1659*0Sstevel@tonic-gate                         printf("kssl_check_authent rtn %d [%d]\n",
1660*0Sstevel@tonic-gate                                 krb5rc, kssl_err.reason);
1661*0Sstevel@tonic-gate                         if (kssl_err.text)
1662*0Sstevel@tonic-gate                                 printf("kssl_err text= %s\n", kssl_err.text);
1663*0Sstevel@tonic-gate #endif	/* KSSL_DEBUG */
1664*0Sstevel@tonic-gate                         SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
1665*0Sstevel@tonic-gate                                 kssl_err.reason);
1666*0Sstevel@tonic-gate                         goto err;
1667*0Sstevel@tonic-gate 			}
1668*0Sstevel@tonic-gate 
1669*0Sstevel@tonic-gate 		if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
1670*0Sstevel@tonic-gate 			{
1671*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc);
1672*0Sstevel@tonic-gate                         goto err;
1673*0Sstevel@tonic-gate 			}
1674*0Sstevel@tonic-gate 
1675*0Sstevel@tonic-gate #ifdef KSSL_DEBUG
1676*0Sstevel@tonic-gate                 kssl_ctx_show(kssl_ctx);
1677*0Sstevel@tonic-gate #endif	/* KSSL_DEBUG */
1678*0Sstevel@tonic-gate 
1679*0Sstevel@tonic-gate 		enc = kssl_map_enc(kssl_ctx->enctype);
1680*0Sstevel@tonic-gate                 if (enc == NULL)
1681*0Sstevel@tonic-gate                     goto err;
1682*0Sstevel@tonic-gate 
1683*0Sstevel@tonic-gate 		memset(iv, 0, sizeof iv);	/* per RFC 1510 */
1684*0Sstevel@tonic-gate 
1685*0Sstevel@tonic-gate 		if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
1686*0Sstevel@tonic-gate 			{
1687*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1688*0Sstevel@tonic-gate 				SSL_R_DECRYPTION_FAILED);
1689*0Sstevel@tonic-gate 			goto err;
1690*0Sstevel@tonic-gate 			}
1691*0Sstevel@tonic-gate 		if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
1692*0Sstevel@tonic-gate 					(unsigned char *)enc_pms.data, enc_pms.length))
1693*0Sstevel@tonic-gate 			{
1694*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1695*0Sstevel@tonic-gate 				SSL_R_DECRYPTION_FAILED);
1696*0Sstevel@tonic-gate 			goto err;
1697*0Sstevel@tonic-gate 			}
1698*0Sstevel@tonic-gate 		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
1699*0Sstevel@tonic-gate 			{
1700*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1701*0Sstevel@tonic-gate 				SSL_R_DATA_LENGTH_TOO_LONG);
1702*0Sstevel@tonic-gate 			goto err;
1703*0Sstevel@tonic-gate 			}
1704*0Sstevel@tonic-gate 		if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
1705*0Sstevel@tonic-gate 			{
1706*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1707*0Sstevel@tonic-gate 				SSL_R_DECRYPTION_FAILED);
1708*0Sstevel@tonic-gate 			goto err;
1709*0Sstevel@tonic-gate 			}
1710*0Sstevel@tonic-gate 		outl += padl;
1711*0Sstevel@tonic-gate 		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
1712*0Sstevel@tonic-gate 			{
1713*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1714*0Sstevel@tonic-gate 				SSL_R_DATA_LENGTH_TOO_LONG);
1715*0Sstevel@tonic-gate 			goto err;
1716*0Sstevel@tonic-gate 			}
1717*0Sstevel@tonic-gate 		EVP_CIPHER_CTX_cleanup(&ciph_ctx);
1718*0Sstevel@tonic-gate 
1719*0Sstevel@tonic-gate                 s->session->master_key_length=
1720*0Sstevel@tonic-gate                         s->method->ssl3_enc->generate_master_secret(s,
1721*0Sstevel@tonic-gate                                 s->session->master_key, pms, outl);
1722*0Sstevel@tonic-gate 
1723*0Sstevel@tonic-gate                 if (kssl_ctx->client_princ)
1724*0Sstevel@tonic-gate                         {
1725*0Sstevel@tonic-gate                         int len = strlen(kssl_ctx->client_princ);
1726*0Sstevel@tonic-gate                         if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH )
1727*0Sstevel@tonic-gate                                 {
1728*0Sstevel@tonic-gate                                 s->session->krb5_client_princ_len = len;
1729*0Sstevel@tonic-gate                                 memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
1730*0Sstevel@tonic-gate                                 }
1731*0Sstevel@tonic-gate                         }
1732*0Sstevel@tonic-gate 
1733*0Sstevel@tonic-gate 
1734*0Sstevel@tonic-gate                 /*  Was doing kssl_ctx_free() here,
1735*0Sstevel@tonic-gate 		**  but it caused problems for apache.
1736*0Sstevel@tonic-gate                 **  kssl_ctx = kssl_ctx_free(kssl_ctx);
1737*0Sstevel@tonic-gate                 **  if (s->kssl_ctx)  s->kssl_ctx = NULL;
1738*0Sstevel@tonic-gate                 */
1739*0Sstevel@tonic-gate                 }
1740*0Sstevel@tonic-gate 	else
1741*0Sstevel@tonic-gate #endif	/* OPENSSL_NO_KRB5 */
1742*0Sstevel@tonic-gate 		{
1743*0Sstevel@tonic-gate 		al=SSL_AD_HANDSHAKE_FAILURE;
1744*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
1745*0Sstevel@tonic-gate 				SSL_R_UNKNOWN_CIPHER_TYPE);
1746*0Sstevel@tonic-gate 		goto f_err;
1747*0Sstevel@tonic-gate 		}
1748*0Sstevel@tonic-gate 
1749*0Sstevel@tonic-gate 	return(1);
1750*0Sstevel@tonic-gate f_err:
1751*0Sstevel@tonic-gate 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
1752*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA)
1753*0Sstevel@tonic-gate err:
1754*0Sstevel@tonic-gate #endif
1755*0Sstevel@tonic-gate 	return(-1);
1756*0Sstevel@tonic-gate 	}
1757*0Sstevel@tonic-gate 
1758*0Sstevel@tonic-gate static int ssl3_get_cert_verify(SSL *s)
1759*0Sstevel@tonic-gate 	{
1760*0Sstevel@tonic-gate 	EVP_PKEY *pkey=NULL;
1761*0Sstevel@tonic-gate 	unsigned char *p;
1762*0Sstevel@tonic-gate 	int al,ok,ret=0;
1763*0Sstevel@tonic-gate 	long n;
1764*0Sstevel@tonic-gate 	int type=0,i,j;
1765*0Sstevel@tonic-gate 	X509 *peer;
1766*0Sstevel@tonic-gate 
1767*0Sstevel@tonic-gate 	n=ssl3_get_message(s,
1768*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_VRFY_A,
1769*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_VRFY_B,
1770*0Sstevel@tonic-gate 		-1,
1771*0Sstevel@tonic-gate 		514, /* 514? */
1772*0Sstevel@tonic-gate 		&ok);
1773*0Sstevel@tonic-gate 
1774*0Sstevel@tonic-gate 	if (!ok) return((int)n);
1775*0Sstevel@tonic-gate 
1776*0Sstevel@tonic-gate 	if (s->session->peer != NULL)
1777*0Sstevel@tonic-gate 		{
1778*0Sstevel@tonic-gate 		peer=s->session->peer;
1779*0Sstevel@tonic-gate 		pkey=X509_get_pubkey(peer);
1780*0Sstevel@tonic-gate 		type=X509_certificate_type(peer,pkey);
1781*0Sstevel@tonic-gate 		}
1782*0Sstevel@tonic-gate 	else
1783*0Sstevel@tonic-gate 		{
1784*0Sstevel@tonic-gate 		peer=NULL;
1785*0Sstevel@tonic-gate 		pkey=NULL;
1786*0Sstevel@tonic-gate 		}
1787*0Sstevel@tonic-gate 
1788*0Sstevel@tonic-gate 	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
1789*0Sstevel@tonic-gate 		{
1790*0Sstevel@tonic-gate 		s->s3->tmp.reuse_message=1;
1791*0Sstevel@tonic-gate 		if ((peer != NULL) && (type | EVP_PKT_SIGN))
1792*0Sstevel@tonic-gate 			{
1793*0Sstevel@tonic-gate 			al=SSL_AD_UNEXPECTED_MESSAGE;
1794*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
1795*0Sstevel@tonic-gate 			goto f_err;
1796*0Sstevel@tonic-gate 			}
1797*0Sstevel@tonic-gate 		ret=1;
1798*0Sstevel@tonic-gate 		goto end;
1799*0Sstevel@tonic-gate 		}
1800*0Sstevel@tonic-gate 
1801*0Sstevel@tonic-gate 	if (peer == NULL)
1802*0Sstevel@tonic-gate 		{
1803*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_NO_CLIENT_CERT_RECEIVED);
1804*0Sstevel@tonic-gate 		al=SSL_AD_UNEXPECTED_MESSAGE;
1805*0Sstevel@tonic-gate 		goto f_err;
1806*0Sstevel@tonic-gate 		}
1807*0Sstevel@tonic-gate 
1808*0Sstevel@tonic-gate 	if (!(type & EVP_PKT_SIGN))
1809*0Sstevel@tonic-gate 		{
1810*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
1811*0Sstevel@tonic-gate 		al=SSL_AD_ILLEGAL_PARAMETER;
1812*0Sstevel@tonic-gate 		goto f_err;
1813*0Sstevel@tonic-gate 		}
1814*0Sstevel@tonic-gate 
1815*0Sstevel@tonic-gate 	if (s->s3->change_cipher_spec)
1816*0Sstevel@tonic-gate 		{
1817*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY);
1818*0Sstevel@tonic-gate 		al=SSL_AD_UNEXPECTED_MESSAGE;
1819*0Sstevel@tonic-gate 		goto f_err;
1820*0Sstevel@tonic-gate 		}
1821*0Sstevel@tonic-gate 
1822*0Sstevel@tonic-gate 	/* we now have a signature that we need to verify */
1823*0Sstevel@tonic-gate 	p=(unsigned char *)s->init_msg;
1824*0Sstevel@tonic-gate 	n2s(p,i);
1825*0Sstevel@tonic-gate 	n-=2;
1826*0Sstevel@tonic-gate 	if (i > n)
1827*0Sstevel@tonic-gate 		{
1828*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
1829*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
1830*0Sstevel@tonic-gate 		goto f_err;
1831*0Sstevel@tonic-gate 		}
1832*0Sstevel@tonic-gate 
1833*0Sstevel@tonic-gate 	j=EVP_PKEY_size(pkey);
1834*0Sstevel@tonic-gate 	if ((i > j) || (n > j) || (n <= 0))
1835*0Sstevel@tonic-gate 		{
1836*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_SIZE);
1837*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
1838*0Sstevel@tonic-gate 		goto f_err;
1839*0Sstevel@tonic-gate 		}
1840*0Sstevel@tonic-gate 
1841*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1842*0Sstevel@tonic-gate 	if (pkey->type == EVP_PKEY_RSA)
1843*0Sstevel@tonic-gate 		{
1844*0Sstevel@tonic-gate 		i=RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
1845*0Sstevel@tonic-gate 			MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, p, i,
1846*0Sstevel@tonic-gate 							pkey->pkey.rsa);
1847*0Sstevel@tonic-gate 		if (i < 0)
1848*0Sstevel@tonic-gate 			{
1849*0Sstevel@tonic-gate 			al=SSL_AD_DECRYPT_ERROR;
1850*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_DECRYPT);
1851*0Sstevel@tonic-gate 			goto f_err;
1852*0Sstevel@tonic-gate 			}
1853*0Sstevel@tonic-gate 		if (i == 0)
1854*0Sstevel@tonic-gate 			{
1855*0Sstevel@tonic-gate 			al=SSL_AD_DECRYPT_ERROR;
1856*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_SIGNATURE);
1857*0Sstevel@tonic-gate 			goto f_err;
1858*0Sstevel@tonic-gate 			}
1859*0Sstevel@tonic-gate 		}
1860*0Sstevel@tonic-gate 	else
1861*0Sstevel@tonic-gate #endif
1862*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
1863*0Sstevel@tonic-gate 		if (pkey->type == EVP_PKEY_DSA)
1864*0Sstevel@tonic-gate 		{
1865*0Sstevel@tonic-gate 		j=DSA_verify(pkey->save_type,
1866*0Sstevel@tonic-gate 			&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
1867*0Sstevel@tonic-gate 			SHA_DIGEST_LENGTH,p,i,pkey->pkey.dsa);
1868*0Sstevel@tonic-gate 		if (j <= 0)
1869*0Sstevel@tonic-gate 			{
1870*0Sstevel@tonic-gate 			/* bad signature */
1871*0Sstevel@tonic-gate 			al=SSL_AD_DECRYPT_ERROR;
1872*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_DSA_SIGNATURE);
1873*0Sstevel@tonic-gate 			goto f_err;
1874*0Sstevel@tonic-gate 			}
1875*0Sstevel@tonic-gate 		}
1876*0Sstevel@tonic-gate 	else
1877*0Sstevel@tonic-gate #endif
1878*0Sstevel@tonic-gate 		{
1879*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
1880*0Sstevel@tonic-gate 		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
1881*0Sstevel@tonic-gate 		goto f_err;
1882*0Sstevel@tonic-gate 		}
1883*0Sstevel@tonic-gate 
1884*0Sstevel@tonic-gate 
1885*0Sstevel@tonic-gate 	ret=1;
1886*0Sstevel@tonic-gate 	if (0)
1887*0Sstevel@tonic-gate 		{
1888*0Sstevel@tonic-gate f_err:
1889*0Sstevel@tonic-gate 		ssl3_send_alert(s,SSL3_AL_FATAL,al);
1890*0Sstevel@tonic-gate 		}
1891*0Sstevel@tonic-gate end:
1892*0Sstevel@tonic-gate 	EVP_PKEY_free(pkey);
1893*0Sstevel@tonic-gate 	return(ret);
1894*0Sstevel@tonic-gate 	}
1895*0Sstevel@tonic-gate 
1896*0Sstevel@tonic-gate static int ssl3_get_client_certificate(SSL *s)
1897*0Sstevel@tonic-gate 	{
1898*0Sstevel@tonic-gate 	int i,ok,al,ret= -1;
1899*0Sstevel@tonic-gate 	X509 *x=NULL;
1900*0Sstevel@tonic-gate 	unsigned long l,nc,llen,n;
1901*0Sstevel@tonic-gate 	unsigned char *p,*d,*q;
1902*0Sstevel@tonic-gate 	STACK_OF(X509) *sk=NULL;
1903*0Sstevel@tonic-gate 
1904*0Sstevel@tonic-gate 	n=ssl3_get_message(s,
1905*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_A,
1906*0Sstevel@tonic-gate 		SSL3_ST_SR_CERT_B,
1907*0Sstevel@tonic-gate 		-1,
1908*0Sstevel@tonic-gate 		s->max_cert_list,
1909*0Sstevel@tonic-gate 		&ok);
1910*0Sstevel@tonic-gate 
1911*0Sstevel@tonic-gate 	if (!ok) return((int)n);
1912*0Sstevel@tonic-gate 
1913*0Sstevel@tonic-gate 	if	(s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE)
1914*0Sstevel@tonic-gate 		{
1915*0Sstevel@tonic-gate 		if (	(s->verify_mode & SSL_VERIFY_PEER) &&
1916*0Sstevel@tonic-gate 			(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
1917*0Sstevel@tonic-gate 			{
1918*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
1919*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
1920*0Sstevel@tonic-gate 			goto f_err;
1921*0Sstevel@tonic-gate 			}
1922*0Sstevel@tonic-gate 		/* If tls asked for a client cert, the client must return a 0 list */
1923*0Sstevel@tonic-gate 		if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request)
1924*0Sstevel@tonic-gate 			{
1925*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
1926*0Sstevel@tonic-gate 			al=SSL_AD_UNEXPECTED_MESSAGE;
1927*0Sstevel@tonic-gate 			goto f_err;
1928*0Sstevel@tonic-gate 			}
1929*0Sstevel@tonic-gate 		s->s3->tmp.reuse_message=1;
1930*0Sstevel@tonic-gate 		return(1);
1931*0Sstevel@tonic-gate 		}
1932*0Sstevel@tonic-gate 
1933*0Sstevel@tonic-gate 	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)
1934*0Sstevel@tonic-gate 		{
1935*0Sstevel@tonic-gate 		al=SSL_AD_UNEXPECTED_MESSAGE;
1936*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE);
1937*0Sstevel@tonic-gate 		goto f_err;
1938*0Sstevel@tonic-gate 		}
1939*0Sstevel@tonic-gate 	d=p=(unsigned char *)s->init_msg;
1940*0Sstevel@tonic-gate 
1941*0Sstevel@tonic-gate 	if ((sk=sk_X509_new_null()) == NULL)
1942*0Sstevel@tonic-gate 		{
1943*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1944*0Sstevel@tonic-gate 		goto err;
1945*0Sstevel@tonic-gate 		}
1946*0Sstevel@tonic-gate 
1947*0Sstevel@tonic-gate 	n2l3(p,llen);
1948*0Sstevel@tonic-gate 	if (llen+3 != n)
1949*0Sstevel@tonic-gate 		{
1950*0Sstevel@tonic-gate 		al=SSL_AD_DECODE_ERROR;
1951*0Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_LENGTH_MISMATCH);
1952*0Sstevel@tonic-gate 		goto f_err;
1953*0Sstevel@tonic-gate 		}
1954*0Sstevel@tonic-gate 	for (nc=0; nc<llen; )
1955*0Sstevel@tonic-gate 		{
1956*0Sstevel@tonic-gate 		n2l3(p,l);
1957*0Sstevel@tonic-gate 		if ((l+nc+3) > llen)
1958*0Sstevel@tonic-gate 			{
1959*0Sstevel@tonic-gate 			al=SSL_AD_DECODE_ERROR;
1960*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
1961*0Sstevel@tonic-gate 			goto f_err;
1962*0Sstevel@tonic-gate 			}
1963*0Sstevel@tonic-gate 
1964*0Sstevel@tonic-gate 		q=p;
1965*0Sstevel@tonic-gate 		x=d2i_X509(NULL,&p,l);
1966*0Sstevel@tonic-gate 		if (x == NULL)
1967*0Sstevel@tonic-gate 			{
1968*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_ASN1_LIB);
1969*0Sstevel@tonic-gate 			goto err;
1970*0Sstevel@tonic-gate 			}
1971*0Sstevel@tonic-gate 		if (p != (q+l))
1972*0Sstevel@tonic-gate 			{
1973*0Sstevel@tonic-gate 			al=SSL_AD_DECODE_ERROR;
1974*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
1975*0Sstevel@tonic-gate 			goto f_err;
1976*0Sstevel@tonic-gate 			}
1977*0Sstevel@tonic-gate 		if (!sk_X509_push(sk,x))
1978*0Sstevel@tonic-gate 			{
1979*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1980*0Sstevel@tonic-gate 			goto err;
1981*0Sstevel@tonic-gate 			}
1982*0Sstevel@tonic-gate 		x=NULL;
1983*0Sstevel@tonic-gate 		nc+=l+3;
1984*0Sstevel@tonic-gate 		}
1985*0Sstevel@tonic-gate 
1986*0Sstevel@tonic-gate 	if (sk_X509_num(sk) <= 0)
1987*0Sstevel@tonic-gate 		{
1988*0Sstevel@tonic-gate 		/* TLS does not mind 0 certs returned */
1989*0Sstevel@tonic-gate 		if (s->version == SSL3_VERSION)
1990*0Sstevel@tonic-gate 			{
1991*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
1992*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_RETURNED);
1993*0Sstevel@tonic-gate 			goto f_err;
1994*0Sstevel@tonic-gate 			}
1995*0Sstevel@tonic-gate 		/* Fail for TLS only if we required a certificate */
1996*0Sstevel@tonic-gate 		else if ((s->verify_mode & SSL_VERIFY_PEER) &&
1997*0Sstevel@tonic-gate 			 (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
1998*0Sstevel@tonic-gate 			{
1999*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
2000*0Sstevel@tonic-gate 			al=SSL_AD_HANDSHAKE_FAILURE;
2001*0Sstevel@tonic-gate 			goto f_err;
2002*0Sstevel@tonic-gate 			}
2003*0Sstevel@tonic-gate 		}
2004*0Sstevel@tonic-gate 	else
2005*0Sstevel@tonic-gate 		{
2006*0Sstevel@tonic-gate 		i=ssl_verify_cert_chain(s,sk);
2007*0Sstevel@tonic-gate 		if (!i)
2008*0Sstevel@tonic-gate 			{
2009*0Sstevel@tonic-gate 			al=ssl_verify_alarm_type(s->verify_result);
2010*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED);
2011*0Sstevel@tonic-gate 			goto f_err;
2012*0Sstevel@tonic-gate 			}
2013*0Sstevel@tonic-gate 		}
2014*0Sstevel@tonic-gate 
2015*0Sstevel@tonic-gate 	if (s->session->peer != NULL) /* This should not be needed */
2016*0Sstevel@tonic-gate 		X509_free(s->session->peer);
2017*0Sstevel@tonic-gate 	s->session->peer=sk_X509_shift(sk);
2018*0Sstevel@tonic-gate 	s->session->verify_result = s->verify_result;
2019*0Sstevel@tonic-gate 
2020*0Sstevel@tonic-gate 	/* With the current implementation, sess_cert will always be NULL
2021*0Sstevel@tonic-gate 	 * when we arrive here. */
2022*0Sstevel@tonic-gate 	if (s->session->sess_cert == NULL)
2023*0Sstevel@tonic-gate 		{
2024*0Sstevel@tonic-gate 		s->session->sess_cert = ssl_sess_cert_new();
2025*0Sstevel@tonic-gate 		if (s->session->sess_cert == NULL)
2026*0Sstevel@tonic-gate 			{
2027*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
2028*0Sstevel@tonic-gate 			goto err;
2029*0Sstevel@tonic-gate 			}
2030*0Sstevel@tonic-gate 		}
2031*0Sstevel@tonic-gate 	if (s->session->sess_cert->cert_chain != NULL)
2032*0Sstevel@tonic-gate 		sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
2033*0Sstevel@tonic-gate 	s->session->sess_cert->cert_chain=sk;
2034*0Sstevel@tonic-gate 	/* Inconsistency alert: cert_chain does *not* include the
2035*0Sstevel@tonic-gate 	 * peer's own certificate, while we do include it in s3_clnt.c */
2036*0Sstevel@tonic-gate 
2037*0Sstevel@tonic-gate 	sk=NULL;
2038*0Sstevel@tonic-gate 
2039*0Sstevel@tonic-gate 	ret=1;
2040*0Sstevel@tonic-gate 	if (0)
2041*0Sstevel@tonic-gate 		{
2042*0Sstevel@tonic-gate f_err:
2043*0Sstevel@tonic-gate 		ssl3_send_alert(s,SSL3_AL_FATAL,al);
2044*0Sstevel@tonic-gate 		}
2045*0Sstevel@tonic-gate err:
2046*0Sstevel@tonic-gate 	if (x != NULL) X509_free(x);
2047*0Sstevel@tonic-gate 	if (sk != NULL) sk_X509_pop_free(sk,X509_free);
2048*0Sstevel@tonic-gate 	return(ret);
2049*0Sstevel@tonic-gate 	}
2050*0Sstevel@tonic-gate 
2051*0Sstevel@tonic-gate int ssl3_send_server_certificate(SSL *s)
2052*0Sstevel@tonic-gate 	{
2053*0Sstevel@tonic-gate 	unsigned long l;
2054*0Sstevel@tonic-gate 	X509 *x;
2055*0Sstevel@tonic-gate 
2056*0Sstevel@tonic-gate 	if (s->state == SSL3_ST_SW_CERT_A)
2057*0Sstevel@tonic-gate 		{
2058*0Sstevel@tonic-gate 		x=ssl_get_server_send_cert(s);
2059*0Sstevel@tonic-gate 		if (x == NULL &&
2060*0Sstevel@tonic-gate                         /* VRS: allow null cert if auth == KRB5 */
2061*0Sstevel@tonic-gate                         (s->s3->tmp.new_cipher->algorithms
2062*0Sstevel@tonic-gate                                 & (SSL_MKEY_MASK|SSL_AUTH_MASK))
2063*0Sstevel@tonic-gate                         != (SSL_aKRB5|SSL_kKRB5))
2064*0Sstevel@tonic-gate 			{
2065*0Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
2066*0Sstevel@tonic-gate 			return(0);
2067*0Sstevel@tonic-gate 			}
2068*0Sstevel@tonic-gate 
2069*0Sstevel@tonic-gate 		l=ssl3_output_cert_chain(s,x);
2070*0Sstevel@tonic-gate 		s->state=SSL3_ST_SW_CERT_B;
2071*0Sstevel@tonic-gate 		s->init_num=(int)l;
2072*0Sstevel@tonic-gate 		s->init_off=0;
2073*0Sstevel@tonic-gate 		}
2074*0Sstevel@tonic-gate 
2075*0Sstevel@tonic-gate 	/* SSL3_ST_SW_CERT_B */
2076*0Sstevel@tonic-gate 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
2077*0Sstevel@tonic-gate 	}
2078