]>
Commit | Line | Data |
---|---|---|
36d16f8e | 1 | /* ssl/d1_clnt.c */ |
0f113f3e | 2 | /* |
36d16f8e | 3 | * DTLS implementation written by Nagendra Modadugu |
0f113f3e | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
36d16f8e BL |
5 | */ |
6 | /* ==================================================================== | |
52b8dad8 | 7 | * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. |
36d16f8e BL |
8 | * |
9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | |
12 | * | |
13 | * 1. Redistributions of source code must retain the above copyright | |
0f113f3e | 14 | * notice, this list of conditions and the following disclaimer. |
36d16f8e BL |
15 | * |
16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in | |
18 | * the documentation and/or other materials provided with the | |
19 | * distribution. | |
20 | * | |
21 | * 3. All advertising materials mentioning features or use of this | |
22 | * software must display the following acknowledgment: | |
23 | * "This product includes software developed by the OpenSSL Project | |
24 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
25 | * | |
26 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
27 | * endorse or promote products derived from this software without | |
28 | * prior written permission. For written permission, please contact | |
29 | * openssl-core@OpenSSL.org. | |
30 | * | |
31 | * 5. Products derived from this software may not be called "OpenSSL" | |
32 | * nor may "OpenSSL" appear in their names without prior written | |
33 | * permission of the OpenSSL Project. | |
34 | * | |
35 | * 6. Redistributions of any form whatsoever must retain the following | |
36 | * acknowledgment: | |
37 | * "This product includes software developed by the OpenSSL Project | |
38 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
39 | * | |
40 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
41 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
43 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
44 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
45 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
46 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
47 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
49 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
50 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
51 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
52 | * ==================================================================== | |
53 | * | |
54 | * This product includes cryptographic software written by Eric Young | |
55 | * (eay@cryptsoft.com). This product includes software written by Tim | |
56 | * Hudson (tjh@cryptsoft.com). | |
57 | * | |
58 | */ | |
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |
60 | * All rights reserved. | |
61 | * | |
62 | * This package is an SSL implementation written | |
63 | * by Eric Young (eay@cryptsoft.com). | |
64 | * The implementation was written so as to conform with Netscapes SSL. | |
0f113f3e | 65 | * |
36d16f8e BL |
66 | * This library is free for commercial and non-commercial use as long as |
67 | * the following conditions are aheared to. The following conditions | |
68 | * apply to all code found in this distribution, be it the RC4, RSA, | |
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
70 | * included with this distribution is covered by the same copyright terms | |
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
0f113f3e | 72 | * |
36d16f8e BL |
73 | * Copyright remains Eric Young's, and as such any Copyright notices in |
74 | * the code are not to be removed. | |
75 | * If this package is used in a product, Eric Young should be given attribution | |
76 | * as the author of the parts of the library used. | |
77 | * This can be in the form of a textual message at program startup or | |
78 | * in documentation (online or textual) provided with the package. | |
0f113f3e | 79 | * |
36d16f8e BL |
80 | * Redistribution and use in source and binary forms, with or without |
81 | * modification, are permitted provided that the following conditions | |
82 | * are met: | |
83 | * 1. Redistributions of source code must retain the copyright | |
84 | * notice, this list of conditions and the following disclaimer. | |
85 | * 2. Redistributions in binary form must reproduce the above copyright | |
86 | * notice, this list of conditions and the following disclaimer in the | |
87 | * documentation and/or other materials provided with the distribution. | |
88 | * 3. All advertising materials mentioning features or use of this software | |
89 | * must display the following acknowledgement: | |
90 | * "This product includes cryptographic software written by | |
91 | * Eric Young (eay@cryptsoft.com)" | |
92 | * The word 'cryptographic' can be left out if the rouines from the library | |
93 | * being used are not cryptographic related :-). | |
0f113f3e | 94 | * 4. If you include any Windows specific code (or a derivative thereof) from |
36d16f8e BL |
95 | * the apps directory (application code) you must include an acknowledgement: |
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
0f113f3e | 97 | * |
36d16f8e BL |
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
108 | * SUCH DAMAGE. | |
0f113f3e | 109 | * |
36d16f8e BL |
110 | * The licence and distribution terms for any publically available version or |
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |
112 | * copied and put under another distribution licence | |
113 | * [including the GNU Public Licence.] | |
114 | */ | |
115 | ||
116 | #include <stdio.h> | |
117 | #include "ssl_locl.h" | |
ef236ec3 | 118 | #ifndef OPENSSL_NO_KRB5 |
0f113f3e | 119 | # include "kssl_lcl.h" |
ef236ec3 | 120 | #endif |
36d16f8e BL |
121 | #include <openssl/buffer.h> |
122 | #include <openssl/rand.h> | |
123 | #include <openssl/objects.h> | |
124 | #include <openssl/evp.h> | |
125 | #include <openssl/md5.h> | |
1e26a8ba | 126 | #include <openssl/bn.h> |
3eeaab4b | 127 | #ifndef OPENSSL_NO_DH |
0f113f3e | 128 | # include <openssl/dh.h> |
3eeaab4b | 129 | #endif |
36d16f8e | 130 | |
4ebb342f | 131 | static const SSL_METHOD *dtls1_get_client_method(int ver); |
36d16f8e BL |
132 | static int dtls1_get_hello_verify(SSL *s); |
133 | ||
4ebb342f | 134 | static const SSL_METHOD *dtls1_get_client_method(int ver) |
0f113f3e MC |
135 | { |
136 | if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) | |
137 | return (DTLSv1_client_method()); | |
138 | else if (ver == DTLS1_2_VERSION) | |
139 | return (DTLSv1_2_client_method()); | |
140 | else | |
141 | return (NULL); | |
142 | } | |
36d16f8e | 143 | |
cfd298b7 | 144 | IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, |
0f113f3e MC |
145 | DTLSv1_client_method, |
146 | ssl_undefined_function, | |
147 | dtls1_connect, | |
148 | dtls1_get_client_method, DTLSv1_enc_data) | |
149 | ||
150 | IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, | |
151 | DTLSv1_2_client_method, | |
152 | ssl_undefined_function, | |
153 | dtls1_connect, | |
154 | dtls1_get_client_method, DTLSv1_2_enc_data) | |
155 | ||
156 | IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, | |
157 | DTLS_client_method, | |
158 | ssl_undefined_function, | |
159 | dtls1_connect, | |
160 | dtls1_get_client_method, DTLSv1_2_enc_data) | |
c6913eeb | 161 | |
36d16f8e | 162 | int dtls1_connect(SSL *s) |
0f113f3e MC |
163 | { |
164 | BUF_MEM *buf = NULL; | |
165 | unsigned long Time = (unsigned long)time(NULL); | |
166 | void (*cb) (const SSL *ssl, int type, int val) = NULL; | |
167 | int ret = -1; | |
168 | int new_state, state, skip = 0; | |
7e159e01 | 169 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
170 | unsigned char sctpauthkey[64]; |
171 | char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; | |
7e159e01 | 172 | #endif |
36d16f8e | 173 | |
0f113f3e MC |
174 | RAND_add(&Time, sizeof(Time), 0); |
175 | ERR_clear_error(); | |
176 | clear_sys_error(); | |
36d16f8e | 177 | |
0f113f3e MC |
178 | if (s->info_callback != NULL) |
179 | cb = s->info_callback; | |
180 | else if (s->ctx->info_callback != NULL) | |
181 | cb = s->ctx->info_callback; | |
182 | ||
183 | s->in_handshake++; | |
184 | if (!SSL_in_init(s) || SSL_in_before(s)) | |
185 | SSL_clear(s); | |
36d16f8e | 186 | |
7e159e01 | 187 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
188 | /* |
189 | * Notify SCTP BIO socket to enter handshake mode and prevent stream | |
190 | * identifier other than 0. Will be ignored if no SCTP is used. | |
191 | */ | |
192 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, | |
193 | s->in_handshake, NULL); | |
7e159e01 DSH |
194 | #endif |
195 | ||
4817504d | 196 | #ifndef OPENSSL_NO_HEARTBEATS |
0f113f3e MC |
197 | /* |
198 | * If we're awaiting a HeartbeatResponse, pretend we already got and | |
199 | * don't await it anymore, because Heartbeats don't make sense during | |
200 | * handshakes anyway. | |
201 | */ | |
202 | if (s->tlsext_hb_pending) { | |
203 | dtls1_stop_timer(s); | |
204 | s->tlsext_hb_pending = 0; | |
205 | s->tlsext_hb_seq++; | |
206 | } | |
4817504d DSH |
207 | #endif |
208 | ||
0f113f3e MC |
209 | for (;;) { |
210 | state = s->state; | |
211 | ||
212 | switch (s->state) { | |
213 | case SSL_ST_RENEGOTIATE: | |
214 | s->renegotiate = 1; | |
215 | s->state = SSL_ST_CONNECT; | |
216 | s->ctx->stats.sess_connect_renegotiate++; | |
217 | /* break */ | |
218 | case SSL_ST_BEFORE: | |
219 | case SSL_ST_CONNECT: | |
220 | case SSL_ST_BEFORE | SSL_ST_CONNECT: | |
221 | case SSL_ST_OK | SSL_ST_CONNECT: | |
222 | ||
223 | s->server = 0; | |
224 | if (cb != NULL) | |
225 | cb(s, SSL_CB_HANDSHAKE_START, 1); | |
226 | ||
227 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && | |
228 | (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { | |
229 | SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); | |
230 | ret = -1; | |
231 | goto end; | |
232 | } | |
233 | ||
234 | /* s->version=SSL3_VERSION; */ | |
235 | s->type = SSL_ST_CONNECT; | |
236 | ||
237 | if (s->init_buf == NULL) { | |
238 | if ((buf = BUF_MEM_new()) == NULL) { | |
239 | ret = -1; | |
240 | goto end; | |
241 | } | |
242 | if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { | |
243 | ret = -1; | |
244 | goto end; | |
245 | } | |
246 | s->init_buf = buf; | |
247 | buf = NULL; | |
248 | } | |
249 | ||
250 | if (!ssl3_setup_buffers(s)) { | |
251 | ret = -1; | |
252 | goto end; | |
253 | } | |
254 | ||
255 | /* setup buffing BIO */ | |
256 | if (!ssl_init_wbio_buffer(s, 0)) { | |
257 | ret = -1; | |
258 | goto end; | |
259 | } | |
260 | ||
261 | /* don't push the buffering BIO quite yet */ | |
262 | ||
263 | s->state = SSL3_ST_CW_CLNT_HELLO_A; | |
264 | s->ctx->stats.sess_connect++; | |
265 | s->init_num = 0; | |
266 | /* mark client_random uninitialized */ | |
267 | memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); | |
268 | s->d1->send_cookie = 0; | |
269 | s->hit = 0; | |
270 | s->d1->change_cipher_spec_ok = 0; | |
271 | /* | |
272 | * Should have been reset by ssl3_get_finished, too. | |
273 | */ | |
274 | s->s3->change_cipher_spec = 0; | |
275 | break; | |
36d16f8e | 276 | |
7e159e01 | 277 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
278 | case DTLS1_SCTP_ST_CR_READ_SOCK: |
279 | ||
280 | if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { | |
281 | s->s3->in_read_app_data = 2; | |
282 | s->rwstate = SSL_READING; | |
283 | BIO_clear_retry_flags(SSL_get_rbio(s)); | |
284 | BIO_set_retry_read(SSL_get_rbio(s)); | |
285 | ret = -1; | |
286 | goto end; | |
287 | } | |
288 | ||
289 | s->state = s->s3->tmp.next_state; | |
290 | break; | |
291 | ||
292 | case DTLS1_SCTP_ST_CW_WRITE_SOCK: | |
293 | /* read app data until dry event */ | |
294 | ||
295 | ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); | |
296 | if (ret < 0) | |
297 | goto end; | |
298 | ||
299 | if (ret == 0) { | |
300 | s->s3->in_read_app_data = 2; | |
301 | s->rwstate = SSL_READING; | |
302 | BIO_clear_retry_flags(SSL_get_rbio(s)); | |
303 | BIO_set_retry_read(SSL_get_rbio(s)); | |
304 | ret = -1; | |
305 | goto end; | |
306 | } | |
307 | ||
308 | s->state = s->d1->next_state; | |
309 | break; | |
7e159e01 DSH |
310 | #endif |
311 | ||
0f113f3e MC |
312 | case SSL3_ST_CW_CLNT_HELLO_A: |
313 | case SSL3_ST_CW_CLNT_HELLO_B: | |
36d16f8e | 314 | |
0f113f3e | 315 | s->shutdown = 0; |
0d97d00b | 316 | |
0f113f3e MC |
317 | /* every DTLS ClientHello resets Finished MAC */ |
318 | ssl3_init_finished_mac(s); | |
0d97d00b | 319 | |
0f113f3e MC |
320 | dtls1_start_timer(s); |
321 | ret = ssl3_client_hello(s); | |
322 | if (ret <= 0) | |
323 | goto end; | |
36d16f8e | 324 | |
0f113f3e MC |
325 | if (s->d1->send_cookie) { |
326 | s->state = SSL3_ST_CW_FLUSH; | |
327 | s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; | |
328 | } else | |
329 | s->state = SSL3_ST_CR_SRVR_HELLO_A; | |
36d16f8e | 330 | |
0f113f3e | 331 | s->init_num = 0; |
36d16f8e | 332 | |
7e159e01 | 333 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
334 | /* Disable buffering for SCTP */ |
335 | if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) { | |
7e159e01 | 336 | #endif |
0f113f3e MC |
337 | /* |
338 | * turn on buffering for the next lot of output | |
339 | */ | |
340 | if (s->bbio != s->wbio) | |
341 | s->wbio = BIO_push(s->bbio, s->wbio); | |
7e159e01 | 342 | #ifndef OPENSSL_NO_SCTP |
0f113f3e | 343 | } |
7e159e01 | 344 | #endif |
36d16f8e | 345 | |
0f113f3e | 346 | break; |
36d16f8e | 347 | |
0f113f3e MC |
348 | case SSL3_ST_CR_SRVR_HELLO_A: |
349 | case SSL3_ST_CR_SRVR_HELLO_B: | |
350 | ret = ssl3_get_server_hello(s); | |
351 | if (ret <= 0) | |
352 | goto end; | |
353 | else { | |
354 | if (s->hit) { | |
7e159e01 | 355 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
356 | /* |
357 | * Add new shared key for SCTP-Auth, will be ignored if | |
358 | * no SCTP used. | |
359 | */ | |
360 | snprintf((char *)labelbuffer, | |
361 | sizeof(DTLS1_SCTP_AUTH_LABEL), | |
362 | DTLS1_SCTP_AUTH_LABEL); | |
363 | ||
364 | SSL_export_keying_material(s, sctpauthkey, | |
365 | sizeof(sctpauthkey), | |
366 | labelbuffer, | |
367 | sizeof(labelbuffer), NULL, 0, | |
368 | 0); | |
369 | ||
370 | BIO_ctrl(SSL_get_wbio(s), | |
371 | BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, | |
372 | sizeof(sctpauthkey), sctpauthkey); | |
7e159e01 DSH |
373 | #endif |
374 | ||
0f113f3e MC |
375 | s->state = SSL3_ST_CR_FINISHED_A; |
376 | } else | |
377 | s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; | |
378 | } | |
379 | s->init_num = 0; | |
380 | break; | |
381 | ||
382 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: | |
383 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: | |
384 | ||
385 | ret = dtls1_get_hello_verify(s); | |
386 | if (ret <= 0) | |
387 | goto end; | |
388 | dtls1_stop_timer(s); | |
389 | if (s->d1->send_cookie) /* start again, with a cookie */ | |
390 | s->state = SSL3_ST_CW_CLNT_HELLO_A; | |
391 | else | |
392 | s->state = SSL3_ST_CR_CERT_A; | |
393 | s->init_num = 0; | |
394 | break; | |
395 | ||
396 | case SSL3_ST_CR_CERT_A: | |
397 | case SSL3_ST_CR_CERT_B: | |
398 | /* Check if it is anon DH or PSK */ | |
399 | if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && | |
400 | !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { | |
401 | ret = ssl3_get_server_certificate(s); | |
402 | if (ret <= 0) | |
403 | goto end; | |
8025e251 | 404 | #ifndef OPENSSL_NO_TLSEXT |
0f113f3e MC |
405 | if (s->tlsext_status_expected) |
406 | s->state = SSL3_ST_CR_CERT_STATUS_A; | |
407 | else | |
408 | s->state = SSL3_ST_CR_KEY_EXCH_A; | |
409 | } else { | |
410 | skip = 1; | |
411 | s->state = SSL3_ST_CR_KEY_EXCH_A; | |
412 | } | |
8025e251 | 413 | #else |
0f113f3e MC |
414 | } else |
415 | skip = 1; | |
8025e251 | 416 | |
0f113f3e | 417 | s->state = SSL3_ST_CR_KEY_EXCH_A; |
8025e251 | 418 | #endif |
0f113f3e MC |
419 | s->init_num = 0; |
420 | break; | |
421 | ||
422 | case SSL3_ST_CR_KEY_EXCH_A: | |
423 | case SSL3_ST_CR_KEY_EXCH_B: | |
424 | ret = ssl3_get_key_exchange(s); | |
425 | if (ret <= 0) | |
426 | goto end; | |
427 | s->state = SSL3_ST_CR_CERT_REQ_A; | |
428 | s->init_num = 0; | |
429 | ||
430 | /* | |
431 | * at this point we check that we have the required stuff from | |
432 | * the server | |
433 | */ | |
434 | if (!ssl3_check_cert_and_algorithm(s)) { | |
435 | ret = -1; | |
436 | goto end; | |
437 | } | |
438 | break; | |
439 | ||
440 | case SSL3_ST_CR_CERT_REQ_A: | |
441 | case SSL3_ST_CR_CERT_REQ_B: | |
442 | ret = ssl3_get_certificate_request(s); | |
443 | if (ret <= 0) | |
444 | goto end; | |
445 | s->state = SSL3_ST_CR_SRVR_DONE_A; | |
446 | s->init_num = 0; | |
447 | break; | |
448 | ||
449 | case SSL3_ST_CR_SRVR_DONE_A: | |
450 | case SSL3_ST_CR_SRVR_DONE_B: | |
451 | ret = ssl3_get_server_done(s); | |
452 | if (ret <= 0) | |
453 | goto end; | |
454 | dtls1_stop_timer(s); | |
455 | if (s->s3->tmp.cert_req) | |
456 | s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; | |
457 | else | |
458 | s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; | |
459 | s->init_num = 0; | |
7e159e01 DSH |
460 | |
461 | #ifndef OPENSSL_NO_SCTP | |
0f113f3e MC |
462 | if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && |
463 | state == SSL_ST_RENEGOTIATE) | |
464 | s->state = DTLS1_SCTP_ST_CR_READ_SOCK; | |
465 | else | |
7e159e01 | 466 | #endif |
0f113f3e MC |
467 | s->state = s->s3->tmp.next_state; |
468 | break; | |
469 | ||
470 | case SSL3_ST_CW_CERT_A: | |
471 | case SSL3_ST_CW_CERT_B: | |
472 | case SSL3_ST_CW_CERT_C: | |
473 | case SSL3_ST_CW_CERT_D: | |
474 | dtls1_start_timer(s); | |
475 | ret = ssl3_send_client_certificate(s); | |
476 | if (ret <= 0) | |
477 | goto end; | |
478 | s->state = SSL3_ST_CW_KEY_EXCH_A; | |
479 | s->init_num = 0; | |
480 | break; | |
481 | ||
482 | case SSL3_ST_CW_KEY_EXCH_A: | |
483 | case SSL3_ST_CW_KEY_EXCH_B: | |
484 | dtls1_start_timer(s); | |
485 | ret = ssl3_send_client_key_exchange(s); | |
486 | if (ret <= 0) | |
487 | goto end; | |
7e159e01 | 488 | |
7e159e01 | 489 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
490 | /* |
491 | * Add new shared key for SCTP-Auth, will be ignored if no SCTP | |
492 | * used. | |
493 | */ | |
494 | snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), | |
495 | DTLS1_SCTP_AUTH_LABEL); | |
496 | ||
497 | SSL_export_keying_material(s, sctpauthkey, | |
498 | sizeof(sctpauthkey), labelbuffer, | |
499 | sizeof(labelbuffer), NULL, 0, 0); | |
500 | ||
501 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, | |
502 | sizeof(sctpauthkey), sctpauthkey); | |
7e159e01 | 503 | #endif |
36d16f8e | 504 | |
0f113f3e MC |
505 | /* |
506 | * EAY EAY EAY need to check for DH fix cert sent back | |
507 | */ | |
508 | /* | |
509 | * For TLS, cert_req is set to 2, so a cert chain of nothing is | |
510 | * sent, but no verify packet is sent | |
511 | */ | |
512 | if (s->s3->tmp.cert_req == 1) { | |
513 | s->state = SSL3_ST_CW_CERT_VRFY_A; | |
514 | } else { | |
515 | #ifndef OPENSSL_NO_SCTP | |
516 | if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { | |
517 | s->d1->next_state = SSL3_ST_CW_CHANGE_A; | |
518 | s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; | |
519 | } else | |
520 | #endif | |
521 | s->state = SSL3_ST_CW_CHANGE_A; | |
522 | } | |
523 | ||
524 | s->init_num = 0; | |
525 | break; | |
526 | ||
527 | case SSL3_ST_CW_CERT_VRFY_A: | |
528 | case SSL3_ST_CW_CERT_VRFY_B: | |
529 | dtls1_start_timer(s); | |
530 | ret = ssl3_send_client_verify(s); | |
531 | if (ret <= 0) | |
532 | goto end; | |
7e159e01 | 533 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
534 | if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { |
535 | s->d1->next_state = SSL3_ST_CW_CHANGE_A; | |
536 | s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; | |
537 | } else | |
7e159e01 | 538 | #endif |
0f113f3e MC |
539 | s->state = SSL3_ST_CW_CHANGE_A; |
540 | s->init_num = 0; | |
541 | break; | |
542 | ||
543 | case SSL3_ST_CW_CHANGE_A: | |
544 | case SSL3_ST_CW_CHANGE_B: | |
545 | if (!s->hit) | |
546 | dtls1_start_timer(s); | |
547 | ret = dtls1_send_change_cipher_spec(s, | |
548 | SSL3_ST_CW_CHANGE_A, | |
549 | SSL3_ST_CW_CHANGE_B); | |
550 | if (ret <= 0) | |
551 | goto end; | |
552 | ||
553 | s->state = SSL3_ST_CW_FINISHED_A; | |
554 | s->init_num = 0; | |
555 | ||
556 | s->session->cipher = s->s3->tmp.new_cipher; | |
09b6c2ef | 557 | #ifdef OPENSSL_NO_COMP |
0f113f3e | 558 | s->session->compress_meth = 0; |
09b6c2ef | 559 | #else |
0f113f3e MC |
560 | if (s->s3->tmp.new_compression == NULL) |
561 | s->session->compress_meth = 0; | |
562 | else | |
563 | s->session->compress_meth = s->s3->tmp.new_compression->id; | |
09b6c2ef | 564 | #endif |
0f113f3e MC |
565 | if (!s->method->ssl3_enc->setup_key_block(s)) { |
566 | ret = -1; | |
567 | goto end; | |
568 | } | |
569 | ||
570 | if (!s->method->ssl3_enc->change_cipher_state(s, | |
571 | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) | |
572 | { | |
573 | ret = -1; | |
574 | goto end; | |
575 | } | |
b9ef52b0 | 576 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
577 | if (s->hit) { |
578 | /* | |
579 | * Change to new shared key of SCTP-Auth, will be ignored if | |
580 | * no SCTP used. | |
581 | */ | |
582 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, | |
583 | 0, NULL); | |
584 | } | |
b9ef52b0 RS |
585 | #endif |
586 | ||
0f113f3e MC |
587 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); |
588 | break; | |
589 | ||
590 | case SSL3_ST_CW_FINISHED_A: | |
591 | case SSL3_ST_CW_FINISHED_B: | |
592 | if (!s->hit) | |
593 | dtls1_start_timer(s); | |
594 | ret = ssl3_send_finished(s, | |
595 | SSL3_ST_CW_FINISHED_A, | |
596 | SSL3_ST_CW_FINISHED_B, | |
597 | s->method-> | |
598 | ssl3_enc->client_finished_label, | |
599 | s->method-> | |
600 | ssl3_enc->client_finished_label_len); | |
601 | if (ret <= 0) | |
602 | goto end; | |
603 | s->state = SSL3_ST_CW_FLUSH; | |
604 | ||
605 | /* clear flags */ | |
606 | s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; | |
607 | if (s->hit) { | |
608 | s->s3->tmp.next_state = SSL_ST_OK; | |
7e159e01 | 609 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
610 | if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { |
611 | s->d1->next_state = s->s3->tmp.next_state; | |
612 | s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK; | |
613 | } | |
7e159e01 | 614 | #endif |
0f113f3e MC |
615 | if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { |
616 | s->state = SSL_ST_OK; | |
7e159e01 | 617 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
618 | if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { |
619 | s->d1->next_state = SSL_ST_OK; | |
620 | s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; | |
621 | } | |
7e159e01 | 622 | #endif |
0f113f3e MC |
623 | s->s3->flags |= SSL3_FLAGS_POP_BUFFER; |
624 | s->s3->delay_buf_pop_ret = 0; | |
625 | } | |
626 | } else { | |
b9ef52b0 | 627 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
628 | /* |
629 | * Change to new shared key of SCTP-Auth, will be ignored if | |
630 | * no SCTP used. | |
631 | */ | |
632 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, | |
633 | 0, NULL); | |
b9ef52b0 RS |
634 | #endif |
635 | ||
8025e251 | 636 | #ifndef OPENSSL_NO_TLSEXT |
0f113f3e MC |
637 | /* |
638 | * Allow NewSessionTicket if ticket expected | |
639 | */ | |
640 | if (s->tlsext_ticket_expected) | |
641 | s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; | |
642 | else | |
8025e251 | 643 | #endif |
0f113f3e MC |
644 | |
645 | s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; | |
646 | } | |
647 | s->init_num = 0; | |
648 | break; | |
36d16f8e | 649 | |
8025e251 | 650 | #ifndef OPENSSL_NO_TLSEXT |
0f113f3e MC |
651 | case SSL3_ST_CR_SESSION_TICKET_A: |
652 | case SSL3_ST_CR_SESSION_TICKET_B: | |
653 | ret = ssl3_get_new_session_ticket(s); | |
654 | if (ret <= 0) | |
655 | goto end; | |
656 | s->state = SSL3_ST_CR_FINISHED_A; | |
657 | s->init_num = 0; | |
658 | break; | |
659 | ||
660 | case SSL3_ST_CR_CERT_STATUS_A: | |
661 | case SSL3_ST_CR_CERT_STATUS_B: | |
662 | ret = ssl3_get_cert_status(s); | |
663 | if (ret <= 0) | |
664 | goto end; | |
665 | s->state = SSL3_ST_CR_KEY_EXCH_A; | |
666 | s->init_num = 0; | |
667 | break; | |
8025e251 DSH |
668 | #endif |
669 | ||
0f113f3e MC |
670 | case SSL3_ST_CR_FINISHED_A: |
671 | case SSL3_ST_CR_FINISHED_B: | |
672 | s->d1->change_cipher_spec_ok = 1; | |
673 | ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, | |
674 | SSL3_ST_CR_FINISHED_B); | |
675 | if (ret <= 0) | |
676 | goto end; | |
677 | dtls1_stop_timer(s); | |
36d16f8e | 678 | |
0f113f3e MC |
679 | if (s->hit) |
680 | s->state = SSL3_ST_CW_CHANGE_A; | |
681 | else | |
682 | s->state = SSL_ST_OK; | |
7e159e01 DSH |
683 | |
684 | #ifndef OPENSSL_NO_SCTP | |
0f113f3e MC |
685 | if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && |
686 | state == SSL_ST_RENEGOTIATE) { | |
687 | s->d1->next_state = s->state; | |
688 | s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; | |
689 | } | |
7e159e01 DSH |
690 | #endif |
691 | ||
0f113f3e MC |
692 | s->init_num = 0; |
693 | break; | |
694 | ||
695 | case SSL3_ST_CW_FLUSH: | |
696 | s->rwstate = SSL_WRITING; | |
697 | if (BIO_flush(s->wbio) <= 0) { | |
698 | /* | |
699 | * If the write error was fatal, stop trying | |
700 | */ | |
701 | if (!BIO_should_retry(s->wbio)) { | |
702 | s->rwstate = SSL_NOTHING; | |
703 | s->state = s->s3->tmp.next_state; | |
704 | } | |
705 | ||
706 | ret = -1; | |
707 | goto end; | |
708 | } | |
709 | s->rwstate = SSL_NOTHING; | |
710 | s->state = s->s3->tmp.next_state; | |
711 | break; | |
712 | ||
713 | case SSL_ST_OK: | |
714 | /* clean a few things up */ | |
715 | ssl3_cleanup_key_block(s); | |
36d16f8e BL |
716 | |
717 | #if 0 | |
0f113f3e MC |
718 | if (s->init_buf != NULL) { |
719 | BUF_MEM_free(s->init_buf); | |
720 | s->init_buf = NULL; | |
721 | } | |
36d16f8e BL |
722 | #endif |
723 | ||
0f113f3e MC |
724 | /* |
725 | * If we are not 'joining' the last two packets, remove the | |
726 | * buffering now | |
727 | */ | |
728 | if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) | |
729 | ssl_free_wbio_buffer(s); | |
730 | /* else do it later in ssl3_write */ | |
731 | ||
732 | s->init_num = 0; | |
733 | s->renegotiate = 0; | |
734 | s->new_session = 0; | |
735 | ||
736 | ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); | |
737 | if (s->hit) | |
738 | s->ctx->stats.sess_hit++; | |
739 | ||
740 | ret = 1; | |
741 | /* s->server=0; */ | |
742 | s->handshake_func = dtls1_connect; | |
743 | s->ctx->stats.sess_connect_good++; | |
744 | ||
745 | if (cb != NULL) | |
746 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); | |
747 | ||
748 | /* done with handshaking */ | |
749 | s->d1->handshake_read_seq = 0; | |
750 | s->d1->next_handshake_write_seq = 0; | |
751 | goto end; | |
752 | /* break; */ | |
753 | ||
754 | default: | |
755 | SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); | |
756 | ret = -1; | |
757 | goto end; | |
758 | /* break; */ | |
759 | } | |
760 | ||
761 | /* did we do anything */ | |
762 | if (!s->s3->tmp.reuse_message && !skip) { | |
763 | if (s->debug) { | |
764 | if ((ret = BIO_flush(s->wbio)) <= 0) | |
765 | goto end; | |
766 | } | |
767 | ||
768 | if ((cb != NULL) && (s->state != state)) { | |
769 | new_state = s->state; | |
770 | s->state = state; | |
771 | cb(s, SSL_CB_CONNECT_LOOP, 1); | |
772 | s->state = new_state; | |
773 | } | |
774 | } | |
775 | skip = 0; | |
776 | } | |
777 | end: | |
778 | s->in_handshake--; | |
779 | ||
7e159e01 | 780 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
781 | /* |
782 | * Notify SCTP BIO socket to leave handshake mode and allow stream | |
783 | * identifier other than 0. Will be ignored if no SCTP is used. | |
784 | */ | |
785 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, | |
786 | s->in_handshake, NULL); | |
7e159e01 DSH |
787 | #endif |
788 | ||
0f113f3e MC |
789 | if (buf != NULL) |
790 | BUF_MEM_free(buf); | |
791 | if (cb != NULL) | |
792 | cb(s, SSL_CB_CONNECT_EXIT, ret); | |
793 | return (ret); | |
794 | } | |
36d16f8e | 795 | |
36d16f8e | 796 | static int dtls1_get_hello_verify(SSL *s) |
0f113f3e MC |
797 | { |
798 | int n, al, ok = 0; | |
799 | unsigned char *data; | |
800 | unsigned int cookie_len; | |
801 | ||
802 | s->first_packet = 1; | |
803 | n = s->method->ssl_get_message(s, | |
804 | DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, | |
805 | DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, | |
806 | -1, s->max_cert_list, &ok); | |
807 | s->first_packet = 0; | |
808 | ||
809 | if (!ok) | |
810 | return ((int)n); | |
811 | ||
812 | if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { | |
813 | s->d1->send_cookie = 0; | |
814 | s->s3->tmp.reuse_message = 1; | |
815 | return (1); | |
816 | } | |
817 | ||
818 | data = (unsigned char *)s->init_msg; | |
c6913eeb | 819 | #if 0 |
0f113f3e MC |
820 | if (s->method->version != DTLS_ANY_VERSION && |
821 | ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff)))) | |
822 | { | |
823 | SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); | |
824 | s->version = (s->version & 0xff00) | data[1]; | |
825 | al = SSL_AD_PROTOCOL_VERSION; | |
826 | goto f_err; | |
827 | } | |
c6913eeb | 828 | #endif |
0f113f3e | 829 | data += 2; |
36d16f8e | 830 | |
0f113f3e MC |
831 | cookie_len = *(data++); |
832 | if (cookie_len > sizeof(s->d1->cookie)) { | |
833 | al = SSL_AD_ILLEGAL_PARAMETER; | |
834 | goto f_err; | |
835 | } | |
36d16f8e | 836 | |
0f113f3e MC |
837 | memcpy(s->d1->cookie, data, cookie_len); |
838 | s->d1->cookie_len = cookie_len; | |
36d16f8e | 839 | |
0f113f3e MC |
840 | s->d1->send_cookie = 1; |
841 | return 1; | |
36d16f8e | 842 | |
0f113f3e MC |
843 | f_err: |
844 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | |
845 | return -1; | |
846 | } |