1160814Ssimon/* ssl/d1_clnt.c */ 2160814Ssimon/* 3160814Ssimon * DTLS implementation written by Nagendra Modadugu 4160814Ssimon * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7238405Sjkim * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14160814Ssimon * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * openssl-core@OpenSSL.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 60160814Ssimon * All rights reserved. 61160814Ssimon * 62160814Ssimon * This package is an SSL implementation written 63160814Ssimon * by Eric Young (eay@cryptsoft.com). 64160814Ssimon * The implementation was written so as to conform with Netscapes SSL. 65160814Ssimon * 66160814Ssimon * This library is free for commercial and non-commercial use as long as 67160814Ssimon * the following conditions are aheared to. The following conditions 68160814Ssimon * apply to all code found in this distribution, be it the RC4, RSA, 69160814Ssimon * lhash, DES, etc., code; not just the SSL code. The SSL documentation 70160814Ssimon * included with this distribution is covered by the same copyright terms 71160814Ssimon * except that the holder is Tim Hudson (tjh@cryptsoft.com). 72160814Ssimon * 73160814Ssimon * Copyright remains Eric Young's, and as such any Copyright notices in 74160814Ssimon * the code are not to be removed. 75160814Ssimon * If this package is used in a product, Eric Young should be given attribution 76160814Ssimon * as the author of the parts of the library used. 77160814Ssimon * This can be in the form of a textual message at program startup or 78160814Ssimon * in documentation (online or textual) provided with the package. 79160814Ssimon * 80160814Ssimon * Redistribution and use in source and binary forms, with or without 81160814Ssimon * modification, are permitted provided that the following conditions 82160814Ssimon * are met: 83160814Ssimon * 1. Redistributions of source code must retain the copyright 84160814Ssimon * notice, this list of conditions and the following disclaimer. 85160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 86160814Ssimon * notice, this list of conditions and the following disclaimer in the 87160814Ssimon * documentation and/or other materials provided with the distribution. 88160814Ssimon * 3. All advertising materials mentioning features or use of this software 89160814Ssimon * must display the following acknowledgement: 90160814Ssimon * "This product includes cryptographic software written by 91160814Ssimon * Eric Young (eay@cryptsoft.com)" 92160814Ssimon * The word 'cryptographic' can be left out if the rouines from the library 93160814Ssimon * being used are not cryptographic related :-). 94160814Ssimon * 4. If you include any Windows specific code (or a derivative thereof) from 95160814Ssimon * the apps directory (application code) you must include an acknowledgement: 96160814Ssimon * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 97160814Ssimon * 98160814Ssimon * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 99160814Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 100160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 101160814Ssimon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 102160814Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 103160814Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 104160814Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 105160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 106160814Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 107160814Ssimon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 108160814Ssimon * SUCH DAMAGE. 109160814Ssimon * 110160814Ssimon * The licence and distribution terms for any publically available version or 111160814Ssimon * derivative of this code cannot be changed. i.e. this code cannot simply be 112160814Ssimon * copied and put under another distribution licence 113160814Ssimon * [including the GNU Public Licence.] 114160814Ssimon */ 115160814Ssimon 116160814Ssimon#include <stdio.h> 117160814Ssimon#include "ssl_locl.h" 118238405Sjkim#ifndef OPENSSL_NO_KRB5 119160814Ssimon#include "kssl_lcl.h" 120238405Sjkim#endif 121160814Ssimon#include <openssl/buffer.h> 122160814Ssimon#include <openssl/rand.h> 123160814Ssimon#include <openssl/objects.h> 124160814Ssimon#include <openssl/evp.h> 125160814Ssimon#include <openssl/md5.h> 126238405Sjkim#include <openssl/bn.h> 127160814Ssimon#ifndef OPENSSL_NO_DH 128160814Ssimon#include <openssl/dh.h> 129160814Ssimon#endif 130160814Ssimon 131238405Sjkimstatic const SSL_METHOD *dtls1_get_client_method(int ver); 132160814Ssimonstatic int dtls1_get_hello_verify(SSL *s); 133160814Ssimon 134238405Sjkimstatic const SSL_METHOD *dtls1_get_client_method(int ver) 135160814Ssimon { 136205128Ssimon if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) 137160814Ssimon return(DTLSv1_client_method()); 138160814Ssimon else 139160814Ssimon return(NULL); 140160814Ssimon } 141160814Ssimon 142160814SsimonIMPLEMENT_dtls1_meth_func(DTLSv1_client_method, 143160814Ssimon ssl_undefined_function, 144160814Ssimon dtls1_connect, 145160814Ssimon dtls1_get_client_method) 146160814Ssimon 147160814Ssimonint dtls1_connect(SSL *s) 148160814Ssimon { 149160814Ssimon BUF_MEM *buf=NULL; 150215697Ssimon unsigned long Time=(unsigned long)time(NULL); 151160814Ssimon void (*cb)(const SSL *ssl,int type,int val)=NULL; 152160814Ssimon int ret= -1; 153238405Sjkim int new_state,state,skip=0; 154238405Sjkim#ifndef OPENSSL_NO_SCTP 155238405Sjkim unsigned char sctpauthkey[64]; 156238405Sjkim char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; 157238405Sjkim#endif 158160814Ssimon 159160814Ssimon RAND_add(&Time,sizeof(Time),0); 160160814Ssimon ERR_clear_error(); 161160814Ssimon clear_sys_error(); 162160814Ssimon 163160814Ssimon if (s->info_callback != NULL) 164160814Ssimon cb=s->info_callback; 165160814Ssimon else if (s->ctx->info_callback != NULL) 166160814Ssimon cb=s->ctx->info_callback; 167160814Ssimon 168160814Ssimon s->in_handshake++; 169160814Ssimon if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 170160814Ssimon 171238405Sjkim#ifndef OPENSSL_NO_SCTP 172238405Sjkim /* Notify SCTP BIO socket to enter handshake 173238405Sjkim * mode and prevent stream identifier other 174238405Sjkim * than 0. Will be ignored if no SCTP is used. 175238405Sjkim */ 176238405Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL); 177238405Sjkim#endif 178238405Sjkim 179238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 180238405Sjkim /* If we're awaiting a HeartbeatResponse, pretend we 181238405Sjkim * already got and don't await it anymore, because 182238405Sjkim * Heartbeats don't make sense during handshakes anyway. 183238405Sjkim */ 184238405Sjkim if (s->tlsext_hb_pending) 185238405Sjkim { 186238405Sjkim dtls1_stop_timer(s); 187238405Sjkim s->tlsext_hb_pending = 0; 188238405Sjkim s->tlsext_hb_seq++; 189238405Sjkim } 190238405Sjkim#endif 191238405Sjkim 192160814Ssimon for (;;) 193160814Ssimon { 194160814Ssimon state=s->state; 195160814Ssimon 196160814Ssimon switch(s->state) 197160814Ssimon { 198160814Ssimon case SSL_ST_RENEGOTIATE: 199238405Sjkim s->renegotiate=1; 200160814Ssimon s->state=SSL_ST_CONNECT; 201160814Ssimon s->ctx->stats.sess_connect_renegotiate++; 202160814Ssimon /* break */ 203160814Ssimon case SSL_ST_BEFORE: 204160814Ssimon case SSL_ST_CONNECT: 205160814Ssimon case SSL_ST_BEFORE|SSL_ST_CONNECT: 206160814Ssimon case SSL_ST_OK|SSL_ST_CONNECT: 207160814Ssimon 208160814Ssimon s->server=0; 209160814Ssimon if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); 210160814Ssimon 211205128Ssimon if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) && 212205128Ssimon (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00)) 213160814Ssimon { 214160814Ssimon SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); 215160814Ssimon ret = -1; 216160814Ssimon goto end; 217160814Ssimon } 218160814Ssimon 219160814Ssimon /* s->version=SSL3_VERSION; */ 220160814Ssimon s->type=SSL_ST_CONNECT; 221160814Ssimon 222160814Ssimon if (s->init_buf == NULL) 223160814Ssimon { 224160814Ssimon if ((buf=BUF_MEM_new()) == NULL) 225160814Ssimon { 226160814Ssimon ret= -1; 227160814Ssimon goto end; 228160814Ssimon } 229160814Ssimon if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) 230160814Ssimon { 231160814Ssimon ret= -1; 232160814Ssimon goto end; 233160814Ssimon } 234160814Ssimon s->init_buf=buf; 235160814Ssimon buf=NULL; 236160814Ssimon } 237160814Ssimon 238160814Ssimon if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } 239160814Ssimon 240160814Ssimon /* setup buffing BIO */ 241160814Ssimon if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; } 242160814Ssimon 243160814Ssimon /* don't push the buffering BIO quite yet */ 244160814Ssimon 245160814Ssimon s->state=SSL3_ST_CW_CLNT_HELLO_A; 246160814Ssimon s->ctx->stats.sess_connect++; 247160814Ssimon s->init_num=0; 248194206Ssimon /* mark client_random uninitialized */ 249194206Ssimon memset(s->s3->client_random,0,sizeof(s->s3->client_random)); 250205128Ssimon s->d1->send_cookie = 0; 251205128Ssimon s->hit = 0; 252279264Sdelphij s->d1->change_cipher_spec_ok = 0; 253279264Sdelphij /* Should have been reset by ssl3_get_finished, too. */ 254279264Sdelphij s->s3->change_cipher_spec = 0; 255160814Ssimon break; 256160814Ssimon 257238405Sjkim#ifndef OPENSSL_NO_SCTP 258238405Sjkim case DTLS1_SCTP_ST_CR_READ_SOCK: 259238405Sjkim 260238405Sjkim if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) 261238405Sjkim { 262238405Sjkim s->s3->in_read_app_data=2; 263238405Sjkim s->rwstate=SSL_READING; 264238405Sjkim BIO_clear_retry_flags(SSL_get_rbio(s)); 265238405Sjkim BIO_set_retry_read(SSL_get_rbio(s)); 266238405Sjkim ret = -1; 267238405Sjkim goto end; 268238405Sjkim } 269238405Sjkim 270238405Sjkim s->state=s->s3->tmp.next_state; 271238405Sjkim break; 272238405Sjkim 273238405Sjkim case DTLS1_SCTP_ST_CW_WRITE_SOCK: 274238405Sjkim /* read app data until dry event */ 275238405Sjkim 276238405Sjkim ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); 277238405Sjkim if (ret < 0) goto end; 278238405Sjkim 279238405Sjkim if (ret == 0) 280238405Sjkim { 281238405Sjkim s->s3->in_read_app_data=2; 282238405Sjkim s->rwstate=SSL_READING; 283238405Sjkim BIO_clear_retry_flags(SSL_get_rbio(s)); 284238405Sjkim BIO_set_retry_read(SSL_get_rbio(s)); 285238405Sjkim ret = -1; 286238405Sjkim goto end; 287238405Sjkim } 288238405Sjkim 289238405Sjkim s->state=s->d1->next_state; 290238405Sjkim break; 291238405Sjkim#endif 292238405Sjkim 293160814Ssimon case SSL3_ST_CW_CLNT_HELLO_A: 294160814Ssimon case SSL3_ST_CW_CLNT_HELLO_B: 295160814Ssimon 296160814Ssimon s->shutdown=0; 297194206Ssimon 298194206Ssimon /* every DTLS ClientHello resets Finished MAC */ 299194206Ssimon ssl3_init_finished_mac(s); 300194206Ssimon 301205128Ssimon dtls1_start_timer(s); 302160814Ssimon ret=dtls1_client_hello(s); 303160814Ssimon if (ret <= 0) goto end; 304160814Ssimon 305160814Ssimon if ( s->d1->send_cookie) 306160814Ssimon { 307160814Ssimon s->state=SSL3_ST_CW_FLUSH; 308160814Ssimon s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A; 309160814Ssimon } 310160814Ssimon else 311160814Ssimon s->state=SSL3_ST_CR_SRVR_HELLO_A; 312160814Ssimon 313160814Ssimon s->init_num=0; 314160814Ssimon 315238405Sjkim#ifndef OPENSSL_NO_SCTP 316238405Sjkim /* Disable buffering for SCTP */ 317238405Sjkim if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) 318238405Sjkim { 319238405Sjkim#endif 320238405Sjkim /* turn on buffering for the next lot of output */ 321238405Sjkim if (s->bbio != s->wbio) 322238405Sjkim s->wbio=BIO_push(s->bbio,s->wbio); 323238405Sjkim#ifndef OPENSSL_NO_SCTP 324238405Sjkim } 325238405Sjkim#endif 326160814Ssimon 327160814Ssimon break; 328160814Ssimon 329160814Ssimon case SSL3_ST_CR_SRVR_HELLO_A: 330160814Ssimon case SSL3_ST_CR_SRVR_HELLO_B: 331160814Ssimon ret=ssl3_get_server_hello(s); 332160814Ssimon if (ret <= 0) goto end; 333160814Ssimon else 334160814Ssimon { 335160814Ssimon if (s->hit) 336238405Sjkim { 337238405Sjkim#ifndef OPENSSL_NO_SCTP 338238405Sjkim /* Add new shared key for SCTP-Auth, 339238405Sjkim * will be ignored if no SCTP used. 340238405Sjkim */ 341238405Sjkim snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), 342238405Sjkim DTLS1_SCTP_AUTH_LABEL); 343238405Sjkim 344238405Sjkim SSL_export_keying_material(s, sctpauthkey, 345238405Sjkim sizeof(sctpauthkey), labelbuffer, 346238405Sjkim sizeof(labelbuffer), NULL, 0, 0); 347238405Sjkim 348238405Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, 349238405Sjkim sizeof(sctpauthkey), sctpauthkey); 350238405Sjkim#endif 351238405Sjkim 352160814Ssimon s->state=SSL3_ST_CR_FINISHED_A; 353238405Sjkim } 354160814Ssimon else 355160814Ssimon s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; 356160814Ssimon } 357160814Ssimon s->init_num=0; 358160814Ssimon break; 359160814Ssimon 360160814Ssimon case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: 361160814Ssimon case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: 362160814Ssimon 363160814Ssimon ret = dtls1_get_hello_verify(s); 364160814Ssimon if ( ret <= 0) 365160814Ssimon goto end; 366205128Ssimon dtls1_stop_timer(s); 367160814Ssimon if ( s->d1->send_cookie) /* start again, with a cookie */ 368160814Ssimon s->state=SSL3_ST_CW_CLNT_HELLO_A; 369160814Ssimon else 370160814Ssimon s->state = SSL3_ST_CR_CERT_A; 371160814Ssimon s->init_num = 0; 372160814Ssimon break; 373160814Ssimon 374160814Ssimon case SSL3_ST_CR_CERT_A: 375160814Ssimon case SSL3_ST_CR_CERT_B: 376238405Sjkim /* Check if it is anon DH or PSK */ 377238405Sjkim if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && 378238405Sjkim !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) 379160814Ssimon { 380160814Ssimon ret=ssl3_get_server_certificate(s); 381160814Ssimon if (ret <= 0) goto end; 382205128Ssimon#ifndef OPENSSL_NO_TLSEXT 383205128Ssimon if (s->tlsext_status_expected) 384205128Ssimon s->state=SSL3_ST_CR_CERT_STATUS_A; 385205128Ssimon else 386205128Ssimon s->state=SSL3_ST_CR_KEY_EXCH_A; 387160814Ssimon } 388160814Ssimon else 389205128Ssimon { 390205128Ssimon skip = 1; 391205128Ssimon s->state=SSL3_ST_CR_KEY_EXCH_A; 392205128Ssimon } 393205128Ssimon#else 394205128Ssimon } 395205128Ssimon else 396160814Ssimon skip=1; 397205128Ssimon 398160814Ssimon s->state=SSL3_ST_CR_KEY_EXCH_A; 399205128Ssimon#endif 400160814Ssimon s->init_num=0; 401160814Ssimon break; 402160814Ssimon 403160814Ssimon case SSL3_ST_CR_KEY_EXCH_A: 404160814Ssimon case SSL3_ST_CR_KEY_EXCH_B: 405160814Ssimon ret=ssl3_get_key_exchange(s); 406160814Ssimon if (ret <= 0) goto end; 407160814Ssimon s->state=SSL3_ST_CR_CERT_REQ_A; 408160814Ssimon s->init_num=0; 409160814Ssimon 410160814Ssimon /* at this point we check that we have the 411160814Ssimon * required stuff from the server */ 412160814Ssimon if (!ssl3_check_cert_and_algorithm(s)) 413160814Ssimon { 414160814Ssimon ret= -1; 415160814Ssimon goto end; 416160814Ssimon } 417160814Ssimon break; 418160814Ssimon 419160814Ssimon case SSL3_ST_CR_CERT_REQ_A: 420160814Ssimon case SSL3_ST_CR_CERT_REQ_B: 421160814Ssimon ret=ssl3_get_certificate_request(s); 422160814Ssimon if (ret <= 0) goto end; 423160814Ssimon s->state=SSL3_ST_CR_SRVR_DONE_A; 424160814Ssimon s->init_num=0; 425160814Ssimon break; 426160814Ssimon 427160814Ssimon case SSL3_ST_CR_SRVR_DONE_A: 428160814Ssimon case SSL3_ST_CR_SRVR_DONE_B: 429160814Ssimon ret=ssl3_get_server_done(s); 430160814Ssimon if (ret <= 0) goto end; 431237657Sjkim dtls1_stop_timer(s); 432160814Ssimon if (s->s3->tmp.cert_req) 433238405Sjkim s->s3->tmp.next_state=SSL3_ST_CW_CERT_A; 434160814Ssimon else 435238405Sjkim s->s3->tmp.next_state=SSL3_ST_CW_KEY_EXCH_A; 436160814Ssimon s->init_num=0; 437160814Ssimon 438238405Sjkim#ifndef OPENSSL_NO_SCTP 439238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && 440238405Sjkim state == SSL_ST_RENEGOTIATE) 441238405Sjkim s->state=DTLS1_SCTP_ST_CR_READ_SOCK; 442238405Sjkim else 443238405Sjkim#endif 444238405Sjkim s->state=s->s3->tmp.next_state; 445160814Ssimon break; 446160814Ssimon 447160814Ssimon case SSL3_ST_CW_CERT_A: 448160814Ssimon case SSL3_ST_CW_CERT_B: 449160814Ssimon case SSL3_ST_CW_CERT_C: 450160814Ssimon case SSL3_ST_CW_CERT_D: 451205128Ssimon dtls1_start_timer(s); 452160814Ssimon ret=dtls1_send_client_certificate(s); 453160814Ssimon if (ret <= 0) goto end; 454160814Ssimon s->state=SSL3_ST_CW_KEY_EXCH_A; 455160814Ssimon s->init_num=0; 456160814Ssimon break; 457160814Ssimon 458160814Ssimon case SSL3_ST_CW_KEY_EXCH_A: 459160814Ssimon case SSL3_ST_CW_KEY_EXCH_B: 460205128Ssimon dtls1_start_timer(s); 461160814Ssimon ret=dtls1_send_client_key_exchange(s); 462160814Ssimon if (ret <= 0) goto end; 463238405Sjkim 464238405Sjkim#ifndef OPENSSL_NO_SCTP 465238405Sjkim /* Add new shared key for SCTP-Auth, 466238405Sjkim * will be ignored if no SCTP used. 467238405Sjkim */ 468238405Sjkim snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), 469238405Sjkim DTLS1_SCTP_AUTH_LABEL); 470238405Sjkim 471238405Sjkim SSL_export_keying_material(s, sctpauthkey, 472238405Sjkim sizeof(sctpauthkey), labelbuffer, 473238405Sjkim sizeof(labelbuffer), NULL, 0, 0); 474238405Sjkim 475238405Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, 476238405Sjkim sizeof(sctpauthkey), sctpauthkey); 477238405Sjkim#endif 478238405Sjkim 479160814Ssimon /* EAY EAY EAY need to check for DH fix cert 480160814Ssimon * sent back */ 481160814Ssimon /* For TLS, cert_req is set to 2, so a cert chain 482160814Ssimon * of nothing is sent, but no verify packet is sent */ 483160814Ssimon if (s->s3->tmp.cert_req == 1) 484160814Ssimon { 485160814Ssimon s->state=SSL3_ST_CW_CERT_VRFY_A; 486160814Ssimon } 487160814Ssimon else 488160814Ssimon { 489238405Sjkim#ifndef OPENSSL_NO_SCTP 490238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) 491238405Sjkim { 492238405Sjkim s->d1->next_state=SSL3_ST_CW_CHANGE_A; 493238405Sjkim s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK; 494238405Sjkim } 495238405Sjkim else 496238405Sjkim#endif 497238405Sjkim s->state=SSL3_ST_CW_CHANGE_A; 498160814Ssimon } 499160814Ssimon 500160814Ssimon s->init_num=0; 501160814Ssimon break; 502160814Ssimon 503160814Ssimon case SSL3_ST_CW_CERT_VRFY_A: 504160814Ssimon case SSL3_ST_CW_CERT_VRFY_B: 505205128Ssimon dtls1_start_timer(s); 506160814Ssimon ret=dtls1_send_client_verify(s); 507160814Ssimon if (ret <= 0) goto end; 508238405Sjkim#ifndef OPENSSL_NO_SCTP 509238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) 510238405Sjkim { 511238405Sjkim s->d1->next_state=SSL3_ST_CW_CHANGE_A; 512238405Sjkim s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK; 513238405Sjkim } 514238405Sjkim else 515238405Sjkim#endif 516238405Sjkim s->state=SSL3_ST_CW_CHANGE_A; 517160814Ssimon s->init_num=0; 518160814Ssimon break; 519160814Ssimon 520160814Ssimon case SSL3_ST_CW_CHANGE_A: 521160814Ssimon case SSL3_ST_CW_CHANGE_B: 522237657Sjkim if (!s->hit) 523237657Sjkim dtls1_start_timer(s); 524160814Ssimon ret=dtls1_send_change_cipher_spec(s, 525160814Ssimon SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); 526160814Ssimon if (ret <= 0) goto end; 527238405Sjkim 528160814Ssimon s->state=SSL3_ST_CW_FINISHED_A; 529160814Ssimon s->init_num=0; 530160814Ssimon 531160814Ssimon s->session->cipher=s->s3->tmp.new_cipher; 532160814Ssimon#ifdef OPENSSL_NO_COMP 533160814Ssimon s->session->compress_meth=0; 534160814Ssimon#else 535160814Ssimon if (s->s3->tmp.new_compression == NULL) 536160814Ssimon s->session->compress_meth=0; 537160814Ssimon else 538160814Ssimon s->session->compress_meth= 539160814Ssimon s->s3->tmp.new_compression->id; 540160814Ssimon#endif 541160814Ssimon if (!s->method->ssl3_enc->setup_key_block(s)) 542160814Ssimon { 543160814Ssimon ret= -1; 544160814Ssimon goto end; 545160814Ssimon } 546160814Ssimon 547160814Ssimon if (!s->method->ssl3_enc->change_cipher_state(s, 548160814Ssimon SSL3_CHANGE_CIPHER_CLIENT_WRITE)) 549160814Ssimon { 550160814Ssimon ret= -1; 551160814Ssimon goto end; 552160814Ssimon } 553160814Ssimon 554279264Sdelphij#ifndef OPENSSL_NO_SCTP 555279264Sdelphij if (s->hit) 556279264Sdelphij { 557279264Sdelphij /* Change to new shared key of SCTP-Auth, 558279264Sdelphij * will be ignored if no SCTP used. 559279264Sdelphij */ 560279264Sdelphij BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); 561279264Sdelphij } 562279264Sdelphij#endif 563279264Sdelphij 564160814Ssimon dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); 565160814Ssimon break; 566160814Ssimon 567160814Ssimon case SSL3_ST_CW_FINISHED_A: 568160814Ssimon case SSL3_ST_CW_FINISHED_B: 569237657Sjkim if (!s->hit) 570237657Sjkim dtls1_start_timer(s); 571160814Ssimon ret=dtls1_send_finished(s, 572160814Ssimon SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, 573160814Ssimon s->method->ssl3_enc->client_finished_label, 574160814Ssimon s->method->ssl3_enc->client_finished_label_len); 575160814Ssimon if (ret <= 0) goto end; 576160814Ssimon s->state=SSL3_ST_CW_FLUSH; 577160814Ssimon 578160814Ssimon /* clear flags */ 579160814Ssimon s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER; 580160814Ssimon if (s->hit) 581160814Ssimon { 582160814Ssimon s->s3->tmp.next_state=SSL_ST_OK; 583238405Sjkim#ifndef OPENSSL_NO_SCTP 584238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) 585238405Sjkim { 586238405Sjkim s->d1->next_state = s->s3->tmp.next_state; 587238405Sjkim s->s3->tmp.next_state=DTLS1_SCTP_ST_CW_WRITE_SOCK; 588238405Sjkim } 589238405Sjkim#endif 590160814Ssimon if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) 591160814Ssimon { 592160814Ssimon s->state=SSL_ST_OK; 593238405Sjkim#ifndef OPENSSL_NO_SCTP 594238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) 595238405Sjkim { 596238405Sjkim s->d1->next_state = SSL_ST_OK; 597238405Sjkim s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK; 598238405Sjkim } 599238405Sjkim#endif 600160814Ssimon s->s3->flags|=SSL3_FLAGS_POP_BUFFER; 601160814Ssimon s->s3->delay_buf_pop_ret=0; 602160814Ssimon } 603160814Ssimon } 604160814Ssimon else 605160814Ssimon { 606279264Sdelphij#ifndef OPENSSL_NO_SCTP 607279264Sdelphij /* Change to new shared key of SCTP-Auth, 608279264Sdelphij * will be ignored if no SCTP used. 609279264Sdelphij */ 610279264Sdelphij BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); 611279264Sdelphij#endif 612279264Sdelphij 613205128Ssimon#ifndef OPENSSL_NO_TLSEXT 614205128Ssimon /* Allow NewSessionTicket if ticket expected */ 615205128Ssimon if (s->tlsext_ticket_expected) 616205128Ssimon s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A; 617205128Ssimon else 618205128Ssimon#endif 619205128Ssimon 620160814Ssimon s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; 621160814Ssimon } 622160814Ssimon s->init_num=0; 623160814Ssimon break; 624160814Ssimon 625205128Ssimon#ifndef OPENSSL_NO_TLSEXT 626205128Ssimon case SSL3_ST_CR_SESSION_TICKET_A: 627205128Ssimon case SSL3_ST_CR_SESSION_TICKET_B: 628205128Ssimon ret=ssl3_get_new_session_ticket(s); 629205128Ssimon if (ret <= 0) goto end; 630205128Ssimon s->state=SSL3_ST_CR_FINISHED_A; 631205128Ssimon s->init_num=0; 632205128Ssimon break; 633205128Ssimon 634205128Ssimon case SSL3_ST_CR_CERT_STATUS_A: 635205128Ssimon case SSL3_ST_CR_CERT_STATUS_B: 636205128Ssimon ret=ssl3_get_cert_status(s); 637205128Ssimon if (ret <= 0) goto end; 638205128Ssimon s->state=SSL3_ST_CR_KEY_EXCH_A; 639205128Ssimon s->init_num=0; 640205128Ssimon break; 641205128Ssimon#endif 642205128Ssimon 643160814Ssimon case SSL3_ST_CR_FINISHED_A: 644160814Ssimon case SSL3_ST_CR_FINISHED_B: 645205128Ssimon s->d1->change_cipher_spec_ok = 1; 646160814Ssimon ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, 647160814Ssimon SSL3_ST_CR_FINISHED_B); 648160814Ssimon if (ret <= 0) goto end; 649205128Ssimon dtls1_stop_timer(s); 650160814Ssimon 651160814Ssimon if (s->hit) 652160814Ssimon s->state=SSL3_ST_CW_CHANGE_A; 653160814Ssimon else 654160814Ssimon s->state=SSL_ST_OK; 655238405Sjkim 656238405Sjkim#ifndef OPENSSL_NO_SCTP 657238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && 658238405Sjkim state == SSL_ST_RENEGOTIATE) 659238405Sjkim { 660238405Sjkim s->d1->next_state=s->state; 661238405Sjkim s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK; 662238405Sjkim } 663238405Sjkim#endif 664238405Sjkim 665160814Ssimon s->init_num=0; 666160814Ssimon break; 667160814Ssimon 668160814Ssimon case SSL3_ST_CW_FLUSH: 669205128Ssimon s->rwstate=SSL_WRITING; 670205128Ssimon if (BIO_flush(s->wbio) <= 0) 671160814Ssimon { 672238405Sjkim /* If the write error was fatal, stop trying */ 673238405Sjkim if (!BIO_should_retry(s->wbio)) 674238405Sjkim { 675238405Sjkim s->rwstate=SSL_NOTHING; 676238405Sjkim s->state=s->s3->tmp.next_state; 677238405Sjkim } 678238405Sjkim 679205128Ssimon ret= -1; 680205128Ssimon goto end; 681160814Ssimon } 682205128Ssimon s->rwstate=SSL_NOTHING; 683160814Ssimon s->state=s->s3->tmp.next_state; 684160814Ssimon break; 685160814Ssimon 686160814Ssimon case SSL_ST_OK: 687160814Ssimon /* clean a few things up */ 688160814Ssimon ssl3_cleanup_key_block(s); 689160814Ssimon 690160814Ssimon#if 0 691160814Ssimon if (s->init_buf != NULL) 692160814Ssimon { 693160814Ssimon BUF_MEM_free(s->init_buf); 694160814Ssimon s->init_buf=NULL; 695160814Ssimon } 696160814Ssimon#endif 697160814Ssimon 698160814Ssimon /* If we are not 'joining' the last two packets, 699160814Ssimon * remove the buffering now */ 700160814Ssimon if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) 701160814Ssimon ssl_free_wbio_buffer(s); 702160814Ssimon /* else do it later in ssl3_write */ 703160814Ssimon 704160814Ssimon s->init_num=0; 705238405Sjkim s->renegotiate=0; 706160814Ssimon s->new_session=0; 707160814Ssimon 708160814Ssimon ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); 709160814Ssimon if (s->hit) s->ctx->stats.sess_hit++; 710160814Ssimon 711160814Ssimon ret=1; 712160814Ssimon /* s->server=0; */ 713160814Ssimon s->handshake_func=dtls1_connect; 714160814Ssimon s->ctx->stats.sess_connect_good++; 715160814Ssimon 716160814Ssimon if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); 717160814Ssimon 718160814Ssimon /* done with handshaking */ 719160814Ssimon s->d1->handshake_read_seq = 0; 720205128Ssimon s->d1->next_handshake_write_seq = 0; 721160814Ssimon goto end; 722160814Ssimon /* break; */ 723160814Ssimon 724160814Ssimon default: 725160814Ssimon SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE); 726160814Ssimon ret= -1; 727160814Ssimon goto end; 728160814Ssimon /* break; */ 729160814Ssimon } 730160814Ssimon 731160814Ssimon /* did we do anything */ 732160814Ssimon if (!s->s3->tmp.reuse_message && !skip) 733160814Ssimon { 734160814Ssimon if (s->debug) 735160814Ssimon { 736160814Ssimon if ((ret=BIO_flush(s->wbio)) <= 0) 737160814Ssimon goto end; 738160814Ssimon } 739160814Ssimon 740160814Ssimon if ((cb != NULL) && (s->state != state)) 741160814Ssimon { 742160814Ssimon new_state=s->state; 743160814Ssimon s->state=state; 744160814Ssimon cb(s,SSL_CB_CONNECT_LOOP,1); 745160814Ssimon s->state=new_state; 746160814Ssimon } 747160814Ssimon } 748160814Ssimon skip=0; 749160814Ssimon } 750160814Ssimonend: 751160814Ssimon s->in_handshake--; 752238405Sjkim 753238405Sjkim#ifndef OPENSSL_NO_SCTP 754238405Sjkim /* Notify SCTP BIO socket to leave handshake 755238405Sjkim * mode and allow stream identifier other 756238405Sjkim * than 0. Will be ignored if no SCTP is used. 757238405Sjkim */ 758238405Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL); 759238405Sjkim#endif 760238405Sjkim 761160814Ssimon if (buf != NULL) 762160814Ssimon BUF_MEM_free(buf); 763160814Ssimon if (cb != NULL) 764160814Ssimon cb(s,SSL_CB_CONNECT_EXIT,ret); 765160814Ssimon return(ret); 766160814Ssimon } 767160814Ssimon 768160814Ssimonint dtls1_client_hello(SSL *s) 769160814Ssimon { 770160814Ssimon unsigned char *buf; 771160814Ssimon unsigned char *p,*d; 772160814Ssimon unsigned int i,j; 773279264Sdelphij unsigned long l; 774160814Ssimon SSL_COMP *comp; 775160814Ssimon 776160814Ssimon buf=(unsigned char *)s->init_buf->data; 777160814Ssimon if (s->state == SSL3_ST_CW_CLNT_HELLO_A) 778160814Ssimon { 779205128Ssimon SSL_SESSION *sess = s->session; 780160814Ssimon if ((s->session == NULL) || 781160814Ssimon (s->session->ssl_version != s->version) || 782205128Ssimon#ifdef OPENSSL_NO_TLSEXT 783205128Ssimon !sess->session_id_length || 784205128Ssimon#else 785205128Ssimon (!sess->session_id_length && !sess->tlsext_tick) || 786205128Ssimon#endif 787160814Ssimon (s->session->not_resumable)) 788160814Ssimon { 789160814Ssimon if (!ssl_get_new_session(s,0)) 790160814Ssimon goto err; 791160814Ssimon } 792160814Ssimon /* else use the pre-loaded session */ 793160814Ssimon 794160814Ssimon p=s->s3->client_random; 795238405Sjkim 796194206Ssimon /* if client_random is initialized, reuse it, we are 797194206Ssimon * required to use same upon reply to HelloVerify */ 798279264Sdelphij for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) 799279264Sdelphij ; 800194206Ssimon if (i==sizeof(s->s3->client_random)) 801279264Sdelphij ssl_fill_hello_random(s, 0, p, 802279264Sdelphij sizeof(s->s3->client_random)); 803160814Ssimon 804160814Ssimon /* Do the message type and length last */ 805160814Ssimon d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); 806160814Ssimon 807160814Ssimon *(p++)=s->version>>8; 808160814Ssimon *(p++)=s->version&0xff; 809160814Ssimon s->client_version=s->version; 810160814Ssimon 811160814Ssimon /* Random stuff */ 812160814Ssimon memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); 813160814Ssimon p+=SSL3_RANDOM_SIZE; 814160814Ssimon 815160814Ssimon /* Session ID */ 816160814Ssimon if (s->new_session) 817160814Ssimon i=0; 818160814Ssimon else 819160814Ssimon i=s->session->session_id_length; 820160814Ssimon *(p++)=i; 821160814Ssimon if (i != 0) 822160814Ssimon { 823160814Ssimon if (i > sizeof s->session->session_id) 824160814Ssimon { 825160814Ssimon SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); 826160814Ssimon goto err; 827160814Ssimon } 828160814Ssimon memcpy(p,s->session->session_id,i); 829160814Ssimon p+=i; 830160814Ssimon } 831160814Ssimon 832160814Ssimon /* cookie stuff */ 833160814Ssimon if ( s->d1->cookie_len > sizeof(s->d1->cookie)) 834160814Ssimon { 835160814Ssimon SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); 836160814Ssimon goto err; 837160814Ssimon } 838160814Ssimon *(p++) = s->d1->cookie_len; 839160814Ssimon memcpy(p, s->d1->cookie, s->d1->cookie_len); 840160814Ssimon p += s->d1->cookie_len; 841160814Ssimon 842160814Ssimon /* Ciphers supported */ 843160814Ssimon i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0); 844160814Ssimon if (i == 0) 845160814Ssimon { 846160814Ssimon SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); 847160814Ssimon goto err; 848160814Ssimon } 849160814Ssimon s2n(i,p); 850160814Ssimon p+=i; 851160814Ssimon 852160814Ssimon /* COMPRESSION */ 853160814Ssimon if (s->ctx->comp_methods == NULL) 854160814Ssimon j=0; 855160814Ssimon else 856160814Ssimon j=sk_SSL_COMP_num(s->ctx->comp_methods); 857160814Ssimon *(p++)=1+j; 858160814Ssimon for (i=0; i<j; i++) 859160814Ssimon { 860160814Ssimon comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); 861160814Ssimon *(p++)=comp->id; 862160814Ssimon } 863160814Ssimon *(p++)=0; /* Add the NULL method */ 864205128Ssimon 865205128Ssimon#ifndef OPENSSL_NO_TLSEXT 866279264Sdelphij /* TLS extensions*/ 867279264Sdelphij if (ssl_prepare_clienthello_tlsext(s) <= 0) 868279264Sdelphij { 869279264Sdelphij SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); 870279264Sdelphij goto err; 871279264Sdelphij } 872205128Ssimon if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) 873205128Ssimon { 874205128Ssimon SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); 875205128Ssimon goto err; 876205128Ssimon } 877279264Sdelphij#endif 878205128Ssimon 879160814Ssimon l=(p-d); 880160814Ssimon d=buf; 881160814Ssimon 882160814Ssimon d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l); 883160814Ssimon 884160814Ssimon s->state=SSL3_ST_CW_CLNT_HELLO_B; 885160814Ssimon /* number of bytes to write */ 886160814Ssimon s->init_num=p-buf; 887160814Ssimon s->init_off=0; 888160814Ssimon 889160814Ssimon /* buffer the message to handle re-xmits */ 890160814Ssimon dtls1_buffer_message(s, 0); 891160814Ssimon } 892160814Ssimon 893160814Ssimon /* SSL3_ST_CW_CLNT_HELLO_B */ 894160814Ssimon return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); 895160814Ssimonerr: 896160814Ssimon return(-1); 897160814Ssimon } 898160814Ssimon 899160814Ssimonstatic int dtls1_get_hello_verify(SSL *s) 900160814Ssimon { 901160814Ssimon int n, al, ok = 0; 902160814Ssimon unsigned char *data; 903160814Ssimon unsigned int cookie_len; 904160814Ssimon 905160814Ssimon n=s->method->ssl_get_message(s, 906160814Ssimon DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, 907160814Ssimon DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, 908160814Ssimon -1, 909160814Ssimon s->max_cert_list, 910160814Ssimon &ok); 911160814Ssimon 912160814Ssimon if (!ok) return((int)n); 913160814Ssimon 914160814Ssimon if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) 915160814Ssimon { 916160814Ssimon s->d1->send_cookie = 0; 917160814Ssimon s->s3->tmp.reuse_message=1; 918160814Ssimon return(1); 919160814Ssimon } 920160814Ssimon 921160814Ssimon data = (unsigned char *)s->init_msg; 922160814Ssimon 923160814Ssimon if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff))) 924160814Ssimon { 925160814Ssimon SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION); 926160814Ssimon s->version=(s->version&0xff00)|data[1]; 927160814Ssimon al = SSL_AD_PROTOCOL_VERSION; 928160814Ssimon goto f_err; 929160814Ssimon } 930160814Ssimon data+=2; 931160814Ssimon 932160814Ssimon cookie_len = *(data++); 933160814Ssimon if ( cookie_len > sizeof(s->d1->cookie)) 934160814Ssimon { 935160814Ssimon al=SSL_AD_ILLEGAL_PARAMETER; 936160814Ssimon goto f_err; 937160814Ssimon } 938160814Ssimon 939160814Ssimon memcpy(s->d1->cookie, data, cookie_len); 940160814Ssimon s->d1->cookie_len = cookie_len; 941160814Ssimon 942160814Ssimon s->d1->send_cookie = 1; 943160814Ssimon return 1; 944160814Ssimon 945160814Ssimonf_err: 946160814Ssimon ssl3_send_alert(s, SSL3_AL_FATAL, al); 947160814Ssimon return -1; 948160814Ssimon } 949160814Ssimon 950160814Ssimonint dtls1_send_client_key_exchange(SSL *s) 951160814Ssimon { 952160814Ssimon unsigned char *p,*d; 953160814Ssimon int n; 954238405Sjkim unsigned long alg_k; 955160814Ssimon#ifndef OPENSSL_NO_RSA 956160814Ssimon unsigned char *q; 957160814Ssimon EVP_PKEY *pkey=NULL; 958160814Ssimon#endif 959160814Ssimon#ifndef OPENSSL_NO_KRB5 960160814Ssimon KSSL_ERR kssl_err; 961160814Ssimon#endif /* OPENSSL_NO_KRB5 */ 962238405Sjkim#ifndef OPENSSL_NO_ECDH 963238405Sjkim EC_KEY *clnt_ecdh = NULL; 964238405Sjkim const EC_POINT *srvr_ecpoint = NULL; 965238405Sjkim EVP_PKEY *srvr_pub_pkey = NULL; 966238405Sjkim unsigned char *encodedPoint = NULL; 967238405Sjkim int encoded_pt_len = 0; 968238405Sjkim BN_CTX * bn_ctx = NULL; 969238405Sjkim#endif 970160814Ssimon 971160814Ssimon if (s->state == SSL3_ST_CW_KEY_EXCH_A) 972160814Ssimon { 973160814Ssimon d=(unsigned char *)s->init_buf->data; 974160814Ssimon p= &(d[DTLS1_HM_HEADER_LENGTH]); 975238405Sjkim 976238405Sjkim alg_k=s->s3->tmp.new_cipher->algorithm_mkey; 977160814Ssimon 978160814Ssimon /* Fool emacs indentation */ 979160814Ssimon if (0) {} 980160814Ssimon#ifndef OPENSSL_NO_RSA 981238405Sjkim else if (alg_k & SSL_kRSA) 982160814Ssimon { 983160814Ssimon RSA *rsa; 984160814Ssimon unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; 985160814Ssimon 986271304Sdelphij if (s->session->sess_cert == NULL) 987271304Sdelphij { 988271304Sdelphij /* We should always have a server certificate with SSL_kRSA. */ 989271304Sdelphij SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 990271304Sdelphij goto err; 991271304Sdelphij } 992271304Sdelphij 993160814Ssimon if (s->session->sess_cert->peer_rsa_tmp != NULL) 994160814Ssimon rsa=s->session->sess_cert->peer_rsa_tmp; 995160814Ssimon else 996160814Ssimon { 997160814Ssimon pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); 998160814Ssimon if ((pkey == NULL) || 999160814Ssimon (pkey->type != EVP_PKEY_RSA) || 1000160814Ssimon (pkey->pkey.rsa == NULL)) 1001160814Ssimon { 1002160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 1003160814Ssimon goto err; 1004160814Ssimon } 1005160814Ssimon rsa=pkey->pkey.rsa; 1006160814Ssimon EVP_PKEY_free(pkey); 1007160814Ssimon } 1008160814Ssimon 1009160814Ssimon tmp_buf[0]=s->client_version>>8; 1010160814Ssimon tmp_buf[1]=s->client_version&0xff; 1011160814Ssimon if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) 1012160814Ssimon goto err; 1013160814Ssimon 1014160814Ssimon s->session->master_key_length=sizeof tmp_buf; 1015160814Ssimon 1016160814Ssimon q=p; 1017194206Ssimon /* Fix buf for TLS and [incidentally] DTLS */ 1018160814Ssimon if (s->version > SSL3_VERSION) 1019160814Ssimon p+=2; 1020160814Ssimon n=RSA_public_encrypt(sizeof tmp_buf, 1021160814Ssimon tmp_buf,p,rsa,RSA_PKCS1_PADDING); 1022160814Ssimon#ifdef PKCS1_CHECK 1023160814Ssimon if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; 1024160814Ssimon if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70; 1025160814Ssimon#endif 1026160814Ssimon if (n <= 0) 1027160814Ssimon { 1028160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT); 1029160814Ssimon goto err; 1030160814Ssimon } 1031160814Ssimon 1032194206Ssimon /* Fix buf for TLS and [incidentally] DTLS */ 1033160814Ssimon if (s->version > SSL3_VERSION) 1034160814Ssimon { 1035160814Ssimon s2n(n,q); 1036160814Ssimon n+=2; 1037160814Ssimon } 1038160814Ssimon 1039160814Ssimon s->session->master_key_length= 1040160814Ssimon s->method->ssl3_enc->generate_master_secret(s, 1041160814Ssimon s->session->master_key, 1042160814Ssimon tmp_buf,sizeof tmp_buf); 1043160814Ssimon OPENSSL_cleanse(tmp_buf,sizeof tmp_buf); 1044160814Ssimon } 1045160814Ssimon#endif 1046160814Ssimon#ifndef OPENSSL_NO_KRB5 1047238405Sjkim else if (alg_k & SSL_kKRB5) 1048160814Ssimon { 1049160814Ssimon krb5_error_code krb5rc; 1050160814Ssimon KSSL_CTX *kssl_ctx = s->kssl_ctx; 1051160814Ssimon /* krb5_data krb5_ap_req; */ 1052160814Ssimon krb5_data *enc_ticket; 1053160814Ssimon krb5_data authenticator, *authp = NULL; 1054160814Ssimon EVP_CIPHER_CTX ciph_ctx; 1055238405Sjkim const EVP_CIPHER *enc = NULL; 1056160814Ssimon unsigned char iv[EVP_MAX_IV_LENGTH]; 1057160814Ssimon unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; 1058160814Ssimon unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH 1059160814Ssimon + EVP_MAX_IV_LENGTH]; 1060160814Ssimon int padl, outl = sizeof(epms); 1061160814Ssimon 1062160814Ssimon EVP_CIPHER_CTX_init(&ciph_ctx); 1063160814Ssimon 1064160814Ssimon#ifdef KSSL_DEBUG 1065160814Ssimon printf("ssl3_send_client_key_exchange(%lx & %lx)\n", 1066238405Sjkim alg_k, SSL_kKRB5); 1067160814Ssimon#endif /* KSSL_DEBUG */ 1068160814Ssimon 1069160814Ssimon authp = NULL; 1070160814Ssimon#ifdef KRB5SENDAUTH 1071160814Ssimon if (KRB5SENDAUTH) authp = &authenticator; 1072160814Ssimon#endif /* KRB5SENDAUTH */ 1073160814Ssimon 1074160814Ssimon krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, 1075160814Ssimon &kssl_err); 1076160814Ssimon enc = kssl_map_enc(kssl_ctx->enctype); 1077160814Ssimon if (enc == NULL) 1078160814Ssimon goto err; 1079160814Ssimon#ifdef KSSL_DEBUG 1080160814Ssimon { 1081160814Ssimon printf("kssl_cget_tkt rtn %d\n", krb5rc); 1082160814Ssimon if (krb5rc && kssl_err.text) 1083160814Ssimon printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); 1084160814Ssimon } 1085160814Ssimon#endif /* KSSL_DEBUG */ 1086160814Ssimon 1087160814Ssimon if (krb5rc) 1088160814Ssimon { 1089160814Ssimon ssl3_send_alert(s,SSL3_AL_FATAL, 1090160814Ssimon SSL_AD_HANDSHAKE_FAILURE); 1091160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1092160814Ssimon kssl_err.reason); 1093160814Ssimon goto err; 1094160814Ssimon } 1095160814Ssimon 1096160814Ssimon /* 20010406 VRS - Earlier versions used KRB5 AP_REQ 1097160814Ssimon ** in place of RFC 2712 KerberosWrapper, as in: 1098160814Ssimon ** 1099160814Ssimon ** Send ticket (copy to *p, set n = length) 1100160814Ssimon ** n = krb5_ap_req.length; 1101160814Ssimon ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); 1102160814Ssimon ** if (krb5_ap_req.data) 1103160814Ssimon ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); 1104160814Ssimon ** 1105160814Ssimon ** Now using real RFC 2712 KerberosWrapper 1106160814Ssimon ** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>) 1107160814Ssimon ** Note: 2712 "opaque" types are here replaced 1108160814Ssimon ** with a 2-byte length followed by the value. 1109160814Ssimon ** Example: 1110160814Ssimon ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms 1111160814Ssimon ** Where "xx xx" = length bytes. Shown here with 1112160814Ssimon ** optional authenticator omitted. 1113160814Ssimon */ 1114160814Ssimon 1115160814Ssimon /* KerberosWrapper.Ticket */ 1116160814Ssimon s2n(enc_ticket->length,p); 1117160814Ssimon memcpy(p, enc_ticket->data, enc_ticket->length); 1118160814Ssimon p+= enc_ticket->length; 1119160814Ssimon n = enc_ticket->length + 2; 1120160814Ssimon 1121160814Ssimon /* KerberosWrapper.Authenticator */ 1122160814Ssimon if (authp && authp->length) 1123160814Ssimon { 1124160814Ssimon s2n(authp->length,p); 1125160814Ssimon memcpy(p, authp->data, authp->length); 1126160814Ssimon p+= authp->length; 1127160814Ssimon n+= authp->length + 2; 1128160814Ssimon 1129160814Ssimon free(authp->data); 1130160814Ssimon authp->data = NULL; 1131160814Ssimon authp->length = 0; 1132160814Ssimon } 1133160814Ssimon else 1134160814Ssimon { 1135160814Ssimon s2n(0,p);/* null authenticator length */ 1136160814Ssimon n+=2; 1137160814Ssimon } 1138160814Ssimon 1139160814Ssimon if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0) 1140160814Ssimon goto err; 1141160814Ssimon 1142160814Ssimon /* 20010420 VRS. Tried it this way; failed. 1143160814Ssimon ** EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); 1144160814Ssimon ** EVP_CIPHER_CTX_set_key_length(&ciph_ctx, 1145160814Ssimon ** kssl_ctx->length); 1146160814Ssimon ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); 1147160814Ssimon */ 1148160814Ssimon 1149160814Ssimon memset(iv, 0, sizeof iv); /* per RFC 1510 */ 1150160814Ssimon EVP_EncryptInit_ex(&ciph_ctx,enc, NULL, 1151160814Ssimon kssl_ctx->key,iv); 1152160814Ssimon EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf, 1153160814Ssimon sizeof tmp_buf); 1154160814Ssimon EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); 1155160814Ssimon outl += padl; 1156238405Sjkim if (outl > (int)sizeof epms) 1157160814Ssimon { 1158160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); 1159160814Ssimon goto err; 1160160814Ssimon } 1161160814Ssimon EVP_CIPHER_CTX_cleanup(&ciph_ctx); 1162160814Ssimon 1163160814Ssimon /* KerberosWrapper.EncryptedPreMasterSecret */ 1164160814Ssimon s2n(outl,p); 1165160814Ssimon memcpy(p, epms, outl); 1166160814Ssimon p+=outl; 1167160814Ssimon n+=outl + 2; 1168160814Ssimon 1169160814Ssimon s->session->master_key_length= 1170160814Ssimon s->method->ssl3_enc->generate_master_secret(s, 1171160814Ssimon s->session->master_key, 1172160814Ssimon tmp_buf, sizeof tmp_buf); 1173160814Ssimon 1174160814Ssimon OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); 1175160814Ssimon OPENSSL_cleanse(epms, outl); 1176160814Ssimon } 1177160814Ssimon#endif 1178160814Ssimon#ifndef OPENSSL_NO_DH 1179238405Sjkim else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) 1180160814Ssimon { 1181160814Ssimon DH *dh_srvr,*dh_clnt; 1182160814Ssimon 1183271304Sdelphij if (s->session->sess_cert == NULL) 1184271304Sdelphij { 1185271304Sdelphij ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); 1186271304Sdelphij SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); 1187271304Sdelphij goto err; 1188271304Sdelphij } 1189271304Sdelphij 1190160814Ssimon if (s->session->sess_cert->peer_dh_tmp != NULL) 1191160814Ssimon dh_srvr=s->session->sess_cert->peer_dh_tmp; 1192160814Ssimon else 1193160814Ssimon { 1194160814Ssimon /* we get them from the cert */ 1195160814Ssimon ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 1196160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); 1197160814Ssimon goto err; 1198160814Ssimon } 1199160814Ssimon 1200160814Ssimon /* generate a new random key */ 1201160814Ssimon if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) 1202160814Ssimon { 1203160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 1204160814Ssimon goto err; 1205160814Ssimon } 1206160814Ssimon if (!DH_generate_key(dh_clnt)) 1207160814Ssimon { 1208160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 1209160814Ssimon goto err; 1210160814Ssimon } 1211160814Ssimon 1212160814Ssimon /* use the 'p' output buffer for the DH key, but 1213160814Ssimon * make sure to clear it out afterwards */ 1214160814Ssimon 1215160814Ssimon n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); 1216160814Ssimon 1217160814Ssimon if (n <= 0) 1218160814Ssimon { 1219160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 1220160814Ssimon goto err; 1221160814Ssimon } 1222160814Ssimon 1223160814Ssimon /* generate master key from the result */ 1224160814Ssimon s->session->master_key_length= 1225160814Ssimon s->method->ssl3_enc->generate_master_secret(s, 1226160814Ssimon s->session->master_key,p,n); 1227160814Ssimon /* clean up */ 1228160814Ssimon memset(p,0,n); 1229160814Ssimon 1230160814Ssimon /* send off the data */ 1231160814Ssimon n=BN_num_bytes(dh_clnt->pub_key); 1232160814Ssimon s2n(n,p); 1233160814Ssimon BN_bn2bin(dh_clnt->pub_key,p); 1234160814Ssimon n+=2; 1235160814Ssimon 1236160814Ssimon DH_free(dh_clnt); 1237160814Ssimon 1238160814Ssimon /* perhaps clean things up a bit EAY EAY EAY EAY*/ 1239160814Ssimon } 1240160814Ssimon#endif 1241238405Sjkim#ifndef OPENSSL_NO_ECDH 1242238405Sjkim else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) 1243238405Sjkim { 1244238405Sjkim const EC_GROUP *srvr_group = NULL; 1245238405Sjkim EC_KEY *tkey; 1246238405Sjkim int ecdh_clnt_cert = 0; 1247238405Sjkim int field_size = 0; 1248238405Sjkim 1249271304Sdelphij if (s->session->sess_cert == NULL) 1250271304Sdelphij { 1251271304Sdelphij ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); 1252271304Sdelphij SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); 1253271304Sdelphij goto err; 1254271304Sdelphij } 1255271304Sdelphij 1256238405Sjkim /* Did we send out the client's 1257238405Sjkim * ECDH share for use in premaster 1258238405Sjkim * computation as part of client certificate? 1259238405Sjkim * If so, set ecdh_clnt_cert to 1. 1260238405Sjkim */ 1261238405Sjkim if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 1262238405Sjkim { 1263238405Sjkim /* XXX: For now, we do not support client 1264238405Sjkim * authentication using ECDH certificates. 1265238405Sjkim * To add such support, one needs to add 1266238405Sjkim * code that checks for appropriate 1267238405Sjkim * conditions and sets ecdh_clnt_cert to 1. 1268238405Sjkim * For example, the cert have an ECC 1269238405Sjkim * key on the same curve as the server's 1270238405Sjkim * and the key should be authorized for 1271238405Sjkim * key agreement. 1272238405Sjkim * 1273238405Sjkim * One also needs to add code in ssl3_connect 1274238405Sjkim * to skip sending the certificate verify 1275238405Sjkim * message. 1276238405Sjkim * 1277238405Sjkim * if ((s->cert->key->privatekey != NULL) && 1278238405Sjkim * (s->cert->key->privatekey->type == 1279238405Sjkim * EVP_PKEY_EC) && ...) 1280238405Sjkim * ecdh_clnt_cert = 1; 1281238405Sjkim */ 1282238405Sjkim } 1283238405Sjkim 1284238405Sjkim if (s->session->sess_cert->peer_ecdh_tmp != NULL) 1285238405Sjkim { 1286238405Sjkim tkey = s->session->sess_cert->peer_ecdh_tmp; 1287238405Sjkim } 1288238405Sjkim else 1289238405Sjkim { 1290238405Sjkim /* Get the Server Public Key from Cert */ 1291238405Sjkim srvr_pub_pkey = X509_get_pubkey(s->session-> \ 1292238405Sjkim sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); 1293238405Sjkim if ((srvr_pub_pkey == NULL) || 1294238405Sjkim (srvr_pub_pkey->type != EVP_PKEY_EC) || 1295238405Sjkim (srvr_pub_pkey->pkey.ec == NULL)) 1296238405Sjkim { 1297238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1298238405Sjkim ERR_R_INTERNAL_ERROR); 1299238405Sjkim goto err; 1300238405Sjkim } 1301238405Sjkim 1302238405Sjkim tkey = srvr_pub_pkey->pkey.ec; 1303238405Sjkim } 1304238405Sjkim 1305238405Sjkim srvr_group = EC_KEY_get0_group(tkey); 1306238405Sjkim srvr_ecpoint = EC_KEY_get0_public_key(tkey); 1307238405Sjkim 1308238405Sjkim if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) 1309238405Sjkim { 1310238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1311238405Sjkim ERR_R_INTERNAL_ERROR); 1312238405Sjkim goto err; 1313238405Sjkim } 1314238405Sjkim 1315238405Sjkim if ((clnt_ecdh=EC_KEY_new()) == NULL) 1316238405Sjkim { 1317238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1318238405Sjkim goto err; 1319238405Sjkim } 1320238405Sjkim 1321238405Sjkim if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) 1322238405Sjkim { 1323238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); 1324238405Sjkim goto err; 1325238405Sjkim } 1326238405Sjkim if (ecdh_clnt_cert) 1327238405Sjkim { 1328238405Sjkim /* Reuse key info from our certificate 1329238405Sjkim * We only need our private key to perform 1330238405Sjkim * the ECDH computation. 1331238405Sjkim */ 1332238405Sjkim const BIGNUM *priv_key; 1333238405Sjkim tkey = s->cert->key->privatekey->pkey.ec; 1334238405Sjkim priv_key = EC_KEY_get0_private_key(tkey); 1335238405Sjkim if (priv_key == NULL) 1336238405Sjkim { 1337238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1338238405Sjkim goto err; 1339238405Sjkim } 1340238405Sjkim if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) 1341238405Sjkim { 1342238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); 1343238405Sjkim goto err; 1344238405Sjkim } 1345238405Sjkim } 1346238405Sjkim else 1347238405Sjkim { 1348238405Sjkim /* Generate a new ECDH key pair */ 1349238405Sjkim if (!(EC_KEY_generate_key(clnt_ecdh))) 1350238405Sjkim { 1351238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); 1352238405Sjkim goto err; 1353238405Sjkim } 1354238405Sjkim } 1355238405Sjkim 1356238405Sjkim /* use the 'p' output buffer for the ECDH key, but 1357238405Sjkim * make sure to clear it out afterwards 1358238405Sjkim */ 1359238405Sjkim 1360238405Sjkim field_size = EC_GROUP_get_degree(srvr_group); 1361238405Sjkim if (field_size <= 0) 1362238405Sjkim { 1363238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1364238405Sjkim ERR_R_ECDH_LIB); 1365238405Sjkim goto err; 1366238405Sjkim } 1367238405Sjkim n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL); 1368238405Sjkim if (n <= 0) 1369238405Sjkim { 1370238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1371238405Sjkim ERR_R_ECDH_LIB); 1372238405Sjkim goto err; 1373238405Sjkim } 1374238405Sjkim 1375238405Sjkim /* generate master key from the result */ 1376238405Sjkim s->session->master_key_length = s->method->ssl3_enc \ 1377238405Sjkim -> generate_master_secret(s, 1378238405Sjkim s->session->master_key, 1379238405Sjkim p, n); 1380238405Sjkim 1381238405Sjkim memset(p, 0, n); /* clean up */ 1382238405Sjkim 1383238405Sjkim if (ecdh_clnt_cert) 1384238405Sjkim { 1385238405Sjkim /* Send empty client key exch message */ 1386238405Sjkim n = 0; 1387238405Sjkim } 1388238405Sjkim else 1389238405Sjkim { 1390238405Sjkim /* First check the size of encoding and 1391238405Sjkim * allocate memory accordingly. 1392238405Sjkim */ 1393238405Sjkim encoded_pt_len = 1394238405Sjkim EC_POINT_point2oct(srvr_group, 1395238405Sjkim EC_KEY_get0_public_key(clnt_ecdh), 1396238405Sjkim POINT_CONVERSION_UNCOMPRESSED, 1397238405Sjkim NULL, 0, NULL); 1398238405Sjkim 1399238405Sjkim encodedPoint = (unsigned char *) 1400238405Sjkim OPENSSL_malloc(encoded_pt_len * 1401238405Sjkim sizeof(unsigned char)); 1402238405Sjkim bn_ctx = BN_CTX_new(); 1403238405Sjkim if ((encodedPoint == NULL) || 1404238405Sjkim (bn_ctx == NULL)) 1405238405Sjkim { 1406238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1407238405Sjkim goto err; 1408238405Sjkim } 1409238405Sjkim 1410238405Sjkim /* Encode the public key */ 1411238405Sjkim n = EC_POINT_point2oct(srvr_group, 1412238405Sjkim EC_KEY_get0_public_key(clnt_ecdh), 1413238405Sjkim POINT_CONVERSION_UNCOMPRESSED, 1414238405Sjkim encodedPoint, encoded_pt_len, bn_ctx); 1415238405Sjkim 1416238405Sjkim *p = n; /* length of encoded point */ 1417238405Sjkim /* Encoded point will be copied here */ 1418238405Sjkim p += 1; 1419238405Sjkim /* copy the point */ 1420238405Sjkim memcpy((unsigned char *)p, encodedPoint, n); 1421238405Sjkim /* increment n to account for length field */ 1422238405Sjkim n += 1; 1423238405Sjkim } 1424238405Sjkim 1425238405Sjkim /* Free allocated memory */ 1426238405Sjkim BN_CTX_free(bn_ctx); 1427238405Sjkim if (encodedPoint != NULL) OPENSSL_free(encodedPoint); 1428238405Sjkim if (clnt_ecdh != NULL) 1429238405Sjkim EC_KEY_free(clnt_ecdh); 1430238405Sjkim EVP_PKEY_free(srvr_pub_pkey); 1431238405Sjkim } 1432238405Sjkim#endif /* !OPENSSL_NO_ECDH */ 1433238405Sjkim 1434238405Sjkim#ifndef OPENSSL_NO_PSK 1435238405Sjkim else if (alg_k & SSL_kPSK) 1436238405Sjkim { 1437238405Sjkim char identity[PSK_MAX_IDENTITY_LEN]; 1438238405Sjkim unsigned char *t = NULL; 1439238405Sjkim unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; 1440238405Sjkim unsigned int pre_ms_len = 0, psk_len = 0; 1441238405Sjkim int psk_err = 1; 1442238405Sjkim 1443238405Sjkim n = 0; 1444238405Sjkim if (s->psk_client_callback == NULL) 1445238405Sjkim { 1446238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1447238405Sjkim SSL_R_PSK_NO_CLIENT_CB); 1448238405Sjkim goto err; 1449238405Sjkim } 1450238405Sjkim 1451238405Sjkim psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, 1452238405Sjkim identity, PSK_MAX_IDENTITY_LEN, 1453238405Sjkim psk_or_pre_ms, sizeof(psk_or_pre_ms)); 1454238405Sjkim if (psk_len > PSK_MAX_PSK_LEN) 1455238405Sjkim { 1456238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1457238405Sjkim ERR_R_INTERNAL_ERROR); 1458238405Sjkim goto psk_err; 1459238405Sjkim } 1460238405Sjkim else if (psk_len == 0) 1461238405Sjkim { 1462238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1463238405Sjkim SSL_R_PSK_IDENTITY_NOT_FOUND); 1464238405Sjkim goto psk_err; 1465238405Sjkim } 1466238405Sjkim 1467238405Sjkim /* create PSK pre_master_secret */ 1468238405Sjkim pre_ms_len = 2+psk_len+2+psk_len; 1469238405Sjkim t = psk_or_pre_ms; 1470238405Sjkim memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); 1471238405Sjkim s2n(psk_len, t); 1472238405Sjkim memset(t, 0, psk_len); 1473238405Sjkim t+=psk_len; 1474238405Sjkim s2n(psk_len, t); 1475238405Sjkim 1476238405Sjkim if (s->session->psk_identity_hint != NULL) 1477238405Sjkim OPENSSL_free(s->session->psk_identity_hint); 1478238405Sjkim s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); 1479238405Sjkim if (s->ctx->psk_identity_hint != NULL && 1480238405Sjkim s->session->psk_identity_hint == NULL) 1481238405Sjkim { 1482238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1483238405Sjkim ERR_R_MALLOC_FAILURE); 1484238405Sjkim goto psk_err; 1485238405Sjkim } 1486238405Sjkim 1487238405Sjkim if (s->session->psk_identity != NULL) 1488238405Sjkim OPENSSL_free(s->session->psk_identity); 1489238405Sjkim s->session->psk_identity = BUF_strdup(identity); 1490238405Sjkim if (s->session->psk_identity == NULL) 1491238405Sjkim { 1492238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 1493238405Sjkim ERR_R_MALLOC_FAILURE); 1494238405Sjkim goto psk_err; 1495238405Sjkim } 1496238405Sjkim 1497238405Sjkim s->session->master_key_length = 1498238405Sjkim s->method->ssl3_enc->generate_master_secret(s, 1499238405Sjkim s->session->master_key, 1500238405Sjkim psk_or_pre_ms, pre_ms_len); 1501238405Sjkim n = strlen(identity); 1502238405Sjkim s2n(n, p); 1503238405Sjkim memcpy(p, identity, n); 1504238405Sjkim n+=2; 1505238405Sjkim psk_err = 0; 1506238405Sjkim psk_err: 1507238405Sjkim OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN); 1508238405Sjkim OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); 1509238405Sjkim if (psk_err != 0) 1510238405Sjkim { 1511238405Sjkim ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); 1512238405Sjkim goto err; 1513238405Sjkim } 1514238405Sjkim } 1515238405Sjkim#endif 1516160814Ssimon else 1517160814Ssimon { 1518160814Ssimon ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 1519160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 1520160814Ssimon goto err; 1521160814Ssimon } 1522160814Ssimon 1523160814Ssimon d = dtls1_set_message_header(s, d, 1524160814Ssimon SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n); 1525160814Ssimon /* 1526160814Ssimon *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE; 1527160814Ssimon l2n3(n,d); 1528160814Ssimon l2n(s->d1->handshake_write_seq,d); 1529160814Ssimon s->d1->handshake_write_seq++; 1530160814Ssimon */ 1531160814Ssimon 1532160814Ssimon s->state=SSL3_ST_CW_KEY_EXCH_B; 1533160814Ssimon /* number of bytes to write */ 1534160814Ssimon s->init_num=n+DTLS1_HM_HEADER_LENGTH; 1535160814Ssimon s->init_off=0; 1536160814Ssimon 1537160814Ssimon /* buffer the message to handle re-xmits */ 1538160814Ssimon dtls1_buffer_message(s, 0); 1539160814Ssimon } 1540160814Ssimon 1541160814Ssimon /* SSL3_ST_CW_KEY_EXCH_B */ 1542160814Ssimon return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); 1543160814Ssimonerr: 1544238405Sjkim#ifndef OPENSSL_NO_ECDH 1545238405Sjkim BN_CTX_free(bn_ctx); 1546238405Sjkim if (encodedPoint != NULL) OPENSSL_free(encodedPoint); 1547238405Sjkim if (clnt_ecdh != NULL) 1548238405Sjkim EC_KEY_free(clnt_ecdh); 1549238405Sjkim EVP_PKEY_free(srvr_pub_pkey); 1550238405Sjkim#endif 1551160814Ssimon return(-1); 1552160814Ssimon } 1553160814Ssimon 1554160814Ssimonint dtls1_send_client_verify(SSL *s) 1555160814Ssimon { 1556160814Ssimon unsigned char *p,*d; 1557160814Ssimon unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; 1558160814Ssimon EVP_PKEY *pkey; 1559160814Ssimon#ifndef OPENSSL_NO_RSA 1560160814Ssimon unsigned u=0; 1561160814Ssimon#endif 1562160814Ssimon unsigned long n; 1563238405Sjkim#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) 1564160814Ssimon int j; 1565160814Ssimon#endif 1566160814Ssimon 1567160814Ssimon if (s->state == SSL3_ST_CW_CERT_VRFY_A) 1568160814Ssimon { 1569160814Ssimon d=(unsigned char *)s->init_buf->data; 1570160814Ssimon p= &(d[DTLS1_HM_HEADER_LENGTH]); 1571160814Ssimon pkey=s->cert->key->privatekey; 1572160814Ssimon 1573238405Sjkim s->method->ssl3_enc->cert_verify_mac(s, 1574238405Sjkim NID_sha1, 1575160814Ssimon &(data[MD5_DIGEST_LENGTH])); 1576160814Ssimon 1577160814Ssimon#ifndef OPENSSL_NO_RSA 1578160814Ssimon if (pkey->type == EVP_PKEY_RSA) 1579160814Ssimon { 1580160814Ssimon s->method->ssl3_enc->cert_verify_mac(s, 1581238405Sjkim NID_md5, 1582238405Sjkim &(data[0])); 1583160814Ssimon if (RSA_sign(NID_md5_sha1, data, 1584160814Ssimon MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, 1585160814Ssimon &(p[2]), &u, pkey->pkey.rsa) <= 0 ) 1586160814Ssimon { 1587160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB); 1588160814Ssimon goto err; 1589160814Ssimon } 1590160814Ssimon s2n(u,p); 1591160814Ssimon n=u+2; 1592160814Ssimon } 1593160814Ssimon else 1594160814Ssimon#endif 1595160814Ssimon#ifndef OPENSSL_NO_DSA 1596160814Ssimon if (pkey->type == EVP_PKEY_DSA) 1597160814Ssimon { 1598160814Ssimon if (!DSA_sign(pkey->save_type, 1599160814Ssimon &(data[MD5_DIGEST_LENGTH]), 1600160814Ssimon SHA_DIGEST_LENGTH,&(p[2]), 1601160814Ssimon (unsigned int *)&j,pkey->pkey.dsa)) 1602160814Ssimon { 1603160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB); 1604160814Ssimon goto err; 1605160814Ssimon } 1606160814Ssimon s2n(j,p); 1607160814Ssimon n=j+2; 1608160814Ssimon } 1609160814Ssimon else 1610160814Ssimon#endif 1611238405Sjkim#ifndef OPENSSL_NO_ECDSA 1612238405Sjkim if (pkey->type == EVP_PKEY_EC) 1613160814Ssimon { 1614238405Sjkim if (!ECDSA_sign(pkey->save_type, 1615238405Sjkim &(data[MD5_DIGEST_LENGTH]), 1616238405Sjkim SHA_DIGEST_LENGTH,&(p[2]), 1617238405Sjkim (unsigned int *)&j,pkey->pkey.ec)) 1618238405Sjkim { 1619238405Sjkim SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, 1620238405Sjkim ERR_R_ECDSA_LIB); 1621238405Sjkim goto err; 1622238405Sjkim } 1623238405Sjkim s2n(j,p); 1624238405Sjkim n=j+2; 1625238405Sjkim } 1626238405Sjkim else 1627238405Sjkim#endif 1628238405Sjkim { 1629160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR); 1630160814Ssimon goto err; 1631160814Ssimon } 1632160814Ssimon 1633160814Ssimon d = dtls1_set_message_header(s, d, 1634160814Ssimon SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ; 1635160814Ssimon 1636160814Ssimon s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH; 1637160814Ssimon s->init_off=0; 1638160814Ssimon 1639160814Ssimon /* buffer the message to handle re-xmits */ 1640160814Ssimon dtls1_buffer_message(s, 0); 1641160814Ssimon 1642160814Ssimon s->state = SSL3_ST_CW_CERT_VRFY_B; 1643160814Ssimon } 1644160814Ssimon 1645160814Ssimon /* s->state = SSL3_ST_CW_CERT_VRFY_B */ 1646160814Ssimon return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); 1647160814Ssimonerr: 1648160814Ssimon return(-1); 1649160814Ssimon } 1650160814Ssimon 1651160814Ssimonint dtls1_send_client_certificate(SSL *s) 1652160814Ssimon { 1653160814Ssimon X509 *x509=NULL; 1654160814Ssimon EVP_PKEY *pkey=NULL; 1655160814Ssimon int i; 1656160814Ssimon unsigned long l; 1657160814Ssimon 1658160814Ssimon if (s->state == SSL3_ST_CW_CERT_A) 1659160814Ssimon { 1660160814Ssimon if ((s->cert == NULL) || 1661160814Ssimon (s->cert->key->x509 == NULL) || 1662160814Ssimon (s->cert->key->privatekey == NULL)) 1663160814Ssimon s->state=SSL3_ST_CW_CERT_B; 1664160814Ssimon else 1665160814Ssimon s->state=SSL3_ST_CW_CERT_C; 1666160814Ssimon } 1667160814Ssimon 1668160814Ssimon /* We need to get a client cert */ 1669160814Ssimon if (s->state == SSL3_ST_CW_CERT_B) 1670160814Ssimon { 1671160814Ssimon /* If we get an error, we need to 1672160814Ssimon * ssl->rwstate=SSL_X509_LOOKUP; return(-1); 1673160814Ssimon * We then get retied later */ 1674160814Ssimon i=0; 1675194206Ssimon i = ssl_do_client_cert_cb(s, &x509, &pkey); 1676160814Ssimon if (i < 0) 1677160814Ssimon { 1678160814Ssimon s->rwstate=SSL_X509_LOOKUP; 1679160814Ssimon return(-1); 1680160814Ssimon } 1681160814Ssimon s->rwstate=SSL_NOTHING; 1682160814Ssimon if ((i == 1) && (pkey != NULL) && (x509 != NULL)) 1683160814Ssimon { 1684160814Ssimon s->state=SSL3_ST_CW_CERT_B; 1685160814Ssimon if ( !SSL_use_certificate(s,x509) || 1686160814Ssimon !SSL_use_PrivateKey(s,pkey)) 1687160814Ssimon i=0; 1688160814Ssimon } 1689160814Ssimon else if (i == 1) 1690160814Ssimon { 1691160814Ssimon i=0; 1692160814Ssimon SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); 1693160814Ssimon } 1694160814Ssimon 1695160814Ssimon if (x509 != NULL) X509_free(x509); 1696160814Ssimon if (pkey != NULL) EVP_PKEY_free(pkey); 1697160814Ssimon if (i == 0) 1698160814Ssimon { 1699160814Ssimon if (s->version == SSL3_VERSION) 1700160814Ssimon { 1701160814Ssimon s->s3->tmp.cert_req=0; 1702160814Ssimon ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE); 1703160814Ssimon return(1); 1704160814Ssimon } 1705160814Ssimon else 1706160814Ssimon { 1707160814Ssimon s->s3->tmp.cert_req=2; 1708160814Ssimon } 1709160814Ssimon } 1710160814Ssimon 1711160814Ssimon /* Ok, we have a cert */ 1712160814Ssimon s->state=SSL3_ST_CW_CERT_C; 1713160814Ssimon } 1714160814Ssimon 1715160814Ssimon if (s->state == SSL3_ST_CW_CERT_C) 1716160814Ssimon { 1717160814Ssimon s->state=SSL3_ST_CW_CERT_D; 1718160814Ssimon l=dtls1_output_cert_chain(s, 1719160814Ssimon (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); 1720279264Sdelphij if (!l) 1721279264Sdelphij { 1722279264Sdelphij SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); 1723279264Sdelphij ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); 1724279264Sdelphij return 0; 1725279264Sdelphij } 1726160814Ssimon s->init_num=(int)l; 1727160814Ssimon s->init_off=0; 1728160814Ssimon 1729160814Ssimon /* set header called by dtls1_output_cert_chain() */ 1730160814Ssimon 1731160814Ssimon /* buffer the message to handle re-xmits */ 1732160814Ssimon dtls1_buffer_message(s, 0); 1733160814Ssimon } 1734160814Ssimon /* SSL3_ST_CW_CERT_D */ 1735160814Ssimon return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); 1736160814Ssimon } 1737