1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libssl/src/d1_clnt.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1171 @@
1.4 +/* ssl/d1_clnt.c */
1.5 +/*
1.6 + * DTLS implementation written by Nagendra Modadugu
1.7 + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
1.8 + */
1.9 +/* ====================================================================
1.10 + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
1.11 + *
1.12 + * Redistribution and use in source and binary forms, with or without
1.13 + * modification, are permitted provided that the following conditions
1.14 + * are met:
1.15 + *
1.16 + * 1. Redistributions of source code must retain the above copyright
1.17 + * notice, this list of conditions and the following disclaimer.
1.18 + *
1.19 + * 2. Redistributions in binary form must reproduce the above copyright
1.20 + * notice, this list of conditions and the following disclaimer in
1.21 + * the documentation and/or other materials provided with the
1.22 + * distribution.
1.23 + *
1.24 + * 3. All advertising materials mentioning features or use of this
1.25 + * software must display the following acknowledgment:
1.26 + * "This product includes software developed by the OpenSSL Project
1.27 + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
1.28 + *
1.29 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.30 + * endorse or promote products derived from this software without
1.31 + * prior written permission. For written permission, please contact
1.32 + * openssl-core@OpenSSL.org.
1.33 + *
1.34 + * 5. Products derived from this software may not be called "OpenSSL"
1.35 + * nor may "OpenSSL" appear in their names without prior written
1.36 + * permission of the OpenSSL Project.
1.37 + *
1.38 + * 6. Redistributions of any form whatsoever must retain the following
1.39 + * acknowledgment:
1.40 + * "This product includes software developed by the OpenSSL Project
1.41 + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
1.42 + *
1.43 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.44 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.45 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.46 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.47 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.48 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.49 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.50 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.52 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.53 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.54 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.55 + * ====================================================================
1.56 + *
1.57 + * This product includes cryptographic software written by Eric Young
1.58 + * (eay@cryptsoft.com). This product includes software written by Tim
1.59 + * Hudson (tjh@cryptsoft.com).
1.60 + *
1.61 + */
1.62 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.63 + * All rights reserved.
1.64 + *
1.65 + * This package is an SSL implementation written
1.66 + * by Eric Young (eay@cryptsoft.com).
1.67 + * The implementation was written so as to conform with Netscapes SSL.
1.68 + *
1.69 + * This library is free for commercial and non-commercial use as long as
1.70 + * the following conditions are aheared to. The following conditions
1.71 + * apply to all code found in this distribution, be it the RC4, RSA,
1.72 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.73 + * included with this distribution is covered by the same copyright terms
1.74 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.75 + *
1.76 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.77 + * the code are not to be removed.
1.78 + * If this package is used in a product, Eric Young should be given attribution
1.79 + * as the author of the parts of the library used.
1.80 + * This can be in the form of a textual message at program startup or
1.81 + * in documentation (online or textual) provided with the package.
1.82 + *
1.83 + * Redistribution and use in source and binary forms, with or without
1.84 + * modification, are permitted provided that the following conditions
1.85 + * are met:
1.86 + * 1. Redistributions of source code must retain the copyright
1.87 + * notice, this list of conditions and the following disclaimer.
1.88 + * 2. Redistributions in binary form must reproduce the above copyright
1.89 + * notice, this list of conditions and the following disclaimer in the
1.90 + * documentation and/or other materials provided with the distribution.
1.91 + * 3. All advertising materials mentioning features or use of this software
1.92 + * must display the following acknowledgement:
1.93 + * "This product includes cryptographic software written by
1.94 + * Eric Young (eay@cryptsoft.com)"
1.95 + * The word 'cryptographic' can be left out if the rouines from the library
1.96 + * being used are not cryptographic related :-).
1.97 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.98 + * the apps directory (application code) you must include an acknowledgement:
1.99 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.100 + *
1.101 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.102 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.103 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.104 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.105 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.106 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.107 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.108 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.109 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.110 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.111 + * SUCH DAMAGE.
1.112 + *
1.113 + * The licence and distribution terms for any publically available version or
1.114 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.115 + * copied and put under another distribution licence
1.116 + * [including the GNU Public Licence.]
1.117 + */
1.118 +/*
1.119 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.120 + */
1.121 +
1.122 +#include <stdio.h>
1.123 +#include "ssl_locl.h"
1.124 +#include "kssl_lcl.h"
1.125 +#include <openssl/buffer.h>
1.126 +#include <openssl/rand.h>
1.127 +#include <openssl/objects.h>
1.128 +#include <openssl/evp.h>
1.129 +#include <openssl/md5.h>
1.130 +#ifndef OPENSSL_NO_DH
1.131 +#include <openssl/dh.h>
1.132 +#endif
1.133 +
1.134 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.135 +#include "libssl_wsd.h"
1.136 +#endif
1.137 +
1.138 +#ifdef EMULATOR
1.139 +
1.140 + GET_STATIC_VAR_FROM_TLS(DTLSv1_client_method_data,d1_clnt,SSL_METHOD)
1.141 +
1.142 + #define DTLSv1_client_method_data (*GET_WSD_VAR_NAME(DTLSv1_client_method_data,d1_clnt,s)())
1.143 +
1.144 +#endif
1.145 +
1.146 +static SSL_METHOD *dtls1_get_client_method(int ver);
1.147 +static int dtls1_get_hello_verify(SSL *s);
1.148 +
1.149 +static SSL_METHOD *dtls1_get_client_method(int ver)
1.150 + {
1.151 + if (ver == DTLS1_VERSION)
1.152 + return(DTLSv1_client_method());
1.153 + else
1.154 + return(NULL);
1.155 + }
1.156 +
1.157 +EXPORT_C IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
1.158 + ssl_undefined_function,
1.159 + dtls1_connect,
1.160 + dtls1_get_client_method)
1.161 +
1.162 +int dtls1_connect(SSL *s)
1.163 + {
1.164 + BUF_MEM *buf=NULL;
1.165 + unsigned long Time=(unsigned long)time(NULL),l;
1.166 + long num1;
1.167 + void (*cb)(const SSL *ssl,int type,int val)=NULL;
1.168 + int ret= -1;
1.169 + int new_state,state,skip=0;;
1.170 +
1.171 + RAND_add(&Time,sizeof(Time),0);
1.172 + ERR_clear_error();
1.173 + clear_sys_error();
1.174 +
1.175 + if (s->info_callback != NULL)
1.176 + cb=s->info_callback;
1.177 + else if (s->ctx->info_callback != NULL)
1.178 + cb=s->ctx->info_callback;
1.179 +
1.180 + s->in_handshake++;
1.181 + if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
1.182 +
1.183 + for (;;)
1.184 + {
1.185 + state=s->state;
1.186 +
1.187 + switch(s->state)
1.188 + {
1.189 + case SSL_ST_RENEGOTIATE:
1.190 + s->new_session=1;
1.191 + s->state=SSL_ST_CONNECT;
1.192 + s->ctx->stats.sess_connect_renegotiate++;
1.193 + /* break */
1.194 + case SSL_ST_BEFORE:
1.195 + case SSL_ST_CONNECT:
1.196 + case SSL_ST_BEFORE|SSL_ST_CONNECT:
1.197 + case SSL_ST_OK|SSL_ST_CONNECT:
1.198 +
1.199 + s->server=0;
1.200 + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
1.201 +
1.202 + if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00))
1.203 + {
1.204 + SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
1.205 + ret = -1;
1.206 + goto end;
1.207 + }
1.208 +
1.209 + /* s->version=SSL3_VERSION; */
1.210 + s->type=SSL_ST_CONNECT;
1.211 +
1.212 + if (s->init_buf == NULL)
1.213 + {
1.214 + if ((buf=BUF_MEM_new()) == NULL)
1.215 + {
1.216 + ret= -1;
1.217 + goto end;
1.218 + }
1.219 + if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
1.220 + {
1.221 + ret= -1;
1.222 + goto end;
1.223 + }
1.224 + s->init_buf=buf;
1.225 + buf=NULL;
1.226 + }
1.227 +
1.228 + if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
1.229 +
1.230 + /* setup buffing BIO */
1.231 + if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
1.232 +
1.233 + /* don't push the buffering BIO quite yet */
1.234 +
1.235 + s->state=SSL3_ST_CW_CLNT_HELLO_A;
1.236 + s->ctx->stats.sess_connect++;
1.237 + s->init_num=0;
1.238 + /* mark client_random uninitialized */
1.239 + memset(s->s3->client_random,0,sizeof(s->s3->client_random));
1.240 + break;
1.241 +
1.242 + case SSL3_ST_CW_CLNT_HELLO_A:
1.243 + case SSL3_ST_CW_CLNT_HELLO_B:
1.244 +
1.245 + s->shutdown=0;
1.246 +
1.247 + /* every DTLS ClientHello resets Finished MAC */
1.248 + ssl3_init_finished_mac(s);
1.249 +
1.250 + ret=dtls1_client_hello(s);
1.251 + if (ret <= 0) goto end;
1.252 +
1.253 + if ( s->d1->send_cookie)
1.254 + {
1.255 + s->state=SSL3_ST_CW_FLUSH;
1.256 + s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
1.257 + }
1.258 + else
1.259 + s->state=SSL3_ST_CR_SRVR_HELLO_A;
1.260 +
1.261 + s->init_num=0;
1.262 +
1.263 + /* turn on buffering for the next lot of output */
1.264 + if (s->bbio != s->wbio)
1.265 + s->wbio=BIO_push(s->bbio,s->wbio);
1.266 +
1.267 + break;
1.268 +
1.269 + case SSL3_ST_CR_SRVR_HELLO_A:
1.270 + case SSL3_ST_CR_SRVR_HELLO_B:
1.271 + ret=ssl3_get_server_hello(s);
1.272 + if (ret <= 0) goto end;
1.273 + else
1.274 + {
1.275 + if (s->hit)
1.276 + s->state=SSL3_ST_CR_FINISHED_A;
1.277 + else
1.278 + s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
1.279 + }
1.280 + s->init_num=0;
1.281 + break;
1.282 +
1.283 + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
1.284 + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
1.285 +
1.286 + ret = dtls1_get_hello_verify(s);
1.287 + if ( ret <= 0)
1.288 + goto end;
1.289 + if ( s->d1->send_cookie) /* start again, with a cookie */
1.290 + s->state=SSL3_ST_CW_CLNT_HELLO_A;
1.291 + else
1.292 + s->state = SSL3_ST_CR_CERT_A;
1.293 + s->init_num = 0;
1.294 + break;
1.295 +
1.296 + case SSL3_ST_CR_CERT_A:
1.297 + case SSL3_ST_CR_CERT_B:
1.298 + /* Check if it is anon DH */
1.299 + if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
1.300 + {
1.301 + ret=ssl3_get_server_certificate(s);
1.302 + if (ret <= 0) goto end;
1.303 + }
1.304 + else
1.305 + skip=1;
1.306 + s->state=SSL3_ST_CR_KEY_EXCH_A;
1.307 + s->init_num=0;
1.308 + break;
1.309 +
1.310 + case SSL3_ST_CR_KEY_EXCH_A:
1.311 + case SSL3_ST_CR_KEY_EXCH_B:
1.312 + ret=ssl3_get_key_exchange(s);
1.313 + if (ret <= 0) goto end;
1.314 + s->state=SSL3_ST_CR_CERT_REQ_A;
1.315 + s->init_num=0;
1.316 +
1.317 + /* at this point we check that we have the
1.318 + * required stuff from the server */
1.319 + if (!ssl3_check_cert_and_algorithm(s))
1.320 + {
1.321 + ret= -1;
1.322 + goto end;
1.323 + }
1.324 + break;
1.325 +
1.326 + case SSL3_ST_CR_CERT_REQ_A:
1.327 + case SSL3_ST_CR_CERT_REQ_B:
1.328 + ret=ssl3_get_certificate_request(s);
1.329 + if (ret <= 0) goto end;
1.330 + s->state=SSL3_ST_CR_SRVR_DONE_A;
1.331 + s->init_num=0;
1.332 + break;
1.333 +
1.334 + case SSL3_ST_CR_SRVR_DONE_A:
1.335 + case SSL3_ST_CR_SRVR_DONE_B:
1.336 + ret=ssl3_get_server_done(s);
1.337 + if (ret <= 0) goto end;
1.338 + if (s->s3->tmp.cert_req)
1.339 + s->state=SSL3_ST_CW_CERT_A;
1.340 + else
1.341 + s->state=SSL3_ST_CW_KEY_EXCH_A;
1.342 + s->init_num=0;
1.343 +
1.344 + break;
1.345 +
1.346 + case SSL3_ST_CW_CERT_A:
1.347 + case SSL3_ST_CW_CERT_B:
1.348 + case SSL3_ST_CW_CERT_C:
1.349 + case SSL3_ST_CW_CERT_D:
1.350 + ret=dtls1_send_client_certificate(s);
1.351 + if (ret <= 0) goto end;
1.352 + s->state=SSL3_ST_CW_KEY_EXCH_A;
1.353 + s->init_num=0;
1.354 + break;
1.355 +
1.356 + case SSL3_ST_CW_KEY_EXCH_A:
1.357 + case SSL3_ST_CW_KEY_EXCH_B:
1.358 + ret=dtls1_send_client_key_exchange(s);
1.359 + if (ret <= 0) goto end;
1.360 + l=s->s3->tmp.new_cipher->algorithms;
1.361 + /* EAY EAY EAY need to check for DH fix cert
1.362 + * sent back */
1.363 + /* For TLS, cert_req is set to 2, so a cert chain
1.364 + * of nothing is sent, but no verify packet is sent */
1.365 + if (s->s3->tmp.cert_req == 1)
1.366 + {
1.367 + s->state=SSL3_ST_CW_CERT_VRFY_A;
1.368 + }
1.369 + else
1.370 + {
1.371 + s->state=SSL3_ST_CW_CHANGE_A;
1.372 + s->s3->change_cipher_spec=0;
1.373 + }
1.374 +
1.375 + s->init_num=0;
1.376 + break;
1.377 +
1.378 + case SSL3_ST_CW_CERT_VRFY_A:
1.379 + case SSL3_ST_CW_CERT_VRFY_B:
1.380 + ret=dtls1_send_client_verify(s);
1.381 + if (ret <= 0) goto end;
1.382 + s->state=SSL3_ST_CW_CHANGE_A;
1.383 + s->init_num=0;
1.384 + s->s3->change_cipher_spec=0;
1.385 + break;
1.386 +
1.387 + case SSL3_ST_CW_CHANGE_A:
1.388 + case SSL3_ST_CW_CHANGE_B:
1.389 + ret=dtls1_send_change_cipher_spec(s,
1.390 + SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
1.391 + if (ret <= 0) goto end;
1.392 + s->state=SSL3_ST_CW_FINISHED_A;
1.393 + s->init_num=0;
1.394 +
1.395 + s->session->cipher=s->s3->tmp.new_cipher;
1.396 +#ifdef OPENSSL_NO_COMP
1.397 + s->session->compress_meth=0;
1.398 +#else
1.399 + if (s->s3->tmp.new_compression == NULL)
1.400 + s->session->compress_meth=0;
1.401 + else
1.402 + s->session->compress_meth=
1.403 + s->s3->tmp.new_compression->id;
1.404 +#endif
1.405 + if (!s->method->ssl3_enc->setup_key_block(s))
1.406 + {
1.407 + ret= -1;
1.408 + goto end;
1.409 + }
1.410 +
1.411 + if (!s->method->ssl3_enc->change_cipher_state(s,
1.412 + SSL3_CHANGE_CIPHER_CLIENT_WRITE))
1.413 + {
1.414 + ret= -1;
1.415 + goto end;
1.416 + }
1.417 +
1.418 + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
1.419 + break;
1.420 +
1.421 + case SSL3_ST_CW_FINISHED_A:
1.422 + case SSL3_ST_CW_FINISHED_B:
1.423 + ret=dtls1_send_finished(s,
1.424 + SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
1.425 + s->method->ssl3_enc->client_finished_label,
1.426 + s->method->ssl3_enc->client_finished_label_len);
1.427 + if (ret <= 0) goto end;
1.428 + s->state=SSL3_ST_CW_FLUSH;
1.429 +
1.430 + /* clear flags */
1.431 + s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
1.432 + if (s->hit)
1.433 + {
1.434 + s->s3->tmp.next_state=SSL_ST_OK;
1.435 + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
1.436 + {
1.437 + s->state=SSL_ST_OK;
1.438 + s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
1.439 + s->s3->delay_buf_pop_ret=0;
1.440 + }
1.441 + }
1.442 + else
1.443 + {
1.444 + s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
1.445 + }
1.446 + s->init_num=0;
1.447 + /* mark client_random uninitialized */
1.448 + memset (s->s3->client_random,0,sizeof(s->s3->client_random));
1.449 +
1.450 + break;
1.451 +
1.452 + case SSL3_ST_CR_FINISHED_A:
1.453 + case SSL3_ST_CR_FINISHED_B:
1.454 +
1.455 + ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
1.456 + SSL3_ST_CR_FINISHED_B);
1.457 + if (ret <= 0) goto end;
1.458 +
1.459 + if (s->hit)
1.460 + s->state=SSL3_ST_CW_CHANGE_A;
1.461 + else
1.462 + s->state=SSL_ST_OK;
1.463 + s->init_num=0;
1.464 + break;
1.465 +
1.466 + case SSL3_ST_CW_FLUSH:
1.467 + /* number of bytes to be flushed */
1.468 + num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
1.469 + if (num1 > 0)
1.470 + {
1.471 + s->rwstate=SSL_WRITING;
1.472 + num1=BIO_flush(s->wbio);
1.473 + if (num1 <= 0) { ret= -1; goto end; }
1.474 + s->rwstate=SSL_NOTHING;
1.475 + }
1.476 +
1.477 + s->state=s->s3->tmp.next_state;
1.478 + break;
1.479 +
1.480 + case SSL_ST_OK:
1.481 + /* clean a few things up */
1.482 + ssl3_cleanup_key_block(s);
1.483 +
1.484 +#if 0
1.485 + if (s->init_buf != NULL)
1.486 + {
1.487 + BUF_MEM_free(s->init_buf);
1.488 + s->init_buf=NULL;
1.489 + }
1.490 +#endif
1.491 +
1.492 + /* If we are not 'joining' the last two packets,
1.493 + * remove the buffering now */
1.494 + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
1.495 + ssl_free_wbio_buffer(s);
1.496 + /* else do it later in ssl3_write */
1.497 +
1.498 + s->init_num=0;
1.499 + s->new_session=0;
1.500 +
1.501 + ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
1.502 + if (s->hit) s->ctx->stats.sess_hit++;
1.503 +
1.504 + ret=1;
1.505 + /* s->server=0; */
1.506 + s->handshake_func=dtls1_connect;
1.507 + s->ctx->stats.sess_connect_good++;
1.508 +
1.509 + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
1.510 +
1.511 + /* done with handshaking */
1.512 + s->d1->handshake_read_seq = 0;
1.513 + goto end;
1.514 + /* break; */
1.515 +
1.516 + default:
1.517 + SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
1.518 + ret= -1;
1.519 + goto end;
1.520 + /* break; */
1.521 + }
1.522 +
1.523 + /* did we do anything */
1.524 + if (!s->s3->tmp.reuse_message && !skip)
1.525 + {
1.526 + if (s->debug)
1.527 + {
1.528 + if ((ret=BIO_flush(s->wbio)) <= 0)
1.529 + goto end;
1.530 + }
1.531 +
1.532 + if ((cb != NULL) && (s->state != state))
1.533 + {
1.534 + new_state=s->state;
1.535 + s->state=state;
1.536 + cb(s,SSL_CB_CONNECT_LOOP,1);
1.537 + s->state=new_state;
1.538 + }
1.539 + }
1.540 + skip=0;
1.541 + }
1.542 +end:
1.543 + s->in_handshake--;
1.544 + if (buf != NULL)
1.545 + BUF_MEM_free(buf);
1.546 + if (cb != NULL)
1.547 + cb(s,SSL_CB_CONNECT_EXIT,ret);
1.548 + return(ret);
1.549 + }
1.550 +
1.551 +int dtls1_client_hello(SSL *s)
1.552 + {
1.553 + unsigned char *buf;
1.554 + unsigned char *p,*d;
1.555 + unsigned int i,j;
1.556 + unsigned long Time,l;
1.557 + SSL_COMP *comp;
1.558 +
1.559 + buf=(unsigned char *)s->init_buf->data;
1.560 + if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
1.561 + {
1.562 + if ((s->session == NULL) ||
1.563 + (s->session->ssl_version != s->version) ||
1.564 + (s->session->not_resumable))
1.565 + {
1.566 + if (!ssl_get_new_session(s,0))
1.567 + goto err;
1.568 + }
1.569 + /* else use the pre-loaded session */
1.570 +
1.571 + p=s->s3->client_random;
1.572 + /* if client_random is initialized, reuse it, we are
1.573 + * required to use same upon reply to HelloVerify */
1.574 + for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
1.575 + if (i==sizeof(s->s3->client_random))
1.576 + {
1.577 + Time=(unsigned long)time(NULL); /* Time */
1.578 + l2n(Time,p);
1.579 + RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
1.580 + }
1.581 +
1.582 + /* Do the message type and length last */
1.583 + d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
1.584 +
1.585 + *(p++)=s->version>>8;
1.586 + *(p++)=s->version&0xff;
1.587 + s->client_version=s->version;
1.588 +
1.589 + /* Random stuff */
1.590 + memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
1.591 + p+=SSL3_RANDOM_SIZE;
1.592 +
1.593 + /* Session ID */
1.594 + if (s->new_session)
1.595 + i=0;
1.596 + else
1.597 + i=s->session->session_id_length;
1.598 + *(p++)=i;
1.599 + if (i != 0)
1.600 + {
1.601 + if (i > sizeof s->session->session_id)
1.602 + {
1.603 + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
1.604 + goto err;
1.605 + }
1.606 + memcpy(p,s->session->session_id,i);
1.607 + p+=i;
1.608 + }
1.609 +
1.610 + /* cookie stuff */
1.611 + if ( s->d1->cookie_len > sizeof(s->d1->cookie))
1.612 + {
1.613 + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
1.614 + goto err;
1.615 + }
1.616 + *(p++) = s->d1->cookie_len;
1.617 + memcpy(p, s->d1->cookie, s->d1->cookie_len);
1.618 + p += s->d1->cookie_len;
1.619 +
1.620 + /* Ciphers supported */
1.621 + i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
1.622 + if (i == 0)
1.623 + {
1.624 + SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
1.625 + goto err;
1.626 + }
1.627 + s2n(i,p);
1.628 + p+=i;
1.629 +
1.630 + /* COMPRESSION */
1.631 + if (s->ctx->comp_methods == NULL)
1.632 + j=0;
1.633 + else
1.634 + j=sk_SSL_COMP_num(s->ctx->comp_methods);
1.635 + *(p++)=1+j;
1.636 + for (i=0; i<j; i++)
1.637 + {
1.638 + comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
1.639 + *(p++)=comp->id;
1.640 + }
1.641 + *(p++)=0; /* Add the NULL method */
1.642 +
1.643 + l=(p-d);
1.644 + d=buf;
1.645 +
1.646 + d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
1.647 +
1.648 + s->state=SSL3_ST_CW_CLNT_HELLO_B;
1.649 + /* number of bytes to write */
1.650 + s->init_num=p-buf;
1.651 + s->init_off=0;
1.652 +
1.653 + /* buffer the message to handle re-xmits */
1.654 + dtls1_buffer_message(s, 0);
1.655 + }
1.656 +
1.657 + /* SSL3_ST_CW_CLNT_HELLO_B */
1.658 + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1.659 +err:
1.660 + return(-1);
1.661 + }
1.662 +
1.663 +static int dtls1_get_hello_verify(SSL *s)
1.664 + {
1.665 + int n, al, ok = 0;
1.666 + unsigned char *data;
1.667 + unsigned int cookie_len;
1.668 +
1.669 + n=s->method->ssl_get_message(s,
1.670 + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
1.671 + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
1.672 + -1,
1.673 + s->max_cert_list,
1.674 + &ok);
1.675 +
1.676 + if (!ok) return((int)n);
1.677 +
1.678 + if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
1.679 + {
1.680 + s->d1->send_cookie = 0;
1.681 + s->s3->tmp.reuse_message=1;
1.682 + return(1);
1.683 + }
1.684 +
1.685 + data = (unsigned char *)s->init_msg;
1.686 +
1.687 + if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff)))
1.688 + {
1.689 + SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
1.690 + s->version=(s->version&0xff00)|data[1];
1.691 + al = SSL_AD_PROTOCOL_VERSION;
1.692 + goto f_err;
1.693 + }
1.694 + data+=2;
1.695 +
1.696 + cookie_len = *(data++);
1.697 + if ( cookie_len > sizeof(s->d1->cookie))
1.698 + {
1.699 + al=SSL_AD_ILLEGAL_PARAMETER;
1.700 + goto f_err;
1.701 + }
1.702 +
1.703 + memcpy(s->d1->cookie, data, cookie_len);
1.704 + s->d1->cookie_len = cookie_len;
1.705 +
1.706 + s->d1->send_cookie = 1;
1.707 + return 1;
1.708 +
1.709 +f_err:
1.710 + ssl3_send_alert(s, SSL3_AL_FATAL, al);
1.711 + return -1;
1.712 + }
1.713 +
1.714 +int dtls1_send_client_key_exchange(SSL *s)
1.715 + {
1.716 + unsigned char *p,*d;
1.717 + int n;
1.718 + unsigned long l;
1.719 +#ifndef OPENSSL_NO_RSA
1.720 + unsigned char *q;
1.721 + EVP_PKEY *pkey=NULL;
1.722 +#endif
1.723 +#ifndef OPENSSL_NO_KRB5
1.724 + KSSL_ERR kssl_err;
1.725 +#endif /* OPENSSL_NO_KRB5 */
1.726 +
1.727 + if (s->state == SSL3_ST_CW_KEY_EXCH_A)
1.728 + {
1.729 + d=(unsigned char *)s->init_buf->data;
1.730 + p= &(d[DTLS1_HM_HEADER_LENGTH]);
1.731 +
1.732 + l=s->s3->tmp.new_cipher->algorithms;
1.733 +
1.734 + /* Fool emacs indentation */
1.735 + if (0) {}
1.736 +#ifndef OPENSSL_NO_RSA
1.737 + else if (l & SSL_kRSA)
1.738 + {
1.739 + RSA *rsa;
1.740 + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
1.741 +
1.742 + if (s->session->sess_cert->peer_rsa_tmp != NULL)
1.743 + rsa=s->session->sess_cert->peer_rsa_tmp;
1.744 + else
1.745 + {
1.746 + pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
1.747 + if ((pkey == NULL) ||
1.748 + (pkey->type != EVP_PKEY_RSA) ||
1.749 + (pkey->pkey.rsa == NULL))
1.750 + {
1.751 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
1.752 + goto err;
1.753 + }
1.754 + rsa=pkey->pkey.rsa;
1.755 + EVP_PKEY_free(pkey);
1.756 + }
1.757 +
1.758 + tmp_buf[0]=s->client_version>>8;
1.759 + tmp_buf[1]=s->client_version&0xff;
1.760 + if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
1.761 + goto err;
1.762 +
1.763 + s->session->master_key_length=sizeof tmp_buf;
1.764 +
1.765 + q=p;
1.766 + /* Fix buf for TLS and [incidentally] DTLS */
1.767 + if (s->version > SSL3_VERSION)
1.768 + p+=2;
1.769 + n=RSA_public_encrypt(sizeof tmp_buf,
1.770 + tmp_buf,p,rsa,RSA_PKCS1_PADDING);
1.771 +#ifdef PKCS1_CHECK
1.772 + if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
1.773 + if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
1.774 +#endif
1.775 + if (n <= 0)
1.776 + {
1.777 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
1.778 + goto err;
1.779 + }
1.780 +
1.781 + /* Fix buf for TLS and [incidentally] DTLS */
1.782 + if (s->version > SSL3_VERSION)
1.783 + {
1.784 + s2n(n,q);
1.785 + n+=2;
1.786 + }
1.787 +
1.788 + s->session->master_key_length=
1.789 + s->method->ssl3_enc->generate_master_secret(s,
1.790 + s->session->master_key,
1.791 + tmp_buf,sizeof tmp_buf);
1.792 + OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
1.793 + }
1.794 +#endif
1.795 +#ifndef OPENSSL_NO_KRB5
1.796 + else if (l & SSL_kKRB5)
1.797 + {
1.798 + krb5_error_code krb5rc;
1.799 + KSSL_CTX *kssl_ctx = s->kssl_ctx;
1.800 + /* krb5_data krb5_ap_req; */
1.801 + krb5_data *enc_ticket;
1.802 + krb5_data authenticator, *authp = NULL;
1.803 + EVP_CIPHER_CTX ciph_ctx;
1.804 + EVP_CIPHER *enc = NULL;
1.805 + unsigned char iv[EVP_MAX_IV_LENGTH];
1.806 + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
1.807 + unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH
1.808 + + EVP_MAX_IV_LENGTH];
1.809 + int padl, outl = sizeof(epms);
1.810 +
1.811 + EVP_CIPHER_CTX_init(&ciph_ctx);
1.812 +
1.813 +#ifdef KSSL_DEBUG
1.814 + printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
1.815 + l, SSL_kKRB5);
1.816 +#endif /* KSSL_DEBUG */
1.817 +
1.818 + authp = NULL;
1.819 +#ifdef KRB5SENDAUTH
1.820 + if (KRB5SENDAUTH) authp = &authenticator;
1.821 +#endif /* KRB5SENDAUTH */
1.822 +
1.823 + krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
1.824 + &kssl_err);
1.825 + enc = kssl_map_enc(kssl_ctx->enctype);
1.826 + if (enc == NULL)
1.827 + goto err;
1.828 +#ifdef KSSL_DEBUG
1.829 + {
1.830 + printf("kssl_cget_tkt rtn %d\n", krb5rc);
1.831 + if (krb5rc && kssl_err.text)
1.832 + printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
1.833 + }
1.834 +#endif /* KSSL_DEBUG */
1.835 +
1.836 + if (krb5rc)
1.837 + {
1.838 + ssl3_send_alert(s,SSL3_AL_FATAL,
1.839 + SSL_AD_HANDSHAKE_FAILURE);
1.840 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
1.841 + kssl_err.reason);
1.842 + goto err;
1.843 + }
1.844 +
1.845 + /* 20010406 VRS - Earlier versions used KRB5 AP_REQ
1.846 + ** in place of RFC 2712 KerberosWrapper, as in:
1.847 + **
1.848 + ** Send ticket (copy to *p, set n = length)
1.849 + ** n = krb5_ap_req.length;
1.850 + ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
1.851 + ** if (krb5_ap_req.data)
1.852 + ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
1.853 + **
1.854 + ** Now using real RFC 2712 KerberosWrapper
1.855 + ** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
1.856 + ** Note: 2712 "opaque" types are here replaced
1.857 + ** with a 2-byte length followed by the value.
1.858 + ** Example:
1.859 + ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
1.860 + ** Where "xx xx" = length bytes. Shown here with
1.861 + ** optional authenticator omitted.
1.862 + */
1.863 +
1.864 + /* KerberosWrapper.Ticket */
1.865 + s2n(enc_ticket->length,p);
1.866 + memcpy(p, enc_ticket->data, enc_ticket->length);
1.867 + p+= enc_ticket->length;
1.868 + n = enc_ticket->length + 2;
1.869 +
1.870 + /* KerberosWrapper.Authenticator */
1.871 + if (authp && authp->length)
1.872 + {
1.873 + s2n(authp->length,p);
1.874 + memcpy(p, authp->data, authp->length);
1.875 + p+= authp->length;
1.876 + n+= authp->length + 2;
1.877 +
1.878 + free(authp->data);
1.879 + authp->data = NULL;
1.880 + authp->length = 0;
1.881 + }
1.882 + else
1.883 + {
1.884 + s2n(0,p);/* null authenticator length */
1.885 + n+=2;
1.886 + }
1.887 +
1.888 + if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0)
1.889 + goto err;
1.890 +
1.891 + /* 20010420 VRS. Tried it this way; failed.
1.892 + ** EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
1.893 + ** EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
1.894 + ** kssl_ctx->length);
1.895 + ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
1.896 + */
1.897 +
1.898 + memset(iv, 0, sizeof iv); /* per RFC 1510 */
1.899 + EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
1.900 + kssl_ctx->key,iv);
1.901 + EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
1.902 + sizeof tmp_buf);
1.903 + EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
1.904 + outl += padl;
1.905 + if (outl > sizeof epms)
1.906 + {
1.907 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
1.908 + goto err;
1.909 + }
1.910 + EVP_CIPHER_CTX_cleanup(&ciph_ctx);
1.911 +
1.912 + /* KerberosWrapper.EncryptedPreMasterSecret */
1.913 + s2n(outl,p);
1.914 + memcpy(p, epms, outl);
1.915 + p+=outl;
1.916 + n+=outl + 2;
1.917 +
1.918 + s->session->master_key_length=
1.919 + s->method->ssl3_enc->generate_master_secret(s,
1.920 + s->session->master_key,
1.921 + tmp_buf, sizeof tmp_buf);
1.922 +
1.923 + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
1.924 + OPENSSL_cleanse(epms, outl);
1.925 + }
1.926 +#endif
1.927 +#ifndef OPENSSL_NO_DH
1.928 + else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
1.929 + {
1.930 + DH *dh_srvr,*dh_clnt;
1.931 +
1.932 + if (s->session->sess_cert->peer_dh_tmp != NULL)
1.933 + dh_srvr=s->session->sess_cert->peer_dh_tmp;
1.934 + else
1.935 + {
1.936 + /* we get them from the cert */
1.937 + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
1.938 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
1.939 + goto err;
1.940 + }
1.941 +
1.942 + /* generate a new random key */
1.943 + if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
1.944 + {
1.945 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1.946 + goto err;
1.947 + }
1.948 + if (!DH_generate_key(dh_clnt))
1.949 + {
1.950 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1.951 + goto err;
1.952 + }
1.953 +
1.954 + /* use the 'p' output buffer for the DH key, but
1.955 + * make sure to clear it out afterwards */
1.956 +
1.957 + n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
1.958 +
1.959 + if (n <= 0)
1.960 + {
1.961 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
1.962 + goto err;
1.963 + }
1.964 +
1.965 + /* generate master key from the result */
1.966 + s->session->master_key_length=
1.967 + s->method->ssl3_enc->generate_master_secret(s,
1.968 + s->session->master_key,p,n);
1.969 + /* clean up */
1.970 + memset(p,0,n);
1.971 +
1.972 + /* send off the data */
1.973 + n=BN_num_bytes(dh_clnt->pub_key);
1.974 + s2n(n,p);
1.975 + BN_bn2bin(dh_clnt->pub_key,p);
1.976 + n+=2;
1.977 +
1.978 + DH_free(dh_clnt);
1.979 +
1.980 + /* perhaps clean things up a bit EAY EAY EAY EAY*/
1.981 + }
1.982 +#endif
1.983 + else
1.984 + {
1.985 + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
1.986 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
1.987 + goto err;
1.988 + }
1.989 +
1.990 + d = dtls1_set_message_header(s, d,
1.991 + SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
1.992 + /*
1.993 + *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
1.994 + l2n3(n,d);
1.995 + l2n(s->d1->handshake_write_seq,d);
1.996 + s->d1->handshake_write_seq++;
1.997 + */
1.998 +
1.999 + s->state=SSL3_ST_CW_KEY_EXCH_B;
1.1000 + /* number of bytes to write */
1.1001 + s->init_num=n+DTLS1_HM_HEADER_LENGTH;
1.1002 + s->init_off=0;
1.1003 +
1.1004 + /* buffer the message to handle re-xmits */
1.1005 + dtls1_buffer_message(s, 0);
1.1006 + }
1.1007 +
1.1008 + /* SSL3_ST_CW_KEY_EXCH_B */
1.1009 + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1.1010 +err:
1.1011 + return(-1);
1.1012 + }
1.1013 +
1.1014 +int dtls1_send_client_verify(SSL *s)
1.1015 + {
1.1016 + unsigned char *p,*d;
1.1017 + unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
1.1018 + EVP_PKEY *pkey;
1.1019 +#ifndef OPENSSL_NO_RSA
1.1020 + unsigned u=0;
1.1021 +#endif
1.1022 + unsigned long n;
1.1023 +#ifndef OPENSSL_NO_DSA
1.1024 + int j;
1.1025 +#endif
1.1026 +
1.1027 + if (s->state == SSL3_ST_CW_CERT_VRFY_A)
1.1028 + {
1.1029 + d=(unsigned char *)s->init_buf->data;
1.1030 + p= &(d[DTLS1_HM_HEADER_LENGTH]);
1.1031 + pkey=s->cert->key->privatekey;
1.1032 +
1.1033 + s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
1.1034 + &(data[MD5_DIGEST_LENGTH]));
1.1035 +
1.1036 +#ifndef OPENSSL_NO_RSA
1.1037 + if (pkey->type == EVP_PKEY_RSA)
1.1038 + {
1.1039 + s->method->ssl3_enc->cert_verify_mac(s,
1.1040 + &(s->s3->finish_dgst1),&(data[0]));
1.1041 + if (RSA_sign(NID_md5_sha1, data,
1.1042 + MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
1.1043 + &(p[2]), &u, pkey->pkey.rsa) <= 0 )
1.1044 + {
1.1045 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
1.1046 + goto err;
1.1047 + }
1.1048 + s2n(u,p);
1.1049 + n=u+2;
1.1050 + }
1.1051 + else
1.1052 +#endif
1.1053 +#ifndef OPENSSL_NO_DSA
1.1054 + if (pkey->type == EVP_PKEY_DSA)
1.1055 + {
1.1056 + if (!DSA_sign(pkey->save_type,
1.1057 + &(data[MD5_DIGEST_LENGTH]),
1.1058 + SHA_DIGEST_LENGTH,&(p[2]),
1.1059 + (unsigned int *)&j,pkey->pkey.dsa))
1.1060 + {
1.1061 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
1.1062 + goto err;
1.1063 + }
1.1064 + s2n(j,p);
1.1065 + n=j+2;
1.1066 + }
1.1067 + else
1.1068 +#endif
1.1069 + {
1.1070 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
1.1071 + goto err;
1.1072 + }
1.1073 +
1.1074 + d = dtls1_set_message_header(s, d,
1.1075 + SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ;
1.1076 +
1.1077 + s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH;
1.1078 + s->init_off=0;
1.1079 +
1.1080 + /* buffer the message to handle re-xmits */
1.1081 + dtls1_buffer_message(s, 0);
1.1082 +
1.1083 + s->state = SSL3_ST_CW_CERT_VRFY_B;
1.1084 + }
1.1085 +
1.1086 + /* s->state = SSL3_ST_CW_CERT_VRFY_B */
1.1087 + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1.1088 +err:
1.1089 + return(-1);
1.1090 + }
1.1091 +
1.1092 +int dtls1_send_client_certificate(SSL *s)
1.1093 + {
1.1094 + X509 *x509=NULL;
1.1095 + EVP_PKEY *pkey=NULL;
1.1096 + int i;
1.1097 + unsigned long l;
1.1098 +
1.1099 + if (s->state == SSL3_ST_CW_CERT_A)
1.1100 + {
1.1101 + if ((s->cert == NULL) ||
1.1102 + (s->cert->key->x509 == NULL) ||
1.1103 + (s->cert->key->privatekey == NULL))
1.1104 + s->state=SSL3_ST_CW_CERT_B;
1.1105 + else
1.1106 + s->state=SSL3_ST_CW_CERT_C;
1.1107 + }
1.1108 +
1.1109 + /* We need to get a client cert */
1.1110 + if (s->state == SSL3_ST_CW_CERT_B)
1.1111 + {
1.1112 + /* If we get an error, we need to
1.1113 + * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
1.1114 + * We then get retied later */
1.1115 + i=0;
1.1116 + if (s->ctx->client_cert_cb != NULL)
1.1117 + i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
1.1118 + if (i < 0)
1.1119 + {
1.1120 + s->rwstate=SSL_X509_LOOKUP;
1.1121 + return(-1);
1.1122 + }
1.1123 + s->rwstate=SSL_NOTHING;
1.1124 + if ((i == 1) && (pkey != NULL) && (x509 != NULL))
1.1125 + {
1.1126 + s->state=SSL3_ST_CW_CERT_B;
1.1127 + if ( !SSL_use_certificate(s,x509) ||
1.1128 + !SSL_use_PrivateKey(s,pkey))
1.1129 + i=0;
1.1130 + }
1.1131 + else if (i == 1)
1.1132 + {
1.1133 + i=0;
1.1134 + SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
1.1135 + }
1.1136 +
1.1137 + if (x509 != NULL) X509_free(x509);
1.1138 + if (pkey != NULL) EVP_PKEY_free(pkey);
1.1139 + if (i == 0)
1.1140 + {
1.1141 + if (s->version == SSL3_VERSION)
1.1142 + {
1.1143 + s->s3->tmp.cert_req=0;
1.1144 + ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
1.1145 + return(1);
1.1146 + }
1.1147 + else
1.1148 + {
1.1149 + s->s3->tmp.cert_req=2;
1.1150 + }
1.1151 + }
1.1152 +
1.1153 + /* Ok, we have a cert */
1.1154 + s->state=SSL3_ST_CW_CERT_C;
1.1155 + }
1.1156 +
1.1157 + if (s->state == SSL3_ST_CW_CERT_C)
1.1158 + {
1.1159 + s->state=SSL3_ST_CW_CERT_D;
1.1160 + l=dtls1_output_cert_chain(s,
1.1161 + (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
1.1162 + s->init_num=(int)l;
1.1163 + s->init_off=0;
1.1164 +
1.1165 + /* set header called by dtls1_output_cert_chain() */
1.1166 +
1.1167 + /* buffer the message to handle re-xmits */
1.1168 + dtls1_buffer_message(s, 0);
1.1169 + }
1.1170 + /* SSL3_ST_CW_CERT_D */
1.1171 + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1.1172 + }
1.1173 +
1.1174 +