Branch data Line data Source code
1 : : /* ssl/s2_clnt.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/rand.h>
116 : : #include <openssl/buffer.h>
117 : : #include <openssl/objects.h>
118 : : #include <openssl/evp.h>
119 : :
120 : : static const SSL_METHOD *ssl2_get_client_method(int ver);
121 : : static int get_server_finished(SSL *s);
122 : : static int get_server_verify(SSL *s);
123 : : static int get_server_hello(SSL *s);
124 : : static int client_hello(SSL *s);
125 : : static int client_master_key(SSL *s);
126 : : static int client_finished(SSL *s);
127 : : static int client_certificate(SSL *s);
128 : : static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
129 : : unsigned char *to,int padding);
130 : : #define BREAK break
131 : :
132 : 0 : static const SSL_METHOD *ssl2_get_client_method(int ver)
133 : : {
134 [ # # ]: 0 : if (ver == SSL2_VERSION)
135 : 0 : return(SSLv2_client_method());
136 : : else
137 : : return(NULL);
138 : : }
139 : :
140 : 0 : IMPLEMENT_ssl2_meth_func(SSLv2_client_method,
141 : : ssl_undefined_function,
142 : : ssl2_connect,
143 : : ssl2_get_client_method)
144 : :
145 : 2148 : int ssl2_connect(SSL *s)
146 : : {
147 : 2148 : unsigned long l=(unsigned long)time(NULL);
148 : 2148 : BUF_MEM *buf=NULL;
149 : 2148 : int ret= -1;
150 : 2148 : void (*cb)(const SSL *ssl,int type,int val)=NULL;
151 : : int new_state,state;
152 : :
153 : 2148 : RAND_add(&l,sizeof(l),0);
154 : 2148 : ERR_clear_error();
155 : 2148 : clear_sys_error();
156 : :
157 [ + - ]: 2148 : if (s->info_callback != NULL)
158 : : cb=s->info_callback;
159 [ - + ]: 2148 : else if (s->ctx->info_callback != NULL)
160 : 0 : cb=s->ctx->info_callback;
161 : :
162 : : /* init things to blank */
163 : 2148 : s->in_handshake++;
164 [ + - ][ + + ]: 3160 : if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
165 : :
166 : : for (;;)
167 : : {
168 : 3160 : state=s->state;
169 : :
170 [ + + + + : 3160 : switch (s->state)
+ + + + +
+ - ]
171 : : {
172 : : case SSL_ST_BEFORE:
173 : : case SSL_ST_CONNECT:
174 : : case SSL_ST_BEFORE|SSL_ST_CONNECT:
175 : : case SSL_ST_OK|SSL_ST_CONNECT:
176 : :
177 : 132 : s->server=0;
178 [ - + ]: 132 : if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
179 : :
180 : 132 : s->version=SSL2_VERSION;
181 : 132 : s->type=SSL_ST_CONNECT;
182 : :
183 : 132 : buf=s->init_buf;
184 [ + - ][ + - ]: 132 : if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
185 : : {
186 : : ret= -1;
187 : : goto end;
188 : : }
189 [ - + ]: 132 : if (!BUF_MEM_grow(buf,
190 : : SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
191 : : {
192 [ # # ]: 0 : if (buf == s->init_buf)
193 : 0 : buf=NULL;
194 : : ret= -1;
195 : : goto end;
196 : : }
197 : 132 : s->init_buf=buf;
198 : 132 : buf=NULL;
199 : 132 : s->init_num=0;
200 : 132 : s->state=SSL2_ST_SEND_CLIENT_HELLO_A;
201 : 132 : s->ctx->stats.sess_connect++;
202 : 132 : s->handshake_func=ssl2_connect;
203 : 132 : BREAK;
204 : :
205 : : case SSL2_ST_SEND_CLIENT_HELLO_A:
206 : : case SSL2_ST_SEND_CLIENT_HELLO_B:
207 : 132 : s->shutdown=0;
208 : 132 : ret=client_hello(s);
209 [ + - ]: 132 : if (ret <= 0) goto end;
210 : 132 : s->init_num=0;
211 : 132 : s->state=SSL2_ST_GET_SERVER_HELLO_A;
212 : 132 : BREAK;
213 : :
214 : : case SSL2_ST_GET_SERVER_HELLO_A:
215 : : case SSL2_ST_GET_SERVER_HELLO_B:
216 : 916 : ret=get_server_hello(s);
217 [ + + ]: 916 : if (ret <= 0) goto end;
218 : 110 : s->init_num=0;
219 [ + - ]: 110 : if (!s->hit) /* new session */
220 : : {
221 : 110 : s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_A;
222 : 110 : BREAK;
223 : : }
224 : : else
225 : : {
226 : 0 : s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
227 : 0 : break;
228 : : }
229 : :
230 : : case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:
231 : : case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:
232 : 110 : ret=client_master_key(s);
233 [ + - ]: 110 : if (ret <= 0) goto end;
234 : 110 : s->init_num=0;
235 : 110 : s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
236 : 110 : break;
237 : :
238 : : case SSL2_ST_CLIENT_START_ENCRYPTION:
239 : : /* Ok, we now have all the stuff needed to
240 : : * start encrypting, so lets fire it up :-) */
241 [ + - ]: 110 : if (!ssl2_enc_init(s,1))
242 : : {
243 : : ret= -1;
244 : : goto end;
245 : : }
246 : 110 : s->s2->clear_text=0;
247 : 110 : s->state=SSL2_ST_SEND_CLIENT_FINISHED_A;
248 : 110 : break;
249 : :
250 : : case SSL2_ST_SEND_CLIENT_FINISHED_A:
251 : : case SSL2_ST_SEND_CLIENT_FINISHED_B:
252 : 110 : ret=client_finished(s);
253 [ + - ]: 110 : if (ret <= 0) goto end;
254 : 110 : s->init_num=0;
255 : 110 : s->state=SSL2_ST_GET_SERVER_VERIFY_A;
256 : 110 : break;
257 : :
258 : : case SSL2_ST_GET_SERVER_VERIFY_A:
259 : : case SSL2_ST_GET_SERVER_VERIFY_B:
260 : 616 : ret=get_server_verify(s);
261 [ + + ]: 616 : if (ret <= 0) goto end;
262 : 110 : s->init_num=0;
263 : 110 : s->state=SSL2_ST_GET_SERVER_FINISHED_A;
264 : 110 : break;
265 : :
266 : : case SSL2_ST_GET_SERVER_FINISHED_A:
267 : : case SSL2_ST_GET_SERVER_FINISHED_B:
268 : 660 : ret=get_server_finished(s);
269 [ + + ]: 660 : if (ret <= 0) goto end;
270 : : break;
271 : :
272 : : case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:
273 : : case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:
274 : : case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:
275 : : case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:
276 : : case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:
277 : 264 : ret=client_certificate(s);
278 [ + + ]: 264 : if (ret <= 0) goto end;
279 : 44 : s->init_num=0;
280 : 44 : s->state=SSL2_ST_GET_SERVER_FINISHED_A;
281 : 44 : break;
282 : :
283 : : case SSL_ST_OK:
284 [ + - ]: 110 : if (s->init_buf != NULL)
285 : : {
286 : 110 : BUF_MEM_free(s->init_buf);
287 : 110 : s->init_buf=NULL;
288 : : }
289 : 110 : s->init_num=0;
290 : : /* ERR_clear_error();*/
291 : :
292 : : /* If we want to cache session-ids in the client
293 : : * and we successfully add the session-id to the
294 : : * cache, and there is a callback, then pass it out.
295 : : * 26/11/96 - eay - only add if not a re-used session.
296 : : */
297 : :
298 : 110 : ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
299 [ - + ]: 110 : if (s->hit) s->ctx->stats.sess_hit++;
300 : :
301 : 110 : ret=1;
302 : : /* s->server=0; */
303 : 110 : s->ctx->stats.sess_connect_good++;
304 : :
305 [ - + ]: 110 : if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
306 : :
307 : : goto end;
308 : : /* break; */
309 : : default:
310 : 0 : SSLerr(SSL_F_SSL2_CONNECT,SSL_R_UNKNOWN_STATE);
311 : 0 : return(-1);
312 : : /* break; */
313 : : }
314 : :
315 [ + - ][ # # ]: 1012 : if ((cb != NULL) && (s->state != state))
316 : : {
317 : 0 : new_state=s->state;
318 : 0 : s->state=state;
319 : 0 : cb(s,SSL_CB_CONNECT_LOOP,1);
320 : 0 : s->state=new_state;
321 : : }
322 : : }
323 : : end:
324 : 2148 : s->in_handshake--;
325 [ - + ]: 2148 : if (buf != NULL)
326 : 0 : BUF_MEM_free(buf);
327 [ - + ]: 2148 : if (cb != NULL)
328 : 0 : cb(s,SSL_CB_CONNECT_EXIT,ret);
329 : 2148 : return(ret);
330 : : }
331 : :
332 : 916 : static int get_server_hello(SSL *s)
333 : : {
334 : : unsigned char *buf;
335 : : unsigned char *p;
336 : : int i,j;
337 : : unsigned long len;
338 : 916 : STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;
339 : :
340 : 916 : buf=(unsigned char *)s->init_buf->data;
341 : 916 : p=buf;
342 [ + - ]: 916 : if (s->state == SSL2_ST_GET_SERVER_HELLO_A)
343 : : {
344 : 916 : i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);
345 [ + + ]: 916 : if (i < (11-s->init_num))
346 : 784 : return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
347 : 132 : s->init_num = 11;
348 : :
349 [ - + ]: 132 : if (*(p++) != SSL2_MT_SERVER_HELLO)
350 : : {
351 [ # # ]: 0 : if (p[-1] != SSL2_MT_ERROR)
352 : : {
353 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
354 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,
355 : : SSL_R_READ_WRONG_PACKET_TYPE);
356 : : }
357 : : else
358 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,
359 : : SSL_R_PEER_ERROR);
360 : : return(-1);
361 : : }
362 : : #if 0
363 : : s->hit=(*(p++))?1:0;
364 : : /* Some [PPC?] compilers fail to increment p in above
365 : : statement, e.g. one provided with Rhapsody 5.5, but
366 : : most recent example XL C 11.1 for AIX, even without
367 : : optimization flag... */
368 : : #else
369 : 132 : s->hit=(*p)?1:0; p++;
370 : : #endif
371 : 132 : s->s2->tmp.cert_type= *(p++);
372 : 132 : n2s(p,i);
373 [ - + ]: 132 : if (i < s->version) s->version=i;
374 : 132 : n2s(p,i); s->s2->tmp.cert_length=i;
375 : 132 : n2s(p,i); s->s2->tmp.csl=i;
376 : 132 : n2s(p,i); s->s2->tmp.conn_id_length=i;
377 : 132 : s->state=SSL2_ST_GET_SERVER_HELLO_B;
378 : : }
379 : :
380 : : /* SSL2_ST_GET_SERVER_HELLO_B */
381 : 132 : len = 11 + (unsigned long)s->s2->tmp.cert_length + (unsigned long)s->s2->tmp.csl + (unsigned long)s->s2->tmp.conn_id_length;
382 [ - + ]: 132 : if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
383 : : {
384 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_MESSAGE_TOO_LONG);
385 : 0 : return -1;
386 : : }
387 : 132 : j = (int)len - s->init_num;
388 : 132 : i = ssl2_read(s,(char *)&(buf[s->init_num]),j);
389 [ - + ]: 132 : if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
390 [ - + ]: 132 : if (s->msg_callback)
391 : 0 : s->msg_callback(0, s->version, 0, buf, (size_t)len, s, s->msg_callback_arg); /* SERVER-HELLO */
392 : :
393 : : /* things are looking good */
394 : :
395 : 132 : p = buf + 11;
396 [ - + ]: 132 : if (s->hit)
397 : : {
398 [ # # ]: 0 : if (s->s2->tmp.cert_length != 0)
399 : : {
400 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
401 : 0 : return(-1);
402 : : }
403 [ # # ]: 0 : if (s->s2->tmp.cert_type != 0)
404 : : {
405 : : if (!(s->options &
406 : : SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))
407 : : {
408 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
409 : 0 : return(-1);
410 : : }
411 : : }
412 [ # # ]: 0 : if (s->s2->tmp.csl != 0)
413 : : {
414 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
415 : 0 : return(-1);
416 : : }
417 : : }
418 : : else
419 : : {
420 : : #ifdef undef
421 : : /* very bad */
422 : : memset(s->session->session_id,0,
423 : : SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
424 : : s->session->session_id_length=0;
425 : : */
426 : : #endif
427 : :
428 : : /* we need to do this in case we were trying to reuse a
429 : : * client session but others are already reusing it.
430 : : * If this was a new 'blank' session ID, the session-id
431 : : * length will still be 0 */
432 [ - + ]: 132 : if (s->session->session_id_length > 0)
433 : : {
434 [ # # ]: 0 : if (!ssl_get_new_session(s,0))
435 : : {
436 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
437 : 0 : return(-1);
438 : : }
439 : : }
440 : :
441 [ + + ]: 132 : if (ssl2_set_certificate(s,s->s2->tmp.cert_type,
442 : 132 : s->s2->tmp.cert_length,p) <= 0)
443 : : {
444 : 22 : ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
445 : 22 : return(-1);
446 : : }
447 : 110 : p+=s->s2->tmp.cert_length;
448 : :
449 [ - + ]: 110 : if (s->s2->tmp.csl == 0)
450 : : {
451 : 0 : ssl2_return_error(s,SSL2_PE_NO_CIPHER);
452 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);
453 : 0 : return(-1);
454 : : }
455 : :
456 : : /* We have just received a list of ciphers back from the
457 : : * server. We need to get the ones that match, then select
458 : : * the one we want the most :-). */
459 : :
460 : : /* load the ciphers */
461 : 110 : sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,
462 : 110 : &s->session->ciphers);
463 : 110 : p+=s->s2->tmp.csl;
464 [ - + ]: 110 : if (sk == NULL)
465 : : {
466 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
467 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);
468 : 0 : return(-1);
469 : : }
470 : :
471 : 110 : (void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);
472 : :
473 : : /* get the array of ciphers we will accept */
474 : 110 : cl=SSL_get_ciphers(s);
475 : 110 : (void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);
476 : :
477 : : /*
478 : : * If server preference flag set, choose the first
479 : : * (highest priority) cipher the server sends, otherwise
480 : : * client preference has priority.
481 : : */
482 [ + - ]: 110 : if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
483 : : {
484 : : prio = sk;
485 : : allow = cl;
486 : : }
487 : : else
488 : : {
489 : 110 : prio = cl;
490 : 110 : allow = sk;
491 : : }
492 : : /* In theory we could have ciphers sent back that we
493 : : * don't want to use but that does not matter since we
494 : : * will check against the list we originally sent and
495 : : * for performance reasons we should not bother to match
496 : : * the two lists up just to check. */
497 [ + - ]: 110 : for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
498 : : {
499 [ - + ]: 110 : if (sk_SSL_CIPHER_find(allow,
500 : : sk_SSL_CIPHER_value(prio,i)) >= 0)
501 : : break;
502 : : }
503 : :
504 [ - + ]: 110 : if (i >= sk_SSL_CIPHER_num(prio))
505 : : {
506 : 0 : ssl2_return_error(s,SSL2_PE_NO_CIPHER);
507 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);
508 : 0 : return(-1);
509 : : }
510 : 110 : s->session->cipher=sk_SSL_CIPHER_value(prio,i);
511 : :
512 : :
513 [ - + ]: 110 : if (s->session->peer != NULL) /* can't happen*/
514 : : {
515 : 0 : ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
516 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
517 : 0 : return(-1);
518 : : }
519 : :
520 : 110 : s->session->peer = s->session->sess_cert->peer_key->x509;
521 : : /* peer_key->x509 has been set by ssl2_set_certificate. */
522 : 110 : CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
523 : : }
524 : :
525 [ + - ]: 110 : if (s->session->sess_cert == NULL
526 [ - + ]: 110 : || s->session->peer != s->session->sess_cert->peer_key->x509)
527 : : /* can't happen */
528 : : {
529 : 0 : ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
530 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
531 : 0 : return(-1);
532 : : }
533 : :
534 : 110 : s->s2->conn_id_length=s->s2->tmp.conn_id_length;
535 [ - + ]: 110 : if (s->s2->conn_id_length > sizeof s->s2->conn_id)
536 : : {
537 : 0 : ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
538 : 0 : SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
539 : 0 : return -1;
540 : : }
541 : 110 : memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
542 : 110 : return(1);
543 : : }
544 : :
545 : 132 : static int client_hello(SSL *s)
546 : : {
547 : : unsigned char *buf;
548 : : unsigned char *p,*d;
549 : : /* CIPHER **cipher;*/
550 : : int i,n,j;
551 : :
552 : 132 : buf=(unsigned char *)s->init_buf->data;
553 [ + - ]: 132 : if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A)
554 : : {
555 [ - + ][ # # ]: 132 : if ((s->session == NULL) ||
556 : 0 : (s->session->ssl_version != s->version))
557 : : {
558 [ - + ]: 132 : if (!ssl_get_new_session(s,0))
559 : : {
560 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
561 : 0 : return(-1);
562 : : }
563 : : }
564 : : /* else use the pre-loaded session */
565 : :
566 : 132 : p=buf; /* header */
567 : 132 : d=p+9; /* data section */
568 : 132 : *(p++)=SSL2_MT_CLIENT_HELLO; /* type */
569 : 132 : s2n(SSL2_VERSION,p); /* version */
570 : 132 : n=j=0;
571 : :
572 : 132 : n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d,0);
573 : 132 : d+=n;
574 : :
575 [ - + ]: 132 : if (n == 0)
576 : : {
577 : 0 : SSLerr(SSL_F_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
578 : 0 : return(-1);
579 : : }
580 : :
581 : 132 : s2n(n,p); /* cipher spec num bytes */
582 : :
583 [ - + ]: 132 : if ((s->session->session_id_length > 0) &&
584 : : (s->session->session_id_length <=
585 : : SSL2_MAX_SSL_SESSION_ID_LENGTH))
586 : : {
587 : 0 : i=s->session->session_id_length;
588 : 0 : s2n(i,p); /* session id length */
589 : 0 : memcpy(d,s->session->session_id,(unsigned int)i);
590 : 0 : d+=i;
591 : : }
592 : : else
593 : : {
594 : 132 : s2n(0,p);
595 : : }
596 : :
597 : 132 : s->s2->challenge_length=SSL2_CHALLENGE_LENGTH;
598 : 132 : s2n(SSL2_CHALLENGE_LENGTH,p); /* challenge length */
599 : : /*challenge id data*/
600 [ + - ]: 132 : if (RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH) <= 0)
601 : : return -1;
602 : 132 : memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH);
603 : 132 : d+=SSL2_CHALLENGE_LENGTH;
604 : :
605 : 132 : s->state=SSL2_ST_SEND_CLIENT_HELLO_B;
606 : 132 : s->init_num=d-buf;
607 : 132 : s->init_off=0;
608 : : }
609 : : /* SSL2_ST_SEND_CLIENT_HELLO_B */
610 : 132 : return(ssl2_do_write(s));
611 : : }
612 : :
613 : 110 : static int client_master_key(SSL *s)
614 : : {
615 : : unsigned char *buf;
616 : : unsigned char *p,*d;
617 : : int clear,enc,karg,i;
618 : : SSL_SESSION *sess;
619 : : const EVP_CIPHER *c;
620 : : const EVP_MD *md;
621 : :
622 : 110 : buf=(unsigned char *)s->init_buf->data;
623 [ + - ]: 110 : if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
624 : : {
625 : :
626 [ - + ]: 110 : if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL, 0))
627 : : {
628 : 0 : ssl2_return_error(s,SSL2_PE_NO_CIPHER);
629 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
630 : 0 : return(-1);
631 : : }
632 : 110 : sess=s->session;
633 : 110 : p=buf;
634 : 110 : d=p+10;
635 : 110 : *(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */
636 : :
637 : 110 : i=ssl_put_cipher_by_char(s,sess->cipher,p);
638 : 110 : p+=i;
639 : :
640 : : /* make key_arg data */
641 : 110 : i=EVP_CIPHER_iv_length(c);
642 : 110 : sess->key_arg_length=i;
643 [ - + ]: 110 : if (i > SSL_MAX_KEY_ARG_LENGTH)
644 : : {
645 : 0 : ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
646 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
647 : 0 : return -1;
648 : : }
649 [ + - ]: 110 : if (i > 0)
650 [ + - ]: 110 : if (RAND_pseudo_bytes(sess->key_arg,i) <= 0)
651 : : return -1;
652 : :
653 : : /* make a master key */
654 : 110 : i=EVP_CIPHER_key_length(c);
655 : 110 : sess->master_key_length=i;
656 [ + - ]: 110 : if (i > 0)
657 : : {
658 [ - + ]: 110 : if (i > (int)sizeof(sess->master_key))
659 : : {
660 : 0 : ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
661 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
662 : 0 : return -1;
663 : : }
664 [ - + ]: 110 : if (RAND_bytes(sess->master_key,i) <= 0)
665 : : {
666 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
667 : 0 : return(-1);
668 : : }
669 : : }
670 : :
671 [ + - ]: 110 : if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
672 : : enc=8;
673 [ + - ]: 110 : else if (SSL_C_IS_EXPORT(sess->cipher))
674 : : enc=5;
675 : : else
676 : 110 : enc=i;
677 : :
678 [ - + ]: 110 : if ((int)i < enc)
679 : : {
680 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
681 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR);
682 : 0 : return(-1);
683 : : }
684 : 110 : clear=i-enc;
685 : 110 : s2n(clear,p);
686 : 110 : memcpy(d,sess->master_key,(unsigned int)clear);
687 : 110 : d+=clear;
688 : :
689 [ + - ]: 110 : enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
690 : : &(sess->master_key[clear]),d,
691 : 110 : (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
692 [ - + ]: 110 : if (enc <= 0)
693 : : {
694 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
695 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
696 : 0 : return(-1);
697 : : }
698 : : #ifdef PKCS1_CHECK
699 : : if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++;
700 : : if (s->options & SSL_OP_PKCS1_CHECK_2)
701 : : sess->master_key[clear]++;
702 : : #endif
703 : 110 : s2n(enc,p);
704 : 110 : d+=enc;
705 : 110 : karg=sess->key_arg_length;
706 : 110 : s2n(karg,p); /* key arg size */
707 [ - + ]: 110 : if (karg > (int)sizeof(sess->key_arg))
708 : : {
709 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
710 : 0 : SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
711 : 0 : return -1;
712 : : }
713 : 110 : memcpy(d,sess->key_arg,(unsigned int)karg);
714 : 110 : d+=karg;
715 : :
716 : 110 : s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
717 : 110 : s->init_num=d-buf;
718 : 110 : s->init_off=0;
719 : : }
720 : :
721 : : /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */
722 : 110 : return(ssl2_do_write(s));
723 : : }
724 : :
725 : 110 : static int client_finished(SSL *s)
726 : : {
727 : : unsigned char *p;
728 : :
729 [ + - ]: 110 : if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A)
730 : : {
731 : 110 : p=(unsigned char *)s->init_buf->data;
732 : 110 : *(p++)=SSL2_MT_CLIENT_FINISHED;
733 [ - + ]: 110 : if (s->s2->conn_id_length > sizeof s->s2->conn_id)
734 : : {
735 : 0 : SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
736 : 0 : return -1;
737 : : }
738 : 110 : memcpy(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length);
739 : :
740 : 110 : s->state=SSL2_ST_SEND_CLIENT_FINISHED_B;
741 : 110 : s->init_num=s->s2->conn_id_length+1;
742 : 110 : s->init_off=0;
743 : : }
744 : 110 : return(ssl2_do_write(s));
745 : : }
746 : :
747 : : /* read the data and then respond */
748 : 264 : static int client_certificate(SSL *s)
749 : : {
750 : : unsigned char *buf;
751 : : unsigned char *p,*d;
752 : : int i;
753 : : unsigned int n;
754 : : int cert_ch_len;
755 : : unsigned char *cert_ch;
756 : :
757 : 264 : buf=(unsigned char *)s->init_buf->data;
758 : :
759 : : /* We have a cert associated with the SSL, so attach it to
760 : : * the session if it does not have one */
761 : :
762 [ + + ]: 264 : if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
763 : : {
764 : 44 : i=ssl2_read(s,(char *)&(buf[s->init_num]),
765 : 44 : SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
766 [ - + ]: 44 : if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
767 : 0 : return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
768 : 44 : s->init_num += i;
769 [ - + ]: 44 : if (s->msg_callback)
770 : 0 : s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */
771 : :
772 : : /* type=buf[0]; */
773 : : /* type eq x509 */
774 [ - + ]: 44 : if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
775 : : {
776 : 0 : ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
777 : 0 : SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
778 : 0 : return(-1);
779 : : }
780 : :
781 [ + - ][ + - ]: 44 : if ((s->cert == NULL) ||
782 [ - + ]: 44 : (s->cert->key->x509 == NULL) ||
783 : 44 : (s->cert->key->privatekey == NULL))
784 : : {
785 : 0 : s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
786 : : }
787 : : else
788 : 44 : s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
789 : : }
790 : :
791 : 264 : cert_ch = buf + 2;
792 : 264 : cert_ch_len = s->init_num - 2;
793 : :
794 [ - + ]: 264 : if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
795 : : {
796 : 0 : X509 *x509=NULL;
797 : 0 : EVP_PKEY *pkey=NULL;
798 : :
799 : : /* If we get an error we need to
800 : : * ssl->rwstate=SSL_X509_LOOKUP;
801 : : * return(error);
802 : : * We should then be retried when things are ok and we
803 : : * can get a cert or not */
804 : :
805 : 0 : i=0;
806 [ # # ]: 0 : if (s->ctx->client_cert_cb != NULL)
807 : : {
808 : 0 : i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
809 : : }
810 : :
811 [ # # ]: 0 : if (i < 0)
812 : : {
813 : 0 : s->rwstate=SSL_X509_LOOKUP;
814 : 0 : return(-1);
815 : : }
816 : 0 : s->rwstate=SSL_NOTHING;
817 : :
818 [ # # ][ # # ]: 0 : if ((i == 1) && (pkey != NULL) && (x509 != NULL))
[ # # ]
819 : : {
820 : 0 : s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
821 [ # # # # ]: 0 : if ( !SSL_use_certificate(s,x509) ||
822 : 0 : !SSL_use_PrivateKey(s,pkey))
823 : : {
824 : : i=0;
825 : : }
826 : 0 : X509_free(x509);
827 : 0 : EVP_PKEY_free(pkey);
828 : : }
829 [ # # ]: 0 : else if (i == 1)
830 : : {
831 [ # # ]: 0 : if (x509 != NULL) X509_free(x509);
832 [ # # ]: 0 : if (pkey != NULL) EVP_PKEY_free(pkey);
833 : 0 : SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
834 : 0 : i=0;
835 : : }
836 : :
837 [ # # ]: 0 : if (i == 0)
838 : : {
839 : : /* We have no client certificate to respond with
840 : : * so send the correct error message back */
841 : 0 : s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
842 : 0 : p=buf;
843 : 0 : *(p++)=SSL2_MT_ERROR;
844 : 0 : s2n(SSL2_PE_NO_CERTIFICATE,p);
845 : 0 : s->init_off=0;
846 : 0 : s->init_num=3;
847 : : /* Write is done at the end */
848 : : }
849 : : }
850 : :
851 [ - + ]: 264 : if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
852 : : {
853 : 0 : return(ssl2_do_write(s));
854 : : }
855 : :
856 [ + + ]: 264 : if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
857 : : {
858 : : EVP_MD_CTX ctx;
859 : :
860 : : /* ok, now we calculate the checksum
861 : : * do it first so we can reuse buf :-) */
862 : 44 : p=buf;
863 : 44 : EVP_MD_CTX_init(&ctx);
864 : 44 : EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
865 : 44 : EVP_SignUpdate(&ctx,s->s2->key_material,
866 : : s->s2->key_material_length);
867 : 44 : EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
868 : 44 : i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
869 : : /* Don't update the signature if it fails - FIXME: probably should handle this better */
870 [ + - ]: 44 : if(i > 0)
871 : 44 : EVP_SignUpdate(&ctx,buf,(unsigned int)i);
872 : :
873 : 44 : p=buf;
874 : 44 : d=p+6;
875 : 44 : *(p++)=SSL2_MT_CLIENT_CERTIFICATE;
876 : 44 : *(p++)=SSL2_CT_X509_CERTIFICATE;
877 : 44 : n=i2d_X509(s->cert->key->x509,&d);
878 : 44 : s2n(n,p);
879 : :
880 : 44 : if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
881 : : {
882 : : /* this is not good. If things have failed it
883 : : * means there so something wrong with the key.
884 : : * We will continue with a 0 length signature
885 : : */
886 : : }
887 : 44 : EVP_MD_CTX_cleanup(&ctx);
888 : 44 : s2n(n,p);
889 : 44 : d+=n;
890 : :
891 : 44 : s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
892 : 44 : s->init_num=d-buf;
893 : 44 : s->init_off=0;
894 : : }
895 : : /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
896 : 264 : return(ssl2_do_write(s));
897 : : }
898 : :
899 : 616 : static int get_server_verify(SSL *s)
900 : : {
901 : : unsigned char *p;
902 : : int i, n, len;
903 : :
904 : 616 : p=(unsigned char *)s->init_buf->data;
905 [ + - ]: 616 : if (s->state == SSL2_ST_GET_SERVER_VERIFY_A)
906 : : {
907 : 616 : i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
908 [ + + ]: 616 : if (i < (1-s->init_num))
909 : 506 : return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
910 : 110 : s->init_num += i;
911 : :
912 : 110 : s->state= SSL2_ST_GET_SERVER_VERIFY_B;
913 [ - + ]: 110 : if (*p != SSL2_MT_SERVER_VERIFY)
914 : : {
915 [ # # ]: 0 : if (p[0] != SSL2_MT_ERROR)
916 : : {
917 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
918 : 0 : SSLerr(SSL_F_GET_SERVER_VERIFY,
919 : : SSL_R_READ_WRONG_PACKET_TYPE);
920 : : }
921 : : else
922 : : {
923 : 0 : SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR);
924 : : /* try to read the error message */
925 : 0 : i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
926 : 0 : return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
927 : : }
928 : 0 : return(-1);
929 : : }
930 : : }
931 : :
932 : 110 : p=(unsigned char *)s->init_buf->data;
933 : 110 : len = 1 + s->s2->challenge_length;
934 : 110 : n = len - s->init_num;
935 : 110 : i = ssl2_read(s,(char *)&(p[s->init_num]),n);
936 [ - + ]: 110 : if (i < n)
937 : 0 : return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
938 [ - + ]: 110 : if (s->msg_callback)
939 : 0 : s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
940 : 110 : p += 1;
941 : :
942 [ - + ]: 110 : if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
943 : : {
944 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
945 : 0 : SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
946 : 0 : return(-1);
947 : : }
948 : : return(1);
949 : : }
950 : :
951 : 660 : static int get_server_finished(SSL *s)
952 : : {
953 : : unsigned char *buf;
954 : : unsigned char *p;
955 : : int i, n, len;
956 : :
957 : 660 : buf=(unsigned char *)s->init_buf->data;
958 : 660 : p=buf;
959 [ + - ]: 660 : if (s->state == SSL2_ST_GET_SERVER_FINISHED_A)
960 : : {
961 : 660 : i=ssl2_read(s,(char *)&(buf[s->init_num]),1-s->init_num);
962 [ + + ]: 660 : if (i < (1-s->init_num))
963 : 506 : return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
964 : 154 : s->init_num += i;
965 : :
966 [ + + ]: 154 : if (*p == SSL2_MT_REQUEST_CERTIFICATE)
967 : : {
968 : 44 : s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_A;
969 : 44 : return(1);
970 : : }
971 [ - + ]: 110 : else if (*p != SSL2_MT_SERVER_FINISHED)
972 : : {
973 [ # # ]: 0 : if (p[0] != SSL2_MT_ERROR)
974 : : {
975 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
976 : 0 : SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
977 : : }
978 : : else
979 : : {
980 : 0 : SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_PEER_ERROR);
981 : : /* try to read the error message */
982 : 0 : i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
983 : 0 : return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
984 : : }
985 : 0 : return(-1);
986 : : }
987 : 110 : s->state=SSL2_ST_GET_SERVER_FINISHED_B;
988 : : }
989 : :
990 : 110 : len = 1 + SSL2_SSL_SESSION_ID_LENGTH;
991 : 110 : n = len - s->init_num;
992 : 110 : i = ssl2_read(s,(char *)&(buf[s->init_num]), n);
993 [ - + ]: 110 : if (i < n) /* XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, that's the maximum */
994 : 0 : return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
995 : 110 : s->init_num += i;
996 [ - + ]: 110 : if (s->msg_callback)
997 : 0 : s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* SERVER-FINISHED */
998 : :
999 [ + - ]: 110 : if (!s->hit) /* new session */
1000 : : {
1001 : : /* new session-id */
1002 : : /* Make sure we were not trying to re-use an old SSL_SESSION
1003 : : * or bad things can happen */
1004 : : /* ZZZZZZZZZZZZZ */
1005 : 110 : s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
1006 : 110 : memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH);
1007 : : }
1008 : : else
1009 : : {
1010 [ # # ]: 0 : if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG))
1011 : : {
1012 [ # # ]: 0 : if ((s->session->session_id_length > sizeof s->session->session_id)
1013 [ # # ]: 0 : || (0 != memcmp(buf + 1, s->session->session_id,
1014 : : (unsigned int)s->session->session_id_length)))
1015 : : {
1016 : 0 : ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
1017 : 0 : SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
1018 : 0 : return(-1);
1019 : : }
1020 : : }
1021 : : }
1022 : 110 : s->state = SSL_ST_OK;
1023 : 110 : return(1);
1024 : : }
1025 : :
1026 : : /* loads in the certificate from the server */
1027 : 132 : int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
1028 : : {
1029 : 132 : STACK_OF(X509) *sk=NULL;
1030 : 132 : EVP_PKEY *pkey=NULL;
1031 : 132 : SESS_CERT *sc=NULL;
1032 : : int i;
1033 : 132 : X509 *x509=NULL;
1034 : 132 : int ret=0;
1035 : :
1036 : 132 : x509=d2i_X509(NULL,&data,(long)len);
1037 [ - + ]: 132 : if (x509 == NULL)
1038 : : {
1039 : 0 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
1040 : 0 : goto err;
1041 : : }
1042 : :
1043 [ + - ][ - + ]: 132 : if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509))
1044 : : {
1045 : 0 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE);
1046 : 0 : goto err;
1047 : : }
1048 : :
1049 : 132 : i=ssl_verify_cert_chain(s,sk);
1050 : :
1051 [ + + ][ + + ]: 132 : if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
1052 : : {
1053 : 22 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
1054 : 22 : goto err;
1055 : : }
1056 : 110 : ERR_clear_error(); /* but we keep s->verify_result */
1057 : 110 : s->session->verify_result = s->verify_result;
1058 : :
1059 [ - + ]: 110 : if (i > 1)
1060 : : {
1061 : 0 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE, i);
1062 : 0 : goto err;
1063 : : }
1064 : :
1065 : : /* server's cert for this session */
1066 : 110 : sc=ssl_sess_cert_new();
1067 [ + - ]: 110 : if (sc == NULL)
1068 : : {
1069 : : ret= -1;
1070 : : goto err;
1071 : : }
1072 [ - + ]: 110 : if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
1073 : 110 : s->session->sess_cert=sc;
1074 : :
1075 : 110 : sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
1076 : 110 : sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
1077 : :
1078 : 110 : pkey=X509_get_pubkey(x509);
1079 : 110 : x509=NULL;
1080 [ - + ]: 110 : if (pkey == NULL)
1081 : : {
1082 : 0 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
1083 : 0 : goto err;
1084 : : }
1085 [ - + ]: 110 : if (pkey->type != EVP_PKEY_RSA)
1086 : : {
1087 : 0 : SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
1088 : 0 : goto err;
1089 : : }
1090 : :
1091 [ + - ]: 110 : if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
1092 : : goto err;
1093 : 110 : ret=1;
1094 : : err:
1095 : 132 : sk_X509_free(sk);
1096 : 132 : X509_free(x509);
1097 : 132 : EVP_PKEY_free(pkey);
1098 : 132 : return(ret);
1099 : : }
1100 : :
1101 : 110 : static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
1102 : : unsigned char *to, int padding)
1103 : : {
1104 : 110 : EVP_PKEY *pkey=NULL;
1105 : 110 : int i= -1;
1106 : :
1107 [ + - ][ + - ]: 110 : if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
[ - + ]
1108 : : ((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
1109 : : {
1110 : 0 : SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
1111 : 0 : return(-1);
1112 : : }
1113 [ - + ]: 110 : if (pkey->type != EVP_PKEY_RSA)
1114 : : {
1115 : 0 : SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
1116 : 0 : goto end;
1117 : : }
1118 : :
1119 : : /* we have the public key */
1120 : 110 : i=RSA_public_encrypt(len,from,to,pkey->pkey.rsa,padding);
1121 [ - + ]: 110 : if (i < 0)
1122 : 0 : SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,ERR_R_RSA_LIB);
1123 : : end:
1124 : 110 : EVP_PKEY_free(pkey);
1125 : 110 : return(i);
1126 : : }
1127 : : #else /* !OPENSSL_NO_SSL2 */
1128 : :
1129 : : # if PEDANTIC
1130 : : static void *dummy=&dummy;
1131 : : # endif
1132 : :
1133 : : #endif
|