s2_srvr.c revision 237998
155714Skris/* ssl/s2_srvr.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5889840Skris/* ==================================================================== 5989840Skris * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 6089840Skris * 6189840Skris * Redistribution and use in source and binary forms, with or without 6289840Skris * modification, are permitted provided that the following conditions 6389840Skris * are met: 6489840Skris * 6589840Skris * 1. Redistributions of source code must retain the above copyright 6689840Skris * notice, this list of conditions and the following disclaimer. 6789840Skris * 6889840Skris * 2. Redistributions in binary form must reproduce the above copyright 6989840Skris * notice, this list of conditions and the following disclaimer in 7089840Skris * the documentation and/or other materials provided with the 7189840Skris * distribution. 7289840Skris * 7389840Skris * 3. All advertising materials mentioning features or use of this 7489840Skris * software must display the following acknowledgment: 7589840Skris * "This product includes software developed by the OpenSSL Project 7689840Skris * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7789840Skris * 7889840Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 7989840Skris * endorse or promote products derived from this software without 8089840Skris * prior written permission. For written permission, please contact 8189840Skris * openssl-core@openssl.org. 8289840Skris * 8389840Skris * 5. Products derived from this software may not be called "OpenSSL" 8489840Skris * nor may "OpenSSL" appear in their names without prior written 8589840Skris * permission of the OpenSSL Project. 8689840Skris * 8789840Skris * 6. Redistributions of any form whatsoever must retain the following 8889840Skris * acknowledgment: 8989840Skris * "This product includes software developed by the OpenSSL Project 9089840Skris * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9189840Skris * 9289840Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9389840Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9489840Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9589840Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9689840Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9789840Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9889840Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 9989840Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10089840Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10189840Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10289840Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10389840Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 10489840Skris * ==================================================================== 10589840Skris * 10689840Skris * This product includes cryptographic software written by Eric Young 10789840Skris * (eay@cryptsoft.com). This product includes software written by Tim 10889840Skris * Hudson (tjh@cryptsoft.com). 10989840Skris * 11089840Skris */ 11155714Skris 11259194Skris#include "ssl_locl.h" 113110007Smarkm#ifndef OPENSSL_NO_SSL2 11455714Skris#include <stdio.h> 11555714Skris#include <openssl/bio.h> 11655714Skris#include <openssl/rand.h> 11755714Skris#include <openssl/objects.h> 11855714Skris#include <openssl/evp.h> 11955714Skris 12055714Skrisstatic SSL_METHOD *ssl2_get_server_method(int ver); 12155714Skrisstatic int get_client_master_key(SSL *s); 12255714Skrisstatic int get_client_hello(SSL *s); 12355714Skrisstatic int server_hello(SSL *s); 12455714Skrisstatic int get_client_finished(SSL *s); 12555714Skrisstatic int server_verify(SSL *s); 12655714Skrisstatic int server_finish(SSL *s); 12755714Skrisstatic int request_certificate(SSL *s); 12855714Skrisstatic int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, 12955714Skris unsigned char *to,int padding); 13055714Skris#define BREAK break 13155714Skris 13255714Skrisstatic SSL_METHOD *ssl2_get_server_method(int ver) 13355714Skris { 13455714Skris if (ver == SSL2_VERSION) 13555714Skris return(SSLv2_server_method()); 13655714Skris else 13755714Skris return(NULL); 13855714Skris } 13955714Skris 140160817SsimonIMPLEMENT_ssl2_meth_func(SSLv2_server_method, 141160817Ssimon ssl2_accept, 142160817Ssimon ssl_undefined_function, 143160817Ssimon ssl2_get_server_method) 14455714Skris 14555714Skrisint ssl2_accept(SSL *s) 14655714Skris { 147160817Ssimon unsigned long l=(unsigned long)time(NULL); 14855714Skris BUF_MEM *buf=NULL; 14955714Skris int ret= -1; 15055714Skris long num1; 151110007Smarkm void (*cb)(const SSL *ssl,int type,int val)=NULL; 15255714Skris int new_state,state; 15355714Skris 15459194Skris RAND_add(&l,sizeof(l),0); 15555714Skris ERR_clear_error(); 15655714Skris clear_sys_error(); 15755714Skris 15855714Skris if (s->info_callback != NULL) 15955714Skris cb=s->info_callback; 16055714Skris else if (s->ctx->info_callback != NULL) 16155714Skris cb=s->ctx->info_callback; 16255714Skris 16355714Skris /* init things to blank */ 16489840Skris s->in_handshake++; 16555714Skris if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 16655714Skris 16755714Skris if (s->cert == NULL) 16855714Skris { 16955714Skris SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET); 17055714Skris return(-1); 17155714Skris } 17255714Skris 17355714Skris clear_sys_error(); 17455714Skris for (;;) 17555714Skris { 17655714Skris state=s->state; 17755714Skris 17855714Skris switch (s->state) 17955714Skris { 18055714Skris case SSL_ST_BEFORE: 18155714Skris case SSL_ST_ACCEPT: 18255714Skris case SSL_ST_BEFORE|SSL_ST_ACCEPT: 18355714Skris case SSL_ST_OK|SSL_ST_ACCEPT: 18455714Skris 18555714Skris s->server=1; 18655714Skris if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); 18755714Skris 18855714Skris s->version=SSL2_VERSION; 18955714Skris s->type=SSL_ST_ACCEPT; 19055714Skris 19155714Skris buf=s->init_buf; 19255714Skris if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL)) 19355714Skris { ret= -1; goto end; } 19455714Skris if (!BUF_MEM_grow(buf,(int) 19555714Skris SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) 19655714Skris { ret= -1; goto end; } 19755714Skris s->init_buf=buf; 19855714Skris s->init_num=0; 19955714Skris s->ctx->stats.sess_accept++; 20055714Skris s->handshake_func=ssl2_accept; 20155714Skris s->state=SSL2_ST_GET_CLIENT_HELLO_A; 20255714Skris BREAK; 20355714Skris 20455714Skris case SSL2_ST_GET_CLIENT_HELLO_A: 20555714Skris case SSL2_ST_GET_CLIENT_HELLO_B: 20655714Skris case SSL2_ST_GET_CLIENT_HELLO_C: 20755714Skris s->shutdown=0; 20855714Skris ret=get_client_hello(s); 20955714Skris if (ret <= 0) goto end; 21055714Skris s->init_num=0; 21155714Skris s->state=SSL2_ST_SEND_SERVER_HELLO_A; 21255714Skris BREAK; 21355714Skris 21455714Skris case SSL2_ST_SEND_SERVER_HELLO_A: 21555714Skris case SSL2_ST_SEND_SERVER_HELLO_B: 21655714Skris ret=server_hello(s); 21755714Skris if (ret <= 0) goto end; 21855714Skris s->init_num=0; 21955714Skris if (!s->hit) 22055714Skris { 22155714Skris s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A; 22255714Skris BREAK; 22355714Skris } 22455714Skris else 22555714Skris { 22655714Skris s->state=SSL2_ST_SERVER_START_ENCRYPTION; 22755714Skris BREAK; 22855714Skris } 22955714Skris case SSL2_ST_GET_CLIENT_MASTER_KEY_A: 23055714Skris case SSL2_ST_GET_CLIENT_MASTER_KEY_B: 23155714Skris ret=get_client_master_key(s); 23255714Skris if (ret <= 0) goto end; 23355714Skris s->init_num=0; 23455714Skris s->state=SSL2_ST_SERVER_START_ENCRYPTION; 23555714Skris BREAK; 23655714Skris 23755714Skris case SSL2_ST_SERVER_START_ENCRYPTION: 23855714Skris /* Ok we how have sent all the stuff needed to 23955714Skris * start encrypting, the next packet back will 24055714Skris * be encrypted. */ 24155714Skris if (!ssl2_enc_init(s,0)) 24255714Skris { ret= -1; goto end; } 24355714Skris s->s2->clear_text=0; 24455714Skris s->state=SSL2_ST_SEND_SERVER_VERIFY_A; 24555714Skris BREAK; 24655714Skris 24755714Skris case SSL2_ST_SEND_SERVER_VERIFY_A: 24855714Skris case SSL2_ST_SEND_SERVER_VERIFY_B: 24955714Skris ret=server_verify(s); 25055714Skris if (ret <= 0) goto end; 25155714Skris s->init_num=0; 25255714Skris if (s->hit) 25355714Skris { 25455714Skris /* If we are in here, we have been 25555714Skris * buffering the output, so we need to 25655714Skris * flush it and remove buffering from 25755714Skris * future traffic */ 25855714Skris s->state=SSL2_ST_SEND_SERVER_VERIFY_C; 25955714Skris BREAK; 26055714Skris } 26155714Skris else 26255714Skris { 26355714Skris s->state=SSL2_ST_GET_CLIENT_FINISHED_A; 26455714Skris break; 26555714Skris } 26655714Skris 26755714Skris case SSL2_ST_SEND_SERVER_VERIFY_C: 26855714Skris /* get the number of bytes to write */ 26955714Skris num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL); 270205128Ssimon if (num1 > 0) 27155714Skris { 27255714Skris s->rwstate=SSL_WRITING; 27355714Skris num1=BIO_flush(s->wbio); 27455714Skris if (num1 <= 0) { ret= -1; goto end; } 27555714Skris s->rwstate=SSL_NOTHING; 27655714Skris } 27755714Skris 27855714Skris /* flushed and now remove buffering */ 27955714Skris s->wbio=BIO_pop(s->wbio); 28055714Skris 28155714Skris s->state=SSL2_ST_GET_CLIENT_FINISHED_A; 28255714Skris BREAK; 28355714Skris 28455714Skris case SSL2_ST_GET_CLIENT_FINISHED_A: 28555714Skris case SSL2_ST_GET_CLIENT_FINISHED_B: 28655714Skris ret=get_client_finished(s); 28755714Skris if (ret <= 0) 28855714Skris goto end; 28955714Skris s->init_num=0; 29055714Skris s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A; 29155714Skris BREAK; 29255714Skris 29355714Skris case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: 29455714Skris case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: 29555714Skris case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: 29655714Skris case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: 29755714Skris /* don't do a 'request certificate' if we 29855714Skris * don't want to, or we already have one, and 29955714Skris * we only want to do it once. */ 30055714Skris if (!(s->verify_mode & SSL_VERIFY_PEER) || 30155714Skris ((s->session->peer != NULL) && 30255714Skris (s->verify_mode & SSL_VERIFY_CLIENT_ONCE))) 30355714Skris { 30455714Skris s->state=SSL2_ST_SEND_SERVER_FINISHED_A; 30555714Skris break; 30655714Skris } 30755714Skris else 30855714Skris { 30955714Skris ret=request_certificate(s); 31055714Skris if (ret <= 0) goto end; 31155714Skris s->init_num=0; 31255714Skris s->state=SSL2_ST_SEND_SERVER_FINISHED_A; 31355714Skris } 31455714Skris BREAK; 31555714Skris 31655714Skris case SSL2_ST_SEND_SERVER_FINISHED_A: 31755714Skris case SSL2_ST_SEND_SERVER_FINISHED_B: 31855714Skris ret=server_finish(s); 31955714Skris if (ret <= 0) goto end; 32055714Skris s->init_num=0; 32155714Skris s->state=SSL_ST_OK; 32255714Skris break; 32355714Skris 32455714Skris case SSL_ST_OK: 32555714Skris BUF_MEM_free(s->init_buf); 32655714Skris ssl_free_wbio_buffer(s); 32755714Skris s->init_buf=NULL; 32855714Skris s->init_num=0; 32955714Skris /* ERR_clear_error();*/ 33055714Skris 33155714Skris ssl_update_cache(s,SSL_SESS_CACHE_SERVER); 33255714Skris 33355714Skris s->ctx->stats.sess_accept_good++; 33455714Skris /* s->server=1; */ 33555714Skris ret=1; 33655714Skris 33755714Skris if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); 33855714Skris 33955714Skris goto end; 34055714Skris /* BREAK; */ 34155714Skris 34255714Skris default: 34355714Skris SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE); 34455714Skris ret= -1; 34555714Skris goto end; 34655714Skris /* BREAK; */ 34755714Skris } 34855714Skris 34955714Skris if ((cb != NULL) && (s->state != state)) 35055714Skris { 35155714Skris new_state=s->state; 35255714Skris s->state=state; 35355714Skris cb(s,SSL_CB_ACCEPT_LOOP,1); 35455714Skris s->state=new_state; 35555714Skris } 35655714Skris } 35755714Skrisend: 35855714Skris s->in_handshake--; 35955714Skris if (cb != NULL) 36055714Skris cb(s,SSL_CB_ACCEPT_EXIT,ret); 36155714Skris return(ret); 36255714Skris } 36355714Skris 36455714Skrisstatic int get_client_master_key(SSL *s) 36555714Skris { 36655714Skris int is_export,i,n,keya,ek; 36789840Skris unsigned long len; 36855714Skris unsigned char *p; 36955714Skris SSL_CIPHER *cp; 37055714Skris const EVP_CIPHER *c; 37155714Skris const EVP_MD *md; 37255714Skris 37355714Skris p=(unsigned char *)s->init_buf->data; 37455714Skris if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) 37555714Skris { 37655714Skris i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num); 37755714Skris 37855714Skris if (i < (10-s->init_num)) 37955714Skris return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i)); 38089840Skris s->init_num = 10; 38189840Skris 38255714Skris if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY) 38355714Skris { 38455714Skris if (p[-1] != SSL2_MT_ERROR) 38555714Skris { 38655714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 38755714Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE); 38855714Skris } 38955714Skris else 390101621Snectar SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); 39155714Skris return(-1); 39255714Skris } 39355714Skris 39455714Skris cp=ssl2_get_cipher_by_char(p); 39555714Skris if (cp == NULL) 39655714Skris { 39755714Skris ssl2_return_error(s,SSL2_PE_NO_CIPHER); 398101621Snectar SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); 39955714Skris return(-1); 40055714Skris } 40155714Skris s->session->cipher= cp; 40255714Skris 40355714Skris p+=3; 40455714Skris n2s(p,i); s->s2->tmp.clear=i; 40555714Skris n2s(p,i); s->s2->tmp.enc=i; 406237998Sjkim n2s(p,i); 407237998Sjkim if(i > SSL_MAX_KEY_ARG_LENGTH) 408100943Snectar { 409101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 410101621Snectar SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); 411100943Snectar return -1; 412100943Snectar } 413237998Sjkim s->session->key_arg_length=i; 41455714Skris s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; 41555714Skris } 41655714Skris 41755714Skris /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ 41855714Skris p=(unsigned char *)s->init_buf->data; 419101621Snectar if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 420101621Snectar { 421101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 422110007Smarkm SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); 423101621Snectar return -1; 424101621Snectar } 42555714Skris keya=s->session->key_arg_length; 42689840Skris len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya; 42789840Skris if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 42889840Skris { 429101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 43089840Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG); 43189840Skris return -1; 43289840Skris } 43389840Skris n = (int)len - s->init_num; 43489840Skris i = ssl2_read(s,(char *)&(p[s->init_num]),n); 43555714Skris if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i)); 436110007Smarkm if (s->msg_callback) 437110007Smarkm s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */ 43889840Skris p += 10; 43955714Skris 44055714Skris memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]), 44155714Skris (unsigned int)keya); 44255714Skris 44355714Skris if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) 44455714Skris { 44555714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 44655714Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY); 44755714Skris return(-1); 44855714Skris } 44955714Skris i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc, 45055714Skris &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]), 45155714Skris (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); 45255714Skris 45355714Skris is_export=SSL_C_IS_EXPORT(s->session->cipher); 45455714Skris 45555714Skris if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) 45655714Skris { 45755714Skris ssl2_return_error(s,SSL2_PE_NO_CIPHER); 45855714Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); 45955714Skris return(0); 46055714Skris } 46155714Skris 46255714Skris if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) 46355714Skris { 46455714Skris is_export=1; 46555714Skris ek=8; 46655714Skris } 46755714Skris else 46855714Skris ek=5; 46955714Skris 47055714Skris /* bad decrypt */ 47155714Skris#if 1 47255714Skris /* If a bad decrypt, continue with protocol but with a 47380001Skris * random master secret (Bleichenbacher attack) */ 47455714Skris if ((i < 0) || 47555714Skris ((!is_export && (i != EVP_CIPHER_key_length(c))) 47689840Skris || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i != 47789840Skris (unsigned int)EVP_CIPHER_key_length(c)))))) 47855714Skris { 47980001Skris ERR_clear_error(); 48055714Skris if (is_export) 48155714Skris i=ek; 48255714Skris else 48355714Skris i=EVP_CIPHER_key_length(c); 484160817Ssimon if (RAND_pseudo_bytes(p,i) <= 0) 485160817Ssimon return 0; 48655714Skris } 48755714Skris#else 48855714Skris if (i < 0) 48955714Skris { 49055714Skris error=1; 49155714Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT); 49255714Skris } 49355714Skris /* incorrect number of key bytes for non export cipher */ 49455714Skris else if ((!is_export && (i != EVP_CIPHER_key_length(c))) 49555714Skris || (is_export && ((i != ek) || (s->s2->tmp.clear+i != 49655714Skris EVP_CIPHER_key_length(c))))) 49755714Skris { 49855714Skris error=1; 49955714Skris SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS); 50055714Skris } 50155714Skris if (error) 50255714Skris { 50355714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 50455714Skris return(-1); 50555714Skris } 50655714Skris#endif 50755714Skris 50855714Skris if (is_export) i+=s->s2->tmp.clear; 509101621Snectar 510101621Snectar if (i > SSL_MAX_MASTER_KEY_LENGTH) 511101621Snectar { 512101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 513110007Smarkm SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); 514101621Snectar return -1; 515101621Snectar } 51655714Skris s->session->master_key_length=i; 51755714Skris memcpy(s->session->master_key,p,(unsigned int)i); 51855714Skris return(1); 51955714Skris } 52055714Skris 52155714Skrisstatic int get_client_hello(SSL *s) 52255714Skris { 52355714Skris int i,n; 52489840Skris unsigned long len; 52555714Skris unsigned char *p; 52655714Skris STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ 52755714Skris STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ 528110007Smarkm STACK_OF(SSL_CIPHER) *prio, *allow; 52955714Skris int z; 53055714Skris 53155714Skris /* This is a bit of a hack to check for the correct packet 53255714Skris * type the first time round. */ 53355714Skris if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) 53455714Skris { 53555714Skris s->first_packet=1; 53655714Skris s->state=SSL2_ST_GET_CLIENT_HELLO_B; 53755714Skris } 53855714Skris 53955714Skris p=(unsigned char *)s->init_buf->data; 54055714Skris if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) 54155714Skris { 54255714Skris i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num); 54355714Skris if (i < (9-s->init_num)) 54455714Skris return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i)); 54589840Skris s->init_num = 9; 54655714Skris 54755714Skris if (*(p++) != SSL2_MT_CLIENT_HELLO) 54855714Skris { 54955714Skris if (p[-1] != SSL2_MT_ERROR) 55055714Skris { 55155714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 55255714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE); 55355714Skris } 55455714Skris else 55555714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR); 55655714Skris return(-1); 55755714Skris } 55855714Skris n2s(p,i); 55955714Skris if (i < s->version) s->version=i; 56055714Skris n2s(p,i); s->s2->tmp.cipher_spec_length=i; 56155714Skris n2s(p,i); s->s2->tmp.session_id_length=i; 56255714Skris n2s(p,i); s->s2->challenge_length=i; 56355714Skris if ( (i < SSL2_MIN_CHALLENGE_LENGTH) || 56455714Skris (i > SSL2_MAX_CHALLENGE_LENGTH)) 56555714Skris { 566101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 56755714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH); 56855714Skris return(-1); 56955714Skris } 57055714Skris s->state=SSL2_ST_GET_CLIENT_HELLO_C; 57155714Skris } 57255714Skris 57355714Skris /* SSL2_ST_GET_CLIENT_HELLO_C */ 57455714Skris p=(unsigned char *)s->init_buf->data; 57589840Skris len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length; 57689840Skris if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 57789840Skris { 578101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 57989840Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG); 58089840Skris return -1; 58189840Skris } 58289840Skris n = (int)len - s->init_num; 58389840Skris i = ssl2_read(s,(char *)&(p[s->init_num]),n); 58455714Skris if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i)); 585110007Smarkm if (s->msg_callback) 586110007Smarkm s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */ 58789840Skris p += 9; 58855714Skris 58955714Skris /* get session-id before cipher stuff so we can get out session 59055714Skris * structure if it is cached */ 59155714Skris /* session-id */ 59255714Skris if ((s->s2->tmp.session_id_length != 0) && 59355714Skris (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) 59455714Skris { 59555714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 59655714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH); 59755714Skris return(-1); 59855714Skris } 59955714Skris 60055714Skris if (s->s2->tmp.session_id_length == 0) 60155714Skris { 60255714Skris if (!ssl_get_new_session(s,1)) 60355714Skris { 60455714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 60555714Skris return(-1); 60655714Skris } 60755714Skris } 60855714Skris else 60955714Skris { 61055714Skris i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]), 611194206Ssimon s->s2->tmp.session_id_length, NULL); 61255714Skris if (i == 1) 61355714Skris { /* previous session */ 61455714Skris s->hit=1; 61555714Skris } 61655714Skris else if (i == -1) 61755714Skris { 61855714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 61955714Skris return(-1); 62055714Skris } 62155714Skris else 62255714Skris { 62355714Skris if (s->cert == NULL) 62455714Skris { 62555714Skris ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE); 62655714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET); 62755714Skris return(-1); 62855714Skris } 62955714Skris 63055714Skris if (!ssl_get_new_session(s,1)) 63155714Skris { 63255714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 63355714Skris return(-1); 63455714Skris } 63555714Skris } 63655714Skris } 63755714Skris 63855714Skris if (!s->hit) 63955714Skris { 64055714Skris cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length, 64155714Skris &s->session->ciphers); 64255714Skris if (cs == NULL) goto mem_err; 64355714Skris 644110007Smarkm cl=SSL_get_ciphers(s); 64555714Skris 646110007Smarkm if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) 647110007Smarkm { 648110007Smarkm prio=sk_SSL_CIPHER_dup(cl); 649110007Smarkm if (prio == NULL) goto mem_err; 650110007Smarkm allow = cs; 651110007Smarkm } 652110007Smarkm else 653110007Smarkm { 654110007Smarkm prio = cs; 655110007Smarkm allow = cl; 656110007Smarkm } 657110007Smarkm for (z=0; z<sk_SSL_CIPHER_num(prio); z++) 65855714Skris { 659110007Smarkm if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0) 66055714Skris { 661194206Ssimon (void)sk_SSL_CIPHER_delete(prio,z); 66255714Skris z--; 66355714Skris } 66455714Skris } 665110007Smarkm if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) 666110007Smarkm { 667110007Smarkm sk_SSL_CIPHER_free(s->session->ciphers); 668110007Smarkm s->session->ciphers = prio; 669110007Smarkm } 67055714Skris /* s->session->ciphers should now have a list of 67155714Skris * ciphers that are on both the client and server. 67255714Skris * This list is ordered by the order the client sent 673110007Smarkm * the ciphers or in the order of the server's preference 674110007Smarkm * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. 67555714Skris */ 67655714Skris } 67755714Skris p+=s->s2->tmp.cipher_spec_length; 67855714Skris /* done cipher selection */ 67955714Skris 68055714Skris /* session id extracted already */ 68155714Skris p+=s->s2->tmp.session_id_length; 68255714Skris 68355714Skris /* challenge */ 684101621Snectar if (s->s2->challenge_length > sizeof s->s2->challenge) 685101621Snectar { 686101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 687110007Smarkm SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); 688101621Snectar return -1; 689101621Snectar } 69055714Skris memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length); 69155714Skris return(1); 69255714Skrismem_err: 69355714Skris SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE); 69455714Skris return(0); 69555714Skris } 69655714Skris 69755714Skrisstatic int server_hello(SSL *s) 69855714Skris { 69955714Skris unsigned char *p,*d; 70055714Skris int n,hit; 70155714Skris 70255714Skris p=(unsigned char *)s->init_buf->data; 70355714Skris if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) 70455714Skris { 70555714Skris d=p+11; 70655714Skris *(p++)=SSL2_MT_SERVER_HELLO; /* type */ 70755714Skris hit=s->hit; 70855714Skris *(p++)=(unsigned char)hit; 70955714Skris#if 1 71055714Skris if (!hit) 71155714Skris { 71255714Skris if (s->session->sess_cert != NULL) 71355714Skris /* This can't really happen because get_client_hello 71455714Skris * has called ssl_get_new_session, which does not set 71555714Skris * sess_cert. */ 71655714Skris ssl_sess_cert_free(s->session->sess_cert); 71755714Skris s->session->sess_cert = ssl_sess_cert_new(); 71855714Skris if (s->session->sess_cert == NULL) 71955714Skris { 72055714Skris SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); 72155714Skris return(-1); 72255714Skris } 72355714Skris } 72455714Skris /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL, 72555714Skris * depending on whether it survived in the internal cache 72655714Skris * or was retrieved from an external cache. 72755714Skris * If it is NULL, we cannot put any useful data in it anyway, 72855714Skris * so we don't touch it. 72955714Skris */ 73055714Skris 73155714Skris#else /* That's what used to be done when cert_st and sess_cert_st were 73255714Skris * the same. */ 73355714Skris if (!hit) 73455714Skris { /* else add cert to session */ 73555714Skris CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT); 73655714Skris if (s->session->sess_cert != NULL) 73755714Skris ssl_cert_free(s->session->sess_cert); 73855714Skris s->session->sess_cert=s->cert; 73955714Skris } 74055714Skris else /* We have a session id-cache hit, if the 74155714Skris * session-id has no certificate listed against 74255714Skris * the 'cert' structure, grab the 'old' one 74355714Skris * listed against the SSL connection */ 74455714Skris { 74555714Skris if (s->session->sess_cert == NULL) 74655714Skris { 74755714Skris CRYPTO_add(&s->cert->references,1, 74855714Skris CRYPTO_LOCK_SSL_CERT); 74955714Skris s->session->sess_cert=s->cert; 75055714Skris } 75155714Skris } 75255714Skris#endif 75355714Skris 75455714Skris if (s->cert == NULL) 75555714Skris { 75655714Skris ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE); 75755714Skris SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED); 75855714Skris return(-1); 75955714Skris } 76055714Skris 76155714Skris if (hit) 76255714Skris { 76355714Skris *(p++)=0; /* no certificate type */ 76455714Skris s2n(s->version,p); /* version */ 76555714Skris s2n(0,p); /* cert len */ 76655714Skris s2n(0,p); /* ciphers len */ 76755714Skris } 76855714Skris else 76955714Skris { 77055714Skris /* EAY EAY */ 77155714Skris /* put certificate type */ 77255714Skris *(p++)=SSL2_CT_X509_CERTIFICATE; 77355714Skris s2n(s->version,p); /* version */ 77455714Skris n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL); 77555714Skris s2n(n,p); /* certificate length */ 77655714Skris i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d); 77755714Skris n=0; 77855714Skris 77955714Skris /* lets send out the ciphers we like in the 78055714Skris * prefered order */ 781160817Ssimon n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0); 78255714Skris d+=n; 78355714Skris s2n(n,p); /* add cipher length */ 78455714Skris } 78555714Skris 78655714Skris /* make and send conn_id */ 78755714Skris s2n(SSL2_CONNECTION_ID_LENGTH,p); /* add conn_id length */ 78855714Skris s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH; 789160817Ssimon if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0) 790160817Ssimon return -1; 79155714Skris memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH); 79255714Skris d+=SSL2_CONNECTION_ID_LENGTH; 79355714Skris 79455714Skris s->state=SSL2_ST_SEND_SERVER_HELLO_B; 79555714Skris s->init_num=d-(unsigned char *)s->init_buf->data; 79655714Skris s->init_off=0; 79755714Skris } 79855714Skris /* SSL2_ST_SEND_SERVER_HELLO_B */ 79959194Skris /* If we are using TCP/IP, the performance is bad if we do 2 80055714Skris * writes without a read between them. This occurs when 80155714Skris * Session-id reuse is used, so I will put in a buffering module 80255714Skris */ 80355714Skris if (s->hit) 80455714Skris { 80555714Skris if (!ssl_init_wbio_buffer(s,1)) return(-1); 80655714Skris } 80755714Skris 80855714Skris return(ssl2_do_write(s)); 80955714Skris } 81055714Skris 81155714Skrisstatic int get_client_finished(SSL *s) 81255714Skris { 81355714Skris unsigned char *p; 81489840Skris int i, n; 81589840Skris unsigned long len; 81655714Skris 81755714Skris p=(unsigned char *)s->init_buf->data; 81855714Skris if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A) 81955714Skris { 82055714Skris i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num); 82155714Skris if (i < 1-s->init_num) 82255714Skris return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i)); 82389840Skris s->init_num += i; 82455714Skris 82555714Skris if (*p != SSL2_MT_CLIENT_FINISHED) 82655714Skris { 82755714Skris if (*p != SSL2_MT_ERROR) 82855714Skris { 82955714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 83055714Skris SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE); 83155714Skris } 83255714Skris else 833110007Smarkm { 83455714Skris SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR); 835110007Smarkm /* try to read the error message */ 836110007Smarkm i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num); 837110007Smarkm return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i); 838110007Smarkm } 83955714Skris return(-1); 84055714Skris } 84155714Skris s->state=SSL2_ST_GET_CLIENT_FINISHED_B; 84255714Skris } 84355714Skris 84455714Skris /* SSL2_ST_GET_CLIENT_FINISHED_B */ 845101621Snectar if (s->s2->conn_id_length > sizeof s->s2->conn_id) 846101621Snectar { 847101621Snectar ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 848110007Smarkm SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); 849101621Snectar return -1; 850101621Snectar } 85189840Skris len = 1 + (unsigned long)s->s2->conn_id_length; 85289840Skris n = (int)len - s->init_num; 85389840Skris i = ssl2_read(s,(char *)&(p[s->init_num]),n); 85489840Skris if (i < n) 85555714Skris { 85655714Skris return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i)); 85755714Skris } 858110007Smarkm if (s->msg_callback) 859110007Smarkm s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */ 86089840Skris p += 1; 861110007Smarkm if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0) 86255714Skris { 86355714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 86455714Skris SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT); 86555714Skris return(-1); 86655714Skris } 86755714Skris return(1); 86855714Skris } 86955714Skris 87055714Skrisstatic int server_verify(SSL *s) 87155714Skris { 87255714Skris unsigned char *p; 87355714Skris 87455714Skris if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A) 87555714Skris { 87655714Skris p=(unsigned char *)s->init_buf->data; 87755714Skris *(p++)=SSL2_MT_SERVER_VERIFY; 878101621Snectar if (s->s2->challenge_length > sizeof s->s2->challenge) 879101621Snectar { 880110007Smarkm SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR); 881101621Snectar return -1; 882101621Snectar } 88355714Skris memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length); 88455714Skris /* p+=s->s2->challenge_length; */ 88555714Skris 88655714Skris s->state=SSL2_ST_SEND_SERVER_VERIFY_B; 88755714Skris s->init_num=s->s2->challenge_length+1; 88855714Skris s->init_off=0; 88955714Skris } 89055714Skris return(ssl2_do_write(s)); 89155714Skris } 89255714Skris 89355714Skrisstatic int server_finish(SSL *s) 89455714Skris { 89555714Skris unsigned char *p; 89655714Skris 89755714Skris if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A) 89855714Skris { 89955714Skris p=(unsigned char *)s->init_buf->data; 90055714Skris *(p++)=SSL2_MT_SERVER_FINISHED; 90155714Skris 902101621Snectar if (s->session->session_id_length > sizeof s->session->session_id) 903101621Snectar { 904110007Smarkm SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR); 905101621Snectar return -1; 906101621Snectar } 907101621Snectar memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length); 90855714Skris /* p+=s->session->session_id_length; */ 90955714Skris 91055714Skris s->state=SSL2_ST_SEND_SERVER_FINISHED_B; 91155714Skris s->init_num=s->session->session_id_length+1; 91255714Skris s->init_off=0; 91355714Skris } 91455714Skris 91555714Skris /* SSL2_ST_SEND_SERVER_FINISHED_B */ 91655714Skris return(ssl2_do_write(s)); 91755714Skris } 91855714Skris 91955714Skris/* send the request and check the response */ 92055714Skrisstatic int request_certificate(SSL *s) 92155714Skris { 922160817Ssimon const unsigned char *cp; 92355714Skris unsigned char *p,*p2,*buf2; 92455714Skris unsigned char *ccd; 92555714Skris int i,j,ctype,ret= -1; 92689840Skris unsigned long len; 92755714Skris X509 *x509=NULL; 92855714Skris STACK_OF(X509) *sk=NULL; 92955714Skris 93055714Skris ccd=s->s2->tmp.ccl; 93155714Skris if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A) 93255714Skris { 93355714Skris p=(unsigned char *)s->init_buf->data; 93455714Skris *(p++)=SSL2_MT_REQUEST_CERTIFICATE; 93555714Skris *(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION; 936160817Ssimon if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) 937142428Snectar return -1; 93855714Skris memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH); 93955714Skris 94055714Skris s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B; 94155714Skris s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2; 94255714Skris s->init_off=0; 94355714Skris } 94455714Skris 94555714Skris if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B) 94655714Skris { 94755714Skris i=ssl2_do_write(s); 94855714Skris if (i <= 0) 94955714Skris { 95055714Skris ret=i; 95155714Skris goto end; 95255714Skris } 95355714Skris 95455714Skris s->init_num=0; 95555714Skris s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C; 95655714Skris } 95755714Skris 95855714Skris if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C) 95955714Skris { 96055714Skris p=(unsigned char *)s->init_buf->data; 96189840Skris i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */ 96289840Skris if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3 96389840Skris * (probably NO-CERTIFICATE-ERROR) */ 96455714Skris { 96555714Skris ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i); 96655714Skris goto end; 96755714Skris } 96889840Skris s->init_num += i; 96955714Skris 97089840Skris if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR)) 97155714Skris { 97255714Skris n2s(p,i); 97389840Skris if (i != SSL2_PE_NO_CERTIFICATE) 97489840Skris { 97589840Skris /* not the error message we expected -- let ssl2_part_read handle it */ 97689840Skris s->init_num -= 3; 97789840Skris ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3); 97889840Skris goto end; 97989840Skris } 98089840Skris 981110007Smarkm if (s->msg_callback) 982110007Smarkm s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */ 983110007Smarkm 98489840Skris /* this is the one place where we can recover from an SSL 2.0 error */ 98589840Skris 98655714Skris if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) 98755714Skris { 98855714Skris ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE); 98955714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); 99055714Skris goto end; 99155714Skris } 99255714Skris ret=1; 99355714Skris goto end; 99455714Skris } 99589840Skris if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6)) 99655714Skris { 99755714Skris ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); 99855714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ); 99955714Skris goto end; 100055714Skris } 100189840Skris if (s->init_num != 6) 100289840Skris { 1003110007Smarkm SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR); 100489840Skris goto end; 100589840Skris } 100689840Skris 100755714Skris /* ok we have a response */ 100855714Skris /* certificate type, there is only one right now. */ 100955714Skris ctype= *(p++); 101055714Skris if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) 101155714Skris { 101255714Skris ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); 101355714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT); 101455714Skris goto end; 101555714Skris } 101655714Skris n2s(p,i); s->s2->tmp.clen=i; 101755714Skris n2s(p,i); s->s2->tmp.rlen=i; 101855714Skris s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D; 101955714Skris } 102055714Skris 102155714Skris /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */ 102255714Skris p=(unsigned char *)s->init_buf->data; 102389840Skris len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen; 102489840Skris if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) 102589840Skris { 1026110007Smarkm SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG); 102789840Skris goto end; 102889840Skris } 102989840Skris j = (int)len - s->init_num; 103089840Skris i = ssl2_read(s,(char *)&(p[s->init_num]),j); 103155714Skris if (i < j) 103255714Skris { 103355714Skris ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i); 103455714Skris goto end; 103555714Skris } 1036110007Smarkm if (s->msg_callback) 1037110007Smarkm s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */ 103889840Skris p += 6; 103955714Skris 1040160817Ssimon cp = p; 1041160817Ssimon x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen); 104255714Skris if (x509 == NULL) 104355714Skris { 104455714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB); 104555714Skris goto msg_end; 104655714Skris } 104755714Skris 104855714Skris if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509))) 104955714Skris { 105055714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE); 105155714Skris goto msg_end; 105255714Skris } 105355714Skris 105455714Skris i=ssl_verify_cert_chain(s,sk); 105555714Skris 1056186872Ssimon if (i > 0) /* we like the packet, now check the chksum */ 105755714Skris { 105855714Skris EVP_MD_CTX ctx; 105955714Skris EVP_PKEY *pkey=NULL; 106055714Skris 1061110007Smarkm EVP_MD_CTX_init(&ctx); 1062110007Smarkm EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL); 106355714Skris EVP_VerifyUpdate(&ctx,s->s2->key_material, 1064110007Smarkm s->s2->key_material_length); 106555714Skris EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH); 106655714Skris 106755714Skris i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL); 106868654Skris buf2=OPENSSL_malloc((unsigned int)i); 106955714Skris if (buf2 == NULL) 107055714Skris { 107155714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE); 107255714Skris goto msg_end; 107355714Skris } 107455714Skris p2=buf2; 107555714Skris i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2); 107655714Skris EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i); 107768654Skris OPENSSL_free(buf2); 107855714Skris 107955714Skris pkey=X509_get_pubkey(x509); 108055714Skris if (pkey == NULL) goto end; 1081160817Ssimon i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey); 108255714Skris EVP_PKEY_free(pkey); 1083110007Smarkm EVP_MD_CTX_cleanup(&ctx); 108455714Skris 1085194206Ssimon if (i > 0) 108655714Skris { 108755714Skris if (s->session->peer != NULL) 108855714Skris X509_free(s->session->peer); 108955714Skris s->session->peer=x509; 109055714Skris CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 109159194Skris s->session->verify_result = s->verify_result; 109255714Skris ret=1; 109355714Skris goto end; 109455714Skris } 109555714Skris else 109655714Skris { 109755714Skris SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM); 109855714Skris goto msg_end; 109955714Skris } 110055714Skris } 110155714Skris else 110255714Skris { 110355714Skrismsg_end: 110455714Skris ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE); 110555714Skris } 110655714Skrisend: 110755714Skris sk_X509_free(sk); 110855714Skris X509_free(x509); 110955714Skris return(ret); 111055714Skris } 111155714Skris 111255714Skrisstatic int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, 111355714Skris unsigned char *to, int padding) 111455714Skris { 111555714Skris RSA *rsa; 111655714Skris int i; 111755714Skris 111855714Skris if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) 111955714Skris { 112055714Skris SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY); 112155714Skris return(-1); 112255714Skris } 112355714Skris if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) 112455714Skris { 112555714Skris SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA); 112655714Skris return(-1); 112755714Skris } 112855714Skris rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; 112955714Skris 113055714Skris /* we have the public key */ 113155714Skris i=RSA_private_decrypt(len,from,to,rsa,padding); 113255714Skris if (i < 0) 113355714Skris SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB); 113455714Skris return(i); 113555714Skris } 1136110007Smarkm#else /* !OPENSSL_NO_SSL2 */ 113759194Skris 113859194Skris# if PEDANTIC 113959194Skrisstatic void *dummy=&dummy; 114059194Skris# endif 114159194Skris 114255714Skris#endif 1143