1 /* 2 * DTLS implementation written by Nagendra Modadugu 3 * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * openssl-core (at) OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay (at) cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh (at) cryptsoft.com). 56 * 57 */ 58 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 59 * All rights reserved. 60 * 61 * This package is an SSL implementation written 62 * by Eric Young (eay (at) cryptsoft.com). 63 * The implementation was written so as to conform with Netscapes SSL. 64 * 65 * This library is free for commercial and non-commercial use as long as 66 * the following conditions are aheared to. The following conditions 67 * apply to all code found in this distribution, be it the RC4, RSA, 68 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 69 * included with this distribution is covered by the same copyright terms 70 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 71 * 72 * Copyright remains Eric Young's, and as such any Copyright notices in 73 * the code are not to be removed. 74 * If this package is used in a product, Eric Young should be given attribution 75 * as the author of the parts of the library used. 76 * This can be in the form of a textual message at program startup or 77 * in documentation (online or textual) provided with the package. 78 * 79 * Redistribution and use in source and binary forms, with or without 80 * modification, are permitted provided that the following conditions 81 * are met: 82 * 1. Redistributions of source code must retain the copyright 83 * notice, this list of conditions and the following disclaimer. 84 * 2. Redistributions in binary form must reproduce the above copyright 85 * notice, this list of conditions and the following disclaimer in the 86 * documentation and/or other materials provided with the distribution. 87 * 3. All advertising materials mentioning features or use of this software 88 * must display the following acknowledgement: 89 * "This product includes cryptographic software written by 90 * Eric Young (eay (at) cryptsoft.com)" 91 * The word 'cryptographic' can be left out if the rouines from the library 92 * being used are not cryptographic related :-). 93 * 4. If you include any Windows specific code (or a derivative thereof) from 94 * the apps directory (application code) you must include an acknowledgement: 95 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 96 * 97 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 98 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 99 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 100 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 101 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 102 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 103 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 104 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 105 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 106 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 107 * SUCH DAMAGE. 108 * 109 * The licence and distribution terms for any publically available version or 110 * derivative of this code cannot be changed. i.e. this code cannot simply be 111 * copied and put under another distribution licence 112 * [including the GNU Public Licence.] 113 */ 114 115 #include <openssl/ssl.h> 116 117 #include <assert.h> 118 #include <stdio.h> 119 #include <string.h> 120 121 #include <openssl/bn.h> 122 #include <openssl/buf.h> 123 #include <openssl/dh.h> 124 #include <openssl/evp.h> 125 #include <openssl/err.h> 126 #include <openssl/md5.h> 127 #include <openssl/mem.h> 128 #include <openssl/obj.h> 129 #include <openssl/rand.h> 130 131 #include "internal.h" 132 133 134 static int dtls1_get_hello_verify(SSL *ssl); 135 136 int dtls1_connect(SSL *ssl) { 137 BUF_MEM *buf = NULL; 138 void (*cb)(const SSL *ssl, int type, int value) = NULL; 139 int ret = -1; 140 int new_state, state, skip = 0; 141 142 assert(ssl->handshake_func == dtls1_connect); 143 assert(!ssl->server); 144 assert(SSL_IS_DTLS(ssl)); 145 146 ERR_clear_error(); 147 ERR_clear_system_error(); 148 149 if (ssl->info_callback != NULL) { 150 cb = ssl->info_callback; 151 } else if (ssl->ctx->info_callback != NULL) { 152 cb = ssl->ctx->info_callback; 153 } 154 155 ssl->in_handshake++; 156 157 for (;;) { 158 state = ssl->state; 159 160 switch (ssl->state) { 161 case SSL_ST_CONNECT: 162 if (cb != NULL) { 163 cb(ssl, SSL_CB_HANDSHAKE_START, 1); 164 } 165 166 if (ssl->init_buf == NULL) { 167 buf = BUF_MEM_new(); 168 if (buf == NULL || 169 !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { 170 ret = -1; 171 goto end; 172 } 173 ssl->init_buf = buf; 174 buf = NULL; 175 } 176 177 if (!ssl_init_wbio_buffer(ssl, 0)) { 178 ret = -1; 179 goto end; 180 } 181 182 /* don't push the buffering BIO quite yet */ 183 184 ssl->state = SSL3_ST_CW_CLNT_HELLO_A; 185 ssl->init_num = 0; 186 ssl->d1->send_cookie = 0; 187 ssl->hit = 0; 188 break; 189 190 case SSL3_ST_CW_CLNT_HELLO_A: 191 case SSL3_ST_CW_CLNT_HELLO_B: 192 ssl->shutdown = 0; 193 dtls1_start_timer(ssl); 194 ret = ssl3_send_client_hello(ssl); 195 if (ret <= 0) { 196 goto end; 197 } 198 199 if (ssl->d1->send_cookie) { 200 ssl->state = SSL3_ST_CW_FLUSH; 201 ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; 202 } else { 203 ssl->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; 204 } 205 206 ssl->init_num = 0; 207 /* turn on buffering for the next lot of output */ 208 if (ssl->bbio != ssl->wbio) { 209 ssl->wbio = BIO_push(ssl->bbio, ssl->wbio); 210 } 211 212 break; 213 214 case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: 215 case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: 216 ret = dtls1_get_hello_verify(ssl); 217 if (ret <= 0) { 218 goto end; 219 } 220 if (ssl->d1->send_cookie) { 221 /* start again, with a cookie */ 222 dtls1_stop_timer(ssl); 223 ssl->state = SSL3_ST_CW_CLNT_HELLO_A; 224 } else { 225 ssl->state = SSL3_ST_CR_SRVR_HELLO_A; 226 } 227 ssl->init_num = 0; 228 break; 229 230 case SSL3_ST_CR_SRVR_HELLO_A: 231 case SSL3_ST_CR_SRVR_HELLO_B: 232 ret = ssl3_get_server_hello(ssl); 233 if (ret <= 0) { 234 goto end; 235 } 236 237 if (ssl->hit) { 238 ssl->state = SSL3_ST_CR_CHANGE; 239 if (ssl->tlsext_ticket_expected) { 240 /* receive renewed session ticket */ 241 ssl->state = SSL3_ST_CR_SESSION_TICKET_A; 242 } 243 } else { 244 ssl->state = SSL3_ST_CR_CERT_A; 245 } 246 ssl->init_num = 0; 247 break; 248 249 case SSL3_ST_CR_CERT_A: 250 case SSL3_ST_CR_CERT_B: 251 if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) { 252 ret = ssl3_get_server_certificate(ssl); 253 if (ret <= 0) { 254 goto end; 255 } 256 if (ssl->s3->tmp.certificate_status_expected) { 257 ssl->state = SSL3_ST_CR_CERT_STATUS_A; 258 } else { 259 ssl->state = SSL3_ST_VERIFY_SERVER_CERT; 260 } 261 } else { 262 skip = 1; 263 ssl->state = SSL3_ST_CR_KEY_EXCH_A; 264 } 265 ssl->init_num = 0; 266 break; 267 268 case SSL3_ST_VERIFY_SERVER_CERT: 269 ret = ssl3_verify_server_cert(ssl); 270 if (ret <= 0) { 271 goto end; 272 } 273 274 ssl->state = SSL3_ST_CR_KEY_EXCH_A; 275 ssl->init_num = 0; 276 break; 277 278 case SSL3_ST_CR_KEY_EXCH_A: 279 case SSL3_ST_CR_KEY_EXCH_B: 280 ret = ssl3_get_server_key_exchange(ssl); 281 if (ret <= 0) { 282 goto end; 283 } 284 ssl->state = SSL3_ST_CR_CERT_REQ_A; 285 ssl->init_num = 0; 286 break; 287 288 case SSL3_ST_CR_CERT_REQ_A: 289 case SSL3_ST_CR_CERT_REQ_B: 290 ret = ssl3_get_certificate_request(ssl); 291 if (ret <= 0) { 292 goto end; 293 } 294 ssl->state = SSL3_ST_CR_SRVR_DONE_A; 295 ssl->init_num = 0; 296 break; 297 298 case SSL3_ST_CR_SRVR_DONE_A: 299 case SSL3_ST_CR_SRVR_DONE_B: 300 ret = ssl3_get_server_done(ssl); 301 if (ret <= 0) { 302 goto end; 303 } 304 dtls1_stop_timer(ssl); 305 if (ssl->s3->tmp.cert_req) { 306 ssl->s3->tmp.next_state = SSL3_ST_CW_CERT_A; 307 } else { 308 ssl->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; 309 } 310 ssl->init_num = 0; 311 ssl->state = ssl->s3->tmp.next_state; 312 break; 313 314 case SSL3_ST_CW_CERT_A: 315 case SSL3_ST_CW_CERT_B: 316 case SSL3_ST_CW_CERT_C: 317 case SSL3_ST_CW_CERT_D: 318 dtls1_start_timer(ssl); 319 ret = ssl3_send_client_certificate(ssl); 320 if (ret <= 0) { 321 goto end; 322 } 323 ssl->state = SSL3_ST_CW_KEY_EXCH_A; 324 ssl->init_num = 0; 325 break; 326 327 case SSL3_ST_CW_KEY_EXCH_A: 328 case SSL3_ST_CW_KEY_EXCH_B: 329 dtls1_start_timer(ssl); 330 ret = ssl3_send_client_key_exchange(ssl); 331 if (ret <= 0) { 332 goto end; 333 } 334 /* For TLS, cert_req is set to 2, so a cert chain 335 * of nothing is sent, but no verify packet is sent */ 336 if (ssl->s3->tmp.cert_req == 1) { 337 ssl->state = SSL3_ST_CW_CERT_VRFY_A; 338 } else { 339 ssl->state = SSL3_ST_CW_CHANGE_A; 340 } 341 342 ssl->init_num = 0; 343 break; 344 345 case SSL3_ST_CW_CERT_VRFY_A: 346 case SSL3_ST_CW_CERT_VRFY_B: 347 case SSL3_ST_CW_CERT_VRFY_C: 348 dtls1_start_timer(ssl); 349 ret = ssl3_send_cert_verify(ssl); 350 if (ret <= 0) { 351 goto end; 352 } 353 ssl->state = SSL3_ST_CW_CHANGE_A; 354 ssl->init_num = 0; 355 break; 356 357 case SSL3_ST_CW_CHANGE_A: 358 case SSL3_ST_CW_CHANGE_B: 359 if (!ssl->hit) { 360 dtls1_start_timer(ssl); 361 } 362 ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A, 363 SSL3_ST_CW_CHANGE_B); 364 if (ret <= 0) { 365 goto end; 366 } 367 368 ssl->state = SSL3_ST_CW_FINISHED_A; 369 ssl->init_num = 0; 370 371 ssl->session->cipher = ssl->s3->tmp.new_cipher; 372 if (!ssl->enc_method->setup_key_block(ssl) || 373 !ssl->enc_method->change_cipher_state( 374 ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { 375 ret = -1; 376 goto end; 377 } 378 break; 379 380 case SSL3_ST_CW_FINISHED_A: 381 case SSL3_ST_CW_FINISHED_B: 382 if (!ssl->hit) { 383 dtls1_start_timer(ssl); 384 } 385 386 ret = 387 ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B, 388 ssl->enc_method->client_finished_label, 389 ssl->enc_method->client_finished_label_len); 390 if (ret <= 0) { 391 goto end; 392 } 393 ssl->state = SSL3_ST_CW_FLUSH; 394 395 if (ssl->hit) { 396 ssl->s3->tmp.next_state = SSL_ST_OK; 397 } else { 398 /* Allow NewSessionTicket if ticket expected */ 399 if (ssl->tlsext_ticket_expected) { 400 ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; 401 } else { 402 ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE; 403 } 404 } 405 ssl->init_num = 0; 406 break; 407 408 case SSL3_ST_CR_SESSION_TICKET_A: 409 case SSL3_ST_CR_SESSION_TICKET_B: 410 ret = ssl3_get_new_session_ticket(ssl); 411 if (ret <= 0) { 412 goto end; 413 } 414 ssl->state = SSL3_ST_CR_CHANGE; 415 ssl->init_num = 0; 416 break; 417 418 case SSL3_ST_CR_CERT_STATUS_A: 419 case SSL3_ST_CR_CERT_STATUS_B: 420 ret = ssl3_get_cert_status(ssl); 421 if (ret <= 0) { 422 goto end; 423 } 424 ssl->state = SSL3_ST_VERIFY_SERVER_CERT; 425 ssl->init_num = 0; 426 break; 427 428 case SSL3_ST_CR_CHANGE: 429 ret = ssl->method->ssl_read_change_cipher_spec(ssl); 430 if (ret <= 0) { 431 goto end; 432 } 433 434 if (!ssl3_do_change_cipher_spec(ssl)) { 435 ret = -1; 436 goto end; 437 } 438 ssl->state = SSL3_ST_CR_FINISHED_A; 439 break; 440 441 case SSL3_ST_CR_FINISHED_A: 442 case SSL3_ST_CR_FINISHED_B: 443 ret = 444 ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); 445 if (ret <= 0) { 446 goto end; 447 } 448 dtls1_stop_timer(ssl); 449 450 if (ssl->hit) { 451 ssl->state = SSL3_ST_CW_CHANGE_A; 452 } else { 453 ssl->state = SSL_ST_OK; 454 } 455 456 ssl->init_num = 0; 457 break; 458 459 case SSL3_ST_CW_FLUSH: 460 ssl->rwstate = SSL_WRITING; 461 if (BIO_flush(ssl->wbio) <= 0) { 462 ret = -1; 463 goto end; 464 } 465 ssl->rwstate = SSL_NOTHING; 466 ssl->state = ssl->s3->tmp.next_state; 467 break; 468 469 case SSL_ST_OK: 470 /* clean a few things up */ 471 ssl3_cleanup_key_block(ssl); 472 473 /* Remove write buffering now. */ 474 ssl_free_wbio_buffer(ssl); 475 476 ssl->init_num = 0; 477 ssl->s3->initial_handshake_complete = 1; 478 479 ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT); 480 481 ret = 1; 482 483 if (cb != NULL) { 484 cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); 485 } 486 487 /* done with handshaking */ 488 ssl->d1->handshake_read_seq = 0; 489 ssl->d1->next_handshake_write_seq = 0; 490 goto end; 491 492 default: 493 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE); 494 ret = -1; 495 goto end; 496 } 497 498 /* did we do anything? */ 499 if (!ssl->s3->tmp.reuse_message && !skip) { 500 if ((cb != NULL) && (ssl->state != state)) { 501 new_state = ssl->state; 502 ssl->state = state; 503 cb(ssl, SSL_CB_CONNECT_LOOP, 1); 504 ssl->state = new_state; 505 } 506 } 507 skip = 0; 508 } 509 510 end: 511 ssl->in_handshake--; 512 513 BUF_MEM_free(buf); 514 if (cb != NULL) { 515 cb(ssl, SSL_CB_CONNECT_EXIT, ret); 516 } 517 return ret; 518 } 519 520 static int dtls1_get_hello_verify(SSL *ssl) { 521 long n; 522 int al, ok = 0; 523 CBS hello_verify_request, cookie; 524 uint16_t server_version; 525 526 n = ssl->method->ssl_get_message( 527 ssl, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, 528 DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, 529 /* Use the same maximum size as ssl3_get_server_hello. */ 530 20000, ssl_hash_message, &ok); 531 532 if (!ok) { 533 return n; 534 } 535 536 if (ssl->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { 537 ssl->d1->send_cookie = 0; 538 ssl->s3->tmp.reuse_message = 1; 539 return 1; 540 } 541 542 CBS_init(&hello_verify_request, ssl->init_msg, n); 543 544 if (!CBS_get_u16(&hello_verify_request, &server_version) || 545 !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || 546 CBS_len(&hello_verify_request) != 0) { 547 al = SSL_AD_DECODE_ERROR; 548 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); 549 goto f_err; 550 } 551 552 if (CBS_len(&cookie) > sizeof(ssl->d1->cookie)) { 553 al = SSL_AD_ILLEGAL_PARAMETER; 554 goto f_err; 555 } 556 557 memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); 558 ssl->d1->cookie_len = CBS_len(&cookie); 559 560 ssl->d1->send_cookie = 1; 561 return 1; 562 563 f_err: 564 ssl3_send_alert(ssl, SSL3_AL_FATAL, al); 565 return -1; 566 } 567