1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ssl/d1_clnt.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DTLS implementation written by Nagendra Modadugu
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@OpenSSL.org.
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ssl_locl.h"
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_KRB5
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "kssl_lcl.h"
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/buffer.h>
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/rand.h>
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/objects.h>
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/md5.h>
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/bn.h>
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DH
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/dh.h>
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const SSL_METHOD *dtls1_get_client_method(int ver);
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dtls1_get_hello_verify(SSL *s);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const SSL_METHOD *dtls1_get_client_method(int ver)
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
13698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(DTLSv1_client_method());
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ssl_undefined_function,
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			dtls1_connect,
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			dtls1_get_client_method)
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dtls1_connect(SSL *s)
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BUF_MEM *buf=NULL;
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long Time=(unsigned long)time(NULL);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void (*cb)(const SSL *ssl,int type,int val)=NULL;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret= -1;
153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int new_state,state,skip=0;
154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char sctpauthkey[64];
156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RAND_add(&Time,sizeof(Time),0);
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_clear_error();
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	clear_sys_error();
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->info_callback != NULL)
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cb=s->info_callback;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (s->ctx->info_callback != NULL)
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cb=s->ctx->info_callback;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->in_handshake++;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Notify SCTP BIO socket to enter handshake
173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * mode and prevent stream identifier other
174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * than 0. Will be ignored if no SCTP is used.
175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_HEARTBEATS
180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If we're awaiting a HeartbeatResponse, pretend we
181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * already got and don't await it anymore, because
182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * Heartbeats don't make sense during handshakes anyway.
183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (s->tlsext_hb_pending)
185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dtls1_stop_timer(s);
187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		s->tlsext_hb_pending = 0;
188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		s->tlsext_hb_seq++;
189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (;;)
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		state=s->state;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		switch(s->state)
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_RENEGOTIATE:
199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			s->renegotiate=1;
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL_ST_CONNECT;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->ctx->stats.sess_connect_renegotiate++;
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* break */
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_BEFORE:
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_CONNECT:
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_BEFORE|SSL_ST_CONNECT:
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_OK|SSL_ST_CONNECT:
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->server=0;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
21198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) &&
21298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			    (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00))
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret = -1;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* s->version=SSL3_VERSION; */
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->type=SSL_ST_CONNECT;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->init_buf == NULL)
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((buf=BUF_MEM_new()) == NULL)
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ret= -1;
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					goto end;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ret= -1;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					goto end;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->init_buf=buf;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				buf=NULL;
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* setup buffing BIO */
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* don't push the buffering BIO quite yet */
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_CLNT_HELLO_A;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->ctx->stats.sess_connect++;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* mark client_random uninitialized */
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memset(s->s3->client_random,0,sizeof(s->s3->client_random));
25098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->d1->send_cookie = 0;
25198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->hit = 0;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case DTLS1_SCTP_ST_CR_READ_SOCK:
256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->s3->in_read_app_data=2;
260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->rwstate=SSL_READING;
261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				BIO_clear_retry_flags(SSL_get_rbio(s));
262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				BIO_set_retry_read(SSL_get_rbio(s));
263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				ret = -1;
264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto end;
265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			s->state=s->s3->tmp.next_state;
268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		case DTLS1_SCTP_ST_CW_WRITE_SOCK:
271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* read app data until dry event */
272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (ret < 0) goto end;
275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (ret == 0)
277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->s3->in_read_app_data=2;
279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->rwstate=SSL_READING;
280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				BIO_clear_retry_flags(SSL_get_rbio(s));
281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				BIO_set_retry_read(SSL_get_rbio(s));
282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				ret = -1;
283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto end;
284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			s->state=s->d1->next_state;
287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CLNT_HELLO_A:
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CLNT_HELLO_B:
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->shutdown=0;
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* every DTLS ClientHello resets Finished MAC */
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ssl3_init_finished_mac(s);
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
29898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_start_timer(s);
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_client_hello(s);
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ( s->d1->send_cookie)
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL3_ST_CW_FLUSH;
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL3_ST_CR_SRVR_HELLO_A;
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
312392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
313392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* Disable buffering for SCTP */
314392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
315392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
316392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
317392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				/* turn on buffering for the next lot of output */
318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (s->bbio != s->wbio)
319392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->wbio=BIO_push(s->bbio,s->wbio);
320392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
322392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_SRVR_HELLO_A:
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_SRVR_HELLO_B:
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=ssl3_get_server_hello(s);
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (s->hit)
333392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{
334392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
335392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					/* Add new shared key for SCTP-Auth,
336392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					 * will be ignored if no SCTP used.
337392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					 */
338392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
339392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					         DTLS1_SCTP_AUTH_LABEL);
340392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
341392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					SSL_export_keying_material(s, sctpauthkey,
342392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					                           sizeof(sctpauthkey), labelbuffer,
343392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					                           sizeof(labelbuffer), NULL, 0, 0);
344392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
345392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							 sizeof(sctpauthkey), sctpauthkey);
347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
348392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->state=SSL3_ST_CR_FINISHED_A;
350392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					}
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				else
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = dtls1_get_hello_verify(s);
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ( ret <= 0)
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
36398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_stop_timer(s);
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ( s->d1->send_cookie) /* start again, with a cookie */
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL3_ST_CW_CLNT_HELLO_A;
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state = SSL3_ST_CR_CERT_A;
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num = 0;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_CERT_A:
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_CERT_B:
37398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifndef OPENSSL_NO_TLSEXT
37498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			ret=ssl3_check_finished(s);
37598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if (ret <= 0) goto end;
37698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if (ret == 2)
37798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				{
37898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				s->hit = 1;
37998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				if (s->tlsext_ticket_expected)
38098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom					s->state=SSL3_ST_CR_SESSION_TICKET_A;
38198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				else
38298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom					s->state=SSL3_ST_CR_FINISHED_A;
38398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				s->init_num=0;
38498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				break;
38598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				}
38698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* Check if it is anon DH or PSK */
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=ssl3_get_server_certificate(s);
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (ret <= 0) goto end;
39398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifndef OPENSSL_NO_TLSEXT
39498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				if (s->tlsext_status_expected)
39598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom					s->state=SSL3_ST_CR_CERT_STATUS_A;
39698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				else
39798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom					s->state=SSL3_ST_CR_KEY_EXCH_A;
39898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				}
39998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			else
40098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				{
40198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				skip = 1;
40298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				s->state=SSL3_ST_CR_KEY_EXCH_A;
40398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				}
40498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#else
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				skip=1;
40898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CR_KEY_EXCH_A;
41098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_KEY_EXCH_A:
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_KEY_EXCH_B:
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=ssl3_get_key_exchange(s);
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CR_CERT_REQ_A;
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* at this point we check that we have the
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * required stuff from the server */
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ssl3_check_cert_and_algorithm(s))
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret= -1;
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_CERT_REQ_A:
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_CERT_REQ_B:
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=ssl3_get_certificate_request(s);
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CR_SRVR_DONE_A;
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_SRVR_DONE_A:
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_SRVR_DONE_B:
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=ssl3_get_server_done(s);
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
44221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom			dtls1_stop_timer(s);
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->s3->tmp.cert_req)
444392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->s3->tmp.next_state=SSL3_ST_CW_CERT_A;
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
446392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->s3->tmp.next_state=SSL3_ST_CW_KEY_EXCH_A;
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
449392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
450392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
451392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			    state == SSL_ST_RENEGOTIATE)
452392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->state=DTLS1_SCTP_ST_CR_READ_SOCK;
453392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
454392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
455392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			s->state=s->s3->tmp.next_state;
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_A:
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_B:
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_C:
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_D:
46298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_start_timer(s);
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_send_client_certificate(s);
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_KEY_EXCH_A;
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_KEY_EXCH_A:
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_KEY_EXCH_B:
47198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_start_timer(s);
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_send_client_key_exchange(s);
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
474392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
475392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
476392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* Add new shared key for SCTP-Auth,
477392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			 * will be ignored if no SCTP used.
478392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			 */
479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
480392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			         DTLS1_SCTP_AUTH_LABEL);
481392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
482392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			SSL_export_keying_material(s, sctpauthkey,
483392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			                           sizeof(sctpauthkey), labelbuffer,
484392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			                           sizeof(labelbuffer), NULL, 0, 0);
485392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
486392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
487392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					 sizeof(sctpauthkey), sctpauthkey);
488392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
489392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* EAY EAY EAY need to check for DH fix cert
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * sent back */
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* For TLS, cert_req is set to 2, so a cert chain
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * of nothing is sent, but no verify packet is sent */
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->s3->tmp.cert_req == 1)
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL3_ST_CW_CERT_VRFY_A;
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
500392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
501392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
502392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{
503392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->d1->next_state=SSL3_ST_CW_CHANGE_A;
504392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
505392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					}
506392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				else
507392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
508392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->state=SSL3_ST_CW_CHANGE_A;
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->change_cipher_spec=0;
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_VRFY_A:
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CERT_VRFY_B:
51798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_start_timer(s);
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_send_client_verify(s);
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
520392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
521392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
522392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
523392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->d1->next_state=SSL3_ST_CW_CHANGE_A;
524392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
525392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
526392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
527392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
528392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->state=SSL3_ST_CW_CHANGE_A;
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->s3->change_cipher_spec=0;
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CHANGE_A:
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_CHANGE_B:
535ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom			if (!s->hit)
536ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom				dtls1_start_timer(s);
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_send_change_cipher_spec(s,
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
540392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_FINISHED_A;
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->session->cipher=s->s3->tmp.new_cipher;
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_NO_COMP
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->session->compress_meth=0;
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->s3->tmp.new_compression == NULL)
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->session->compress_meth=0;
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->session->compress_meth=
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->s3->tmp.new_compression->id;
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!s->method->ssl3_enc->setup_key_block(s))
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret= -1;
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!s->method->ssl3_enc->change_cipher_state(s,
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret= -1;
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
567ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#ifndef OPENSSL_NO_SCTP
568ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root				if (s->hit)
569ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					{
570ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					/* Change to new shared key of SCTP-Auth,
571ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					 * will be ignored if no SCTP used.
572ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					 */
573ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
574ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					}
575ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#endif
576ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_FINISHED_A:
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_FINISHED_B:
582ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom			if (!s->hit)
583ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom				dtls1_start_timer(s);
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=dtls1_send_finished(s,
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->method->ssl3_enc->client_finished_label,
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->method->ssl3_enc->client_finished_label_len);
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_FLUSH;
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* clear flags */
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->hit)
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->tmp.next_state=SSL_ST_OK;
596392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
597392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
598392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{
599392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						s->d1->next_state = s->s3->tmp.next_state;
600392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						s->s3->tmp.next_state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
601392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					}
602392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->state=SSL_ST_OK;
606392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
607392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
608392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						{
609392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							s->d1->next_state = SSL_ST_OK;
610392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
611392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						}
612392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->s3->delay_buf_pop_ret=0;
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
619ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#ifndef OPENSSL_NO_SCTP
620ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root				/* Change to new shared key of SCTP-Auth,
621ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root				 * will be ignored if no SCTP used.
622ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root				 */
623ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
624ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#endif
625ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root
62698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifndef OPENSSL_NO_TLSEXT
62798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				/* Allow NewSessionTicket if ticket expected */
62898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				if (s->tlsext_ticket_expected)
62998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
63098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				else
63198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
63298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifndef OPENSSL_NO_TLSEXT
63998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		case SSL3_ST_CR_SESSION_TICKET_A:
64098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		case SSL3_ST_CR_SESSION_TICKET_B:
64198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			ret=ssl3_get_new_session_ticket(s);
64298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if (ret <= 0) goto end;
64398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->state=SSL3_ST_CR_FINISHED_A;
64498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->init_num=0;
64598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		break;
64698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
64798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		case SSL3_ST_CR_CERT_STATUS_A:
64898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		case SSL3_ST_CR_CERT_STATUS_B:
64998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			ret=ssl3_get_cert_status(s);
65098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if (ret <= 0) goto end;
65198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->state=SSL3_ST_CR_KEY_EXCH_A;
65298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->init_num=0;
65398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		break;
65498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
65598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_FINISHED_A:
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CR_FINISHED_B:
65898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->d1->change_cipher_spec_ok = 1;
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSL3_ST_CR_FINISHED_B);
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) goto end;
66298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			dtls1_stop_timer(s);
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->hit)
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL3_ST_CW_CHANGE_A;
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=SSL_ST_OK;
668392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
669392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
670392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
671392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				state == SSL_ST_RENEGOTIATE)
672392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
673392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->d1->next_state=s->state;
674392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
675392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
676392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
677392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL3_ST_CW_FLUSH:
68298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->rwstate=SSL_WRITING;
68398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			if (BIO_flush(s->wbio) <= 0)
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
685392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				/* If the write error was fatal, stop trying */
686392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (!BIO_should_retry(s->wbio))
687392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{
688392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->rwstate=SSL_NOTHING;
689392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					s->state=s->s3->tmp.next_state;
690392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					}
691392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
69298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				ret= -1;
69398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom				goto end;
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
69598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->rwstate=SSL_NOTHING;
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=s->s3->tmp.next_state;
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case SSL_ST_OK:
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* clean a few things up */
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ssl3_cleanup_key_block(s);
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->init_buf != NULL)
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BUF_MEM_free(s->init_buf);
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->init_buf=NULL;
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* If we are not 'joining' the last two packets,
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * remove the buffering now */
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ssl_free_wbio_buffer(s);
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* else do it later in ssl3_write */
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->init_num=0;
718392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			s->renegotiate=0;
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->new_session=0;
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->hit) s->ctx->stats.sess_hit++;
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=1;
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* s->server=0; */
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->handshake_func=dtls1_connect;
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->ctx->stats.sess_connect_good++;
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* done with handshaking */
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->d1->handshake_read_seq  = 0;
73398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			s->d1->next_handshake_write_seq = 0;
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* break; */
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		default:
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret= -1;
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* break; */
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* did we do anything */
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!s->s3->tmp.reuse_message && !skip)
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->debug)
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((ret=BIO_flush(s->wbio)) <= 0)
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					goto end;
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((cb != NULL) && (s->state != state))
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				new_state=s->state;
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=state;
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				cb(s,SSL_CB_CONNECT_LOOP,1);
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->state=new_state;
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		skip=0;
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectend:
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->in_handshake--;
765392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
766392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_SCTP
767392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Notify SCTP BIO socket to leave handshake
768392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * mode and allow stream identifier other
769392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * than 0. Will be ignored if no SCTP is used.
770392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
771392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
772392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
773392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buf != NULL)
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BUF_MEM_free(buf);
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (cb != NULL)
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cb(s,SSL_CB_CONNECT_EXIT,ret);
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dtls1_client_hello(SSL *s)
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *buf;
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *p,*d;
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int i,j;
786ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root	unsigned long l;
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	SSL_COMP *comp;
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buf=(unsigned char *)s->init_buf->data;
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
79298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		SSL_SESSION *sess = s->session;
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((s->session == NULL) ||
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(s->session->ssl_version != s->version) ||
79598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifdef OPENSSL_NO_TLSEXT
79698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			!sess->session_id_length ||
79798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#else
79898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			(!sess->session_id_length && !sess->tlsext_tick) ||
79998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(s->session->not_resumable))
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
802fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom		        if (!s->session_creation_enabled)
803fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom				{
804fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
805fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
806fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom				goto err;
807fd113c07c3c2a6b07f8ab69dfae7d104e769f469Brian Carlstrom				}
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ssl_get_new_session(s,0))
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* else use the pre-loaded session */
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p=s->s3->client_random;
814221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* if client_random is initialized, reuse it, we are
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * required to use same upon reply to HelloVerify */
817ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++)
818ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root			;
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i==sizeof(s->s3->client_random))
820ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root			ssl_fill_hello_random(s, 0, p,
821ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root					      sizeof(s->s3->client_random));
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Do the message type and length last */
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++)=s->version>>8;
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++)=s->version&0xff;
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->client_version=s->version;
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Random stuff */
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p+=SSL3_RANDOM_SIZE;
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Session ID */
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->new_session)
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=0;
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=s->session->session_id_length;
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++)=i;
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i != 0)
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i > sizeof s->session->session_id)
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(p,s->session->session_id,i);
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p+=i;
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* cookie stuff */
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ( s->d1->cookie_len > sizeof(s->d1->cookie))
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++) = s->d1->cookie_len;
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(p, s->d1->cookie, s->d1->cookie_len);
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p += s->d1->cookie_len;
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Ciphers supported */
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i == 0)
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s2n(i,p);
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p+=i;
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* COMPRESSION */
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->ctx->comp_methods == NULL)
873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			j=0;
874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			j=sk_SSL_COMP_num(s->ctx->comp_methods);
876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++)=1+j;
877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (i=0; i<j; i++)
878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*(p++)=comp->id;
881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*(p++)=0; /* Add the NULL method */
88398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
88498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifndef OPENSSL_NO_TLSEXT
885c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		/* TLS extensions*/
886c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		if (ssl_prepare_clienthello_tlsext(s) <= 0)
887c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			{
888c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
889c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			goto err;
890c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			}
89198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
89298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			{
89398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
89498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			goto err;
89598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			}
896c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root#endif
89798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=(p-d);
899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d=buf;
900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->state=SSL3_ST_CW_CLNT_HELLO_B;
904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* number of bytes to write */
905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_num=p-buf;
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_off=0;
907656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* buffer the message to handle re-xmits */
909656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dtls1_buffer_message(s, 0);
910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* SSL3_ST_CW_CLNT_HELLO_B */
913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(-1);
916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dtls1_get_hello_verify(SSL *s)
919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int n, al, ok = 0;
921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *data;
922656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int cookie_len;
923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	n=s->method->ssl_get_message(s,
925656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
926656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		-1,
928656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->max_cert_list,
929656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&ok);
930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ok) return((int)n);
932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
934656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
935656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->d1->send_cookie = 0;
936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->s3->tmp.reuse_message=1;
937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(1);
938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
939656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	data = (unsigned char *)s->init_msg;
941656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
942656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff)))
943656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
944656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->version=(s->version&0xff00)|data[1];
946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		al = SSL_AD_PROTOCOL_VERSION;
947656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto f_err;
948656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
949656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	data+=2;
950656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cookie_len = *(data++);
952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ( cookie_len > sizeof(s->d1->cookie))
953656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
954656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		al=SSL_AD_ILLEGAL_PARAMETER;
955656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto f_err;
956656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
957656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
958656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(s->d1->cookie, data, cookie_len);
959656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->d1->cookie_len = cookie_len;
960656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
961656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->d1->send_cookie = 1;
962656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
963656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
964656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectf_err:
965656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ssl3_send_alert(s, SSL3_AL_FATAL, al);
966656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return -1;
967656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
968656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
969656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dtls1_send_client_key_exchange(SSL *s)
970656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
971656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *p,*d;
972656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int n;
973221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long alg_k;
974656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
975656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *q;
976656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *pkey=NULL;
977656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
978656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_KRB5
979656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        KSSL_ERR kssl_err;
980656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* OPENSSL_NO_KRB5 */
981221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ECDH
982221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EC_KEY *clnt_ecdh = NULL;
983221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EC_POINT *srvr_ecpoint = NULL;
984221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY *srvr_pub_pkey = NULL;
985221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *encodedPoint = NULL;
986221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int encoded_pt_len = 0;
987221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BN_CTX * bn_ctx = NULL;
988221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
989656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
990656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
991656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
992656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d=(unsigned char *)s->init_buf->data;
993656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p= &(d[DTLS1_HM_HEADER_LENGTH]);
994221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
995221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
996656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
997656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                /* Fool emacs indentation */
998656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                if (0) {}
999656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
1000221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (alg_k & SSL_kRSA)
1001656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1002656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			RSA *rsa;
1003656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
1004656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1005c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (s->session->sess_cert == NULL)
1006c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				{
1007c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				/* We should always have a server certificate with SSL_kRSA. */
1008c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
1009c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				goto err;
1010c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				}
1011c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root
1012656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->session->sess_cert->peer_rsa_tmp != NULL)
1013656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				rsa=s->session->sess_cert->peer_rsa_tmp;
1014656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
1015656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1016656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
1017656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((pkey == NULL) ||
1018656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(pkey->type != EVP_PKEY_RSA) ||
1019656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(pkey->pkey.rsa == NULL))
1020656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
1021656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
1022656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					goto err;
1023656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
1024656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				rsa=pkey->pkey.rsa;
1025656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				EVP_PKEY_free(pkey);
1026656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1027656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1028656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tmp_buf[0]=s->client_version>>8;
1029656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tmp_buf[1]=s->client_version&0xff;
1030656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
1031656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					goto err;
1032656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1033656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->session->master_key_length=sizeof tmp_buf;
1034656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1035656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			q=p;
1036656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Fix buf for TLS and [incidentally] DTLS */
1037656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->version > SSL3_VERSION)
1038656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				p+=2;
1039656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n=RSA_public_encrypt(sizeof tmp_buf,
1040656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
1041656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef PKCS1_CHECK
1042656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
1043656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
1044656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1045656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (n <= 0)
1046656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1047656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
1048656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1049656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1050656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1051656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Fix buf for TLS and [incidentally] DTLS */
1052656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->version > SSL3_VERSION)
1053656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1054656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s2n(n,q);
1055656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				n+=2;
1056656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1058656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->session->master_key_length=
1059656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->method->ssl3_enc->generate_master_secret(s,
1060656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->session->master_key,
1061656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					tmp_buf,sizeof tmp_buf);
1062656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
1063656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_KRB5
1066221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (alg_k & SSL_kKRB5)
1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        {
1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        krb5_error_code	krb5rc;
1069656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        KSSL_CTX	*kssl_ctx = s->kssl_ctx;
1070656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        /*  krb5_data	krb5_ap_req;  */
1071656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        krb5_data	*enc_ticket;
1072656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        krb5_data	authenticator, *authp = NULL;
1073656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CIPHER_CTX	ciph_ctx;
1074221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const EVP_CIPHER *enc = NULL;
1075656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char	iv[EVP_MAX_IV_LENGTH];
1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH
1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						+ EVP_MAX_IV_LENGTH];
1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			int 		padl, outl = sizeof(epms);
1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1081656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CIPHER_CTX_init(&ciph_ctx);
1082656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1083656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
1085221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                alg_k, SSL_kKRB5);
1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
1087656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			authp = NULL;
1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KRB5SENDAUTH
1090656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (KRB5SENDAUTH)  authp = &authenticator;
1091656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KRB5SENDAUTH */
1092656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1093656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
1094656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&kssl_err);
1095656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			enc = kssl_map_enc(kssl_ctx->enctype);
1096656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        if (enc == NULL)
1097656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                            goto err;
1098656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
1099656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        {
1100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        printf("kssl_cget_tkt rtn %d\n", krb5rc);
1101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        if (krb5rc && kssl_err.text)
1102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
1103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        }
1104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
1105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        if (krb5rc)
1107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                {
1108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                ssl3_send_alert(s,SSL3_AL_FATAL,
1109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						SSL_AD_HANDSHAKE_FAILURE);
1110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						kssl_err.reason);
1112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                goto err;
1113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                }
1114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*  20010406 VRS - Earlier versions used KRB5 AP_REQ
1116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  in place of RFC 2712 KerberosWrapper, as in:
1117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**
1118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **  Send ticket (copy to *p, set n = length)
1119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **  n = krb5_ap_req.length;
1120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **  if (krb5_ap_req.data)
1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        **
1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  Now using real RFC 2712 KerberosWrapper
1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  Note: 2712 "opaque" types are here replaced
1127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  with a 2-byte length followed by the value.
1128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  Example:
1129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
1130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  Where "xx xx" = length bytes.  Shown here with
1131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**  optional authenticator omitted.
1132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*/
1133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*  KerberosWrapper.Ticket		*/
1135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s2n(enc_ticket->length,p);
1136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(p, enc_ticket->data, enc_ticket->length);
1137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p+= enc_ticket->length;
1138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n = enc_ticket->length + 2;
1139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*  KerberosWrapper.Authenticator	*/
1141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (authp  &&  authp->length)
1142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s2n(authp->length,p);
1144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				memcpy(p, authp->data, authp->length);
1145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				p+= authp->length;
1146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				n+= authp->length + 2;
1147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				free(authp->data);
1149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				authp->data = NULL;
1150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				authp->length = 0;
1151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
1153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s2n(0,p);/*  null authenticator length	*/
1155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				n+=2;
1156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0)
1159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			    goto err;
1160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*  20010420 VRS.  Tried it this way; failed.
1162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**	EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
1163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**	EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
1164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**				kssl_ctx->length);
1165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			**	EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
1166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*/
1167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memset(iv, 0, sizeof iv);  /* per RFC 1510 */
1169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
1170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				kssl_ctx->key,iv);
1171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
1172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				sizeof tmp_buf);
1173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
1174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			outl += padl;
1175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (outl > (int)sizeof epms)
1176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
1178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CIPHER_CTX_cleanup(&ciph_ctx);
1181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/*  KerberosWrapper.EncryptedPreMasterSecret	*/
1183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s2n(outl,p);
1184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(p, epms, outl);
1185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p+=outl;
1186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n+=outl + 2;
1187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        s->session->master_key_length=
1189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                s->method->ssl3_enc->generate_master_secret(s,
1190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->session->master_key,
1191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					tmp_buf, sizeof tmp_buf);
1192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
1194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_cleanse(epms, outl);
1195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        }
1196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DH
1198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
1199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DH *dh_srvr,*dh_clnt;
1201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1202c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (s->session->sess_cert == NULL)
1203c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				{
1204c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
1205c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
1206c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				goto err;
1207c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				}
1208c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root
1209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->session->sess_cert->peer_dh_tmp != NULL)
1210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				dh_srvr=s->session->sess_cert->peer_dh_tmp;
1211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
1212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* we get them from the cert */
1214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
1215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
1216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* generate a new random key */
1220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
1221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!DH_generate_key(dh_clnt))
1226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* use the 'p' output buffer for the DH key, but
1232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * make sure to clear it out afterwards */
1233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
1235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (n <= 0)
1237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* generate master key from the result */
1243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->session->master_key_length=
1244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->method->ssl3_enc->generate_master_secret(s,
1245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->session->master_key,p,n);
1246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* clean up */
1247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memset(p,0,n);
1248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* send off the data */
1250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n=BN_num_bytes(dh_clnt->pub_key);
1251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s2n(n,p);
1252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BN_bn2bin(dh_clnt->pub_key,p);
1253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n+=2;
1254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DH_free(dh_clnt);
1256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* perhaps clean things up a bit EAY EAY EAY EAY*/
1258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ECDH
1261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
1262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
1263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const EC_GROUP *srvr_group = NULL;
1264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EC_KEY *tkey;
1265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int ecdh_clnt_cert = 0;
1266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int field_size = 0;
1267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1268c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (s->session->sess_cert == NULL)
1269c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				{
1270c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
1271c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
1272c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				goto err;
1273c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				}
1274c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root
1275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* Did we send out the client's
1276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 * ECDH share for use in premaster
1277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 * computation as part of client certificate?
1278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 * If so, set ecdh_clnt_cert to 1.
1279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 */
1280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL))
1281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* XXX: For now, we do not support client
1283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * authentication using ECDH certificates.
1284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * To add such support, one needs to add
1285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * code that checks for appropriate
1286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * conditions and sets ecdh_clnt_cert to 1.
1287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * For example, the cert have an ECC
1288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * key on the same curve as the server's
1289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * and the key should be authorized for
1290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * key agreement.
1291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 *
1292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * One also needs to add code in ssl3_connect
1293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * to skip sending the certificate verify
1294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * message.
1295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 *
1296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * if ((s->cert->key->privatekey != NULL) &&
1297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 *     (s->cert->key->privatekey->type ==
1298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 *      EVP_PKEY_EC) && ...)
1299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * ecdh_clnt_cert = 1;
1300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 */
1301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
1304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				tkey = s->session->sess_cert->peer_ecdh_tmp;
1306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
1308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Get the Server Public Key from Cert */
1310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				srvr_pub_pkey = X509_get_pubkey(s->session-> \
1311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
1312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if ((srvr_pub_pkey == NULL) ||
1313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
1314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    (srvr_pub_pkey->pkey.ec == NULL))
1315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
1316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					    ERR_R_INTERNAL_ERROR);
1318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto err;
1319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
1320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				tkey = srvr_pub_pkey->pkey.ec;
1322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			srvr_group   = EC_KEY_get0_group(tkey);
1325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
1326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
1328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    ERR_R_INTERNAL_ERROR);
1331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if ((clnt_ecdh=EC_KEY_new()) == NULL)
1335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
1337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
1341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
1343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ecdh_clnt_cert)
1346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Reuse key info from our certificate
1348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * We only need our private key to perform
1349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * the ECDH computation.
1350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 */
1351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				const BIGNUM *priv_key;
1352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				tkey = s->cert->key->privatekey->pkey.ec;
1353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				priv_key = EC_KEY_get0_private_key(tkey);
1354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (priv_key == NULL)
1355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
1356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
1357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto err;
1358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
1359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
1360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
1361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
1362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto err;
1363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
1364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
1366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Generate a new ECDH key pair */
1368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (!(EC_KEY_generate_key(clnt_ecdh)))
1369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
1370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
1371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto err;
1372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
1373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* use the 'p' output buffer for the ECDH key, but
1376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 * make sure to clear it out afterwards
1377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 */
1378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			field_size = EC_GROUP_get_degree(srvr_group);
1380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (field_size <= 0)
1381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				       ERR_R_ECDH_LIB);
1384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
1387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (n <= 0)
1388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				       ERR_R_ECDH_LIB);
1391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* generate master key from the result */
1395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->session->master_key_length = s->method->ssl3_enc \
1396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			    -> generate_master_secret(s,
1397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				s->session->master_key,
1398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				p, n);
1399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memset(p, 0, n); /* clean up */
1401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (ecdh_clnt_cert)
1403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Send empty client key exch message */
1405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				n = 0;
1406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
1408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* First check the size of encoding and
1410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 * allocate memory accordingly.
1411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 */
1412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				encoded_pt_len =
1413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    EC_POINT_point2oct(srvr_group,
1414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					EC_KEY_get0_public_key(clnt_ecdh),
1415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					POINT_CONVERSION_UNCOMPRESSED,
1416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					NULL, 0, NULL);
1417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				encodedPoint = (unsigned char *)
1419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    OPENSSL_malloc(encoded_pt_len *
1420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					sizeof(unsigned char));
1421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				bn_ctx = BN_CTX_new();
1422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if ((encodedPoint == NULL) ||
1423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    (bn_ctx == NULL))
1424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
1425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
1426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					goto err;
1427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
1428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Encode the public key */
1430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				n = EC_POINT_point2oct(srvr_group,
1431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    EC_KEY_get0_public_key(clnt_ecdh),
1432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    POINT_CONVERSION_UNCOMPRESSED,
1433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    encodedPoint, encoded_pt_len, bn_ctx);
1434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				*p = n; /* length of encoded point */
1436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* Encoded point will be copied here */
1437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				p += 1;
1438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* copy the point */
1439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				memcpy((unsigned char *)p, encodedPoint, n);
1440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* increment n to account for length field */
1441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				n += 1;
1442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* Free allocated memory */
1445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BN_CTX_free(bn_ctx);
1446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
1447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (clnt_ecdh != NULL)
1448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 EC_KEY_free(clnt_ecdh);
1449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_PKEY_free(srvr_pub_pkey);
1450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
1451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif /* !OPENSSL_NO_ECDH */
1452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_PSK
1454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (alg_k & SSL_kPSK)
1455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
1456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			char identity[PSK_MAX_IDENTITY_LEN];
1457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char *t = NULL;
1458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
1459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned int pre_ms_len = 0, psk_len = 0;
1460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int psk_err = 1;
1461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n = 0;
1463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->psk_client_callback == NULL)
1464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSL_R_PSK_NO_CLIENT_CB);
1467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
14703355e0f024c4cd610fbb32fdf148a6f376e9e74eAlex Klyubin			psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
1471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				identity, PSK_MAX_IDENTITY_LEN,
1472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				psk_or_pre_ms, sizeof(psk_or_pre_ms));
1473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (psk_len > PSK_MAX_PSK_LEN)
1474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					ERR_R_INTERNAL_ERROR);
1477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto psk_err;
1478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else if (psk_len == 0)
1480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					SSL_R_PSK_IDENTITY_NOT_FOUND);
1483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto psk_err;
1484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			/* create PSK pre_master_secret */
1487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pre_ms_len = 2+psk_len+2+psk_len;
1488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			t = psk_or_pre_ms;
1489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
1490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s2n(psk_len, t);
1491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memset(t, 0, psk_len);
1492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			t+=psk_len;
1493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s2n(psk_len, t);
1494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->session->psk_identity != NULL)
1496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				OPENSSL_free(s->session->psk_identity);
1497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->session->psk_identity = BUF_strdup(identity);
1498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->session->psk_identity == NULL)
1499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					ERR_R_MALLOC_FAILURE);
1502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto psk_err;
1503221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1504221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1505221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->session->master_key_length =
1506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				s->method->ssl3_enc->generate_master_secret(s,
1507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					s->session->master_key,
1508221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					psk_or_pre_ms, pre_ms_len);
1509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n = strlen(identity);
1510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s2n(n, p);
1511221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memcpy(p, identity, n);
1512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n+=2;
1513221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			psk_err = 0;
1514221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		psk_err:
1515221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
1516221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
1517221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (psk_err != 0)
1518221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1519221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1522221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
1523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
1524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
1525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
1527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
1528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d = dtls1_set_message_header(s, d,
1532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
1533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/*
1534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
1535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 l2n3(n,d);
1536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 l2n(s->d1->handshake_write_seq,d);
1537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 s->d1->handshake_write_seq++;
1538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*/
1539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->state=SSL3_ST_CW_KEY_EXCH_B;
1541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* number of bytes to write */
1542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
1543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_off=0;
1544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* buffer the message to handle re-xmits */
1546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dtls1_buffer_message(s, 0);
1547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* SSL3_ST_CW_KEY_EXCH_B */
1550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1552221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ECDH
1553221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BN_CTX_free(bn_ctx);
1554221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
1555221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (clnt_ecdh != NULL)
1556221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EC_KEY_free(clnt_ecdh);
1557221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_free(srvr_pub_pkey);
1558221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
1559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(-1);
1560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dtls1_send_client_verify(SSL *s)
1563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *p,*d;
1565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
1566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *pkey;
1567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
1568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned u=0;
1569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long n;
1571221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
1572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int j;
1573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
1576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d=(unsigned char *)s->init_buf->data;
1578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p= &(d[DTLS1_HM_HEADER_LENGTH]);
1579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pkey=s->cert->key->privatekey;
1580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		s->method->ssl3_enc->cert_verify_mac(s,
1582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		NID_sha1,
1583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&(data[MD5_DIGEST_LENGTH]));
1584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
1586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (pkey->type == EVP_PKEY_RSA)
1587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->method->ssl3_enc->cert_verify_mac(s,
1589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				NID_md5,
1590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				&(data[0]));
1591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (RSA_sign(NID_md5_sha1, data,
1592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
1593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
1594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
1596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s2n(u,p);
1599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n=u+2;
1600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
1602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DSA
1604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (pkey->type == EVP_PKEY_DSA)
1605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!DSA_sign(pkey->save_type,
1607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&(data[MD5_DIGEST_LENGTH]),
1608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SHA_DIGEST_LENGTH,&(p[2]),
1609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(unsigned int *)&j,pkey->pkey.dsa))
1610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
1612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s2n(j,p);
1615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n=j+2;
1616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
1618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1619221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ECDSA
1620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (pkey->type == EVP_PKEY_EC)
1621221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
1622221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!ECDSA_sign(pkey->save_type,
1623221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				&(data[MD5_DIGEST_LENGTH]),
1624221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SHA_DIGEST_LENGTH,&(p[2]),
1625221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				(unsigned int *)&j,pkey->pkey.ec))
1626221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
1627221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,
1628221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				    ERR_R_ECDSA_LIB);
1629221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				goto err;
1630221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
1631221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s2n(j,p);
1632221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			n=j+2;
1633221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
1634221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
1635221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
1636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
1638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		d = dtls1_set_message_header(s, d,
1642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ;
1643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH;
1645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_off=0;
1646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* buffer the message to handle re-xmits */
1648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dtls1_buffer_message(s, 0);
1649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->state = SSL3_ST_CW_CERT_VRFY_B;
1651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* s->state = SSL3_ST_CW_CERT_VRFY_B */
1654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(-1);
1657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dtls1_send_client_certificate(SSL *s)
1660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *x509=NULL;
1662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *pkey=NULL;
1663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
1664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long l;
1665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state ==	SSL3_ST_CW_CERT_A)
1667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((s->cert == NULL) ||
1669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(s->cert->key->x509 == NULL) ||
1670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(s->cert->key->privatekey == NULL))
1671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_CERT_B;
1672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
1673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_CERT_C;
1674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* We need to get a client cert */
1677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state == SSL3_ST_CW_CERT_B)
1678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If we get an error, we need to
1680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
1681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * We then get retied later */
1682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=0;
1683e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		i = ssl_do_client_cert_cb(s, &x509, &pkey);
1684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i < 0)
1685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->rwstate=SSL_X509_LOOKUP;
1687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(-1);
1688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->rwstate=SSL_NOTHING;
1690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
1691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->state=SSL3_ST_CW_CERT_B;
1693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (	!SSL_use_certificate(s,x509) ||
1694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				!SSL_use_PrivateKey(s,pkey))
1695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				i=0;
1696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (i == 1)
1698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=0;
1700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
1701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (x509 != NULL) X509_free(x509);
1704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (pkey != NULL) EVP_PKEY_free(pkey);
1705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i == 0)
1706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->version == SSL3_VERSION)
1708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->tmp.cert_req=0;
1710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
1711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return(1);
1712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
1714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->tmp.cert_req=2;
1716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Ok, we have a cert */
1720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->state=SSL3_ST_CW_CERT_C;
1721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->state == SSL3_ST_CW_CERT_C)
1724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->state=SSL3_ST_CW_CERT_D;
1726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=dtls1_output_cert_chain(s,
1727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
1728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_num=(int)l;
1729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->init_off=0;
1730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* set header called by dtls1_output_cert_chain() */
1732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* buffer the message to handle re-xmits */
1734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dtls1_buffer_message(s, 0);
1735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* SSL3_ST_CW_CERT_D */
1737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1739