Branch data Line data Source code
1 : : /* ssl/s2_srvr.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : : /* ====================================================================
59 : : * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 : : *
61 : : * Redistribution and use in source and binary forms, with or without
62 : : * modification, are permitted provided that the following conditions
63 : : * are met:
64 : : *
65 : : * 1. Redistributions of source code must retain the above copyright
66 : : * notice, this list of conditions and the following disclaimer.
67 : : *
68 : : * 2. Redistributions in binary form must reproduce the above copyright
69 : : * notice, this list of conditions and the following disclaimer in
70 : : * the documentation and/or other materials provided with the
71 : : * distribution.
72 : : *
73 : : * 3. All advertising materials mentioning features or use of this
74 : : * software must display the following acknowledgment:
75 : : * "This product includes software developed by the OpenSSL Project
76 : : * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 : : *
78 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 : : * endorse or promote products derived from this software without
80 : : * prior written permission. For written permission, please contact
81 : : * openssl-core@openssl.org.
82 : : *
83 : : * 5. Products derived from this software may not be called "OpenSSL"
84 : : * nor may "OpenSSL" appear in their names without prior written
85 : : * permission of the OpenSSL Project.
86 : : *
87 : : * 6. Redistributions of any form whatsoever must retain the following
88 : : * acknowledgment:
89 : : * "This product includes software developed by the OpenSSL Project
90 : : * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 : : *
92 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
104 : : * ====================================================================
105 : : *
106 : : * This product includes cryptographic software written by Eric Young
107 : : * (eay@cryptsoft.com). This product includes software written by Tim
108 : : * Hudson (tjh@cryptsoft.com).
109 : : *
110 : : */
111 : :
112 : : #include "ssl_locl.h"
113 : : #ifndef OPENSSL_NO_SSL2
114 : : #include <stdio.h>
115 : : #include <openssl/bio.h>
116 : : #include <openssl/rand.h>
117 : : #include <openssl/objects.h>
118 : : #include <openssl/evp.h>
119 : :
120 : : static const SSL_METHOD *ssl2_get_server_method(int ver);
121 : : static int get_client_master_key(SSL *s);
122 : : static int get_client_hello(SSL *s);
123 : : static int server_hello(SSL *s);
124 : : static int get_client_finished(SSL *s);
125 : : static int server_verify(SSL *s);
126 : : static int server_finish(SSL *s);
127 : : static int request_certificate(SSL *s);
128 : : static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
129 : : unsigned char *to,int padding);
130 : : #define BREAK break
131 : :
132 : 0 : static const SSL_METHOD *ssl2_get_server_method(int ver)
133 : : {
134 [ # # ]: 0 : if (ver == SSL2_VERSION)
135 : 0 : return(SSLv2_server_method());
136 : : else
137 : : return(NULL);
138 : : }
139 : :
140 : 0 : IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
141 : : ssl2_accept,
142 : : ssl_undefined_function,
143 : : ssl2_get_server_method)
144 : :
145 : 1972 : int ssl2_accept(SSL *s)
146 : : {
147 : 1972 : unsigned long l=(unsigned long)time(NULL);
148 : 1972 : BUF_MEM *buf=NULL;
149 : 1972 : int ret= -1;
150 : : long num1;
151 : 1972 : void (*cb)(const SSL *ssl,int type,int val)=NULL;
152 : : int new_state,state;
153 : :
154 : 1972 : RAND_add(&l,sizeof(l),0);
155 : 1972 : ERR_clear_error();
156 : 1972 : clear_sys_error();
157 : :
158 [ + - ]: 1972 : if (s->info_callback != NULL)
159 : : cb=s->info_callback;
160 [ - + ]: 1972 : else if (s->ctx->info_callback != NULL)
161 : 0 : cb=s->ctx->info_callback;
162 : :
163 : : /* init things to blank */
164 : 1972 : s->in_handshake++;
165 [ + - ][ + + ]: 1972 : if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
166 : :
167 [ - + ]: 1972 : if (s->cert == NULL)
168 : : {
169 : 0 : SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
170 : 0 : return(-1);
171 : : }
172 : :
173 : 3028 : clear_sys_error();
174 : : for (;;)
175 : : {
176 : 3028 : state=s->state;
177 : :
178 [ + + + + : 3028 : switch (s->state)
+ + - + +
+ + - ]
179 : : {
180 : : case SSL_ST_BEFORE:
181 : : case SSL_ST_ACCEPT:
182 : : case SSL_ST_BEFORE|SSL_ST_ACCEPT:
183 : : case SSL_ST_OK|SSL_ST_ACCEPT:
184 : :
185 : 132 : s->server=1;
186 [ - + ]: 132 : if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
187 : :
188 : 132 : s->version=SSL2_VERSION;
189 : 132 : s->type=SSL_ST_ACCEPT;
190 : :
191 : 132 : buf=s->init_buf;
192 [ + - ][ + - ]: 132 : if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
193 : : { ret= -1; goto end; }
194 [ + - ]: 132 : if (!BUF_MEM_grow(buf,(int)
195 : : SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
196 : : { ret= -1; goto end; }
197 : 132 : s->init_buf=buf;
198 : 132 : s->init_num=0;
199 : 132 : s->ctx->stats.sess_accept++;
200 : 132 : s->handshake_func=ssl2_accept;
201 : 132 : s->state=SSL2_ST_GET_CLIENT_HELLO_A;
202 : 132 : BREAK;
203 : :
204 : : case SSL2_ST_GET_CLIENT_HELLO_A:
205 : : case SSL2_ST_GET_CLIENT_HELLO_B:
206 : : case SSL2_ST_GET_CLIENT_HELLO_C:
207 : 484 : s->shutdown=0;
208 : 484 : ret=get_client_hello(s);
209 [ + + ]: 484 : if (ret <= 0) goto end;
210 : 132 : s->init_num=0;
211 : 132 : s->state=SSL2_ST_SEND_SERVER_HELLO_A;
212 : 132 : BREAK;
213 : :
214 : : case SSL2_ST_SEND_SERVER_HELLO_A:
215 : : case SSL2_ST_SEND_SERVER_HELLO_B:
216 : 388 : ret=server_hello(s);
217 [ + + ]: 388 : if (ret <= 0) goto end;
218 : 132 : s->init_num=0;
219 [ + - ]: 132 : if (!s->hit)
220 : : {
221 : 132 : s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
222 : 132 : BREAK;
223 : : }
224 : : else
225 : : {
226 : 0 : s->state=SSL2_ST_SERVER_START_ENCRYPTION;
227 : 0 : BREAK;
228 : : }
229 : : case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
230 : : case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
231 : 638 : ret=get_client_master_key(s);
232 [ + + ]: 638 : if (ret <= 0) goto end;
233 : 110 : s->init_num=0;
234 : 110 : s->state=SSL2_ST_SERVER_START_ENCRYPTION;
235 : 110 : BREAK;
236 : :
237 : : case SSL2_ST_SERVER_START_ENCRYPTION:
238 : : /* Ok we how have sent all the stuff needed to
239 : : * start encrypting, the next packet back will
240 : : * be encrypted. */
241 [ + - ]: 110 : if (!ssl2_enc_init(s,0))
242 : : { ret= -1; goto end; }
243 : 110 : s->s2->clear_text=0;
244 : 110 : s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
245 : 110 : BREAK;
246 : :
247 : : case SSL2_ST_SEND_SERVER_VERIFY_A:
248 : : case SSL2_ST_SEND_SERVER_VERIFY_B:
249 : 110 : ret=server_verify(s);
250 [ + - ]: 110 : if (ret <= 0) goto end;
251 : 110 : s->init_num=0;
252 [ - + ]: 110 : if (s->hit)
253 : : {
254 : : /* If we are in here, we have been
255 : : * buffering the output, so we need to
256 : : * flush it and remove buffering from
257 : : * future traffic */
258 : 0 : s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
259 : 0 : BREAK;
260 : : }
261 : : else
262 : : {
263 : 110 : s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
264 : 110 : break;
265 : : }
266 : :
267 : : case SSL2_ST_SEND_SERVER_VERIFY_C:
268 : : /* get the number of bytes to write */
269 : 0 : num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
270 [ # # ]: 0 : if (num1 > 0)
271 : : {
272 : 0 : s->rwstate=SSL_WRITING;
273 : 0 : num1=BIO_flush(s->wbio);
274 [ # # ]: 0 : if (num1 <= 0) { ret= -1; goto end; }
275 : 0 : s->rwstate=SSL_NOTHING;
276 : : }
277 : :
278 : : /* flushed and now remove buffering */
279 : 0 : s->wbio=BIO_pop(s->wbio);
280 : :
281 : 0 : s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
282 : 0 : BREAK;
283 : :
284 : : case SSL2_ST_GET_CLIENT_FINISHED_A:
285 : : case SSL2_ST_GET_CLIENT_FINISHED_B:
286 : 462 : ret=get_client_finished(s);
287 [ + + ]: 462 : if (ret <= 0)
288 : : goto end;
289 : 110 : s->init_num=0;
290 : 110 : s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
291 : 110 : BREAK;
292 : :
293 : : case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
294 : : case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
295 : : case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
296 : : case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
297 : : /* don't do a 'request certificate' if we
298 : : * don't want to, or we already have one, and
299 : : * we only want to do it once. */
300 [ + + ][ - + ]: 484 : if (!(s->verify_mode & SSL_VERIFY_PEER) ||
301 [ # # ]: 0 : ((s->session->peer != NULL) &&
302 : 0 : (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
303 : : {
304 : 66 : s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
305 : 66 : break;
306 : : }
307 : : else
308 : : {
309 : 418 : ret=request_certificate(s);
310 [ + + ]: 418 : if (ret <= 0) goto end;
311 : 44 : s->init_num=0;
312 : 44 : s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
313 : : }
314 : 44 : BREAK;
315 : :
316 : : case SSL2_ST_SEND_SERVER_FINISHED_A:
317 : : case SSL2_ST_SEND_SERVER_FINISHED_B:
318 : 110 : ret=server_finish(s);
319 [ + - ]: 110 : if (ret <= 0) goto end;
320 : 110 : s->init_num=0;
321 : 110 : s->state=SSL_ST_OK;
322 : 110 : break;
323 : :
324 : : case SSL_ST_OK:
325 : 110 : BUF_MEM_free(s->init_buf);
326 : 110 : ssl_free_wbio_buffer(s);
327 : 110 : s->init_buf=NULL;
328 : 110 : s->init_num=0;
329 : : /* ERR_clear_error();*/
330 : :
331 : 110 : ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
332 : :
333 : 110 : s->ctx->stats.sess_accept_good++;
334 : : /* s->server=1; */
335 : 110 : ret=1;
336 : :
337 [ - + ]: 110 : if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
338 : :
339 : : goto end;
340 : : /* BREAK; */
341 : :
342 : : default:
343 : 0 : SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
344 : 0 : ret= -1;
345 : 0 : goto end;
346 : : /* BREAK; */
347 : : }
348 : :
349 [ + - ][ # # ]: 1056 : if ((cb != NULL) && (s->state != state))
350 : : {
351 : 0 : new_state=s->state;
352 : 0 : s->state=state;
353 : 0 : cb(s,SSL_CB_ACCEPT_LOOP,1);
354 : 0 : s->state=new_state;
355 : : }
356 : : }
357 : : end:
358 : 1972 : s->in_handshake--;
359 [ - + ]: 1972 : if (cb != NULL)
360 : 0 : cb(s,SSL_CB_ACCEPT_EXIT,ret);
361 : 1972 : return(ret);
362 : : }
363 : :
364 : 638 : static int get_client_master_key(SSL *s)
365 : : {
366 : : int is_export,i,n,keya,ek;
367 : : unsigned long len;
368 : : unsigned char *p;
369 : : const SSL_CIPHER *cp;
370 : : const EVP_CIPHER *c;
371 : : const EVP_MD *md;
372 : :
373 : 638 : p=(unsigned char *)s->init_buf->data;
374 [ + - ]: 638 : if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
375 : : {
376 : 638 : i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
377 : :
378 [ + + ]: 638 : if (i < (10-s->init_num))
379 : 528 : return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
380 : 110 : s->init_num = 10;
381 : :
382 [ - + ]: 110 : if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
383 : : {
384 [ # # ]: 0 : if (p[-1] != SSL2_MT_ERROR)
385 : : {
386 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
387 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
388 : : }
389 : : else
390 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
391 : : return(-1);
392 : : }
393 : :
394 : 110 : cp=ssl2_get_cipher_by_char(p);
395 [ - + ]: 110 : if (cp == NULL)
396 : : {
397 : 0 : ssl2_return_error(s,SSL2_PE_NO_CIPHER);
398 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
399 : 0 : return(-1);
400 : : }
401 : 110 : s->session->cipher= cp;
402 : :
403 : 110 : p+=3;
404 : 110 : n2s(p,i); s->s2->tmp.clear=i;
405 : 110 : n2s(p,i); s->s2->tmp.enc=i;
406 : 110 : n2s(p,i);
407 [ - + ]: 110 : if(i > SSL_MAX_KEY_ARG_LENGTH)
408 : : {
409 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
410 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
411 : 0 : return -1;
412 : : }
413 : 110 : s->session->key_arg_length=i;
414 : 110 : s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
415 : : }
416 : :
417 : : /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
418 : 110 : p=(unsigned char *)s->init_buf->data;
419 [ - + ]: 110 : if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
420 : : {
421 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
422 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
423 : 0 : return -1;
424 : : }
425 : 110 : keya=s->session->key_arg_length;
426 : 110 : len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
427 [ - + ]: 110 : if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
428 : : {
429 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
430 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
431 : 0 : return -1;
432 : : }
433 : 110 : n = (int)len - s->init_num;
434 : 110 : i = ssl2_read(s,(char *)&(p[s->init_num]),n);
435 [ - + ]: 110 : if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
436 [ - + ]: 110 : if (s->msg_callback)
437 : 0 : s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
438 : 110 : p += 10;
439 : :
440 : 110 : memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
441 : : (unsigned int)keya);
442 : :
443 [ - + ]: 110 : if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
444 : : {
445 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
446 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
447 : 0 : return(-1);
448 : : }
449 [ + - ]: 110 : i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
450 : 110 : &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
451 : 110 : (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
452 : :
453 : 110 : is_export=SSL_C_IS_EXPORT(s->session->cipher);
454 : :
455 [ - + ]: 110 : if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL, 0))
456 : : {
457 : 0 : ssl2_return_error(s,SSL2_PE_NO_CIPHER);
458 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
459 : 0 : return(0);
460 : : }
461 : :
462 [ + - ]: 110 : if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
463 : : {
464 : : is_export=1;
465 : : ek=8;
466 : : }
467 : : else
468 : 110 : ek=5;
469 : :
470 : : /* bad decrypt */
471 : : #if 1
472 : : /* If a bad decrypt, continue with protocol but with a
473 : : * random master secret (Bleichenbacher attack) */
474 [ + - ][ + - ]: 110 : if ((i < 0) ||
475 [ + - ]: 110 : ((!is_export && (i != EVP_CIPHER_key_length(c)))
476 [ - + ]: 110 : || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
[ # # # # ]
477 : 0 : (unsigned int)EVP_CIPHER_key_length(c))))))
478 : : {
479 : 0 : ERR_clear_error();
480 [ # # ]: 0 : if (is_export)
481 : : i=ek;
482 : : else
483 : 0 : i=EVP_CIPHER_key_length(c);
484 [ # # ]: 0 : if (RAND_pseudo_bytes(p,i) <= 0)
485 : : return 0;
486 : : }
487 : : #else
488 : : if (i < 0)
489 : : {
490 : : error=1;
491 : : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
492 : : }
493 : : /* incorrect number of key bytes for non export cipher */
494 : : else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
495 : : || (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
496 : : EVP_CIPHER_key_length(c)))))
497 : : {
498 : : error=1;
499 : : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
500 : : }
501 : : if (error)
502 : : {
503 : : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
504 : : return(-1);
505 : : }
506 : : #endif
507 : :
508 [ - + ]: 110 : if (is_export) i+=s->s2->tmp.clear;
509 : :
510 [ - + ]: 110 : if (i > SSL_MAX_MASTER_KEY_LENGTH)
511 : : {
512 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
513 : 0 : SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
514 : 0 : return -1;
515 : : }
516 : 110 : s->session->master_key_length=i;
517 : 110 : memcpy(s->session->master_key,p,(unsigned int)i);
518 : 110 : return(1);
519 : : }
520 : :
521 : 484 : static int get_client_hello(SSL *s)
522 : : {
523 : : int i,n;
524 : : unsigned long len;
525 : : unsigned char *p;
526 : : STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
527 : : STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
528 : : STACK_OF(SSL_CIPHER) *prio, *allow;
529 : : int z;
530 : :
531 : : /* This is a bit of a hack to check for the correct packet
532 : : * type the first time round. */
533 [ + + ]: 484 : if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
534 : : {
535 : 132 : s->first_packet=1;
536 : 132 : s->state=SSL2_ST_GET_CLIENT_HELLO_B;
537 : : }
538 : :
539 : 484 : p=(unsigned char *)s->init_buf->data;
540 [ + - ]: 484 : if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
541 : : {
542 : 484 : i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
543 [ + + ]: 484 : if (i < (9-s->init_num))
544 : 352 : return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
545 : 132 : s->init_num = 9;
546 : :
547 [ - + ]: 132 : if (*(p++) != SSL2_MT_CLIENT_HELLO)
548 : : {
549 [ # # ]: 0 : if (p[-1] != SSL2_MT_ERROR)
550 : : {
551 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
552 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
553 : : }
554 : : else
555 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
556 : : return(-1);
557 : : }
558 : 132 : n2s(p,i);
559 [ - + ]: 132 : if (i < s->version) s->version=i;
560 : 132 : n2s(p,i); s->s2->tmp.cipher_spec_length=i;
561 : 132 : n2s(p,i); s->s2->tmp.session_id_length=i;
562 : 132 : n2s(p,i); s->s2->challenge_length=i;
563 [ - + ]: 132 : if ( (i < SSL2_MIN_CHALLENGE_LENGTH) ||
564 : : (i > SSL2_MAX_CHALLENGE_LENGTH))
565 : : {
566 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
567 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
568 : 0 : return(-1);
569 : : }
570 : 132 : s->state=SSL2_ST_GET_CLIENT_HELLO_C;
571 : : }
572 : :
573 : : /* SSL2_ST_GET_CLIENT_HELLO_C */
574 : 132 : p=(unsigned char *)s->init_buf->data;
575 : 132 : len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
576 [ - + ]: 132 : if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
577 : : {
578 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
579 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
580 : 0 : return -1;
581 : : }
582 : 132 : n = (int)len - s->init_num;
583 : 132 : i = ssl2_read(s,(char *)&(p[s->init_num]),n);
584 [ - + ]: 132 : if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
585 [ - + ]: 132 : if (s->msg_callback)
586 : 0 : s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
587 : 132 : p += 9;
588 : :
589 : : /* get session-id before cipher stuff so we can get out session
590 : : * structure if it is cached */
591 : : /* session-id */
592 [ - + ]: 132 : if ((s->s2->tmp.session_id_length != 0) &&
593 : : (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
594 : : {
595 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
596 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
597 : 0 : return(-1);
598 : : }
599 : :
600 [ + - ]: 132 : if (s->s2->tmp.session_id_length == 0)
601 : : {
602 [ - + ]: 132 : if (!ssl_get_new_session(s,1))
603 : : {
604 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
605 : 0 : return(-1);
606 : : }
607 : : }
608 : : else
609 : : {
610 : 0 : i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
611 : : s->s2->tmp.session_id_length, NULL);
612 [ # # ]: 0 : if (i == 1)
613 : : { /* previous session */
614 : 0 : s->hit=1;
615 : : }
616 [ # # ]: 0 : else if (i == -1)
617 : : {
618 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
619 : 0 : return(-1);
620 : : }
621 : : else
622 : : {
623 [ # # ]: 0 : if (s->cert == NULL)
624 : : {
625 : 0 : ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
626 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
627 : 0 : return(-1);
628 : : }
629 : :
630 [ # # ]: 0 : if (!ssl_get_new_session(s,1))
631 : : {
632 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
633 : 0 : return(-1);
634 : : }
635 : : }
636 : : }
637 : :
638 [ + - ]: 132 : if (!s->hit)
639 : : {
640 : 132 : cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
641 : 132 : &s->session->ciphers);
642 [ + - ]: 132 : if (cs == NULL) goto mem_err;
643 : :
644 : 132 : cl=SSL_get_ciphers(s);
645 : :
646 [ - + ]: 132 : if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
647 : : {
648 : 0 : prio=sk_SSL_CIPHER_dup(cl);
649 [ # # ]: 0 : if (prio == NULL) goto mem_err;
650 : : allow = cs;
651 : : }
652 : : else
653 : : {
654 : : prio = cs;
655 : : allow = cl;
656 : : }
657 [ + + ]: 1056 : for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
658 : : {
659 [ - + ]: 924 : if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
660 : : {
661 : 0 : (void)sk_SSL_CIPHER_delete(prio,z);
662 : 0 : z--;
663 : : }
664 : : }
665 [ - + ]: 132 : if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
666 : : {
667 : 0 : sk_SSL_CIPHER_free(s->session->ciphers);
668 : 0 : s->session->ciphers = prio;
669 : : }
670 : : /* s->session->ciphers should now have a list of
671 : : * ciphers that are on both the client and server.
672 : : * This list is ordered by the order the client sent
673 : : * the ciphers or in the order of the server's preference
674 : : * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
675 : : */
676 : : }
677 : 132 : p+=s->s2->tmp.cipher_spec_length;
678 : : /* done cipher selection */
679 : :
680 : : /* session id extracted already */
681 : 132 : p+=s->s2->tmp.session_id_length;
682 : :
683 : : /* challenge */
684 [ - + ]: 132 : if (s->s2->challenge_length > sizeof s->s2->challenge)
685 : : {
686 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
687 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
688 : 0 : return -1;
689 : : }
690 : 132 : memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
691 : 132 : return(1);
692 : : mem_err:
693 : 0 : SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
694 : 0 : return(0);
695 : : }
696 : :
697 : 388 : static int server_hello(SSL *s)
698 : : {
699 : : unsigned char *p,*d;
700 : : int n,hit;
701 : :
702 : 388 : p=(unsigned char *)s->init_buf->data;
703 [ + + ]: 388 : if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
704 : : {
705 : 132 : d=p+11;
706 : 132 : *(p++)=SSL2_MT_SERVER_HELLO; /* type */
707 : 132 : hit=s->hit;
708 : 132 : *(p++)=(unsigned char)hit;
709 : : #if 1
710 [ + - ]: 132 : if (!hit)
711 : : {
712 [ - + ]: 132 : if (s->session->sess_cert != NULL)
713 : : /* This can't really happen because get_client_hello
714 : : * has called ssl_get_new_session, which does not set
715 : : * sess_cert. */
716 : 0 : ssl_sess_cert_free(s->session->sess_cert);
717 : 132 : s->session->sess_cert = ssl_sess_cert_new();
718 [ - + ]: 132 : if (s->session->sess_cert == NULL)
719 : : {
720 : 0 : SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
721 : 0 : return(-1);
722 : : }
723 : : }
724 : : /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
725 : : * depending on whether it survived in the internal cache
726 : : * or was retrieved from an external cache.
727 : : * If it is NULL, we cannot put any useful data in it anyway,
728 : : * so we don't touch it.
729 : : */
730 : :
731 : : #else /* That's what used to be done when cert_st and sess_cert_st were
732 : : * the same. */
733 : : if (!hit)
734 : : { /* else add cert to session */
735 : : CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
736 : : if (s->session->sess_cert != NULL)
737 : : ssl_cert_free(s->session->sess_cert);
738 : : s->session->sess_cert=s->cert;
739 : : }
740 : : else /* We have a session id-cache hit, if the
741 : : * session-id has no certificate listed against
742 : : * the 'cert' structure, grab the 'old' one
743 : : * listed against the SSL connection */
744 : : {
745 : : if (s->session->sess_cert == NULL)
746 : : {
747 : : CRYPTO_add(&s->cert->references,1,
748 : : CRYPTO_LOCK_SSL_CERT);
749 : : s->session->sess_cert=s->cert;
750 : : }
751 : : }
752 : : #endif
753 : :
754 [ - + ]: 132 : if (s->cert == NULL)
755 : : {
756 : 0 : ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
757 : 0 : SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
758 : 0 : return(-1);
759 : : }
760 : :
761 [ - + ]: 132 : if (hit)
762 : : {
763 : 0 : *(p++)=0; /* no certificate type */
764 : 0 : s2n(s->version,p); /* version */
765 : 0 : s2n(0,p); /* cert len */
766 : 0 : s2n(0,p); /* ciphers len */
767 : : }
768 : : else
769 : : {
770 : : /* EAY EAY */
771 : : /* put certificate type */
772 : 132 : *(p++)=SSL2_CT_X509_CERTIFICATE;
773 : 132 : s2n(s->version,p); /* version */
774 : 132 : n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
775 : 132 : s2n(n,p); /* certificate length */
776 : 132 : i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
777 : 132 : n=0;
778 : :
779 : : /* lets send out the ciphers we like in the
780 : : * prefered order */
781 : 132 : n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
782 : 132 : d+=n;
783 : 132 : s2n(n,p); /* add cipher length */
784 : : }
785 : :
786 : : /* make and send conn_id */
787 : 132 : s2n(SSL2_CONNECTION_ID_LENGTH,p); /* add conn_id length */
788 : 132 : s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
789 [ + - ]: 132 : if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
790 : : return -1;
791 : 132 : memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
792 : 132 : d+=SSL2_CONNECTION_ID_LENGTH;
793 : :
794 : 132 : s->state=SSL2_ST_SEND_SERVER_HELLO_B;
795 : 132 : s->init_num=d-(unsigned char *)s->init_buf->data;
796 : 132 : s->init_off=0;
797 : : }
798 : : /* SSL2_ST_SEND_SERVER_HELLO_B */
799 : : /* If we are using TCP/IP, the performance is bad if we do 2
800 : : * writes without a read between them. This occurs when
801 : : * Session-id reuse is used, so I will put in a buffering module
802 : : */
803 [ - + ]: 388 : if (s->hit)
804 : : {
805 [ # # ]: 0 : if (!ssl_init_wbio_buffer(s,1)) return(-1);
806 : : }
807 : :
808 : 388 : return(ssl2_do_write(s));
809 : : }
810 : :
811 : 462 : static int get_client_finished(SSL *s)
812 : : {
813 : : unsigned char *p;
814 : : int i, n;
815 : : unsigned long len;
816 : :
817 : 462 : p=(unsigned char *)s->init_buf->data;
818 [ + - ]: 462 : if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
819 : : {
820 : 462 : i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
821 [ + + ]: 462 : if (i < 1-s->init_num)
822 : 352 : return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
823 : 110 : s->init_num += i;
824 : :
825 [ - + ]: 110 : if (*p != SSL2_MT_CLIENT_FINISHED)
826 : : {
827 [ # # ]: 0 : if (*p != SSL2_MT_ERROR)
828 : : {
829 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
830 : 0 : SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
831 : : }
832 : : else
833 : : {
834 : 0 : SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
835 : : /* try to read the error message */
836 : 0 : i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
837 : 0 : return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
838 : : }
839 : 0 : return(-1);
840 : : }
841 : 110 : s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
842 : : }
843 : :
844 : : /* SSL2_ST_GET_CLIENT_FINISHED_B */
845 [ - + ]: 110 : if (s->s2->conn_id_length > sizeof s->s2->conn_id)
846 : : {
847 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
848 : 0 : SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
849 : 0 : return -1;
850 : : }
851 : 110 : len = 1 + (unsigned long)s->s2->conn_id_length;
852 : 110 : n = (int)len - s->init_num;
853 : 110 : i = ssl2_read(s,(char *)&(p[s->init_num]),n);
854 [ - + ]: 110 : if (i < n)
855 : : {
856 : 0 : return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
857 : : }
858 [ - + ]: 110 : if (s->msg_callback)
859 : 0 : s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
860 : 110 : p += 1;
861 [ - + ]: 110 : if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
862 : : {
863 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
864 : 0 : SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
865 : 0 : return(-1);
866 : : }
867 : : return(1);
868 : : }
869 : :
870 : 110 : static int server_verify(SSL *s)
871 : : {
872 : : unsigned char *p;
873 : :
874 [ + - ]: 110 : if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
875 : : {
876 : 110 : p=(unsigned char *)s->init_buf->data;
877 : 110 : *(p++)=SSL2_MT_SERVER_VERIFY;
878 [ - + ]: 110 : if (s->s2->challenge_length > sizeof s->s2->challenge)
879 : : {
880 : 0 : SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
881 : 0 : return -1;
882 : : }
883 : 110 : memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
884 : : /* p+=s->s2->challenge_length; */
885 : :
886 : 110 : s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
887 : 110 : s->init_num=s->s2->challenge_length+1;
888 : 110 : s->init_off=0;
889 : : }
890 : 110 : return(ssl2_do_write(s));
891 : : }
892 : :
893 : 110 : static int server_finish(SSL *s)
894 : : {
895 : : unsigned char *p;
896 : :
897 [ + - ]: 110 : if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
898 : : {
899 : 110 : p=(unsigned char *)s->init_buf->data;
900 : 110 : *(p++)=SSL2_MT_SERVER_FINISHED;
901 : :
902 [ - + ]: 110 : if (s->session->session_id_length > sizeof s->session->session_id)
903 : : {
904 : 0 : SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
905 : 0 : return -1;
906 : : }
907 : 110 : memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
908 : : /* p+=s->session->session_id_length; */
909 : :
910 : 110 : s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
911 : 110 : s->init_num=s->session->session_id_length+1;
912 : 110 : s->init_off=0;
913 : : }
914 : :
915 : : /* SSL2_ST_SEND_SERVER_FINISHED_B */
916 : 110 : return(ssl2_do_write(s));
917 : : }
918 : :
919 : : /* send the request and check the response */
920 : 418 : static int request_certificate(SSL *s)
921 : : {
922 : : const unsigned char *cp;
923 : : unsigned char *p,*p2,*buf2;
924 : : unsigned char *ccd;
925 : 418 : int i,j,ctype,ret= -1;
926 : : unsigned long len;
927 : 418 : X509 *x509=NULL;
928 : 418 : STACK_OF(X509) *sk=NULL;
929 : :
930 : 418 : ccd=s->s2->tmp.ccl;
931 [ + + ]: 418 : if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
932 : : {
933 : 44 : p=(unsigned char *)s->init_buf->data;
934 : 44 : *(p++)=SSL2_MT_REQUEST_CERTIFICATE;
935 : 44 : *(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
936 [ + - ]: 44 : if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
937 : : return -1;
938 : : memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
939 : :
940 : 44 : s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
941 : 44 : s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
942 : 44 : s->init_off=0;
943 : : }
944 : :
945 [ + + ]: 418 : if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
946 : : {
947 : 44 : i=ssl2_do_write(s);
948 [ + - ]: 44 : if (i <= 0)
949 : : {
950 : : ret=i;
951 : : goto end;
952 : : }
953 : :
954 : 44 : s->init_num=0;
955 : 44 : s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
956 : : }
957 : :
958 [ + - ]: 418 : if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
959 : : {
960 : 418 : p=(unsigned char *)s->init_buf->data;
961 : 418 : i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
962 [ + + ]: 418 : if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
963 : : * (probably NO-CERTIFICATE-ERROR) */
964 : : {
965 : 374 : ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
966 : 374 : goto end;
967 : : }
968 : 44 : s->init_num += i;
969 : :
970 [ + - ][ - + ]: 44 : if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
971 : : {
972 : 0 : n2s(p,i);
973 [ # # ]: 0 : if (i != SSL2_PE_NO_CERTIFICATE)
974 : : {
975 : : /* not the error message we expected -- let ssl2_part_read handle it */
976 : 0 : s->init_num -= 3;
977 : 0 : ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
978 : 0 : goto end;
979 : : }
980 : :
981 [ # # ]: 0 : if (s->msg_callback)
982 : 0 : s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
983 : :
984 : : /* this is the one place where we can recover from an SSL 2.0 error */
985 : :
986 [ # # ]: 0 : if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
987 : : {
988 : 0 : ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
989 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
990 : 0 : goto end;
991 : : }
992 : : ret=1;
993 : : goto end;
994 : : }
995 [ + - ][ - + ]: 44 : if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
996 : : {
997 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
998 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
999 : 0 : goto end;
1000 : : }
1001 [ - + ]: 44 : if (s->init_num != 6)
1002 : : {
1003 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
1004 : 0 : goto end;
1005 : : }
1006 : :
1007 : : /* ok we have a response */
1008 : : /* certificate type, there is only one right now. */
1009 : 44 : ctype= *(p++);
1010 [ - + ]: 44 : if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
1011 : : {
1012 : 0 : ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
1013 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
1014 : 0 : goto end;
1015 : : }
1016 : 44 : n2s(p,i); s->s2->tmp.clen=i;
1017 : 44 : n2s(p,i); s->s2->tmp.rlen=i;
1018 : 44 : s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
1019 : : }
1020 : :
1021 : : /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
1022 : 44 : p=(unsigned char *)s->init_buf->data;
1023 : 44 : len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
1024 [ - + ]: 44 : if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
1025 : : {
1026 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
1027 : 0 : goto end;
1028 : : }
1029 : 44 : j = (int)len - s->init_num;
1030 : 44 : i = ssl2_read(s,(char *)&(p[s->init_num]),j);
1031 [ - + ]: 44 : if (i < j)
1032 : : {
1033 : 0 : ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
1034 : 0 : goto end;
1035 : : }
1036 [ - + ]: 44 : if (s->msg_callback)
1037 : 0 : s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
1038 : 44 : p += 6;
1039 : :
1040 : 44 : cp = p;
1041 : 44 : x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
1042 [ - + ]: 44 : if (x509 == NULL)
1043 : : {
1044 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
1045 : 0 : goto msg_end;
1046 : : }
1047 : :
1048 [ + - ][ - + ]: 44 : if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
1049 : : {
1050 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1051 : 0 : goto msg_end;
1052 : : }
1053 : :
1054 : 44 : i=ssl_verify_cert_chain(s,sk);
1055 : :
1056 [ - + ]: 44 : if (i > 1)
1057 : : {
1058 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE, i);
1059 : 0 : goto msg_end;
1060 : : }
1061 : :
1062 [ + - ]: 44 : if (i > 0) /* we like the packet, now check the chksum */
1063 : : {
1064 : : EVP_MD_CTX ctx;
1065 : 44 : EVP_PKEY *pkey=NULL;
1066 : :
1067 : 44 : EVP_MD_CTX_init(&ctx);
1068 [ + - ]: 44 : if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL)
1069 [ + - ]: 44 : || !EVP_VerifyUpdate(&ctx,s->s2->key_material,
1070 : : s->s2->key_material_length)
1071 [ + - ]: 44 : || !EVP_VerifyUpdate(&ctx,ccd,
1072 : : SSL2_MIN_CERT_CHALLENGE_LENGTH))
1073 : : goto msg_end;
1074 : :
1075 : 44 : i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
1076 : 44 : buf2=OPENSSL_malloc((unsigned int)i);
1077 [ - + ]: 44 : if (buf2 == NULL)
1078 : : {
1079 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1080 : 0 : goto msg_end;
1081 : : }
1082 : 44 : p2=buf2;
1083 : 44 : i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
1084 [ - + ]: 44 : if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i))
1085 : : {
1086 : 0 : OPENSSL_free(buf2);
1087 : 0 : goto msg_end;
1088 : : }
1089 : 44 : OPENSSL_free(buf2);
1090 : :
1091 : 44 : pkey=X509_get_pubkey(x509);
1092 [ + - ]: 44 : if (pkey == NULL) goto end;
1093 : 44 : i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
1094 : 44 : EVP_PKEY_free(pkey);
1095 : 44 : EVP_MD_CTX_cleanup(&ctx);
1096 : :
1097 [ + - ]: 44 : if (i > 0)
1098 : : {
1099 [ - + ]: 44 : if (s->session->peer != NULL)
1100 : 0 : X509_free(s->session->peer);
1101 : 44 : s->session->peer=x509;
1102 : 44 : CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
1103 : 44 : s->session->verify_result = s->verify_result;
1104 : 44 : ret=1;
1105 : 44 : goto end;
1106 : : }
1107 : : else
1108 : : {
1109 : 0 : SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
1110 : 44 : goto msg_end;
1111 : : }
1112 : : }
1113 : : else
1114 : : {
1115 : : msg_end:
1116 : 0 : ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
1117 : : }
1118 : : end:
1119 : 418 : sk_X509_free(sk);
1120 : 418 : X509_free(x509);
1121 : 418 : return(ret);
1122 : : }
1123 : :
1124 : 110 : static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
1125 : : unsigned char *to, int padding)
1126 : : {
1127 : : RSA *rsa;
1128 : : int i;
1129 : :
1130 [ + - ][ - + ]: 110 : if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
1131 : : {
1132 : 0 : SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
1133 : 0 : return(-1);
1134 : : }
1135 [ - + ]: 110 : if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
1136 : : {
1137 : 0 : SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
1138 : 0 : return(-1);
1139 : : }
1140 : 110 : rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
1141 : :
1142 : : /* we have the public key */
1143 : 110 : i=RSA_private_decrypt(len,from,to,rsa,padding);
1144 [ - + ]: 110 : if (i < 0)
1145 : 0 : SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
1146 : 110 : return(i);
1147 : : }
1148 : : #else /* !OPENSSL_NO_SSL2 */
1149 : :
1150 : : # if PEDANTIC
1151 : : static void *dummy=&dummy;
1152 : : # endif
1153 : :
1154 : : #endif
|