1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libssl/src/s2_srvr.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1157 @@
1.4 +/* ssl/s2_srvr.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/* ====================================================================
1.62 + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
1.63 + *
1.64 + * Redistribution and use in source and binary forms, with or without
1.65 + * modification, are permitted provided that the following conditions
1.66 + * are met:
1.67 + *
1.68 + * 1. Redistributions of source code must retain the above copyright
1.69 + * notice, this list of conditions and the following disclaimer.
1.70 + *
1.71 + * 2. Redistributions in binary form must reproduce the above copyright
1.72 + * notice, this list of conditions and the following disclaimer in
1.73 + * the documentation and/or other materials provided with the
1.74 + * distribution.
1.75 + *
1.76 + * 3. All advertising materials mentioning features or use of this
1.77 + * software must display the following acknowledgment:
1.78 + * "This product includes software developed by the OpenSSL Project
1.79 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.80 + *
1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.82 + * endorse or promote products derived from this software without
1.83 + * prior written permission. For written permission, please contact
1.84 + * openssl-core@openssl.org.
1.85 + *
1.86 + * 5. Products derived from this software may not be called "OpenSSL"
1.87 + * nor may "OpenSSL" appear in their names without prior written
1.88 + * permission of the OpenSSL Project.
1.89 + *
1.90 + * 6. Redistributions of any form whatsoever must retain the following
1.91 + * acknowledgment:
1.92 + * "This product includes software developed by the OpenSSL Project
1.93 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.94 + *
1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.98 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.107 + * ====================================================================
1.108 + *
1.109 + * This product includes cryptographic software written by Eric Young
1.110 + * (eay@cryptsoft.com). This product includes software written by Tim
1.111 + * Hudson (tjh@cryptsoft.com).
1.112 + *
1.113 + */
1.114 +/*
1.115 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.116 + */
1.117 +
1.118 +#include "ssl_locl.h"
1.119 +#ifndef OPENSSL_NO_SSL2
1.120 +#include <stdio.h>
1.121 +#include <openssl/bio.h>
1.122 +#include <openssl/rand.h>
1.123 +#include <openssl/objects.h>
1.124 +#include <openssl/evp.h>
1.125 +
1.126 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.127 +#include "libssl_wsd.h"
1.128 +#endif
1.129 +
1.130 +#ifdef EMULATOR
1.131 +
1.132 + GET_STATIC_VAR_FROM_TLS(SSLv2_server_method_data,s2_srvr,SSL_METHOD)
1.133 +
1.134 + #define SSLv2_server_method_data (*GET_WSD_VAR_NAME(SSLv2_server_method_data,s2_srvr,s)())
1.135 +
1.136 +#endif
1.137 +static SSL_METHOD *ssl2_get_server_method(int ver);
1.138 +static int get_client_master_key(SSL *s);
1.139 +static int get_client_hello(SSL *s);
1.140 +static int server_hello(SSL *s);
1.141 +static int get_client_finished(SSL *s);
1.142 +static int server_verify(SSL *s);
1.143 +static int server_finish(SSL *s);
1.144 +static int request_certificate(SSL *s);
1.145 +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
1.146 + unsigned char *to,int padding);
1.147 +#define BREAK break
1.148 +
1.149 +static SSL_METHOD *ssl2_get_server_method(int ver)
1.150 + {
1.151 + if (ver == SSL2_VERSION)
1.152 + return(SSLv2_server_method());
1.153 + else
1.154 + return(NULL);
1.155 + }
1.156 +
1.157 +EXPORT_C IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
1.158 + ssl2_accept,
1.159 + ssl_undefined_function,
1.160 + ssl2_get_server_method)
1.161 +
1.162 +int ssl2_accept(SSL *s)
1.163 + {
1.164 + unsigned long l=(unsigned long)time(NULL);
1.165 + BUF_MEM *buf=NULL;
1.166 + int ret= -1;
1.167 + long num1;
1.168 + void (*cb)(const SSL *ssl,int type,int val)=NULL;
1.169 + int new_state,state;
1.170 +
1.171 + RAND_add(&l,sizeof(l),0);
1.172 + ERR_clear_error();
1.173 + clear_sys_error();
1.174 +
1.175 + if (s->info_callback != NULL)
1.176 + cb=s->info_callback;
1.177 + else if (s->ctx->info_callback != NULL)
1.178 + cb=s->ctx->info_callback;
1.179 +
1.180 + /* init things to blank */
1.181 + s->in_handshake++;
1.182 + if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
1.183 +
1.184 + if (s->cert == NULL)
1.185 + {
1.186 + SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
1.187 + return(-1);
1.188 + }
1.189 +
1.190 + clear_sys_error();
1.191 + for (;;)
1.192 + {
1.193 + state=s->state;
1.194 +
1.195 + switch (s->state)
1.196 + {
1.197 + case SSL_ST_BEFORE:
1.198 + case SSL_ST_ACCEPT:
1.199 + case SSL_ST_BEFORE|SSL_ST_ACCEPT:
1.200 + case SSL_ST_OK|SSL_ST_ACCEPT:
1.201 +
1.202 + s->server=1;
1.203 + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
1.204 +
1.205 + s->version=SSL2_VERSION;
1.206 + s->type=SSL_ST_ACCEPT;
1.207 +
1.208 + buf=s->init_buf;
1.209 + if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
1.210 + { ret= -1; goto end; }
1.211 + if (!BUF_MEM_grow(buf,(int)
1.212 + SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
1.213 + { ret= -1; goto end; }
1.214 + s->init_buf=buf;
1.215 + s->init_num=0;
1.216 + s->ctx->stats.sess_accept++;
1.217 + s->handshake_func=ssl2_accept;
1.218 + s->state=SSL2_ST_GET_CLIENT_HELLO_A;
1.219 + BREAK;
1.220 +
1.221 + case SSL2_ST_GET_CLIENT_HELLO_A:
1.222 + case SSL2_ST_GET_CLIENT_HELLO_B:
1.223 + case SSL2_ST_GET_CLIENT_HELLO_C:
1.224 + s->shutdown=0;
1.225 + ret=get_client_hello(s);
1.226 + if (ret <= 0) goto end;
1.227 + s->init_num=0;
1.228 + s->state=SSL2_ST_SEND_SERVER_HELLO_A;
1.229 + BREAK;
1.230 +
1.231 + case SSL2_ST_SEND_SERVER_HELLO_A:
1.232 + case SSL2_ST_SEND_SERVER_HELLO_B:
1.233 + ret=server_hello(s);
1.234 + if (ret <= 0) goto end;
1.235 + s->init_num=0;
1.236 + if (!s->hit)
1.237 + {
1.238 + s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
1.239 + BREAK;
1.240 + }
1.241 + else
1.242 + {
1.243 + s->state=SSL2_ST_SERVER_START_ENCRYPTION;
1.244 + BREAK;
1.245 + }
1.246 + case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
1.247 + case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
1.248 + ret=get_client_master_key(s);
1.249 + if (ret <= 0) goto end;
1.250 + s->init_num=0;
1.251 + s->state=SSL2_ST_SERVER_START_ENCRYPTION;
1.252 + BREAK;
1.253 +
1.254 + case SSL2_ST_SERVER_START_ENCRYPTION:
1.255 + /* Ok we how have sent all the stuff needed to
1.256 + * start encrypting, the next packet back will
1.257 + * be encrypted. */
1.258 + if (!ssl2_enc_init(s,0))
1.259 + { ret= -1; goto end; }
1.260 + s->s2->clear_text=0;
1.261 + s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
1.262 + BREAK;
1.263 +
1.264 + case SSL2_ST_SEND_SERVER_VERIFY_A:
1.265 + case SSL2_ST_SEND_SERVER_VERIFY_B:
1.266 + ret=server_verify(s);
1.267 + if (ret <= 0) goto end;
1.268 + s->init_num=0;
1.269 + if (s->hit)
1.270 + {
1.271 + /* If we are in here, we have been
1.272 + * buffering the output, so we need to
1.273 + * flush it and remove buffering from
1.274 + * future traffic */
1.275 + s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
1.276 + BREAK;
1.277 + }
1.278 + else
1.279 + {
1.280 + s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
1.281 + break;
1.282 + }
1.283 +
1.284 + case SSL2_ST_SEND_SERVER_VERIFY_C:
1.285 + /* get the number of bytes to write */
1.286 + num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
1.287 + if (num1 != 0)
1.288 + {
1.289 + s->rwstate=SSL_WRITING;
1.290 + num1=BIO_flush(s->wbio);
1.291 + if (num1 <= 0) { ret= -1; goto end; }
1.292 + s->rwstate=SSL_NOTHING;
1.293 + }
1.294 +
1.295 + /* flushed and now remove buffering */
1.296 + s->wbio=BIO_pop(s->wbio);
1.297 +
1.298 + s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
1.299 + BREAK;
1.300 +
1.301 + case SSL2_ST_GET_CLIENT_FINISHED_A:
1.302 + case SSL2_ST_GET_CLIENT_FINISHED_B:
1.303 + ret=get_client_finished(s);
1.304 + if (ret <= 0)
1.305 + goto end;
1.306 + s->init_num=0;
1.307 + s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
1.308 + BREAK;
1.309 +
1.310 + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
1.311 + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
1.312 + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
1.313 + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
1.314 + /* don't do a 'request certificate' if we
1.315 + * don't want to, or we already have one, and
1.316 + * we only want to do it once. */
1.317 + if (!(s->verify_mode & SSL_VERIFY_PEER) ||
1.318 + ((s->session->peer != NULL) &&
1.319 + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
1.320 + {
1.321 + s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
1.322 + break;
1.323 + }
1.324 + else
1.325 + {
1.326 + ret=request_certificate(s);
1.327 + if (ret <= 0) goto end;
1.328 + s->init_num=0;
1.329 + s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
1.330 + }
1.331 + BREAK;
1.332 +
1.333 + case SSL2_ST_SEND_SERVER_FINISHED_A:
1.334 + case SSL2_ST_SEND_SERVER_FINISHED_B:
1.335 + ret=server_finish(s);
1.336 + if (ret <= 0) goto end;
1.337 + s->init_num=0;
1.338 + s->state=SSL_ST_OK;
1.339 + break;
1.340 +
1.341 + case SSL_ST_OK:
1.342 + BUF_MEM_free(s->init_buf);
1.343 + ssl_free_wbio_buffer(s);
1.344 + s->init_buf=NULL;
1.345 + s->init_num=0;
1.346 + /* ERR_clear_error();*/
1.347 +
1.348 + ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
1.349 +
1.350 + s->ctx->stats.sess_accept_good++;
1.351 + /* s->server=1; */
1.352 + ret=1;
1.353 +
1.354 + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
1.355 +
1.356 + goto end;
1.357 + /* BREAK; */
1.358 +
1.359 + default:
1.360 + SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
1.361 + ret= -1;
1.362 + goto end;
1.363 + /* BREAK; */
1.364 + }
1.365 +
1.366 + if ((cb != NULL) && (s->state != state))
1.367 + {
1.368 + new_state=s->state;
1.369 + s->state=state;
1.370 + cb(s,SSL_CB_ACCEPT_LOOP,1);
1.371 + s->state=new_state;
1.372 + }
1.373 + }
1.374 +end:
1.375 + s->in_handshake--;
1.376 + if (cb != NULL)
1.377 + cb(s,SSL_CB_ACCEPT_EXIT,ret);
1.378 + return(ret);
1.379 + }
1.380 +
1.381 +static int get_client_master_key(SSL *s)
1.382 + {
1.383 + int is_export,i,n,keya,ek;
1.384 + unsigned long len;
1.385 + unsigned char *p;
1.386 + SSL_CIPHER *cp;
1.387 + const EVP_CIPHER *c;
1.388 + const EVP_MD *md;
1.389 +
1.390 + p=(unsigned char *)s->init_buf->data;
1.391 + if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
1.392 + {
1.393 + i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
1.394 +
1.395 + if (i < (10-s->init_num))
1.396 + return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
1.397 + s->init_num = 10;
1.398 +
1.399 + if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
1.400 + {
1.401 + if (p[-1] != SSL2_MT_ERROR)
1.402 + {
1.403 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.404 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
1.405 + }
1.406 + else
1.407 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
1.408 + return(-1);
1.409 + }
1.410 +
1.411 + cp=ssl2_get_cipher_by_char(p);
1.412 + if (cp == NULL)
1.413 + {
1.414 + ssl2_return_error(s,SSL2_PE_NO_CIPHER);
1.415 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
1.416 + return(-1);
1.417 + }
1.418 + s->session->cipher= cp;
1.419 +
1.420 + p+=3;
1.421 + n2s(p,i); s->s2->tmp.clear=i;
1.422 + n2s(p,i); s->s2->tmp.enc=i;
1.423 + n2s(p,i); s->session->key_arg_length=i;
1.424 + if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH)
1.425 + {
1.426 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.427 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
1.428 + return -1;
1.429 + }
1.430 + s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
1.431 + }
1.432 +
1.433 + /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
1.434 + p=(unsigned char *)s->init_buf->data;
1.435 + if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
1.436 + {
1.437 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.438 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
1.439 + return -1;
1.440 + }
1.441 + keya=s->session->key_arg_length;
1.442 + len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
1.443 + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
1.444 + {
1.445 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.446 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
1.447 + return -1;
1.448 + }
1.449 + n = (int)len - s->init_num;
1.450 + i = ssl2_read(s,(char *)&(p[s->init_num]),n);
1.451 + if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
1.452 + if (s->msg_callback)
1.453 + s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
1.454 + p += 10;
1.455 +
1.456 + memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
1.457 + (unsigned int)keya);
1.458 +
1.459 + if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
1.460 + {
1.461 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.462 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
1.463 + return(-1);
1.464 + }
1.465 + i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
1.466 + &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
1.467 + (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
1.468 +
1.469 + is_export=SSL_C_IS_EXPORT(s->session->cipher);
1.470 +
1.471 + if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
1.472 + {
1.473 + ssl2_return_error(s,SSL2_PE_NO_CIPHER);
1.474 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
1.475 + return(0);
1.476 + }
1.477 +
1.478 + if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
1.479 + {
1.480 + is_export=1;
1.481 + ek=8;
1.482 + }
1.483 + else
1.484 + ek=5;
1.485 +
1.486 + /* bad decrypt */
1.487 +#if 1
1.488 + /* If a bad decrypt, continue with protocol but with a
1.489 + * random master secret (Bleichenbacher attack) */
1.490 + if ((i < 0) ||
1.491 + ((!is_export && (i != EVP_CIPHER_key_length(c)))
1.492 + || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
1.493 + (unsigned int)EVP_CIPHER_key_length(c))))))
1.494 + {
1.495 + ERR_clear_error();
1.496 + if (is_export)
1.497 + i=ek;
1.498 + else
1.499 + i=EVP_CIPHER_key_length(c);
1.500 + if (RAND_pseudo_bytes(p,i) <= 0)
1.501 + return 0;
1.502 + }
1.503 +#else
1.504 + if (i < 0)
1.505 + {
1.506 + error=1;
1.507 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
1.508 + }
1.509 + /* incorrect number of key bytes for non export cipher */
1.510 + else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
1.511 + || (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
1.512 + EVP_CIPHER_key_length(c)))))
1.513 + {
1.514 + error=1;
1.515 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
1.516 + }
1.517 + if (error)
1.518 + {
1.519 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.520 + return(-1);
1.521 + }
1.522 +#endif
1.523 +
1.524 + if (is_export) i+=s->s2->tmp.clear;
1.525 +
1.526 + if (i > SSL_MAX_MASTER_KEY_LENGTH)
1.527 + {
1.528 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.529 + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
1.530 + return -1;
1.531 + }
1.532 + s->session->master_key_length=i;
1.533 + memcpy(s->session->master_key,p,(unsigned int)i);
1.534 + return(1);
1.535 + }
1.536 +
1.537 +static int get_client_hello(SSL *s)
1.538 + {
1.539 + int i,n;
1.540 + unsigned long len;
1.541 + unsigned char *p;
1.542 + STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
1.543 + STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
1.544 + STACK_OF(SSL_CIPHER) *prio, *allow;
1.545 + int z;
1.546 +
1.547 + /* This is a bit of a hack to check for the correct packet
1.548 + * type the first time round. */
1.549 + if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
1.550 + {
1.551 + s->first_packet=1;
1.552 + s->state=SSL2_ST_GET_CLIENT_HELLO_B;
1.553 + }
1.554 +
1.555 + p=(unsigned char *)s->init_buf->data;
1.556 + if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
1.557 + {
1.558 + i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
1.559 + if (i < (9-s->init_num))
1.560 + return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
1.561 + s->init_num = 9;
1.562 +
1.563 + if (*(p++) != SSL2_MT_CLIENT_HELLO)
1.564 + {
1.565 + if (p[-1] != SSL2_MT_ERROR)
1.566 + {
1.567 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.568 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
1.569 + }
1.570 + else
1.571 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
1.572 + return(-1);
1.573 + }
1.574 + n2s(p,i);
1.575 + if (i < s->version) s->version=i;
1.576 + n2s(p,i); s->s2->tmp.cipher_spec_length=i;
1.577 + n2s(p,i); s->s2->tmp.session_id_length=i;
1.578 + n2s(p,i); s->s2->challenge_length=i;
1.579 + if ( (i < SSL2_MIN_CHALLENGE_LENGTH) ||
1.580 + (i > SSL2_MAX_CHALLENGE_LENGTH))
1.581 + {
1.582 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.583 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
1.584 + return(-1);
1.585 + }
1.586 + s->state=SSL2_ST_GET_CLIENT_HELLO_C;
1.587 + }
1.588 +
1.589 + /* SSL2_ST_GET_CLIENT_HELLO_C */
1.590 + p=(unsigned char *)s->init_buf->data;
1.591 + len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
1.592 + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
1.593 + {
1.594 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.595 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
1.596 + return -1;
1.597 + }
1.598 + n = (int)len - s->init_num;
1.599 + i = ssl2_read(s,(char *)&(p[s->init_num]),n);
1.600 + if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
1.601 + if (s->msg_callback)
1.602 + s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
1.603 + p += 9;
1.604 +
1.605 + /* get session-id before cipher stuff so we can get out session
1.606 + * structure if it is cached */
1.607 + /* session-id */
1.608 + if ((s->s2->tmp.session_id_length != 0) &&
1.609 + (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
1.610 + {
1.611 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.612 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
1.613 + return(-1);
1.614 + }
1.615 +
1.616 + if (s->s2->tmp.session_id_length == 0)
1.617 + {
1.618 + if (!ssl_get_new_session(s,1))
1.619 + {
1.620 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.621 + return(-1);
1.622 + }
1.623 + }
1.624 + else
1.625 + {
1.626 + i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
1.627 + s->s2->tmp.session_id_length, NULL);
1.628 + if (i == 1)
1.629 + { /* previous session */
1.630 + s->hit=1;
1.631 + }
1.632 + else if (i == -1)
1.633 + {
1.634 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.635 + return(-1);
1.636 + }
1.637 + else
1.638 + {
1.639 + if (s->cert == NULL)
1.640 + {
1.641 + ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
1.642 + SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
1.643 + return(-1);
1.644 + }
1.645 +
1.646 + if (!ssl_get_new_session(s,1))
1.647 + {
1.648 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.649 + return(-1);
1.650 + }
1.651 + }
1.652 + }
1.653 +
1.654 + if (!s->hit)
1.655 + {
1.656 + cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
1.657 + &s->session->ciphers);
1.658 + if (cs == NULL) goto mem_err;
1.659 +
1.660 + cl=SSL_get_ciphers(s);
1.661 +
1.662 + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
1.663 + {
1.664 + prio=sk_SSL_CIPHER_dup(cl);
1.665 + if (prio == NULL) goto mem_err;
1.666 + allow = cs;
1.667 + }
1.668 + else
1.669 + {
1.670 + prio = cs;
1.671 + allow = cl;
1.672 + }
1.673 + for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
1.674 + {
1.675 + if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
1.676 + {
1.677 + (void)sk_SSL_CIPHER_delete(prio,z);
1.678 + z--;
1.679 + }
1.680 + }
1.681 + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
1.682 + {
1.683 + sk_SSL_CIPHER_free(s->session->ciphers);
1.684 + s->session->ciphers = prio;
1.685 + }
1.686 + /* s->session->ciphers should now have a list of
1.687 + * ciphers that are on both the client and server.
1.688 + * This list is ordered by the order the client sent
1.689 + * the ciphers or in the order of the server's preference
1.690 + * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
1.691 + */
1.692 + }
1.693 + p+=s->s2->tmp.cipher_spec_length;
1.694 + /* done cipher selection */
1.695 +
1.696 + /* session id extracted already */
1.697 + p+=s->s2->tmp.session_id_length;
1.698 +
1.699 + /* challenge */
1.700 + if (s->s2->challenge_length > sizeof s->s2->challenge)
1.701 + {
1.702 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.703 + SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
1.704 + return -1;
1.705 + }
1.706 + memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
1.707 + return(1);
1.708 +mem_err:
1.709 + SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
1.710 + return(0);
1.711 + }
1.712 +
1.713 +static int server_hello(SSL *s)
1.714 + {
1.715 + unsigned char *p,*d;
1.716 + int n,hit;
1.717 + STACK_OF(SSL_CIPHER) *sk;
1.718 +
1.719 + p=(unsigned char *)s->init_buf->data;
1.720 + if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
1.721 + {
1.722 + d=p+11;
1.723 + *(p++)=SSL2_MT_SERVER_HELLO; /* type */
1.724 + hit=s->hit;
1.725 + *(p++)=(unsigned char)hit;
1.726 +#if 1
1.727 + if (!hit)
1.728 + {
1.729 + if (s->session->sess_cert != NULL)
1.730 + /* This can't really happen because get_client_hello
1.731 + * has called ssl_get_new_session, which does not set
1.732 + * sess_cert. */
1.733 + ssl_sess_cert_free(s->session->sess_cert);
1.734 + s->session->sess_cert = ssl_sess_cert_new();
1.735 + if (s->session->sess_cert == NULL)
1.736 + {
1.737 + SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
1.738 + return(-1);
1.739 + }
1.740 + }
1.741 + /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
1.742 + * depending on whether it survived in the internal cache
1.743 + * or was retrieved from an external cache.
1.744 + * If it is NULL, we cannot put any useful data in it anyway,
1.745 + * so we don't touch it.
1.746 + */
1.747 +
1.748 +#else /* That's what used to be done when cert_st and sess_cert_st were
1.749 + * the same. */
1.750 + if (!hit)
1.751 + { /* else add cert to session */
1.752 + CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
1.753 + if (s->session->sess_cert != NULL)
1.754 + ssl_cert_free(s->session->sess_cert);
1.755 + s->session->sess_cert=s->cert;
1.756 + }
1.757 + else /* We have a session id-cache hit, if the
1.758 + * session-id has no certificate listed against
1.759 + * the 'cert' structure, grab the 'old' one
1.760 + * listed against the SSL connection */
1.761 + {
1.762 + if (s->session->sess_cert == NULL)
1.763 + {
1.764 + CRYPTO_add(&s->cert->references,1,
1.765 + CRYPTO_LOCK_SSL_CERT);
1.766 + s->session->sess_cert=s->cert;
1.767 + }
1.768 + }
1.769 +#endif
1.770 +
1.771 + if (s->cert == NULL)
1.772 + {
1.773 + ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
1.774 + SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
1.775 + return(-1);
1.776 + }
1.777 +
1.778 + if (hit)
1.779 + {
1.780 + *(p++)=0; /* no certificate type */
1.781 + s2n(s->version,p); /* version */
1.782 + s2n(0,p); /* cert len */
1.783 + s2n(0,p); /* ciphers len */
1.784 + }
1.785 + else
1.786 + {
1.787 + /* EAY EAY */
1.788 + /* put certificate type */
1.789 + *(p++)=SSL2_CT_X509_CERTIFICATE;
1.790 + s2n(s->version,p); /* version */
1.791 + n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
1.792 + s2n(n,p); /* certificate length */
1.793 + i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
1.794 + n=0;
1.795 +
1.796 + /* lets send out the ciphers we like in the
1.797 + * prefered order */
1.798 + sk= s->session->ciphers;
1.799 + n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
1.800 + d+=n;
1.801 + s2n(n,p); /* add cipher length */
1.802 + }
1.803 +
1.804 + /* make and send conn_id */
1.805 + s2n(SSL2_CONNECTION_ID_LENGTH,p); /* add conn_id length */
1.806 + s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
1.807 + if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
1.808 + return -1;
1.809 + memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
1.810 + d+=SSL2_CONNECTION_ID_LENGTH;
1.811 +
1.812 + s->state=SSL2_ST_SEND_SERVER_HELLO_B;
1.813 + s->init_num=d-(unsigned char *)s->init_buf->data;
1.814 + s->init_off=0;
1.815 + }
1.816 + /* SSL2_ST_SEND_SERVER_HELLO_B */
1.817 + /* If we are using TCP/IP, the performance is bad if we do 2
1.818 + * writes without a read between them. This occurs when
1.819 + * Session-id reuse is used, so I will put in a buffering module
1.820 + */
1.821 + if (s->hit)
1.822 + {
1.823 + if (!ssl_init_wbio_buffer(s,1)) return(-1);
1.824 + }
1.825 +
1.826 + return(ssl2_do_write(s));
1.827 + }
1.828 +
1.829 +static int get_client_finished(SSL *s)
1.830 + {
1.831 + unsigned char *p;
1.832 + int i, n;
1.833 + unsigned long len;
1.834 +
1.835 + p=(unsigned char *)s->init_buf->data;
1.836 + if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
1.837 + {
1.838 + i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
1.839 + if (i < 1-s->init_num)
1.840 + return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
1.841 + s->init_num += i;
1.842 +
1.843 + if (*p != SSL2_MT_CLIENT_FINISHED)
1.844 + {
1.845 + if (*p != SSL2_MT_ERROR)
1.846 + {
1.847 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.848 + SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
1.849 + }
1.850 + else
1.851 + {
1.852 + SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
1.853 + /* try to read the error message */
1.854 + i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
1.855 + return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
1.856 + }
1.857 + return(-1);
1.858 + }
1.859 + s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
1.860 + }
1.861 +
1.862 + /* SSL2_ST_GET_CLIENT_FINISHED_B */
1.863 + if (s->s2->conn_id_length > sizeof s->s2->conn_id)
1.864 + {
1.865 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.866 + SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
1.867 + return -1;
1.868 + }
1.869 + len = 1 + (unsigned long)s->s2->conn_id_length;
1.870 + n = (int)len - s->init_num;
1.871 + i = ssl2_read(s,(char *)&(p[s->init_num]),n);
1.872 + if (i < n)
1.873 + {
1.874 + return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
1.875 + }
1.876 + if (s->msg_callback)
1.877 + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
1.878 + p += 1;
1.879 + if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
1.880 + {
1.881 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.882 + SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
1.883 + return(-1);
1.884 + }
1.885 + return(1);
1.886 + }
1.887 +
1.888 +static int server_verify(SSL *s)
1.889 + {
1.890 + unsigned char *p;
1.891 +
1.892 + if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
1.893 + {
1.894 + p=(unsigned char *)s->init_buf->data;
1.895 + *(p++)=SSL2_MT_SERVER_VERIFY;
1.896 + if (s->s2->challenge_length > sizeof s->s2->challenge)
1.897 + {
1.898 + SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
1.899 + return -1;
1.900 + }
1.901 + memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
1.902 + /* p+=s->s2->challenge_length; */
1.903 +
1.904 + s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
1.905 + s->init_num=s->s2->challenge_length+1;
1.906 + s->init_off=0;
1.907 + }
1.908 + return(ssl2_do_write(s));
1.909 + }
1.910 +
1.911 +static int server_finish(SSL *s)
1.912 + {
1.913 + unsigned char *p;
1.914 +
1.915 + if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
1.916 + {
1.917 + p=(unsigned char *)s->init_buf->data;
1.918 + *(p++)=SSL2_MT_SERVER_FINISHED;
1.919 +
1.920 + if (s->session->session_id_length > sizeof s->session->session_id)
1.921 + {
1.922 + SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
1.923 + return -1;
1.924 + }
1.925 + memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
1.926 + /* p+=s->session->session_id_length; */
1.927 +
1.928 + s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
1.929 + s->init_num=s->session->session_id_length+1;
1.930 + s->init_off=0;
1.931 + }
1.932 +
1.933 + /* SSL2_ST_SEND_SERVER_FINISHED_B */
1.934 + return(ssl2_do_write(s));
1.935 + }
1.936 +
1.937 +/* send the request and check the response */
1.938 +static int request_certificate(SSL *s)
1.939 + {
1.940 + const unsigned char *cp;
1.941 + unsigned char *p,*p2,*buf2;
1.942 + unsigned char *ccd;
1.943 + int i,j,ctype,ret= -1;
1.944 + unsigned long len;
1.945 + X509 *x509=NULL;
1.946 + STACK_OF(X509) *sk=NULL;
1.947 +
1.948 + ccd=s->s2->tmp.ccl;
1.949 + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
1.950 + {
1.951 + p=(unsigned char *)s->init_buf->data;
1.952 + *(p++)=SSL2_MT_REQUEST_CERTIFICATE;
1.953 + *(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
1.954 + if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
1.955 + return -1;
1.956 + memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
1.957 +
1.958 + s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
1.959 + s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
1.960 + s->init_off=0;
1.961 + }
1.962 +
1.963 + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
1.964 + {
1.965 + i=ssl2_do_write(s);
1.966 + if (i <= 0)
1.967 + {
1.968 + ret=i;
1.969 + goto end;
1.970 + }
1.971 +
1.972 + s->init_num=0;
1.973 + s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
1.974 + }
1.975 +
1.976 + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
1.977 + {
1.978 + p=(unsigned char *)s->init_buf->data;
1.979 + i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
1.980 + if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
1.981 + * (probably NO-CERTIFICATE-ERROR) */
1.982 + {
1.983 + ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
1.984 + goto end;
1.985 + }
1.986 + s->init_num += i;
1.987 +
1.988 + if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
1.989 + {
1.990 + n2s(p,i);
1.991 + if (i != SSL2_PE_NO_CERTIFICATE)
1.992 + {
1.993 + /* not the error message we expected -- let ssl2_part_read handle it */
1.994 + s->init_num -= 3;
1.995 + ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
1.996 + goto end;
1.997 + }
1.998 +
1.999 + if (s->msg_callback)
1.1000 + s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
1.1001 +
1.1002 + /* this is the one place where we can recover from an SSL 2.0 error */
1.1003 +
1.1004 + if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
1.1005 + {
1.1006 + ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
1.1007 + SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
1.1008 + goto end;
1.1009 + }
1.1010 + ret=1;
1.1011 + goto end;
1.1012 + }
1.1013 + if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
1.1014 + {
1.1015 + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1.1016 + SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
1.1017 + goto end;
1.1018 + }
1.1019 + if (s->init_num != 6)
1.1020 + {
1.1021 + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
1.1022 + goto end;
1.1023 + }
1.1024 +
1.1025 + /* ok we have a response */
1.1026 + /* certificate type, there is only one right now. */
1.1027 + ctype= *(p++);
1.1028 + if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
1.1029 + {
1.1030 + ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
1.1031 + SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
1.1032 + goto end;
1.1033 + }
1.1034 + n2s(p,i); s->s2->tmp.clen=i;
1.1035 + n2s(p,i); s->s2->tmp.rlen=i;
1.1036 + s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
1.1037 + }
1.1038 +
1.1039 + /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
1.1040 + p=(unsigned char *)s->init_buf->data;
1.1041 + len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
1.1042 + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
1.1043 + {
1.1044 + SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
1.1045 + goto end;
1.1046 + }
1.1047 + j = (int)len - s->init_num;
1.1048 + i = ssl2_read(s,(char *)&(p[s->init_num]),j);
1.1049 + if (i < j)
1.1050 + {
1.1051 + ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
1.1052 + goto end;
1.1053 + }
1.1054 + if (s->msg_callback)
1.1055 + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
1.1056 + p += 6;
1.1057 +
1.1058 + cp = p;
1.1059 + x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
1.1060 + if (x509 == NULL)
1.1061 + {
1.1062 + SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
1.1063 + goto msg_end;
1.1064 + }
1.1065 +
1.1066 + if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
1.1067 + {
1.1068 + SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1.1069 + goto msg_end;
1.1070 + }
1.1071 +
1.1072 + i=ssl_verify_cert_chain(s,sk);
1.1073 +
1.1074 + if (i) /* we like the packet, now check the chksum */
1.1075 + {
1.1076 + EVP_MD_CTX ctx;
1.1077 + EVP_PKEY *pkey=NULL;
1.1078 +
1.1079 + EVP_MD_CTX_init(&ctx);
1.1080 + EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
1.1081 + EVP_VerifyUpdate(&ctx,s->s2->key_material,
1.1082 + s->s2->key_material_length);
1.1083 + EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
1.1084 +
1.1085 + i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
1.1086 + buf2=OPENSSL_malloc((unsigned int)i);
1.1087 + if (buf2 == NULL)
1.1088 + {
1.1089 + SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1.1090 + goto msg_end;
1.1091 + }
1.1092 + p2=buf2;
1.1093 + i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
1.1094 + EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
1.1095 + OPENSSL_free(buf2);
1.1096 +
1.1097 + pkey=X509_get_pubkey(x509);
1.1098 + if (pkey == NULL) goto end;
1.1099 + i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
1.1100 + EVP_PKEY_free(pkey);
1.1101 + EVP_MD_CTX_cleanup(&ctx);
1.1102 +
1.1103 + if (i)
1.1104 + {
1.1105 + if (s->session->peer != NULL)
1.1106 + X509_free(s->session->peer);
1.1107 + s->session->peer=x509;
1.1108 + CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
1.1109 + s->session->verify_result = s->verify_result;
1.1110 + ret=1;
1.1111 + goto end;
1.1112 + }
1.1113 + else
1.1114 + {
1.1115 + SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
1.1116 + goto msg_end;
1.1117 + }
1.1118 + }
1.1119 + else
1.1120 + {
1.1121 +msg_end:
1.1122 + ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
1.1123 + }
1.1124 +end:
1.1125 + sk_X509_free(sk);
1.1126 + X509_free(x509);
1.1127 + return(ret);
1.1128 + }
1.1129 +
1.1130 +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
1.1131 + unsigned char *to, int padding)
1.1132 + {
1.1133 + RSA *rsa;
1.1134 + int i;
1.1135 +
1.1136 + if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
1.1137 + {
1.1138 + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
1.1139 + return(-1);
1.1140 + }
1.1141 + if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
1.1142 + {
1.1143 + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
1.1144 + return(-1);
1.1145 + }
1.1146 + rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
1.1147 +
1.1148 + /* we have the public key */
1.1149 + i=RSA_private_decrypt(len,from,to,rsa,padding);
1.1150 + if (i < 0)
1.1151 + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
1.1152 + return(i);
1.1153 + }
1.1154 +#else /* !OPENSSL_NO_SSL2 */
1.1155 +
1.1156 +# if PEDANTIC
1.1157 +static void *dummy=&dummy;
1.1158 +# endif
1.1159 +
1.1160 +#endif