10Sstevel@tonic-gate /* ssl/s3_clnt.c */ 20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 30Sstevel@tonic-gate * All rights reserved. 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * This package is an SSL implementation written 60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 150Sstevel@tonic-gate * 160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 170Sstevel@tonic-gate * the code are not to be removed. 180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 190Sstevel@tonic-gate * as the author of the parts of the library used. 200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 210Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 220Sstevel@tonic-gate * 230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 240Sstevel@tonic-gate * modification, are permitted provided that the following conditions 250Sstevel@tonic-gate * are met: 260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 320Sstevel@tonic-gate * must display the following acknowledgement: 330Sstevel@tonic-gate * "This product includes cryptographic software written by 340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 360Sstevel@tonic-gate * being used are not cryptographic related :-). 370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 400Sstevel@tonic-gate * 410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 510Sstevel@tonic-gate * SUCH DAMAGE. 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 550Sstevel@tonic-gate * copied and put under another distribution licence 560Sstevel@tonic-gate * [including the GNU Public Licence.] 570Sstevel@tonic-gate */ 580Sstevel@tonic-gate /* ==================================================================== 59*2139Sjp161948 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 600Sstevel@tonic-gate * 610Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 620Sstevel@tonic-gate * modification, are permitted provided that the following conditions 630Sstevel@tonic-gate * are met: 640Sstevel@tonic-gate * 650Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 660Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 670Sstevel@tonic-gate * 680Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 690Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 700Sstevel@tonic-gate * the documentation and/or other materials provided with the 710Sstevel@tonic-gate * distribution. 720Sstevel@tonic-gate * 730Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 740Sstevel@tonic-gate * software must display the following acknowledgment: 750Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 760Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 770Sstevel@tonic-gate * 780Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 790Sstevel@tonic-gate * endorse or promote products derived from this software without 800Sstevel@tonic-gate * prior written permission. For written permission, please contact 810Sstevel@tonic-gate * openssl-core@openssl.org. 820Sstevel@tonic-gate * 830Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 840Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 850Sstevel@tonic-gate * permission of the OpenSSL Project. 860Sstevel@tonic-gate * 870Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 880Sstevel@tonic-gate * acknowledgment: 890Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 900Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 910Sstevel@tonic-gate * 920Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 930Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 940Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 950Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 960Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 970Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 980Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 990Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1000Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1010Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1020Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1030Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 1040Sstevel@tonic-gate * ==================================================================== 1050Sstevel@tonic-gate * 1060Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 1070Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 1080Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 1090Sstevel@tonic-gate * 1100Sstevel@tonic-gate */ 111*2139Sjp161948 /* ==================================================================== 112*2139Sjp161948 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113*2139Sjp161948 * 114*2139Sjp161948 * Portions of the attached software ("Contribution") are developed by 115*2139Sjp161948 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 116*2139Sjp161948 * 117*2139Sjp161948 * The Contribution is licensed pursuant to the OpenSSL open source 118*2139Sjp161948 * license provided above. 119*2139Sjp161948 * 120*2139Sjp161948 * ECC cipher suite support in OpenSSL originally written by 121*2139Sjp161948 * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. 122*2139Sjp161948 * 123*2139Sjp161948 */ 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate #include <stdio.h> 1260Sstevel@tonic-gate #include "ssl_locl.h" 1270Sstevel@tonic-gate #include "kssl_lcl.h" 1280Sstevel@tonic-gate #include <openssl/buffer.h> 1290Sstevel@tonic-gate #include <openssl/rand.h> 1300Sstevel@tonic-gate #include <openssl/objects.h> 1310Sstevel@tonic-gate #include <openssl/evp.h> 1320Sstevel@tonic-gate #include <openssl/md5.h> 133*2139Sjp161948 #ifndef OPENSSL_NO_DH 134*2139Sjp161948 #include <openssl/dh.h> 135*2139Sjp161948 #endif 136*2139Sjp161948 #include <openssl/bn.h> 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate static SSL_METHOD *ssl3_get_client_method(int ver); 1390Sstevel@tonic-gate static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); 140*2139Sjp161948 141*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 142*2139Sjp161948 static int curve_id2nid(int curve_id); 143*2139Sjp161948 int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs); 144*2139Sjp161948 #endif 145*2139Sjp161948 1460Sstevel@tonic-gate static SSL_METHOD *ssl3_get_client_method(int ver) 1470Sstevel@tonic-gate { 1480Sstevel@tonic-gate if (ver == SSL3_VERSION) 1490Sstevel@tonic-gate return(SSLv3_client_method()); 1500Sstevel@tonic-gate else 1510Sstevel@tonic-gate return(NULL); 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate 154*2139Sjp161948 IMPLEMENT_ssl3_meth_func(SSLv3_client_method, 155*2139Sjp161948 ssl_undefined_function, 156*2139Sjp161948 ssl3_connect, 157*2139Sjp161948 ssl3_get_client_method) 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate int ssl3_connect(SSL *s) 1600Sstevel@tonic-gate { 1610Sstevel@tonic-gate BUF_MEM *buf=NULL; 1620Sstevel@tonic-gate unsigned long Time=time(NULL),l; 1630Sstevel@tonic-gate long num1; 1640Sstevel@tonic-gate void (*cb)(const SSL *ssl,int type,int val)=NULL; 1650Sstevel@tonic-gate int ret= -1; 1660Sstevel@tonic-gate int new_state,state,skip=0;; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate RAND_add(&Time,sizeof(Time),0); 1690Sstevel@tonic-gate ERR_clear_error(); 1700Sstevel@tonic-gate clear_sys_error(); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate if (s->info_callback != NULL) 1730Sstevel@tonic-gate cb=s->info_callback; 1740Sstevel@tonic-gate else if (s->ctx->info_callback != NULL) 1750Sstevel@tonic-gate cb=s->ctx->info_callback; 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate s->in_handshake++; 1780Sstevel@tonic-gate if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate for (;;) 1810Sstevel@tonic-gate { 1820Sstevel@tonic-gate state=s->state; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate switch(s->state) 1850Sstevel@tonic-gate { 1860Sstevel@tonic-gate case SSL_ST_RENEGOTIATE: 1870Sstevel@tonic-gate s->new_session=1; 1880Sstevel@tonic-gate s->state=SSL_ST_CONNECT; 1890Sstevel@tonic-gate s->ctx->stats.sess_connect_renegotiate++; 1900Sstevel@tonic-gate /* break */ 1910Sstevel@tonic-gate case SSL_ST_BEFORE: 1920Sstevel@tonic-gate case SSL_ST_CONNECT: 1930Sstevel@tonic-gate case SSL_ST_BEFORE|SSL_ST_CONNECT: 1940Sstevel@tonic-gate case SSL_ST_OK|SSL_ST_CONNECT: 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate s->server=0; 1970Sstevel@tonic-gate if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate if ((s->version & 0xff00 ) != 0x0300) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR); 2020Sstevel@tonic-gate ret = -1; 2030Sstevel@tonic-gate goto end; 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate /* s->version=SSL3_VERSION; */ 2070Sstevel@tonic-gate s->type=SSL_ST_CONNECT; 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate if (s->init_buf == NULL) 2100Sstevel@tonic-gate { 2110Sstevel@tonic-gate if ((buf=BUF_MEM_new()) == NULL) 2120Sstevel@tonic-gate { 2130Sstevel@tonic-gate ret= -1; 2140Sstevel@tonic-gate goto end; 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) 2170Sstevel@tonic-gate { 2180Sstevel@tonic-gate ret= -1; 2190Sstevel@tonic-gate goto end; 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate s->init_buf=buf; 2220Sstevel@tonic-gate buf=NULL; 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate /* setup buffing BIO */ 2280Sstevel@tonic-gate if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate /* don't push the buffering BIO quite yet */ 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate ssl3_init_finished_mac(s); 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate s->state=SSL3_ST_CW_CLNT_HELLO_A; 2350Sstevel@tonic-gate s->ctx->stats.sess_connect++; 2360Sstevel@tonic-gate s->init_num=0; 2370Sstevel@tonic-gate break; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate case SSL3_ST_CW_CLNT_HELLO_A: 2400Sstevel@tonic-gate case SSL3_ST_CW_CLNT_HELLO_B: 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate s->shutdown=0; 2430Sstevel@tonic-gate ret=ssl3_client_hello(s); 2440Sstevel@tonic-gate if (ret <= 0) goto end; 2450Sstevel@tonic-gate s->state=SSL3_ST_CR_SRVR_HELLO_A; 2460Sstevel@tonic-gate s->init_num=0; 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate /* turn on buffering for the next lot of output */ 2490Sstevel@tonic-gate if (s->bbio != s->wbio) 2500Sstevel@tonic-gate s->wbio=BIO_push(s->bbio,s->wbio); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate break; 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate case SSL3_ST_CR_SRVR_HELLO_A: 2550Sstevel@tonic-gate case SSL3_ST_CR_SRVR_HELLO_B: 2560Sstevel@tonic-gate ret=ssl3_get_server_hello(s); 2570Sstevel@tonic-gate if (ret <= 0) goto end; 2580Sstevel@tonic-gate if (s->hit) 2590Sstevel@tonic-gate s->state=SSL3_ST_CR_FINISHED_A; 2600Sstevel@tonic-gate else 2610Sstevel@tonic-gate s->state=SSL3_ST_CR_CERT_A; 2620Sstevel@tonic-gate s->init_num=0; 2630Sstevel@tonic-gate break; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate case SSL3_ST_CR_CERT_A: 2660Sstevel@tonic-gate case SSL3_ST_CR_CERT_B: 267*2139Sjp161948 /* Check if it is anon DH/ECDH */ 2680Sstevel@tonic-gate if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) 2690Sstevel@tonic-gate { 2700Sstevel@tonic-gate ret=ssl3_get_server_certificate(s); 2710Sstevel@tonic-gate if (ret <= 0) goto end; 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate else 2740Sstevel@tonic-gate skip=1; 2750Sstevel@tonic-gate s->state=SSL3_ST_CR_KEY_EXCH_A; 2760Sstevel@tonic-gate s->init_num=0; 2770Sstevel@tonic-gate break; 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate case SSL3_ST_CR_KEY_EXCH_A: 2800Sstevel@tonic-gate case SSL3_ST_CR_KEY_EXCH_B: 2810Sstevel@tonic-gate ret=ssl3_get_key_exchange(s); 2820Sstevel@tonic-gate if (ret <= 0) goto end; 2830Sstevel@tonic-gate s->state=SSL3_ST_CR_CERT_REQ_A; 2840Sstevel@tonic-gate s->init_num=0; 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate /* at this point we check that we have the 2870Sstevel@tonic-gate * required stuff from the server */ 2880Sstevel@tonic-gate if (!ssl3_check_cert_and_algorithm(s)) 2890Sstevel@tonic-gate { 2900Sstevel@tonic-gate ret= -1; 2910Sstevel@tonic-gate goto end; 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate break; 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate case SSL3_ST_CR_CERT_REQ_A: 2960Sstevel@tonic-gate case SSL3_ST_CR_CERT_REQ_B: 2970Sstevel@tonic-gate ret=ssl3_get_certificate_request(s); 2980Sstevel@tonic-gate if (ret <= 0) goto end; 2990Sstevel@tonic-gate s->state=SSL3_ST_CR_SRVR_DONE_A; 3000Sstevel@tonic-gate s->init_num=0; 3010Sstevel@tonic-gate break; 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate case SSL3_ST_CR_SRVR_DONE_A: 3040Sstevel@tonic-gate case SSL3_ST_CR_SRVR_DONE_B: 3050Sstevel@tonic-gate ret=ssl3_get_server_done(s); 3060Sstevel@tonic-gate if (ret <= 0) goto end; 3070Sstevel@tonic-gate if (s->s3->tmp.cert_req) 3080Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_A; 3090Sstevel@tonic-gate else 3100Sstevel@tonic-gate s->state=SSL3_ST_CW_KEY_EXCH_A; 3110Sstevel@tonic-gate s->init_num=0; 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate break; 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate case SSL3_ST_CW_CERT_A: 3160Sstevel@tonic-gate case SSL3_ST_CW_CERT_B: 3170Sstevel@tonic-gate case SSL3_ST_CW_CERT_C: 3180Sstevel@tonic-gate case SSL3_ST_CW_CERT_D: 3190Sstevel@tonic-gate ret=ssl3_send_client_certificate(s); 3200Sstevel@tonic-gate if (ret <= 0) goto end; 3210Sstevel@tonic-gate s->state=SSL3_ST_CW_KEY_EXCH_A; 3220Sstevel@tonic-gate s->init_num=0; 3230Sstevel@tonic-gate break; 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate case SSL3_ST_CW_KEY_EXCH_A: 3260Sstevel@tonic-gate case SSL3_ST_CW_KEY_EXCH_B: 3270Sstevel@tonic-gate ret=ssl3_send_client_key_exchange(s); 3280Sstevel@tonic-gate if (ret <= 0) goto end; 3290Sstevel@tonic-gate l=s->s3->tmp.new_cipher->algorithms; 3300Sstevel@tonic-gate /* EAY EAY EAY need to check for DH fix cert 3310Sstevel@tonic-gate * sent back */ 3320Sstevel@tonic-gate /* For TLS, cert_req is set to 2, so a cert chain 3330Sstevel@tonic-gate * of nothing is sent, but no verify packet is sent */ 334*2139Sjp161948 /* XXX: For now, we do not support client 335*2139Sjp161948 * authentication in ECDH cipher suites with 336*2139Sjp161948 * ECDH (rather than ECDSA) certificates. 337*2139Sjp161948 * We need to skip the certificate verify 338*2139Sjp161948 * message when client's ECDH public key is sent 339*2139Sjp161948 * inside the client certificate. 340*2139Sjp161948 */ 3410Sstevel@tonic-gate if (s->s3->tmp.cert_req == 1) 3420Sstevel@tonic-gate { 3430Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_VRFY_A; 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate else 3460Sstevel@tonic-gate { 3470Sstevel@tonic-gate s->state=SSL3_ST_CW_CHANGE_A; 3480Sstevel@tonic-gate s->s3->change_cipher_spec=0; 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate s->init_num=0; 3520Sstevel@tonic-gate break; 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate case SSL3_ST_CW_CERT_VRFY_A: 3550Sstevel@tonic-gate case SSL3_ST_CW_CERT_VRFY_B: 3560Sstevel@tonic-gate ret=ssl3_send_client_verify(s); 3570Sstevel@tonic-gate if (ret <= 0) goto end; 3580Sstevel@tonic-gate s->state=SSL3_ST_CW_CHANGE_A; 3590Sstevel@tonic-gate s->init_num=0; 3600Sstevel@tonic-gate s->s3->change_cipher_spec=0; 3610Sstevel@tonic-gate break; 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate case SSL3_ST_CW_CHANGE_A: 3640Sstevel@tonic-gate case SSL3_ST_CW_CHANGE_B: 3650Sstevel@tonic-gate ret=ssl3_send_change_cipher_spec(s, 3660Sstevel@tonic-gate SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); 3670Sstevel@tonic-gate if (ret <= 0) goto end; 3680Sstevel@tonic-gate s->state=SSL3_ST_CW_FINISHED_A; 3690Sstevel@tonic-gate s->init_num=0; 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate s->session->cipher=s->s3->tmp.new_cipher; 372*2139Sjp161948 #ifdef OPENSSL_NO_COMP 373*2139Sjp161948 s->session->compress_meth=0; 374*2139Sjp161948 #else 3750Sstevel@tonic-gate if (s->s3->tmp.new_compression == NULL) 3760Sstevel@tonic-gate s->session->compress_meth=0; 3770Sstevel@tonic-gate else 3780Sstevel@tonic-gate s->session->compress_meth= 3790Sstevel@tonic-gate s->s3->tmp.new_compression->id; 380*2139Sjp161948 #endif 3810Sstevel@tonic-gate if (!s->method->ssl3_enc->setup_key_block(s)) 3820Sstevel@tonic-gate { 3830Sstevel@tonic-gate ret= -1; 3840Sstevel@tonic-gate goto end; 3850Sstevel@tonic-gate } 3860Sstevel@tonic-gate 3870Sstevel@tonic-gate if (!s->method->ssl3_enc->change_cipher_state(s, 3880Sstevel@tonic-gate SSL3_CHANGE_CIPHER_CLIENT_WRITE)) 3890Sstevel@tonic-gate { 3900Sstevel@tonic-gate ret= -1; 3910Sstevel@tonic-gate goto end; 3920Sstevel@tonic-gate } 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate break; 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate case SSL3_ST_CW_FINISHED_A: 3970Sstevel@tonic-gate case SSL3_ST_CW_FINISHED_B: 3980Sstevel@tonic-gate ret=ssl3_send_finished(s, 3990Sstevel@tonic-gate SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, 4000Sstevel@tonic-gate s->method->ssl3_enc->client_finished_label, 4010Sstevel@tonic-gate s->method->ssl3_enc->client_finished_label_len); 4020Sstevel@tonic-gate if (ret <= 0) goto end; 4030Sstevel@tonic-gate s->state=SSL3_ST_CW_FLUSH; 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate /* clear flags */ 4060Sstevel@tonic-gate s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER; 4070Sstevel@tonic-gate if (s->hit) 4080Sstevel@tonic-gate { 4090Sstevel@tonic-gate s->s3->tmp.next_state=SSL_ST_OK; 4100Sstevel@tonic-gate if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) 4110Sstevel@tonic-gate { 4120Sstevel@tonic-gate s->state=SSL_ST_OK; 4130Sstevel@tonic-gate s->s3->flags|=SSL3_FLAGS_POP_BUFFER; 4140Sstevel@tonic-gate s->s3->delay_buf_pop_ret=0; 4150Sstevel@tonic-gate } 4160Sstevel@tonic-gate } 4170Sstevel@tonic-gate else 4180Sstevel@tonic-gate { 4190Sstevel@tonic-gate s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate s->init_num=0; 4220Sstevel@tonic-gate break; 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate case SSL3_ST_CR_FINISHED_A: 4250Sstevel@tonic-gate case SSL3_ST_CR_FINISHED_B: 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, 4280Sstevel@tonic-gate SSL3_ST_CR_FINISHED_B); 4290Sstevel@tonic-gate if (ret <= 0) goto end; 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate if (s->hit) 4320Sstevel@tonic-gate s->state=SSL3_ST_CW_CHANGE_A; 4330Sstevel@tonic-gate else 4340Sstevel@tonic-gate s->state=SSL_ST_OK; 4350Sstevel@tonic-gate s->init_num=0; 4360Sstevel@tonic-gate break; 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate case SSL3_ST_CW_FLUSH: 4390Sstevel@tonic-gate /* number of bytes to be flushed */ 4400Sstevel@tonic-gate num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL); 4410Sstevel@tonic-gate if (num1 > 0) 4420Sstevel@tonic-gate { 4430Sstevel@tonic-gate s->rwstate=SSL_WRITING; 4440Sstevel@tonic-gate num1=BIO_flush(s->wbio); 4450Sstevel@tonic-gate if (num1 <= 0) { ret= -1; goto end; } 4460Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 4470Sstevel@tonic-gate } 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate s->state=s->s3->tmp.next_state; 4500Sstevel@tonic-gate break; 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate case SSL_ST_OK: 4530Sstevel@tonic-gate /* clean a few things up */ 4540Sstevel@tonic-gate ssl3_cleanup_key_block(s); 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate if (s->init_buf != NULL) 4570Sstevel@tonic-gate { 4580Sstevel@tonic-gate BUF_MEM_free(s->init_buf); 4590Sstevel@tonic-gate s->init_buf=NULL; 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate /* If we are not 'joining' the last two packets, 4630Sstevel@tonic-gate * remove the buffering now */ 4640Sstevel@tonic-gate if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) 4650Sstevel@tonic-gate ssl_free_wbio_buffer(s); 4660Sstevel@tonic-gate /* else do it later in ssl3_write */ 4670Sstevel@tonic-gate 4680Sstevel@tonic-gate s->init_num=0; 4690Sstevel@tonic-gate s->new_session=0; 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); 4720Sstevel@tonic-gate if (s->hit) s->ctx->stats.sess_hit++; 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate ret=1; 4750Sstevel@tonic-gate /* s->server=0; */ 4760Sstevel@tonic-gate s->handshake_func=ssl3_connect; 4770Sstevel@tonic-gate s->ctx->stats.sess_connect_good++; 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate goto end; 4820Sstevel@tonic-gate /* break; */ 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate default: 4850Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CONNECT,SSL_R_UNKNOWN_STATE); 4860Sstevel@tonic-gate ret= -1; 4870Sstevel@tonic-gate goto end; 4880Sstevel@tonic-gate /* break; */ 4890Sstevel@tonic-gate } 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate /* did we do anything */ 4920Sstevel@tonic-gate if (!s->s3->tmp.reuse_message && !skip) 4930Sstevel@tonic-gate { 4940Sstevel@tonic-gate if (s->debug) 4950Sstevel@tonic-gate { 4960Sstevel@tonic-gate if ((ret=BIO_flush(s->wbio)) <= 0) 4970Sstevel@tonic-gate goto end; 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate if ((cb != NULL) && (s->state != state)) 5010Sstevel@tonic-gate { 5020Sstevel@tonic-gate new_state=s->state; 5030Sstevel@tonic-gate s->state=state; 5040Sstevel@tonic-gate cb(s,SSL_CB_CONNECT_LOOP,1); 5050Sstevel@tonic-gate s->state=new_state; 5060Sstevel@tonic-gate } 5070Sstevel@tonic-gate } 5080Sstevel@tonic-gate skip=0; 5090Sstevel@tonic-gate } 5100Sstevel@tonic-gate end: 5110Sstevel@tonic-gate s->in_handshake--; 5120Sstevel@tonic-gate if (buf != NULL) 5130Sstevel@tonic-gate BUF_MEM_free(buf); 5140Sstevel@tonic-gate if (cb != NULL) 5150Sstevel@tonic-gate cb(s,SSL_CB_CONNECT_EXIT,ret); 5160Sstevel@tonic-gate return(ret); 5170Sstevel@tonic-gate } 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate 520*2139Sjp161948 int ssl3_client_hello(SSL *s) 5210Sstevel@tonic-gate { 5220Sstevel@tonic-gate unsigned char *buf; 5230Sstevel@tonic-gate unsigned char *p,*d; 524*2139Sjp161948 int i; 5250Sstevel@tonic-gate unsigned long Time,l; 526*2139Sjp161948 #ifndef OPENSSL_NO_COMP 527*2139Sjp161948 int j; 5280Sstevel@tonic-gate SSL_COMP *comp; 529*2139Sjp161948 #endif 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate buf=(unsigned char *)s->init_buf->data; 5320Sstevel@tonic-gate if (s->state == SSL3_ST_CW_CLNT_HELLO_A) 5330Sstevel@tonic-gate { 5340Sstevel@tonic-gate if ((s->session == NULL) || 5350Sstevel@tonic-gate (s->session->ssl_version != s->version) || 5360Sstevel@tonic-gate (s->session->not_resumable)) 5370Sstevel@tonic-gate { 5380Sstevel@tonic-gate if (!ssl_get_new_session(s,0)) 5390Sstevel@tonic-gate goto err; 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate /* else use the pre-loaded session */ 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate p=s->s3->client_random; 5440Sstevel@tonic-gate Time=time(NULL); /* Time */ 5450Sstevel@tonic-gate l2n(Time,p); 546*2139Sjp161948 if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) 547*2139Sjp161948 goto err; 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate /* Do the message type and length last */ 5500Sstevel@tonic-gate d=p= &(buf[4]); 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate *(p++)=s->version>>8; 5530Sstevel@tonic-gate *(p++)=s->version&0xff; 5540Sstevel@tonic-gate s->client_version=s->version; 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate /* Random stuff */ 5570Sstevel@tonic-gate memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); 5580Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate /* Session ID */ 5610Sstevel@tonic-gate if (s->new_session) 5620Sstevel@tonic-gate i=0; 5630Sstevel@tonic-gate else 5640Sstevel@tonic-gate i=s->session->session_id_length; 5650Sstevel@tonic-gate *(p++)=i; 5660Sstevel@tonic-gate if (i != 0) 5670Sstevel@tonic-gate { 568*2139Sjp161948 if (i > (int)sizeof(s->session->session_id)) 5690Sstevel@tonic-gate { 5700Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); 5710Sstevel@tonic-gate goto err; 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate memcpy(p,s->session->session_id,i); 5740Sstevel@tonic-gate p+=i; 5750Sstevel@tonic-gate } 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate /* Ciphers supported */ 578*2139Sjp161948 i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0); 5790Sstevel@tonic-gate if (i == 0) 5800Sstevel@tonic-gate { 5810Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); 5820Sstevel@tonic-gate goto err; 5830Sstevel@tonic-gate } 5840Sstevel@tonic-gate s2n(i,p); 5850Sstevel@tonic-gate p+=i; 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate /* COMPRESSION */ 588*2139Sjp161948 #ifdef OPENSSL_NO_COMP 589*2139Sjp161948 *(p++)=1; 590*2139Sjp161948 #else 5910Sstevel@tonic-gate if (s->ctx->comp_methods == NULL) 5920Sstevel@tonic-gate j=0; 5930Sstevel@tonic-gate else 5940Sstevel@tonic-gate j=sk_SSL_COMP_num(s->ctx->comp_methods); 5950Sstevel@tonic-gate *(p++)=1+j; 5960Sstevel@tonic-gate for (i=0; i<j; i++) 5970Sstevel@tonic-gate { 5980Sstevel@tonic-gate comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); 5990Sstevel@tonic-gate *(p++)=comp->id; 6000Sstevel@tonic-gate } 601*2139Sjp161948 #endif 6020Sstevel@tonic-gate *(p++)=0; /* Add the NULL method */ 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate l=(p-d); 6050Sstevel@tonic-gate d=buf; 6060Sstevel@tonic-gate *(d++)=SSL3_MT_CLIENT_HELLO; 6070Sstevel@tonic-gate l2n3(l,d); 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate s->state=SSL3_ST_CW_CLNT_HELLO_B; 6100Sstevel@tonic-gate /* number of bytes to write */ 6110Sstevel@tonic-gate s->init_num=p-buf; 6120Sstevel@tonic-gate s->init_off=0; 6130Sstevel@tonic-gate } 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate /* SSL3_ST_CW_CLNT_HELLO_B */ 6160Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); 6170Sstevel@tonic-gate err: 6180Sstevel@tonic-gate return(-1); 6190Sstevel@tonic-gate } 6200Sstevel@tonic-gate 621*2139Sjp161948 int ssl3_get_server_hello(SSL *s) 6220Sstevel@tonic-gate { 6230Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *sk; 6240Sstevel@tonic-gate SSL_CIPHER *c; 6250Sstevel@tonic-gate unsigned char *p,*d; 6260Sstevel@tonic-gate int i,al,ok; 6270Sstevel@tonic-gate unsigned int j; 6280Sstevel@tonic-gate long n; 629*2139Sjp161948 #ifndef OPENSSL_NO_COMP 6300Sstevel@tonic-gate SSL_COMP *comp; 631*2139Sjp161948 #endif 6320Sstevel@tonic-gate 633*2139Sjp161948 n=s->method->ssl_get_message(s, 6340Sstevel@tonic-gate SSL3_ST_CR_SRVR_HELLO_A, 6350Sstevel@tonic-gate SSL3_ST_CR_SRVR_HELLO_B, 636*2139Sjp161948 -1, 6370Sstevel@tonic-gate 300, /* ?? */ 6380Sstevel@tonic-gate &ok); 6390Sstevel@tonic-gate 6400Sstevel@tonic-gate if (!ok) return((int)n); 641*2139Sjp161948 642*2139Sjp161948 if ( SSL_version(s) == DTLS1_VERSION) 643*2139Sjp161948 { 644*2139Sjp161948 if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) 645*2139Sjp161948 { 646*2139Sjp161948 if ( s->d1->send_cookie == 0) 647*2139Sjp161948 { 648*2139Sjp161948 s->s3->tmp.reuse_message = 1; 649*2139Sjp161948 return 1; 650*2139Sjp161948 } 651*2139Sjp161948 else /* already sent a cookie */ 652*2139Sjp161948 { 653*2139Sjp161948 al=SSL_AD_UNEXPECTED_MESSAGE; 654*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE); 655*2139Sjp161948 goto f_err; 656*2139Sjp161948 } 657*2139Sjp161948 } 658*2139Sjp161948 } 659*2139Sjp161948 660*2139Sjp161948 if ( s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) 661*2139Sjp161948 { 662*2139Sjp161948 al=SSL_AD_UNEXPECTED_MESSAGE; 663*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE); 664*2139Sjp161948 goto f_err; 665*2139Sjp161948 } 666*2139Sjp161948 6670Sstevel@tonic-gate d=p=(unsigned char *)s->init_msg; 6680Sstevel@tonic-gate 6690Sstevel@tonic-gate if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff))) 6700Sstevel@tonic-gate { 6710Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_SSL_VERSION); 6720Sstevel@tonic-gate s->version=(s->version&0xff00)|p[1]; 6730Sstevel@tonic-gate al=SSL_AD_PROTOCOL_VERSION; 6740Sstevel@tonic-gate goto f_err; 6750Sstevel@tonic-gate } 6760Sstevel@tonic-gate p+=2; 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate /* load the server hello data */ 6790Sstevel@tonic-gate /* load the server random */ 6800Sstevel@tonic-gate memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE); 6810Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate /* get the session-id */ 6840Sstevel@tonic-gate j= *(p++); 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) 6870Sstevel@tonic-gate { 6880Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 6890Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_LONG); 6900Sstevel@tonic-gate goto f_err; 6910Sstevel@tonic-gate } 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate if (j != 0 && j == s->session->session_id_length 6940Sstevel@tonic-gate && memcmp(p,s->session->session_id,j) == 0) 6950Sstevel@tonic-gate { 6960Sstevel@tonic-gate if(s->sid_ctx_length != s->session->sid_ctx_length 6970Sstevel@tonic-gate || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length)) 6980Sstevel@tonic-gate { 6990Sstevel@tonic-gate /* actually a client application bug */ 7000Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 7010Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); 7020Sstevel@tonic-gate goto f_err; 7030Sstevel@tonic-gate } 7040Sstevel@tonic-gate s->hit=1; 7050Sstevel@tonic-gate } 7060Sstevel@tonic-gate else /* a miss or crap from the other end */ 7070Sstevel@tonic-gate { 7080Sstevel@tonic-gate /* If we were trying for session-id reuse, make a new 7090Sstevel@tonic-gate * SSL_SESSION so we don't stuff up other people */ 7100Sstevel@tonic-gate s->hit=0; 7110Sstevel@tonic-gate if (s->session->session_id_length > 0) 7120Sstevel@tonic-gate { 7130Sstevel@tonic-gate if (!ssl_get_new_session(s,0)) 7140Sstevel@tonic-gate { 7150Sstevel@tonic-gate al=SSL_AD_INTERNAL_ERROR; 7160Sstevel@tonic-gate goto f_err; 7170Sstevel@tonic-gate } 7180Sstevel@tonic-gate } 7190Sstevel@tonic-gate s->session->session_id_length=j; 7200Sstevel@tonic-gate memcpy(s->session->session_id,p,j); /* j could be 0 */ 7210Sstevel@tonic-gate } 7220Sstevel@tonic-gate p+=j; 7230Sstevel@tonic-gate c=ssl_get_cipher_by_char(s,p); 7240Sstevel@tonic-gate if (c == NULL) 7250Sstevel@tonic-gate { 7260Sstevel@tonic-gate /* unknown cipher */ 7270Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 7280Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED); 7290Sstevel@tonic-gate goto f_err; 7300Sstevel@tonic-gate } 7310Sstevel@tonic-gate p+=ssl_put_cipher_by_char(s,NULL,NULL); 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate sk=ssl_get_ciphers_by_id(s); 7340Sstevel@tonic-gate i=sk_SSL_CIPHER_find(sk,c); 7350Sstevel@tonic-gate if (i < 0) 7360Sstevel@tonic-gate { 7370Sstevel@tonic-gate /* we did not say we would use this cipher */ 7380Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 7390Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); 7400Sstevel@tonic-gate goto f_err; 7410Sstevel@tonic-gate } 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate /* Depending on the session caching (internal/external), the cipher 7440Sstevel@tonic-gate and/or cipher_id values may not be set. Make sure that 7450Sstevel@tonic-gate cipher_id is set and use it for comparison. */ 7460Sstevel@tonic-gate if (s->session->cipher) 7470Sstevel@tonic-gate s->session->cipher_id = s->session->cipher->id; 7480Sstevel@tonic-gate if (s->hit && (s->session->cipher_id != c->id)) 7490Sstevel@tonic-gate { 7500Sstevel@tonic-gate if (!(s->options & 7510Sstevel@tonic-gate SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) 7520Sstevel@tonic-gate { 7530Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 7540Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); 7550Sstevel@tonic-gate goto f_err; 7560Sstevel@tonic-gate } 7570Sstevel@tonic-gate } 7580Sstevel@tonic-gate s->s3->tmp.new_cipher=c; 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate /* lets get the compression algorithm */ 7610Sstevel@tonic-gate /* COMPRESSION */ 762*2139Sjp161948 #ifdef OPENSSL_NO_COMP 763*2139Sjp161948 if (*(p++) != 0) 764*2139Sjp161948 { 765*2139Sjp161948 al=SSL_AD_ILLEGAL_PARAMETER; 766*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 767*2139Sjp161948 goto f_err; 768*2139Sjp161948 } 769*2139Sjp161948 #else 7700Sstevel@tonic-gate j= *(p++); 7710Sstevel@tonic-gate if (j == 0) 7720Sstevel@tonic-gate comp=NULL; 7730Sstevel@tonic-gate else 7740Sstevel@tonic-gate comp=ssl3_comp_find(s->ctx->comp_methods,j); 7750Sstevel@tonic-gate 7760Sstevel@tonic-gate if ((j != 0) && (comp == NULL)) 7770Sstevel@tonic-gate { 7780Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 7790Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 7800Sstevel@tonic-gate goto f_err; 7810Sstevel@tonic-gate } 7820Sstevel@tonic-gate else 7830Sstevel@tonic-gate { 7840Sstevel@tonic-gate s->s3->tmp.new_compression=comp; 7850Sstevel@tonic-gate } 786*2139Sjp161948 #endif 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate if (p != (d+n)) 7890Sstevel@tonic-gate { 7900Sstevel@tonic-gate /* wrong packet length */ 7910Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 7920Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH); 7930Sstevel@tonic-gate goto err; 7940Sstevel@tonic-gate } 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate return(1); 7970Sstevel@tonic-gate f_err: 7980Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al); 7990Sstevel@tonic-gate err: 8000Sstevel@tonic-gate return(-1); 8010Sstevel@tonic-gate } 8020Sstevel@tonic-gate 803*2139Sjp161948 int ssl3_get_server_certificate(SSL *s) 8040Sstevel@tonic-gate { 8050Sstevel@tonic-gate int al,i,ok,ret= -1; 8060Sstevel@tonic-gate unsigned long n,nc,llen,l; 8070Sstevel@tonic-gate X509 *x=NULL; 808*2139Sjp161948 const unsigned char *q,*p; 809*2139Sjp161948 unsigned char *d; 8100Sstevel@tonic-gate STACK_OF(X509) *sk=NULL; 8110Sstevel@tonic-gate SESS_CERT *sc; 8120Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 813*2139Sjp161948 int need_cert = 1; /* VRS: 0=> will allow null cert if auth == KRB5 */ 8140Sstevel@tonic-gate 815*2139Sjp161948 n=s->method->ssl_get_message(s, 8160Sstevel@tonic-gate SSL3_ST_CR_CERT_A, 8170Sstevel@tonic-gate SSL3_ST_CR_CERT_B, 8180Sstevel@tonic-gate -1, 8190Sstevel@tonic-gate s->max_cert_list, 8200Sstevel@tonic-gate &ok); 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate if (!ok) return((int)n); 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) 8250Sstevel@tonic-gate { 8260Sstevel@tonic-gate s->s3->tmp.reuse_message=1; 8270Sstevel@tonic-gate return(1); 8280Sstevel@tonic-gate } 8290Sstevel@tonic-gate 8300Sstevel@tonic-gate if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) 8310Sstevel@tonic-gate { 8320Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE; 8330Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE); 8340Sstevel@tonic-gate goto f_err; 8350Sstevel@tonic-gate } 836*2139Sjp161948 p=d=(unsigned char *)s->init_msg; 8370Sstevel@tonic-gate 8380Sstevel@tonic-gate if ((sk=sk_X509_new_null()) == NULL) 8390Sstevel@tonic-gate { 8400Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE); 8410Sstevel@tonic-gate goto err; 8420Sstevel@tonic-gate } 8430Sstevel@tonic-gate 8440Sstevel@tonic-gate n2l3(p,llen); 8450Sstevel@tonic-gate if (llen+3 != n) 8460Sstevel@tonic-gate { 8470Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 8480Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH); 8490Sstevel@tonic-gate goto f_err; 8500Sstevel@tonic-gate } 8510Sstevel@tonic-gate for (nc=0; nc<llen; ) 8520Sstevel@tonic-gate { 8530Sstevel@tonic-gate n2l3(p,l); 8540Sstevel@tonic-gate if ((l+nc+3) > llen) 8550Sstevel@tonic-gate { 8560Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 8570Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); 8580Sstevel@tonic-gate goto f_err; 8590Sstevel@tonic-gate } 8600Sstevel@tonic-gate 8610Sstevel@tonic-gate q=p; 8620Sstevel@tonic-gate x=d2i_X509(NULL,&q,l); 8630Sstevel@tonic-gate if (x == NULL) 8640Sstevel@tonic-gate { 8650Sstevel@tonic-gate al=SSL_AD_BAD_CERTIFICATE; 8660Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB); 8670Sstevel@tonic-gate goto f_err; 8680Sstevel@tonic-gate } 8690Sstevel@tonic-gate if (q != (p+l)) 8700Sstevel@tonic-gate { 8710Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 8720Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); 8730Sstevel@tonic-gate goto f_err; 8740Sstevel@tonic-gate } 8750Sstevel@tonic-gate if (!sk_X509_push(sk,x)) 8760Sstevel@tonic-gate { 8770Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE); 8780Sstevel@tonic-gate goto err; 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate x=NULL; 8810Sstevel@tonic-gate nc+=l+3; 8820Sstevel@tonic-gate p=q; 8830Sstevel@tonic-gate } 8840Sstevel@tonic-gate 8850Sstevel@tonic-gate i=ssl_verify_cert_chain(s,sk); 8860Sstevel@tonic-gate if ((s->verify_mode != SSL_VERIFY_NONE) && (!i) 8870Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5 888*2139Sjp161948 && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) 889*2139Sjp161948 != (SSL_aKRB5|SSL_kKRB5) 8900Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */ 891*2139Sjp161948 ) 8920Sstevel@tonic-gate { 8930Sstevel@tonic-gate al=ssl_verify_alarm_type(s->verify_result); 8940Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); 8950Sstevel@tonic-gate goto f_err; 8960Sstevel@tonic-gate } 8970Sstevel@tonic-gate ERR_clear_error(); /* but we keep s->verify_result */ 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate sc=ssl_sess_cert_new(); 9000Sstevel@tonic-gate if (sc == NULL) goto err; 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert); 9030Sstevel@tonic-gate s->session->sess_cert=sc; 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate sc->cert_chain=sk; 9060Sstevel@tonic-gate /* Inconsistency alert: cert_chain does include the peer's 9070Sstevel@tonic-gate * certificate, which we don't include in s3_srvr.c */ 9080Sstevel@tonic-gate x=sk_X509_value(sk,0); 9090Sstevel@tonic-gate sk=NULL; 9100Sstevel@tonic-gate /* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/ 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate pkey=X509_get_pubkey(x); 9130Sstevel@tonic-gate 914*2139Sjp161948 /* VRS: allow null cert if auth == KRB5 */ 915*2139Sjp161948 need_cert = ((s->s3->tmp.new_cipher->algorithms 916*2139Sjp161948 & (SSL_MKEY_MASK|SSL_AUTH_MASK)) 917*2139Sjp161948 == (SSL_aKRB5|SSL_kKRB5))? 0: 1; 9180Sstevel@tonic-gate 9190Sstevel@tonic-gate #ifdef KSSL_DEBUG 9200Sstevel@tonic-gate printf("pkey,x = %p, %p\n", pkey,x); 9210Sstevel@tonic-gate printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey)); 9220Sstevel@tonic-gate printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name, 923*2139Sjp161948 s->s3->tmp.new_cipher->algorithms, need_cert); 9240Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) 9270Sstevel@tonic-gate { 9280Sstevel@tonic-gate x=NULL; 9290Sstevel@tonic-gate al=SSL3_AL_FATAL; 9300Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, 9310Sstevel@tonic-gate SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); 9320Sstevel@tonic-gate goto f_err; 9330Sstevel@tonic-gate } 9340Sstevel@tonic-gate 9350Sstevel@tonic-gate i=ssl_cert_type(x,pkey); 9360Sstevel@tonic-gate if (need_cert && i < 0) 9370Sstevel@tonic-gate { 9380Sstevel@tonic-gate x=NULL; 9390Sstevel@tonic-gate al=SSL3_AL_FATAL; 9400Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, 9410Sstevel@tonic-gate SSL_R_UNKNOWN_CERTIFICATE_TYPE); 9420Sstevel@tonic-gate goto f_err; 9430Sstevel@tonic-gate } 9440Sstevel@tonic-gate 945*2139Sjp161948 if (need_cert) 946*2139Sjp161948 { 947*2139Sjp161948 sc->peer_cert_type=i; 948*2139Sjp161948 CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); 949*2139Sjp161948 /* Why would the following ever happen? 950*2139Sjp161948 * We just created sc a couple of lines ago. */ 951*2139Sjp161948 if (sc->peer_pkeys[i].x509 != NULL) 952*2139Sjp161948 X509_free(sc->peer_pkeys[i].x509); 953*2139Sjp161948 sc->peer_pkeys[i].x509=x; 954*2139Sjp161948 sc->peer_key= &(sc->peer_pkeys[i]); 9550Sstevel@tonic-gate 956*2139Sjp161948 if (s->session->peer != NULL) 957*2139Sjp161948 X509_free(s->session->peer); 958*2139Sjp161948 CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); 959*2139Sjp161948 s->session->peer=x; 960*2139Sjp161948 } 961*2139Sjp161948 else 962*2139Sjp161948 { 963*2139Sjp161948 sc->peer_cert_type=i; 964*2139Sjp161948 sc->peer_key= NULL; 9650Sstevel@tonic-gate 966*2139Sjp161948 if (s->session->peer != NULL) 967*2139Sjp161948 X509_free(s->session->peer); 968*2139Sjp161948 s->session->peer=NULL; 969*2139Sjp161948 } 9700Sstevel@tonic-gate s->session->verify_result = s->verify_result; 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate x=NULL; 9730Sstevel@tonic-gate ret=1; 9740Sstevel@tonic-gate 9750Sstevel@tonic-gate if (0) 9760Sstevel@tonic-gate { 9770Sstevel@tonic-gate f_err: 9780Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al); 9790Sstevel@tonic-gate } 9800Sstevel@tonic-gate err: 9810Sstevel@tonic-gate EVP_PKEY_free(pkey); 9820Sstevel@tonic-gate X509_free(x); 9830Sstevel@tonic-gate sk_X509_pop_free(sk,X509_free); 9840Sstevel@tonic-gate return(ret); 9850Sstevel@tonic-gate } 9860Sstevel@tonic-gate 987*2139Sjp161948 int ssl3_get_key_exchange(SSL *s) 9880Sstevel@tonic-gate { 9890Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 9900Sstevel@tonic-gate unsigned char *q,md_buf[EVP_MAX_MD_SIZE*2]; 9910Sstevel@tonic-gate #endif 9920Sstevel@tonic-gate EVP_MD_CTX md_ctx; 9930Sstevel@tonic-gate unsigned char *param,*p; 9940Sstevel@tonic-gate int al,i,j,param_len,ok; 9950Sstevel@tonic-gate long n,alg; 9960Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 9970Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 9980Sstevel@tonic-gate RSA *rsa=NULL; 9990Sstevel@tonic-gate #endif 10000Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 10010Sstevel@tonic-gate DH *dh=NULL; 10020Sstevel@tonic-gate #endif 1003*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1004*2139Sjp161948 EC_KEY *ecdh = NULL; 1005*2139Sjp161948 BN_CTX *bn_ctx = NULL; 1006*2139Sjp161948 EC_POINT *srvr_ecpoint = NULL; 1007*2139Sjp161948 int curve_nid = 0; 1008*2139Sjp161948 int encoded_pt_len = 0; 1009*2139Sjp161948 #endif 10100Sstevel@tonic-gate 10110Sstevel@tonic-gate /* use same message size as in ssl3_get_certificate_request() 10120Sstevel@tonic-gate * as ServerKeyExchange message may be skipped */ 1013*2139Sjp161948 n=s->method->ssl_get_message(s, 10140Sstevel@tonic-gate SSL3_ST_CR_KEY_EXCH_A, 10150Sstevel@tonic-gate SSL3_ST_CR_KEY_EXCH_B, 10160Sstevel@tonic-gate -1, 10170Sstevel@tonic-gate s->max_cert_list, 10180Sstevel@tonic-gate &ok); 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate if (!ok) return((int)n); 10210Sstevel@tonic-gate 10220Sstevel@tonic-gate if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) 10230Sstevel@tonic-gate { 10240Sstevel@tonic-gate s->s3->tmp.reuse_message=1; 10250Sstevel@tonic-gate return(1); 10260Sstevel@tonic-gate } 10270Sstevel@tonic-gate 10280Sstevel@tonic-gate param=p=(unsigned char *)s->init_msg; 10290Sstevel@tonic-gate 10300Sstevel@tonic-gate if (s->session->sess_cert != NULL) 10310Sstevel@tonic-gate { 10320Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 10330Sstevel@tonic-gate if (s->session->sess_cert->peer_rsa_tmp != NULL) 10340Sstevel@tonic-gate { 10350Sstevel@tonic-gate RSA_free(s->session->sess_cert->peer_rsa_tmp); 10360Sstevel@tonic-gate s->session->sess_cert->peer_rsa_tmp=NULL; 10370Sstevel@tonic-gate } 10380Sstevel@tonic-gate #endif 10390Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 10400Sstevel@tonic-gate if (s->session->sess_cert->peer_dh_tmp) 10410Sstevel@tonic-gate { 10420Sstevel@tonic-gate DH_free(s->session->sess_cert->peer_dh_tmp); 10430Sstevel@tonic-gate s->session->sess_cert->peer_dh_tmp=NULL; 10440Sstevel@tonic-gate } 10450Sstevel@tonic-gate #endif 1046*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1047*2139Sjp161948 if (s->session->sess_cert->peer_ecdh_tmp) 1048*2139Sjp161948 { 1049*2139Sjp161948 EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); 1050*2139Sjp161948 s->session->sess_cert->peer_ecdh_tmp=NULL; 1051*2139Sjp161948 } 1052*2139Sjp161948 #endif 10530Sstevel@tonic-gate } 10540Sstevel@tonic-gate else 10550Sstevel@tonic-gate { 10560Sstevel@tonic-gate s->session->sess_cert=ssl_sess_cert_new(); 10570Sstevel@tonic-gate } 10580Sstevel@tonic-gate 10590Sstevel@tonic-gate param_len=0; 10600Sstevel@tonic-gate alg=s->s3->tmp.new_cipher->algorithms; 10610Sstevel@tonic-gate EVP_MD_CTX_init(&md_ctx); 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 10640Sstevel@tonic-gate if (alg & SSL_kRSA) 10650Sstevel@tonic-gate { 10660Sstevel@tonic-gate if ((rsa=RSA_new()) == NULL) 10670Sstevel@tonic-gate { 10680Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 10690Sstevel@tonic-gate goto err; 10700Sstevel@tonic-gate } 10710Sstevel@tonic-gate n2s(p,i); 10720Sstevel@tonic-gate param_len=i+2; 10730Sstevel@tonic-gate if (param_len > n) 10740Sstevel@tonic-gate { 10750Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 10760Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH); 10770Sstevel@tonic-gate goto f_err; 10780Sstevel@tonic-gate } 10790Sstevel@tonic-gate if (!(rsa->n=BN_bin2bn(p,i,rsa->n))) 10800Sstevel@tonic-gate { 10810Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); 10820Sstevel@tonic-gate goto err; 10830Sstevel@tonic-gate } 10840Sstevel@tonic-gate p+=i; 10850Sstevel@tonic-gate 10860Sstevel@tonic-gate n2s(p,i); 10870Sstevel@tonic-gate param_len+=i+2; 10880Sstevel@tonic-gate if (param_len > n) 10890Sstevel@tonic-gate { 10900Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 10910Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH); 10920Sstevel@tonic-gate goto f_err; 10930Sstevel@tonic-gate } 10940Sstevel@tonic-gate if (!(rsa->e=BN_bin2bn(p,i,rsa->e))) 10950Sstevel@tonic-gate { 10960Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); 10970Sstevel@tonic-gate goto err; 10980Sstevel@tonic-gate } 10990Sstevel@tonic-gate p+=i; 11000Sstevel@tonic-gate n-=param_len; 11010Sstevel@tonic-gate 11020Sstevel@tonic-gate /* this should be because we are using an export cipher */ 11030Sstevel@tonic-gate if (alg & SSL_aRSA) 11040Sstevel@tonic-gate pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); 11050Sstevel@tonic-gate else 11060Sstevel@tonic-gate { 11070Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 11080Sstevel@tonic-gate goto err; 11090Sstevel@tonic-gate } 11100Sstevel@tonic-gate s->session->sess_cert->peer_rsa_tmp=rsa; 11110Sstevel@tonic-gate rsa=NULL; 11120Sstevel@tonic-gate } 11130Sstevel@tonic-gate #else /* OPENSSL_NO_RSA */ 11140Sstevel@tonic-gate if (0) 11150Sstevel@tonic-gate ; 11160Sstevel@tonic-gate #endif 11170Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 11180Sstevel@tonic-gate else if (alg & SSL_kEDH) 11190Sstevel@tonic-gate { 11200Sstevel@tonic-gate if ((dh=DH_new()) == NULL) 11210Sstevel@tonic-gate { 11220Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB); 11230Sstevel@tonic-gate goto err; 11240Sstevel@tonic-gate } 11250Sstevel@tonic-gate n2s(p,i); 11260Sstevel@tonic-gate param_len=i+2; 11270Sstevel@tonic-gate if (param_len > n) 11280Sstevel@tonic-gate { 11290Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 11300Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH); 11310Sstevel@tonic-gate goto f_err; 11320Sstevel@tonic-gate } 11330Sstevel@tonic-gate if (!(dh->p=BN_bin2bn(p,i,NULL))) 11340Sstevel@tonic-gate { 11350Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); 11360Sstevel@tonic-gate goto err; 11370Sstevel@tonic-gate } 11380Sstevel@tonic-gate p+=i; 11390Sstevel@tonic-gate 11400Sstevel@tonic-gate n2s(p,i); 11410Sstevel@tonic-gate param_len+=i+2; 11420Sstevel@tonic-gate if (param_len > n) 11430Sstevel@tonic-gate { 11440Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 11450Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH); 11460Sstevel@tonic-gate goto f_err; 11470Sstevel@tonic-gate } 11480Sstevel@tonic-gate if (!(dh->g=BN_bin2bn(p,i,NULL))) 11490Sstevel@tonic-gate { 11500Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); 11510Sstevel@tonic-gate goto err; 11520Sstevel@tonic-gate } 11530Sstevel@tonic-gate p+=i; 11540Sstevel@tonic-gate 11550Sstevel@tonic-gate n2s(p,i); 11560Sstevel@tonic-gate param_len+=i+2; 11570Sstevel@tonic-gate if (param_len > n) 11580Sstevel@tonic-gate { 11590Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 11600Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH); 11610Sstevel@tonic-gate goto f_err; 11620Sstevel@tonic-gate } 11630Sstevel@tonic-gate if (!(dh->pub_key=BN_bin2bn(p,i,NULL))) 11640Sstevel@tonic-gate { 11650Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); 11660Sstevel@tonic-gate goto err; 11670Sstevel@tonic-gate } 11680Sstevel@tonic-gate p+=i; 11690Sstevel@tonic-gate n-=param_len; 11700Sstevel@tonic-gate 11710Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 11720Sstevel@tonic-gate if (alg & SSL_aRSA) 11730Sstevel@tonic-gate pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); 11740Sstevel@tonic-gate #else 11750Sstevel@tonic-gate if (0) 11760Sstevel@tonic-gate ; 11770Sstevel@tonic-gate #endif 11780Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 11790Sstevel@tonic-gate else if (alg & SSL_aDSS) 11800Sstevel@tonic-gate pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509); 11810Sstevel@tonic-gate #endif 11820Sstevel@tonic-gate /* else anonymous DH, so no certificate or pkey. */ 11830Sstevel@tonic-gate 11840Sstevel@tonic-gate s->session->sess_cert->peer_dh_tmp=dh; 11850Sstevel@tonic-gate dh=NULL; 11860Sstevel@tonic-gate } 11870Sstevel@tonic-gate else if ((alg & SSL_kDHr) || (alg & SSL_kDHd)) 11880Sstevel@tonic-gate { 11890Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER; 11900Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); 11910Sstevel@tonic-gate goto f_err; 11920Sstevel@tonic-gate } 11930Sstevel@tonic-gate #endif /* !OPENSSL_NO_DH */ 1194*2139Sjp161948 1195*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1196*2139Sjp161948 else if (alg & SSL_kECDHE) 1197*2139Sjp161948 { 1198*2139Sjp161948 EC_GROUP *ngroup; 1199*2139Sjp161948 const EC_GROUP *group; 1200*2139Sjp161948 1201*2139Sjp161948 if ((ecdh=EC_KEY_new()) == NULL) 1202*2139Sjp161948 { 1203*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1204*2139Sjp161948 goto err; 1205*2139Sjp161948 } 1206*2139Sjp161948 1207*2139Sjp161948 /* Extract elliptic curve parameters and the 1208*2139Sjp161948 * server's ephemeral ECDH public key. 1209*2139Sjp161948 * Keep accumulating lengths of various components in 1210*2139Sjp161948 * param_len and make sure it never exceeds n. 1211*2139Sjp161948 */ 1212*2139Sjp161948 1213*2139Sjp161948 /* XXX: For now we only support named (not generic) curves 1214*2139Sjp161948 * and the ECParameters in this case is just two bytes. 1215*2139Sjp161948 */ 1216*2139Sjp161948 param_len=2; 1217*2139Sjp161948 if ((param_len > n) || 1218*2139Sjp161948 (*p != NAMED_CURVE_TYPE) || 1219*2139Sjp161948 ((curve_nid = curve_id2nid(*(p + 1))) == 0)) 1220*2139Sjp161948 { 1221*2139Sjp161948 al=SSL_AD_INTERNAL_ERROR; 1222*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); 1223*2139Sjp161948 goto f_err; 1224*2139Sjp161948 } 1225*2139Sjp161948 1226*2139Sjp161948 ngroup = EC_GROUP_new_by_curve_name(curve_nid); 1227*2139Sjp161948 if (ngroup == NULL) 1228*2139Sjp161948 { 1229*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB); 1230*2139Sjp161948 goto err; 1231*2139Sjp161948 } 1232*2139Sjp161948 if (EC_KEY_set_group(ecdh, ngroup) == 0) 1233*2139Sjp161948 { 1234*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB); 1235*2139Sjp161948 goto err; 1236*2139Sjp161948 } 1237*2139Sjp161948 EC_GROUP_free(ngroup); 1238*2139Sjp161948 1239*2139Sjp161948 group = EC_KEY_get0_group(ecdh); 1240*2139Sjp161948 1241*2139Sjp161948 if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && 1242*2139Sjp161948 (EC_GROUP_get_degree(group) > 163)) 1243*2139Sjp161948 { 1244*2139Sjp161948 al=SSL_AD_EXPORT_RESTRICTION; 1245*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); 1246*2139Sjp161948 goto f_err; 1247*2139Sjp161948 } 1248*2139Sjp161948 1249*2139Sjp161948 p+=2; 1250*2139Sjp161948 1251*2139Sjp161948 /* Next, get the encoded ECPoint */ 1252*2139Sjp161948 if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || 1253*2139Sjp161948 ((bn_ctx = BN_CTX_new()) == NULL)) 1254*2139Sjp161948 { 1255*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1256*2139Sjp161948 goto err; 1257*2139Sjp161948 } 1258*2139Sjp161948 1259*2139Sjp161948 encoded_pt_len = *p; /* length of encoded point */ 1260*2139Sjp161948 p+=1; 1261*2139Sjp161948 param_len += (1 + encoded_pt_len); 1262*2139Sjp161948 if ((param_len > n) || 1263*2139Sjp161948 (EC_POINT_oct2point(group, srvr_ecpoint, 1264*2139Sjp161948 p, encoded_pt_len, bn_ctx) == 0)) 1265*2139Sjp161948 { 1266*2139Sjp161948 al=SSL_AD_DECODE_ERROR; 1267*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT); 1268*2139Sjp161948 goto f_err; 1269*2139Sjp161948 } 1270*2139Sjp161948 1271*2139Sjp161948 n-=param_len; 1272*2139Sjp161948 p+=encoded_pt_len; 1273*2139Sjp161948 1274*2139Sjp161948 /* The ECC/TLS specification does not mention 1275*2139Sjp161948 * the use of DSA to sign ECParameters in the server 1276*2139Sjp161948 * key exchange message. We do support RSA and ECDSA. 1277*2139Sjp161948 */ 1278*2139Sjp161948 if (0) ; 1279*2139Sjp161948 #ifndef OPENSSL_NO_RSA 1280*2139Sjp161948 else if (alg & SSL_aRSA) 1281*2139Sjp161948 pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); 1282*2139Sjp161948 #endif 1283*2139Sjp161948 #ifndef OPENSSL_NO_ECDSA 1284*2139Sjp161948 else if (alg & SSL_aECDSA) 1285*2139Sjp161948 pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); 1286*2139Sjp161948 #endif 1287*2139Sjp161948 /* else anonymous ECDH, so no certificate or pkey. */ 1288*2139Sjp161948 EC_KEY_set_public_key(ecdh, srvr_ecpoint); 1289*2139Sjp161948 s->session->sess_cert->peer_ecdh_tmp=ecdh; 1290*2139Sjp161948 ecdh=NULL; 1291*2139Sjp161948 BN_CTX_free(bn_ctx); 1292*2139Sjp161948 EC_POINT_free(srvr_ecpoint); 1293*2139Sjp161948 srvr_ecpoint = NULL; 1294*2139Sjp161948 } 1295*2139Sjp161948 else if (alg & SSL_kECDH) 1296*2139Sjp161948 { 1297*2139Sjp161948 al=SSL_AD_UNEXPECTED_MESSAGE; 1298*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); 1299*2139Sjp161948 goto f_err; 1300*2139Sjp161948 } 1301*2139Sjp161948 #endif /* !OPENSSL_NO_ECDH */ 13020Sstevel@tonic-gate if (alg & SSL_aFZA) 13030Sstevel@tonic-gate { 13040Sstevel@tonic-gate al=SSL_AD_HANDSHAKE_FAILURE; 13050Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); 13060Sstevel@tonic-gate goto f_err; 13070Sstevel@tonic-gate } 13080Sstevel@tonic-gate 13090Sstevel@tonic-gate 13100Sstevel@tonic-gate /* p points to the next byte, there are 'n' bytes left */ 13110Sstevel@tonic-gate 13120Sstevel@tonic-gate /* if it was signed, check the signature */ 13130Sstevel@tonic-gate if (pkey != NULL) 13140Sstevel@tonic-gate { 13150Sstevel@tonic-gate n2s(p,i); 13160Sstevel@tonic-gate n-=2; 13170Sstevel@tonic-gate j=EVP_PKEY_size(pkey); 13180Sstevel@tonic-gate 13190Sstevel@tonic-gate if ((i != n) || (n > j) || (n <= 0)) 13200Sstevel@tonic-gate { 13210Sstevel@tonic-gate /* wrong packet length */ 13220Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 13230Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH); 13240Sstevel@tonic-gate goto f_err; 13250Sstevel@tonic-gate } 13260Sstevel@tonic-gate 13270Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 13280Sstevel@tonic-gate if (pkey->type == EVP_PKEY_RSA) 13290Sstevel@tonic-gate { 13300Sstevel@tonic-gate int num; 13310Sstevel@tonic-gate 13320Sstevel@tonic-gate j=0; 13330Sstevel@tonic-gate q=md_buf; 13340Sstevel@tonic-gate for (num=2; num > 0; num--) 13350Sstevel@tonic-gate { 13360Sstevel@tonic-gate EVP_DigestInit_ex(&md_ctx,(num == 2) 13370Sstevel@tonic-gate ?s->ctx->md5:s->ctx->sha1, NULL); 13380Sstevel@tonic-gate EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); 13390Sstevel@tonic-gate EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); 13400Sstevel@tonic-gate EVP_DigestUpdate(&md_ctx,param,param_len); 13410Sstevel@tonic-gate EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i); 13420Sstevel@tonic-gate q+=i; 13430Sstevel@tonic-gate j+=i; 13440Sstevel@tonic-gate } 13450Sstevel@tonic-gate i=RSA_verify(NID_md5_sha1, md_buf, j, p, n, 13460Sstevel@tonic-gate pkey->pkey.rsa); 13470Sstevel@tonic-gate if (i < 0) 13480Sstevel@tonic-gate { 13490Sstevel@tonic-gate al=SSL_AD_DECRYPT_ERROR; 13500Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); 13510Sstevel@tonic-gate goto f_err; 13520Sstevel@tonic-gate } 13530Sstevel@tonic-gate if (i == 0) 13540Sstevel@tonic-gate { 13550Sstevel@tonic-gate /* bad signature */ 13560Sstevel@tonic-gate al=SSL_AD_DECRYPT_ERROR; 13570Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE); 13580Sstevel@tonic-gate goto f_err; 13590Sstevel@tonic-gate } 13600Sstevel@tonic-gate } 13610Sstevel@tonic-gate else 13620Sstevel@tonic-gate #endif 13630Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 13640Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 13650Sstevel@tonic-gate { 13660Sstevel@tonic-gate /* lets do DSS */ 13670Sstevel@tonic-gate EVP_VerifyInit_ex(&md_ctx,EVP_dss1(), NULL); 13680Sstevel@tonic-gate EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); 13690Sstevel@tonic-gate EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); 13700Sstevel@tonic-gate EVP_VerifyUpdate(&md_ctx,param,param_len); 13710Sstevel@tonic-gate if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) 13720Sstevel@tonic-gate { 13730Sstevel@tonic-gate /* bad signature */ 13740Sstevel@tonic-gate al=SSL_AD_DECRYPT_ERROR; 13750Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE); 13760Sstevel@tonic-gate goto f_err; 13770Sstevel@tonic-gate } 13780Sstevel@tonic-gate } 13790Sstevel@tonic-gate else 13800Sstevel@tonic-gate #endif 1381*2139Sjp161948 #ifndef OPENSSL_NO_ECDSA 1382*2139Sjp161948 if (pkey->type == EVP_PKEY_EC) 1383*2139Sjp161948 { 1384*2139Sjp161948 /* let's do ECDSA */ 1385*2139Sjp161948 EVP_VerifyInit_ex(&md_ctx,EVP_ecdsa(), NULL); 1386*2139Sjp161948 EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); 1387*2139Sjp161948 EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); 1388*2139Sjp161948 EVP_VerifyUpdate(&md_ctx,param,param_len); 1389*2139Sjp161948 if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) 1390*2139Sjp161948 { 1391*2139Sjp161948 /* bad signature */ 1392*2139Sjp161948 al=SSL_AD_DECRYPT_ERROR; 1393*2139Sjp161948 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE); 1394*2139Sjp161948 goto f_err; 1395*2139Sjp161948 } 1396*2139Sjp161948 } 1397*2139Sjp161948 else 1398*2139Sjp161948 #endif 13990Sstevel@tonic-gate { 14000Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 14010Sstevel@tonic-gate goto err; 14020Sstevel@tonic-gate } 14030Sstevel@tonic-gate } 14040Sstevel@tonic-gate else 14050Sstevel@tonic-gate { 14060Sstevel@tonic-gate /* still data left over */ 14070Sstevel@tonic-gate if (!(alg & SSL_aNULL)) 14080Sstevel@tonic-gate { 14090Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 14100Sstevel@tonic-gate goto err; 14110Sstevel@tonic-gate } 14120Sstevel@tonic-gate if (n != 0) 14130Sstevel@tonic-gate { 14140Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR; 14150Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE); 14160Sstevel@tonic-gate goto f_err; 14170Sstevel@tonic-gate } 14180Sstevel@tonic-gate } 14190Sstevel@tonic-gate EVP_PKEY_free(pkey); 14200Sstevel@tonic-gate EVP_MD_CTX_cleanup(&md_ctx); 14210Sstevel@tonic-gate return(1); 14220Sstevel@tonic-gate f_err: 14230Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al); 14240Sstevel@tonic-gate err: 14250Sstevel@tonic-gate EVP_PKEY_free(pkey); 14260Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 14270Sstevel@tonic-gate if (rsa != NULL) 14280Sstevel@tonic-gate RSA_free(rsa); 14290Sstevel@tonic-gate #endif 14300Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 14310Sstevel@tonic-gate if (dh != NULL) 14320Sstevel@tonic-gate DH_free(dh); 14330Sstevel@tonic-gate #endif 1434*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1435*2139Sjp161948 BN_CTX_free(bn_ctx); 1436*2139Sjp161948 EC_POINT_free(srvr_ecpoint); 1437*2139Sjp161948 if (ecdh != NULL) 1438*2139Sjp161948 EC_KEY_free(ecdh); 1439*2139Sjp161948 #endif 14400Sstevel@tonic-gate EVP_MD_CTX_cleanup(&md_ctx); 14410Sstevel@tonic-gate return(-1); 14420Sstevel@tonic-gate } 14430Sstevel@tonic-gate 1444*2139Sjp161948 int ssl3_get_certificate_request(SSL *s) 14450Sstevel@tonic-gate { 14460Sstevel@tonic-gate int ok,ret=0; 14470Sstevel@tonic-gate unsigned long n,nc,l; 14480Sstevel@tonic-gate unsigned int llen,ctype_num,i; 14490Sstevel@tonic-gate X509_NAME *xn=NULL; 1450*2139Sjp161948 const unsigned char *p,*q; 1451*2139Sjp161948 unsigned char *d; 14520Sstevel@tonic-gate STACK_OF(X509_NAME) *ca_sk=NULL; 14530Sstevel@tonic-gate 1454*2139Sjp161948 n=s->method->ssl_get_message(s, 14550Sstevel@tonic-gate SSL3_ST_CR_CERT_REQ_A, 14560Sstevel@tonic-gate SSL3_ST_CR_CERT_REQ_B, 14570Sstevel@tonic-gate -1, 14580Sstevel@tonic-gate s->max_cert_list, 14590Sstevel@tonic-gate &ok); 14600Sstevel@tonic-gate 14610Sstevel@tonic-gate if (!ok) return((int)n); 14620Sstevel@tonic-gate 14630Sstevel@tonic-gate s->s3->tmp.cert_req=0; 14640Sstevel@tonic-gate 14650Sstevel@tonic-gate if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) 14660Sstevel@tonic-gate { 14670Sstevel@tonic-gate s->s3->tmp.reuse_message=1; 14680Sstevel@tonic-gate return(1); 14690Sstevel@tonic-gate } 14700Sstevel@tonic-gate 14710Sstevel@tonic-gate if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) 14720Sstevel@tonic-gate { 14730Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); 14740Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE); 14750Sstevel@tonic-gate goto err; 14760Sstevel@tonic-gate } 14770Sstevel@tonic-gate 14780Sstevel@tonic-gate /* TLS does not like anon-DH with client cert */ 14790Sstevel@tonic-gate if (s->version > SSL3_VERSION) 14800Sstevel@tonic-gate { 14810Sstevel@tonic-gate l=s->s3->tmp.new_cipher->algorithms; 14820Sstevel@tonic-gate if (l & SSL_aNULL) 14830Sstevel@tonic-gate { 14840Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); 14850Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); 14860Sstevel@tonic-gate goto err; 14870Sstevel@tonic-gate } 14880Sstevel@tonic-gate } 14890Sstevel@tonic-gate 1490*2139Sjp161948 p=d=(unsigned char *)s->init_msg; 14910Sstevel@tonic-gate 14920Sstevel@tonic-gate if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL) 14930Sstevel@tonic-gate { 14940Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE); 14950Sstevel@tonic-gate goto err; 14960Sstevel@tonic-gate } 14970Sstevel@tonic-gate 14980Sstevel@tonic-gate /* get the certificate types */ 14990Sstevel@tonic-gate ctype_num= *(p++); 15000Sstevel@tonic-gate if (ctype_num > SSL3_CT_NUMBER) 15010Sstevel@tonic-gate ctype_num=SSL3_CT_NUMBER; 15020Sstevel@tonic-gate for (i=0; i<ctype_num; i++) 15030Sstevel@tonic-gate s->s3->tmp.ctype[i]= p[i]; 15040Sstevel@tonic-gate p+=ctype_num; 15050Sstevel@tonic-gate 15060Sstevel@tonic-gate /* get the CA RDNs */ 15070Sstevel@tonic-gate n2s(p,llen); 15080Sstevel@tonic-gate #if 0 15090Sstevel@tonic-gate { 15100Sstevel@tonic-gate FILE *out; 15110Sstevel@tonic-gate out=fopen("/tmp/vsign.der","w"); 15120Sstevel@tonic-gate fwrite(p,1,llen,out); 15130Sstevel@tonic-gate fclose(out); 15140Sstevel@tonic-gate } 15150Sstevel@tonic-gate #endif 15160Sstevel@tonic-gate 15170Sstevel@tonic-gate if ((llen+ctype_num+2+1) != n) 15180Sstevel@tonic-gate { 15190Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); 15200Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH); 15210Sstevel@tonic-gate goto err; 15220Sstevel@tonic-gate } 15230Sstevel@tonic-gate 15240Sstevel@tonic-gate for (nc=0; nc<llen; ) 15250Sstevel@tonic-gate { 15260Sstevel@tonic-gate n2s(p,l); 15270Sstevel@tonic-gate if ((l+nc+2) > llen) 15280Sstevel@tonic-gate { 15290Sstevel@tonic-gate if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) 15300Sstevel@tonic-gate goto cont; /* netscape bugs */ 15310Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); 15320Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG); 15330Sstevel@tonic-gate goto err; 15340Sstevel@tonic-gate } 15350Sstevel@tonic-gate 15360Sstevel@tonic-gate q=p; 15370Sstevel@tonic-gate 15380Sstevel@tonic-gate if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL) 15390Sstevel@tonic-gate { 15400Sstevel@tonic-gate /* If netscape tolerance is on, ignore errors */ 15410Sstevel@tonic-gate if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) 15420Sstevel@tonic-gate goto cont; 15430Sstevel@tonic-gate else 15440Sstevel@tonic-gate { 15450Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); 15460Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB); 15470Sstevel@tonic-gate goto err; 15480Sstevel@tonic-gate } 15490Sstevel@tonic-gate } 15500Sstevel@tonic-gate 15510Sstevel@tonic-gate if (q != (p+l)) 15520Sstevel@tonic-gate { 15530Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); 15540Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH); 15550Sstevel@tonic-gate goto err; 15560Sstevel@tonic-gate } 15570Sstevel@tonic-gate if (!sk_X509_NAME_push(ca_sk,xn)) 15580Sstevel@tonic-gate { 15590Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE); 15600Sstevel@tonic-gate goto err; 15610Sstevel@tonic-gate } 15620Sstevel@tonic-gate 15630Sstevel@tonic-gate p+=l; 15640Sstevel@tonic-gate nc+=l+2; 15650Sstevel@tonic-gate } 15660Sstevel@tonic-gate 15670Sstevel@tonic-gate if (0) 15680Sstevel@tonic-gate { 15690Sstevel@tonic-gate cont: 15700Sstevel@tonic-gate ERR_clear_error(); 15710Sstevel@tonic-gate } 15720Sstevel@tonic-gate 15730Sstevel@tonic-gate /* we should setup a certificate to return.... */ 15740Sstevel@tonic-gate s->s3->tmp.cert_req=1; 15750Sstevel@tonic-gate s->s3->tmp.ctype_num=ctype_num; 15760Sstevel@tonic-gate if (s->s3->tmp.ca_names != NULL) 15770Sstevel@tonic-gate sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free); 15780Sstevel@tonic-gate s->s3->tmp.ca_names=ca_sk; 15790Sstevel@tonic-gate ca_sk=NULL; 15800Sstevel@tonic-gate 15810Sstevel@tonic-gate ret=1; 15820Sstevel@tonic-gate err: 15830Sstevel@tonic-gate if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free); 15840Sstevel@tonic-gate return(ret); 15850Sstevel@tonic-gate } 15860Sstevel@tonic-gate 15870Sstevel@tonic-gate static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) 15880Sstevel@tonic-gate { 15890Sstevel@tonic-gate return(X509_NAME_cmp(*a,*b)); 15900Sstevel@tonic-gate } 15910Sstevel@tonic-gate 1592*2139Sjp161948 int ssl3_get_server_done(SSL *s) 15930Sstevel@tonic-gate { 15940Sstevel@tonic-gate int ok,ret=0; 15950Sstevel@tonic-gate long n; 15960Sstevel@tonic-gate 1597*2139Sjp161948 n=s->method->ssl_get_message(s, 15980Sstevel@tonic-gate SSL3_ST_CR_SRVR_DONE_A, 15990Sstevel@tonic-gate SSL3_ST_CR_SRVR_DONE_B, 16000Sstevel@tonic-gate SSL3_MT_SERVER_DONE, 16010Sstevel@tonic-gate 30, /* should be very small, like 0 :-) */ 16020Sstevel@tonic-gate &ok); 16030Sstevel@tonic-gate 16040Sstevel@tonic-gate if (!ok) return((int)n); 16050Sstevel@tonic-gate if (n > 0) 16060Sstevel@tonic-gate { 16070Sstevel@tonic-gate /* should contain no data */ 16080Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); 16090Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH); 16100Sstevel@tonic-gate return -1; 16110Sstevel@tonic-gate } 16120Sstevel@tonic-gate ret=1; 16130Sstevel@tonic-gate return(ret); 16140Sstevel@tonic-gate } 16150Sstevel@tonic-gate 1616*2139Sjp161948 1617*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1618*2139Sjp161948 static const int KDF1_SHA1_len = 20; 1619*2139Sjp161948 static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) 1620*2139Sjp161948 { 1621*2139Sjp161948 #ifndef OPENSSL_NO_SHA 1622*2139Sjp161948 if (*outlen < SHA_DIGEST_LENGTH) 1623*2139Sjp161948 return NULL; 1624*2139Sjp161948 else 1625*2139Sjp161948 *outlen = SHA_DIGEST_LENGTH; 1626*2139Sjp161948 return SHA1(in, inlen, out); 1627*2139Sjp161948 #else 1628*2139Sjp161948 return NULL; 1629*2139Sjp161948 #endif /* OPENSSL_NO_SHA */ 1630*2139Sjp161948 } 1631*2139Sjp161948 #endif /* OPENSSL_NO_ECDH */ 1632*2139Sjp161948 1633*2139Sjp161948 int ssl3_send_client_key_exchange(SSL *s) 16340Sstevel@tonic-gate { 16350Sstevel@tonic-gate unsigned char *p,*d; 16360Sstevel@tonic-gate int n; 16370Sstevel@tonic-gate unsigned long l; 16380Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 16390Sstevel@tonic-gate unsigned char *q; 16400Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 16410Sstevel@tonic-gate #endif 16420Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5 1643*2139Sjp161948 KSSL_ERR kssl_err; 16440Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */ 1645*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1646*2139Sjp161948 EC_KEY *clnt_ecdh = NULL; 1647*2139Sjp161948 const EC_POINT *srvr_ecpoint = NULL; 1648*2139Sjp161948 EVP_PKEY *srvr_pub_pkey = NULL; 1649*2139Sjp161948 unsigned char *encodedPoint = NULL; 1650*2139Sjp161948 int encoded_pt_len = 0; 1651*2139Sjp161948 BN_CTX * bn_ctx = NULL; 1652*2139Sjp161948 #endif 16530Sstevel@tonic-gate 16540Sstevel@tonic-gate if (s->state == SSL3_ST_CW_KEY_EXCH_A) 16550Sstevel@tonic-gate { 16560Sstevel@tonic-gate d=(unsigned char *)s->init_buf->data; 16570Sstevel@tonic-gate p= &(d[4]); 16580Sstevel@tonic-gate 16590Sstevel@tonic-gate l=s->s3->tmp.new_cipher->algorithms; 16600Sstevel@tonic-gate 1661*2139Sjp161948 /* Fool emacs indentation */ 1662*2139Sjp161948 if (0) {} 16630Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 16640Sstevel@tonic-gate else if (l & SSL_kRSA) 16650Sstevel@tonic-gate { 16660Sstevel@tonic-gate RSA *rsa; 16670Sstevel@tonic-gate unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; 16680Sstevel@tonic-gate 16690Sstevel@tonic-gate if (s->session->sess_cert->peer_rsa_tmp != NULL) 16700Sstevel@tonic-gate rsa=s->session->sess_cert->peer_rsa_tmp; 16710Sstevel@tonic-gate else 16720Sstevel@tonic-gate { 16730Sstevel@tonic-gate pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); 16740Sstevel@tonic-gate if ((pkey == NULL) || 16750Sstevel@tonic-gate (pkey->type != EVP_PKEY_RSA) || 16760Sstevel@tonic-gate (pkey->pkey.rsa == NULL)) 16770Sstevel@tonic-gate { 16780Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); 16790Sstevel@tonic-gate goto err; 16800Sstevel@tonic-gate } 16810Sstevel@tonic-gate rsa=pkey->pkey.rsa; 16820Sstevel@tonic-gate EVP_PKEY_free(pkey); 16830Sstevel@tonic-gate } 16840Sstevel@tonic-gate 16850Sstevel@tonic-gate tmp_buf[0]=s->client_version>>8; 16860Sstevel@tonic-gate tmp_buf[1]=s->client_version&0xff; 16870Sstevel@tonic-gate if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) 16880Sstevel@tonic-gate goto err; 16890Sstevel@tonic-gate 16900Sstevel@tonic-gate s->session->master_key_length=sizeof tmp_buf; 16910Sstevel@tonic-gate 16920Sstevel@tonic-gate q=p; 16930Sstevel@tonic-gate /* Fix buf for TLS and beyond */ 16940Sstevel@tonic-gate if (s->version > SSL3_VERSION) 16950Sstevel@tonic-gate p+=2; 16960Sstevel@tonic-gate n=RSA_public_encrypt(sizeof tmp_buf, 16970Sstevel@tonic-gate tmp_buf,p,rsa,RSA_PKCS1_PADDING); 16980Sstevel@tonic-gate #ifdef PKCS1_CHECK 16990Sstevel@tonic-gate if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; 17000Sstevel@tonic-gate if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70; 17010Sstevel@tonic-gate #endif 17020Sstevel@tonic-gate if (n <= 0) 17030Sstevel@tonic-gate { 17040Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT); 17050Sstevel@tonic-gate goto err; 17060Sstevel@tonic-gate } 17070Sstevel@tonic-gate 17080Sstevel@tonic-gate /* Fix buf for TLS and beyond */ 17090Sstevel@tonic-gate if (s->version > SSL3_VERSION) 17100Sstevel@tonic-gate { 17110Sstevel@tonic-gate s2n(n,q); 17120Sstevel@tonic-gate n+=2; 17130Sstevel@tonic-gate } 17140Sstevel@tonic-gate 17150Sstevel@tonic-gate s->session->master_key_length= 17160Sstevel@tonic-gate s->method->ssl3_enc->generate_master_secret(s, 17170Sstevel@tonic-gate s->session->master_key, 17180Sstevel@tonic-gate tmp_buf,sizeof tmp_buf); 17190Sstevel@tonic-gate OPENSSL_cleanse(tmp_buf,sizeof tmp_buf); 17200Sstevel@tonic-gate } 17210Sstevel@tonic-gate #endif 17220Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5 17230Sstevel@tonic-gate else if (l & SSL_kKRB5) 1724*2139Sjp161948 { 1725*2139Sjp161948 krb5_error_code krb5rc; 1726*2139Sjp161948 KSSL_CTX *kssl_ctx = s->kssl_ctx; 1727*2139Sjp161948 /* krb5_data krb5_ap_req; */ 1728*2139Sjp161948 krb5_data *enc_ticket; 1729*2139Sjp161948 krb5_data authenticator, *authp = NULL; 17300Sstevel@tonic-gate EVP_CIPHER_CTX ciph_ctx; 17310Sstevel@tonic-gate EVP_CIPHER *enc = NULL; 17320Sstevel@tonic-gate unsigned char iv[EVP_MAX_IV_LENGTH]; 17330Sstevel@tonic-gate unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; 17340Sstevel@tonic-gate unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH 17350Sstevel@tonic-gate + EVP_MAX_IV_LENGTH]; 17360Sstevel@tonic-gate int padl, outl = sizeof(epms); 17370Sstevel@tonic-gate 17380Sstevel@tonic-gate EVP_CIPHER_CTX_init(&ciph_ctx); 17390Sstevel@tonic-gate 17400Sstevel@tonic-gate #ifdef KSSL_DEBUG 1741*2139Sjp161948 printf("ssl3_send_client_key_exchange(%lx & %lx)\n", 1742*2139Sjp161948 l, SSL_kKRB5); 17430Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 17440Sstevel@tonic-gate 17450Sstevel@tonic-gate authp = NULL; 17460Sstevel@tonic-gate #ifdef KRB5SENDAUTH 17470Sstevel@tonic-gate if (KRB5SENDAUTH) authp = &authenticator; 17480Sstevel@tonic-gate #endif /* KRB5SENDAUTH */ 17490Sstevel@tonic-gate 1750*2139Sjp161948 krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, 17510Sstevel@tonic-gate &kssl_err); 17520Sstevel@tonic-gate enc = kssl_map_enc(kssl_ctx->enctype); 1753*2139Sjp161948 if (enc == NULL) 1754*2139Sjp161948 goto err; 17550Sstevel@tonic-gate #ifdef KSSL_DEBUG 1756*2139Sjp161948 { 1757*2139Sjp161948 printf("kssl_cget_tkt rtn %d\n", krb5rc); 1758*2139Sjp161948 if (krb5rc && kssl_err.text) 17590Sstevel@tonic-gate printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); 1760*2139Sjp161948 } 17610Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 17620Sstevel@tonic-gate 1763*2139Sjp161948 if (krb5rc) 1764*2139Sjp161948 { 1765*2139Sjp161948 ssl3_send_alert(s,SSL3_AL_FATAL, 17660Sstevel@tonic-gate SSL_AD_HANDSHAKE_FAILURE); 1767*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 17680Sstevel@tonic-gate kssl_err.reason); 1769*2139Sjp161948 goto err; 1770*2139Sjp161948 } 17710Sstevel@tonic-gate 17720Sstevel@tonic-gate /* 20010406 VRS - Earlier versions used KRB5 AP_REQ 17730Sstevel@tonic-gate ** in place of RFC 2712 KerberosWrapper, as in: 17740Sstevel@tonic-gate ** 1775*2139Sjp161948 ** Send ticket (copy to *p, set n = length) 1776*2139Sjp161948 ** n = krb5_ap_req.length; 1777*2139Sjp161948 ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); 1778*2139Sjp161948 ** if (krb5_ap_req.data) 1779*2139Sjp161948 ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); 1780*2139Sjp161948 ** 17810Sstevel@tonic-gate ** Now using real RFC 2712 KerberosWrapper 17820Sstevel@tonic-gate ** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>) 17830Sstevel@tonic-gate ** Note: 2712 "opaque" types are here replaced 17840Sstevel@tonic-gate ** with a 2-byte length followed by the value. 17850Sstevel@tonic-gate ** Example: 17860Sstevel@tonic-gate ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms 17870Sstevel@tonic-gate ** Where "xx xx" = length bytes. Shown here with 17880Sstevel@tonic-gate ** optional authenticator omitted. 17890Sstevel@tonic-gate */ 17900Sstevel@tonic-gate 17910Sstevel@tonic-gate /* KerberosWrapper.Ticket */ 17920Sstevel@tonic-gate s2n(enc_ticket->length,p); 17930Sstevel@tonic-gate memcpy(p, enc_ticket->data, enc_ticket->length); 17940Sstevel@tonic-gate p+= enc_ticket->length; 17950Sstevel@tonic-gate n = enc_ticket->length + 2; 17960Sstevel@tonic-gate 17970Sstevel@tonic-gate /* KerberosWrapper.Authenticator */ 17980Sstevel@tonic-gate if (authp && authp->length) 17990Sstevel@tonic-gate { 18000Sstevel@tonic-gate s2n(authp->length,p); 18010Sstevel@tonic-gate memcpy(p, authp->data, authp->length); 18020Sstevel@tonic-gate p+= authp->length; 18030Sstevel@tonic-gate n+= authp->length + 2; 18040Sstevel@tonic-gate 18050Sstevel@tonic-gate free(authp->data); 18060Sstevel@tonic-gate authp->data = NULL; 18070Sstevel@tonic-gate authp->length = 0; 18080Sstevel@tonic-gate } 18090Sstevel@tonic-gate else 18100Sstevel@tonic-gate { 18110Sstevel@tonic-gate s2n(0,p);/* null authenticator length */ 18120Sstevel@tonic-gate n+=2; 18130Sstevel@tonic-gate } 18140Sstevel@tonic-gate 18150Sstevel@tonic-gate if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0) 18160Sstevel@tonic-gate goto err; 18170Sstevel@tonic-gate 18180Sstevel@tonic-gate /* 20010420 VRS. Tried it this way; failed. 18190Sstevel@tonic-gate ** EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); 18200Sstevel@tonic-gate ** EVP_CIPHER_CTX_set_key_length(&ciph_ctx, 18210Sstevel@tonic-gate ** kssl_ctx->length); 18220Sstevel@tonic-gate ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); 18230Sstevel@tonic-gate */ 18240Sstevel@tonic-gate 18250Sstevel@tonic-gate memset(iv, 0, sizeof iv); /* per RFC 1510 */ 18260Sstevel@tonic-gate EVP_EncryptInit_ex(&ciph_ctx,enc, NULL, 18270Sstevel@tonic-gate kssl_ctx->key,iv); 18280Sstevel@tonic-gate EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf, 18290Sstevel@tonic-gate sizeof tmp_buf); 18300Sstevel@tonic-gate EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); 18310Sstevel@tonic-gate outl += padl; 18320Sstevel@tonic-gate if (outl > sizeof epms) 18330Sstevel@tonic-gate { 18340Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); 18350Sstevel@tonic-gate goto err; 18360Sstevel@tonic-gate } 18370Sstevel@tonic-gate EVP_CIPHER_CTX_cleanup(&ciph_ctx); 18380Sstevel@tonic-gate 18390Sstevel@tonic-gate /* KerberosWrapper.EncryptedPreMasterSecret */ 18400Sstevel@tonic-gate s2n(outl,p); 18410Sstevel@tonic-gate memcpy(p, epms, outl); 18420Sstevel@tonic-gate p+=outl; 18430Sstevel@tonic-gate n+=outl + 2; 18440Sstevel@tonic-gate 1845*2139Sjp161948 s->session->master_key_length= 1846*2139Sjp161948 s->method->ssl3_enc->generate_master_secret(s, 18470Sstevel@tonic-gate s->session->master_key, 18480Sstevel@tonic-gate tmp_buf, sizeof tmp_buf); 18490Sstevel@tonic-gate 18500Sstevel@tonic-gate OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); 18510Sstevel@tonic-gate OPENSSL_cleanse(epms, outl); 1852*2139Sjp161948 } 18530Sstevel@tonic-gate #endif 18540Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 18550Sstevel@tonic-gate else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) 18560Sstevel@tonic-gate { 18570Sstevel@tonic-gate DH *dh_srvr,*dh_clnt; 18580Sstevel@tonic-gate 18590Sstevel@tonic-gate if (s->session->sess_cert->peer_dh_tmp != NULL) 18600Sstevel@tonic-gate dh_srvr=s->session->sess_cert->peer_dh_tmp; 18610Sstevel@tonic-gate else 18620Sstevel@tonic-gate { 18630Sstevel@tonic-gate /* we get them from the cert */ 18640Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 18650Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); 18660Sstevel@tonic-gate goto err; 18670Sstevel@tonic-gate } 18680Sstevel@tonic-gate 18690Sstevel@tonic-gate /* generate a new random key */ 18700Sstevel@tonic-gate if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) 18710Sstevel@tonic-gate { 18720Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 18730Sstevel@tonic-gate goto err; 18740Sstevel@tonic-gate } 18750Sstevel@tonic-gate if (!DH_generate_key(dh_clnt)) 18760Sstevel@tonic-gate { 18770Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 18780Sstevel@tonic-gate goto err; 18790Sstevel@tonic-gate } 18800Sstevel@tonic-gate 18810Sstevel@tonic-gate /* use the 'p' output buffer for the DH key, but 18820Sstevel@tonic-gate * make sure to clear it out afterwards */ 18830Sstevel@tonic-gate 18840Sstevel@tonic-gate n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); 18850Sstevel@tonic-gate 18860Sstevel@tonic-gate if (n <= 0) 18870Sstevel@tonic-gate { 18880Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); 18890Sstevel@tonic-gate goto err; 18900Sstevel@tonic-gate } 18910Sstevel@tonic-gate 18920Sstevel@tonic-gate /* generate master key from the result */ 18930Sstevel@tonic-gate s->session->master_key_length= 18940Sstevel@tonic-gate s->method->ssl3_enc->generate_master_secret(s, 18950Sstevel@tonic-gate s->session->master_key,p,n); 18960Sstevel@tonic-gate /* clean up */ 18970Sstevel@tonic-gate memset(p,0,n); 18980Sstevel@tonic-gate 18990Sstevel@tonic-gate /* send off the data */ 19000Sstevel@tonic-gate n=BN_num_bytes(dh_clnt->pub_key); 19010Sstevel@tonic-gate s2n(n,p); 19020Sstevel@tonic-gate BN_bn2bin(dh_clnt->pub_key,p); 19030Sstevel@tonic-gate n+=2; 19040Sstevel@tonic-gate 19050Sstevel@tonic-gate DH_free(dh_clnt); 19060Sstevel@tonic-gate 19070Sstevel@tonic-gate /* perhaps clean things up a bit EAY EAY EAY EAY*/ 19080Sstevel@tonic-gate } 19090Sstevel@tonic-gate #endif 1910*2139Sjp161948 1911*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 1912*2139Sjp161948 else if ((l & SSL_kECDH) || (l & SSL_kECDHE)) 1913*2139Sjp161948 { 1914*2139Sjp161948 const EC_GROUP *srvr_group = NULL; 1915*2139Sjp161948 EC_KEY *tkey; 1916*2139Sjp161948 int ecdh_clnt_cert = 0; 1917*2139Sjp161948 int field_size = 0; 1918*2139Sjp161948 1919*2139Sjp161948 /* Did we send out the client's 1920*2139Sjp161948 * ECDH share for use in premaster 1921*2139Sjp161948 * computation as part of client certificate? 1922*2139Sjp161948 * If so, set ecdh_clnt_cert to 1. 1923*2139Sjp161948 */ 1924*2139Sjp161948 if ((l & SSL_kECDH) && (s->cert != NULL)) 1925*2139Sjp161948 { 1926*2139Sjp161948 /* XXX: For now, we do not support client 1927*2139Sjp161948 * authentication using ECDH certificates. 1928*2139Sjp161948 * To add such support, one needs to add 1929*2139Sjp161948 * code that checks for appropriate 1930*2139Sjp161948 * conditions and sets ecdh_clnt_cert to 1. 1931*2139Sjp161948 * For example, the cert have an ECC 1932*2139Sjp161948 * key on the same curve as the server's 1933*2139Sjp161948 * and the key should be authorized for 1934*2139Sjp161948 * key agreement. 1935*2139Sjp161948 * 1936*2139Sjp161948 * One also needs to add code in ssl3_connect 1937*2139Sjp161948 * to skip sending the certificate verify 1938*2139Sjp161948 * message. 1939*2139Sjp161948 * 1940*2139Sjp161948 * if ((s->cert->key->privatekey != NULL) && 1941*2139Sjp161948 * (s->cert->key->privatekey->type == 1942*2139Sjp161948 * EVP_PKEY_EC) && ...) 1943*2139Sjp161948 * ecdh_clnt_cert = 1; 1944*2139Sjp161948 */ 1945*2139Sjp161948 } 1946*2139Sjp161948 1947*2139Sjp161948 if (s->session->sess_cert->peer_ecdh_tmp != NULL) 1948*2139Sjp161948 { 1949*2139Sjp161948 tkey = s->session->sess_cert->peer_ecdh_tmp; 1950*2139Sjp161948 } 1951*2139Sjp161948 else 1952*2139Sjp161948 { 1953*2139Sjp161948 /* Get the Server Public Key from Cert */ 1954*2139Sjp161948 srvr_pub_pkey = X509_get_pubkey(s->session-> \ 1955*2139Sjp161948 sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); 1956*2139Sjp161948 if ((srvr_pub_pkey == NULL) || 1957*2139Sjp161948 (srvr_pub_pkey->type != EVP_PKEY_EC) || 1958*2139Sjp161948 (srvr_pub_pkey->pkey.ec == NULL)) 1959*2139Sjp161948 { 1960*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 1961*2139Sjp161948 ERR_R_INTERNAL_ERROR); 1962*2139Sjp161948 goto err; 1963*2139Sjp161948 } 1964*2139Sjp161948 1965*2139Sjp161948 tkey = srvr_pub_pkey->pkey.ec; 1966*2139Sjp161948 } 1967*2139Sjp161948 1968*2139Sjp161948 srvr_group = EC_KEY_get0_group(tkey); 1969*2139Sjp161948 srvr_ecpoint = EC_KEY_get0_public_key(tkey); 1970*2139Sjp161948 1971*2139Sjp161948 if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) 1972*2139Sjp161948 { 1973*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 1974*2139Sjp161948 ERR_R_INTERNAL_ERROR); 1975*2139Sjp161948 goto err; 1976*2139Sjp161948 } 1977*2139Sjp161948 1978*2139Sjp161948 if ((clnt_ecdh=EC_KEY_new()) == NULL) 1979*2139Sjp161948 { 1980*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 1981*2139Sjp161948 goto err; 1982*2139Sjp161948 } 1983*2139Sjp161948 1984*2139Sjp161948 if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) 1985*2139Sjp161948 { 1986*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); 1987*2139Sjp161948 goto err; 1988*2139Sjp161948 } 1989*2139Sjp161948 if (ecdh_clnt_cert) 1990*2139Sjp161948 { 1991*2139Sjp161948 /* Reuse key info from our certificate 1992*2139Sjp161948 * We only need our private key to perform 1993*2139Sjp161948 * the ECDH computation. 1994*2139Sjp161948 */ 1995*2139Sjp161948 const BIGNUM *priv_key; 1996*2139Sjp161948 tkey = s->cert->key->privatekey->pkey.ec; 1997*2139Sjp161948 priv_key = EC_KEY_get0_private_key(tkey); 1998*2139Sjp161948 if (priv_key == NULL) 1999*2139Sjp161948 { 2000*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 2001*2139Sjp161948 goto err; 2002*2139Sjp161948 } 2003*2139Sjp161948 if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) 2004*2139Sjp161948 { 2005*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); 2006*2139Sjp161948 goto err; 2007*2139Sjp161948 } 2008*2139Sjp161948 } 2009*2139Sjp161948 else 2010*2139Sjp161948 { 2011*2139Sjp161948 /* Generate a new ECDH key pair */ 2012*2139Sjp161948 if (!(EC_KEY_generate_key(clnt_ecdh))) 2013*2139Sjp161948 { 2014*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); 2015*2139Sjp161948 goto err; 2016*2139Sjp161948 } 2017*2139Sjp161948 } 2018*2139Sjp161948 2019*2139Sjp161948 /* use the 'p' output buffer for the ECDH key, but 2020*2139Sjp161948 * make sure to clear it out afterwards 2021*2139Sjp161948 */ 2022*2139Sjp161948 2023*2139Sjp161948 field_size = EC_GROUP_get_degree(srvr_group); 2024*2139Sjp161948 if (field_size <= 0) 2025*2139Sjp161948 { 2026*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 2027*2139Sjp161948 ERR_R_ECDH_LIB); 2028*2139Sjp161948 goto err; 2029*2139Sjp161948 } 2030*2139Sjp161948 /* If field size is not more than 24 octets, then use SHA-1 hash of result; 2031*2139Sjp161948 * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt; 2032*2139Sjp161948 * this is new with this version of the Internet Draft). 2033*2139Sjp161948 */ 2034*2139Sjp161948 if (field_size <= 24 * 8) 2035*2139Sjp161948 n=ECDH_compute_key(p, KDF1_SHA1_len, srvr_ecpoint, clnt_ecdh, KDF1_SHA1); 2036*2139Sjp161948 else 2037*2139Sjp161948 n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL); 2038*2139Sjp161948 if (n <= 0) 2039*2139Sjp161948 { 2040*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 2041*2139Sjp161948 ERR_R_ECDH_LIB); 2042*2139Sjp161948 goto err; 2043*2139Sjp161948 } 2044*2139Sjp161948 2045*2139Sjp161948 /* generate master key from the result */ 2046*2139Sjp161948 s->session->master_key_length = s->method->ssl3_enc \ 2047*2139Sjp161948 -> generate_master_secret(s, 2048*2139Sjp161948 s->session->master_key, 2049*2139Sjp161948 p, n); 2050*2139Sjp161948 2051*2139Sjp161948 memset(p, 0, n); /* clean up */ 2052*2139Sjp161948 2053*2139Sjp161948 if (ecdh_clnt_cert) 2054*2139Sjp161948 { 2055*2139Sjp161948 /* Send empty client key exch message */ 2056*2139Sjp161948 n = 0; 2057*2139Sjp161948 } 2058*2139Sjp161948 else 2059*2139Sjp161948 { 2060*2139Sjp161948 /* First check the size of encoding and 2061*2139Sjp161948 * allocate memory accordingly. 2062*2139Sjp161948 */ 2063*2139Sjp161948 encoded_pt_len = 2064*2139Sjp161948 EC_POINT_point2oct(srvr_group, 2065*2139Sjp161948 EC_KEY_get0_public_key(clnt_ecdh), 2066*2139Sjp161948 POINT_CONVERSION_UNCOMPRESSED, 2067*2139Sjp161948 NULL, 0, NULL); 2068*2139Sjp161948 2069*2139Sjp161948 encodedPoint = (unsigned char *) 2070*2139Sjp161948 OPENSSL_malloc(encoded_pt_len * 2071*2139Sjp161948 sizeof(unsigned char)); 2072*2139Sjp161948 bn_ctx = BN_CTX_new(); 2073*2139Sjp161948 if ((encodedPoint == NULL) || 2074*2139Sjp161948 (bn_ctx == NULL)) 2075*2139Sjp161948 { 2076*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); 2077*2139Sjp161948 goto err; 2078*2139Sjp161948 } 2079*2139Sjp161948 2080*2139Sjp161948 /* Encode the public key */ 2081*2139Sjp161948 n = EC_POINT_point2oct(srvr_group, 2082*2139Sjp161948 EC_KEY_get0_public_key(clnt_ecdh), 2083*2139Sjp161948 POINT_CONVERSION_UNCOMPRESSED, 2084*2139Sjp161948 encodedPoint, encoded_pt_len, bn_ctx); 2085*2139Sjp161948 2086*2139Sjp161948 *p = n; /* length of encoded point */ 2087*2139Sjp161948 /* Encoded point will be copied here */ 2088*2139Sjp161948 p += 1; 2089*2139Sjp161948 /* copy the point */ 2090*2139Sjp161948 memcpy((unsigned char *)p, encodedPoint, n); 2091*2139Sjp161948 /* increment n to account for length field */ 2092*2139Sjp161948 n += 1; 2093*2139Sjp161948 } 2094*2139Sjp161948 2095*2139Sjp161948 /* Free allocated memory */ 2096*2139Sjp161948 BN_CTX_free(bn_ctx); 2097*2139Sjp161948 if (encodedPoint != NULL) OPENSSL_free(encodedPoint); 2098*2139Sjp161948 if (clnt_ecdh != NULL) 2099*2139Sjp161948 EC_KEY_free(clnt_ecdh); 2100*2139Sjp161948 EVP_PKEY_free(srvr_pub_pkey); 2101*2139Sjp161948 } 2102*2139Sjp161948 #endif /* !OPENSSL_NO_ECDH */ 21030Sstevel@tonic-gate else 21040Sstevel@tonic-gate { 2105*2139Sjp161948 ssl3_send_alert(s, SSL3_AL_FATAL, 2106*2139Sjp161948 SSL_AD_HANDSHAKE_FAILURE); 2107*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 2108*2139Sjp161948 ERR_R_INTERNAL_ERROR); 21090Sstevel@tonic-gate goto err; 21100Sstevel@tonic-gate } 21110Sstevel@tonic-gate 21120Sstevel@tonic-gate *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE; 21130Sstevel@tonic-gate l2n3(n,d); 21140Sstevel@tonic-gate 21150Sstevel@tonic-gate s->state=SSL3_ST_CW_KEY_EXCH_B; 21160Sstevel@tonic-gate /* number of bytes to write */ 21170Sstevel@tonic-gate s->init_num=n+4; 21180Sstevel@tonic-gate s->init_off=0; 21190Sstevel@tonic-gate } 21200Sstevel@tonic-gate 21210Sstevel@tonic-gate /* SSL3_ST_CW_KEY_EXCH_B */ 21220Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); 21230Sstevel@tonic-gate err: 2124*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 2125*2139Sjp161948 BN_CTX_free(bn_ctx); 2126*2139Sjp161948 if (encodedPoint != NULL) OPENSSL_free(encodedPoint); 2127*2139Sjp161948 if (clnt_ecdh != NULL) 2128*2139Sjp161948 EC_KEY_free(clnt_ecdh); 2129*2139Sjp161948 EVP_PKEY_free(srvr_pub_pkey); 2130*2139Sjp161948 #endif 21310Sstevel@tonic-gate return(-1); 21320Sstevel@tonic-gate } 21330Sstevel@tonic-gate 2134*2139Sjp161948 int ssl3_send_client_verify(SSL *s) 21350Sstevel@tonic-gate { 21360Sstevel@tonic-gate unsigned char *p,*d; 21370Sstevel@tonic-gate unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; 21380Sstevel@tonic-gate EVP_PKEY *pkey; 21390Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 21400Sstevel@tonic-gate unsigned u=0; 21410Sstevel@tonic-gate #endif 21420Sstevel@tonic-gate unsigned long n; 2143*2139Sjp161948 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) 21440Sstevel@tonic-gate int j; 21450Sstevel@tonic-gate #endif 21460Sstevel@tonic-gate 21470Sstevel@tonic-gate if (s->state == SSL3_ST_CW_CERT_VRFY_A) 21480Sstevel@tonic-gate { 21490Sstevel@tonic-gate d=(unsigned char *)s->init_buf->data; 21500Sstevel@tonic-gate p= &(d[4]); 21510Sstevel@tonic-gate pkey=s->cert->key->privatekey; 21520Sstevel@tonic-gate 21530Sstevel@tonic-gate s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), 21540Sstevel@tonic-gate &(data[MD5_DIGEST_LENGTH])); 21550Sstevel@tonic-gate 21560Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 21570Sstevel@tonic-gate if (pkey->type == EVP_PKEY_RSA) 21580Sstevel@tonic-gate { 21590Sstevel@tonic-gate s->method->ssl3_enc->cert_verify_mac(s, 21600Sstevel@tonic-gate &(s->s3->finish_dgst1),&(data[0])); 21610Sstevel@tonic-gate if (RSA_sign(NID_md5_sha1, data, 21620Sstevel@tonic-gate MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, 21630Sstevel@tonic-gate &(p[2]), &u, pkey->pkey.rsa) <= 0 ) 21640Sstevel@tonic-gate { 21650Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB); 21660Sstevel@tonic-gate goto err; 21670Sstevel@tonic-gate } 21680Sstevel@tonic-gate s2n(u,p); 21690Sstevel@tonic-gate n=u+2; 21700Sstevel@tonic-gate } 21710Sstevel@tonic-gate else 21720Sstevel@tonic-gate #endif 21730Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 21740Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 21750Sstevel@tonic-gate { 21760Sstevel@tonic-gate if (!DSA_sign(pkey->save_type, 21770Sstevel@tonic-gate &(data[MD5_DIGEST_LENGTH]), 21780Sstevel@tonic-gate SHA_DIGEST_LENGTH,&(p[2]), 21790Sstevel@tonic-gate (unsigned int *)&j,pkey->pkey.dsa)) 21800Sstevel@tonic-gate { 21810Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB); 21820Sstevel@tonic-gate goto err; 21830Sstevel@tonic-gate } 21840Sstevel@tonic-gate s2n(j,p); 21850Sstevel@tonic-gate n=j+2; 21860Sstevel@tonic-gate } 21870Sstevel@tonic-gate else 21880Sstevel@tonic-gate #endif 2189*2139Sjp161948 #ifndef OPENSSL_NO_ECDSA 2190*2139Sjp161948 if (pkey->type == EVP_PKEY_EC) 2191*2139Sjp161948 { 2192*2139Sjp161948 if (!ECDSA_sign(pkey->save_type, 2193*2139Sjp161948 &(data[MD5_DIGEST_LENGTH]), 2194*2139Sjp161948 SHA_DIGEST_LENGTH,&(p[2]), 2195*2139Sjp161948 (unsigned int *)&j,pkey->pkey.ec)) 2196*2139Sjp161948 { 2197*2139Sjp161948 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, 2198*2139Sjp161948 ERR_R_ECDSA_LIB); 2199*2139Sjp161948 goto err; 2200*2139Sjp161948 } 2201*2139Sjp161948 s2n(j,p); 2202*2139Sjp161948 n=j+2; 2203*2139Sjp161948 } 2204*2139Sjp161948 else 2205*2139Sjp161948 #endif 22060Sstevel@tonic-gate { 22070Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR); 22080Sstevel@tonic-gate goto err; 22090Sstevel@tonic-gate } 22100Sstevel@tonic-gate *(d++)=SSL3_MT_CERTIFICATE_VERIFY; 22110Sstevel@tonic-gate l2n3(n,d); 22120Sstevel@tonic-gate 22130Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_VRFY_B; 22140Sstevel@tonic-gate s->init_num=(int)n+4; 22150Sstevel@tonic-gate s->init_off=0; 22160Sstevel@tonic-gate } 22170Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); 22180Sstevel@tonic-gate err: 22190Sstevel@tonic-gate return(-1); 22200Sstevel@tonic-gate } 22210Sstevel@tonic-gate 2222*2139Sjp161948 int ssl3_send_client_certificate(SSL *s) 22230Sstevel@tonic-gate { 22240Sstevel@tonic-gate X509 *x509=NULL; 22250Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 22260Sstevel@tonic-gate int i; 22270Sstevel@tonic-gate unsigned long l; 22280Sstevel@tonic-gate 22290Sstevel@tonic-gate if (s->state == SSL3_ST_CW_CERT_A) 22300Sstevel@tonic-gate { 22310Sstevel@tonic-gate if ((s->cert == NULL) || 22320Sstevel@tonic-gate (s->cert->key->x509 == NULL) || 22330Sstevel@tonic-gate (s->cert->key->privatekey == NULL)) 22340Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_B; 22350Sstevel@tonic-gate else 22360Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_C; 22370Sstevel@tonic-gate } 22380Sstevel@tonic-gate 22390Sstevel@tonic-gate /* We need to get a client cert */ 22400Sstevel@tonic-gate if (s->state == SSL3_ST_CW_CERT_B) 22410Sstevel@tonic-gate { 22420Sstevel@tonic-gate /* If we get an error, we need to 22430Sstevel@tonic-gate * ssl->rwstate=SSL_X509_LOOKUP; return(-1); 22440Sstevel@tonic-gate * We then get retied later */ 22450Sstevel@tonic-gate i=0; 22460Sstevel@tonic-gate if (s->ctx->client_cert_cb != NULL) 22470Sstevel@tonic-gate i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); 22480Sstevel@tonic-gate if (i < 0) 22490Sstevel@tonic-gate { 22500Sstevel@tonic-gate s->rwstate=SSL_X509_LOOKUP; 22510Sstevel@tonic-gate return(-1); 22520Sstevel@tonic-gate } 22530Sstevel@tonic-gate s->rwstate=SSL_NOTHING; 22540Sstevel@tonic-gate if ((i == 1) && (pkey != NULL) && (x509 != NULL)) 22550Sstevel@tonic-gate { 22560Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_B; 22570Sstevel@tonic-gate if ( !SSL_use_certificate(s,x509) || 22580Sstevel@tonic-gate !SSL_use_PrivateKey(s,pkey)) 22590Sstevel@tonic-gate i=0; 22600Sstevel@tonic-gate } 22610Sstevel@tonic-gate else if (i == 1) 22620Sstevel@tonic-gate { 22630Sstevel@tonic-gate i=0; 22640Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); 22650Sstevel@tonic-gate } 22660Sstevel@tonic-gate 22670Sstevel@tonic-gate if (x509 != NULL) X509_free(x509); 22680Sstevel@tonic-gate if (pkey != NULL) EVP_PKEY_free(pkey); 22690Sstevel@tonic-gate if (i == 0) 22700Sstevel@tonic-gate { 22710Sstevel@tonic-gate if (s->version == SSL3_VERSION) 22720Sstevel@tonic-gate { 22730Sstevel@tonic-gate s->s3->tmp.cert_req=0; 22740Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE); 22750Sstevel@tonic-gate return(1); 22760Sstevel@tonic-gate } 22770Sstevel@tonic-gate else 22780Sstevel@tonic-gate { 22790Sstevel@tonic-gate s->s3->tmp.cert_req=2; 22800Sstevel@tonic-gate } 22810Sstevel@tonic-gate } 22820Sstevel@tonic-gate 22830Sstevel@tonic-gate /* Ok, we have a cert */ 22840Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_C; 22850Sstevel@tonic-gate } 22860Sstevel@tonic-gate 22870Sstevel@tonic-gate if (s->state == SSL3_ST_CW_CERT_C) 22880Sstevel@tonic-gate { 22890Sstevel@tonic-gate s->state=SSL3_ST_CW_CERT_D; 22900Sstevel@tonic-gate l=ssl3_output_cert_chain(s, 22910Sstevel@tonic-gate (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); 22920Sstevel@tonic-gate s->init_num=(int)l; 22930Sstevel@tonic-gate s->init_off=0; 22940Sstevel@tonic-gate } 22950Sstevel@tonic-gate /* SSL3_ST_CW_CERT_D */ 22960Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); 22970Sstevel@tonic-gate } 22980Sstevel@tonic-gate 22990Sstevel@tonic-gate #define has_bits(i,m) (((i)&(m)) == (m)) 23000Sstevel@tonic-gate 2301*2139Sjp161948 int ssl3_check_cert_and_algorithm(SSL *s) 23020Sstevel@tonic-gate { 23030Sstevel@tonic-gate int i,idx; 23040Sstevel@tonic-gate long algs; 23050Sstevel@tonic-gate EVP_PKEY *pkey=NULL; 23060Sstevel@tonic-gate SESS_CERT *sc; 23070Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 23080Sstevel@tonic-gate RSA *rsa; 23090Sstevel@tonic-gate #endif 23100Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 23110Sstevel@tonic-gate DH *dh; 23120Sstevel@tonic-gate #endif 23130Sstevel@tonic-gate 23140Sstevel@tonic-gate sc=s->session->sess_cert; 23150Sstevel@tonic-gate 23160Sstevel@tonic-gate if (sc == NULL) 23170Sstevel@tonic-gate { 23180Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR); 23190Sstevel@tonic-gate goto err; 23200Sstevel@tonic-gate } 23210Sstevel@tonic-gate 23220Sstevel@tonic-gate algs=s->s3->tmp.new_cipher->algorithms; 23230Sstevel@tonic-gate 23240Sstevel@tonic-gate /* we don't have a certificate */ 23250Sstevel@tonic-gate if (algs & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) 23260Sstevel@tonic-gate return(1); 23270Sstevel@tonic-gate 23280Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 23290Sstevel@tonic-gate rsa=s->session->sess_cert->peer_rsa_tmp; 23300Sstevel@tonic-gate #endif 23310Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 23320Sstevel@tonic-gate dh=s->session->sess_cert->peer_dh_tmp; 23330Sstevel@tonic-gate #endif 23340Sstevel@tonic-gate 23350Sstevel@tonic-gate /* This is the passed certificate */ 23360Sstevel@tonic-gate 23370Sstevel@tonic-gate idx=sc->peer_cert_type; 2338*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 2339*2139Sjp161948 if (idx == SSL_PKEY_ECC) 2340*2139Sjp161948 { 2341*2139Sjp161948 if (check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, 2342*2139Sjp161948 s->s3->tmp.new_cipher) == 0) 2343*2139Sjp161948 { /* check failed */ 2344*2139Sjp161948 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT); 2345*2139Sjp161948 goto f_err; 2346*2139Sjp161948 } 2347*2139Sjp161948 else 2348*2139Sjp161948 { 2349*2139Sjp161948 return 1; 2350*2139Sjp161948 } 2351*2139Sjp161948 } 2352*2139Sjp161948 #endif 23530Sstevel@tonic-gate pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509); 23540Sstevel@tonic-gate i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey); 23550Sstevel@tonic-gate EVP_PKEY_free(pkey); 23560Sstevel@tonic-gate 23570Sstevel@tonic-gate 23580Sstevel@tonic-gate /* Check that we have a certificate if we require one */ 23590Sstevel@tonic-gate if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN)) 23600Sstevel@tonic-gate { 23610Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT); 23620Sstevel@tonic-gate goto f_err; 23630Sstevel@tonic-gate } 23640Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 23650Sstevel@tonic-gate else if ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN)) 23660Sstevel@tonic-gate { 23670Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT); 23680Sstevel@tonic-gate goto f_err; 23690Sstevel@tonic-gate } 23700Sstevel@tonic-gate #endif 23710Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 23720Sstevel@tonic-gate if ((algs & SSL_kRSA) && 23730Sstevel@tonic-gate !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) 23740Sstevel@tonic-gate { 23750Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT); 23760Sstevel@tonic-gate goto f_err; 23770Sstevel@tonic-gate } 23780Sstevel@tonic-gate #endif 23790Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 23800Sstevel@tonic-gate if ((algs & SSL_kEDH) && 23810Sstevel@tonic-gate !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) 23820Sstevel@tonic-gate { 23830Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); 23840Sstevel@tonic-gate goto f_err; 23850Sstevel@tonic-gate } 23860Sstevel@tonic-gate else if ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) 23870Sstevel@tonic-gate { 23880Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT); 23890Sstevel@tonic-gate goto f_err; 23900Sstevel@tonic-gate } 23910Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 23920Sstevel@tonic-gate else if ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) 23930Sstevel@tonic-gate { 23940Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT); 23950Sstevel@tonic-gate goto f_err; 23960Sstevel@tonic-gate } 23970Sstevel@tonic-gate #endif 23980Sstevel@tonic-gate #endif 23990Sstevel@tonic-gate 24000Sstevel@tonic-gate if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) 24010Sstevel@tonic-gate { 24020Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 24030Sstevel@tonic-gate if (algs & SSL_kRSA) 24040Sstevel@tonic-gate { 24050Sstevel@tonic-gate if (rsa == NULL 24060Sstevel@tonic-gate || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) 24070Sstevel@tonic-gate { 24080Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY); 24090Sstevel@tonic-gate goto f_err; 24100Sstevel@tonic-gate } 24110Sstevel@tonic-gate } 24120Sstevel@tonic-gate else 24130Sstevel@tonic-gate #endif 24140Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 24150Sstevel@tonic-gate if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) 24160Sstevel@tonic-gate { 24170Sstevel@tonic-gate if (dh == NULL 24180Sstevel@tonic-gate || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) 24190Sstevel@tonic-gate { 24200Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY); 24210Sstevel@tonic-gate goto f_err; 24220Sstevel@tonic-gate } 24230Sstevel@tonic-gate } 24240Sstevel@tonic-gate else 24250Sstevel@tonic-gate #endif 24260Sstevel@tonic-gate { 24270Sstevel@tonic-gate SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); 24280Sstevel@tonic-gate goto f_err; 24290Sstevel@tonic-gate } 24300Sstevel@tonic-gate } 24310Sstevel@tonic-gate return(1); 24320Sstevel@tonic-gate f_err: 24330Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 24340Sstevel@tonic-gate err: 24350Sstevel@tonic-gate return(0); 24360Sstevel@tonic-gate } 24370Sstevel@tonic-gate 2438*2139Sjp161948 2439*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 2440*2139Sjp161948 /* This is the complement of nid2curve_id in s3_srvr.c. */ 2441*2139Sjp161948 static int curve_id2nid(int curve_id) 2442*2139Sjp161948 { 2443*2139Sjp161948 /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) 2444*2139Sjp161948 * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */ 2445*2139Sjp161948 static int nid_list[26] = 2446*2139Sjp161948 { 2447*2139Sjp161948 0, 2448*2139Sjp161948 NID_sect163k1, /* sect163k1 (1) */ 2449*2139Sjp161948 NID_sect163r1, /* sect163r1 (2) */ 2450*2139Sjp161948 NID_sect163r2, /* sect163r2 (3) */ 2451*2139Sjp161948 NID_sect193r1, /* sect193r1 (4) */ 2452*2139Sjp161948 NID_sect193r2, /* sect193r2 (5) */ 2453*2139Sjp161948 NID_sect233k1, /* sect233k1 (6) */ 2454*2139Sjp161948 NID_sect233r1, /* sect233r1 (7) */ 2455*2139Sjp161948 NID_sect239k1, /* sect239k1 (8) */ 2456*2139Sjp161948 NID_sect283k1, /* sect283k1 (9) */ 2457*2139Sjp161948 NID_sect283r1, /* sect283r1 (10) */ 2458*2139Sjp161948 NID_sect409k1, /* sect409k1 (11) */ 2459*2139Sjp161948 NID_sect409r1, /* sect409r1 (12) */ 2460*2139Sjp161948 NID_sect571k1, /* sect571k1 (13) */ 2461*2139Sjp161948 NID_sect571r1, /* sect571r1 (14) */ 2462*2139Sjp161948 NID_secp160k1, /* secp160k1 (15) */ 2463*2139Sjp161948 NID_secp160r1, /* secp160r1 (16) */ 2464*2139Sjp161948 NID_secp160r2, /* secp160r2 (17) */ 2465*2139Sjp161948 NID_secp192k1, /* secp192k1 (18) */ 2466*2139Sjp161948 NID_X9_62_prime192v1, /* secp192r1 (19) */ 2467*2139Sjp161948 NID_secp224k1, /* secp224k1 (20) */ 2468*2139Sjp161948 NID_secp224r1, /* secp224r1 (21) */ 2469*2139Sjp161948 NID_secp256k1, /* secp256k1 (22) */ 2470*2139Sjp161948 NID_X9_62_prime256v1, /* secp256r1 (23) */ 2471*2139Sjp161948 NID_secp384r1, /* secp384r1 (24) */ 2472*2139Sjp161948 NID_secp521r1 /* secp521r1 (25) */ 2473*2139Sjp161948 }; 2474*2139Sjp161948 2475*2139Sjp161948 if ((curve_id < 1) || (curve_id > 25)) return 0; 2476*2139Sjp161948 2477*2139Sjp161948 return nid_list[curve_id]; 2478*2139Sjp161948 } 2479*2139Sjp161948 #endif 2480