s23_clnt.c revision 296465
1/* ssl/s23_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#include <stdio.h>
60#include "ssl_locl.h"
61#include <openssl/buffer.h>
62#include <openssl/rand.h>
63#include <openssl/objects.h>
64#include <openssl/evp.h>
65
66static SSL_METHOD *ssl23_get_client_method(int ver);
67static int ssl23_client_hello(SSL *s);
68static int ssl23_get_server_hello(SSL *s);
69static SSL_METHOD *ssl23_get_client_method(int ver)
70{
71#ifndef OPENSSL_NO_SSL2
72    if (ver == SSL2_VERSION)
73        return (SSLv2_client_method());
74#endif
75#ifndef OPENSSL_NO_SSL3
76    if (ver == SSL3_VERSION)
77        return (SSLv3_client_method());
78#endif
79    if (ver == TLS1_VERSION)
80        return (TLSv1_client_method());
81    else
82        return (NULL);
83}
84
85IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
86                          ssl_undefined_function,
87                          ssl23_connect, ssl23_get_client_method)
88
89int ssl23_connect(SSL *s)
90{
91    BUF_MEM *buf = NULL;
92    unsigned long Time = (unsigned long)time(NULL);
93    void (*cb) (const SSL *ssl, int type, int val) = NULL;
94    int ret = -1;
95    int new_state, state;
96
97    RAND_add(&Time, sizeof(Time), 0);
98    ERR_clear_error();
99    clear_sys_error();
100
101    if (s->info_callback != NULL)
102        cb = s->info_callback;
103    else if (s->ctx->info_callback != NULL)
104        cb = s->ctx->info_callback;
105
106    s->in_handshake++;
107    if (!SSL_in_init(s) || SSL_in_before(s))
108        SSL_clear(s);
109
110    for (;;) {
111        state = s->state;
112
113        switch (s->state) {
114        case SSL_ST_BEFORE:
115        case SSL_ST_CONNECT:
116        case SSL_ST_BEFORE | SSL_ST_CONNECT:
117        case SSL_ST_OK | SSL_ST_CONNECT:
118
119            if (s->session != NULL) {
120                SSLerr(SSL_F_SSL23_CONNECT,
121                       SSL_R_SSL23_DOING_SESSION_ID_REUSE);
122                ret = -1;
123                goto end;
124            }
125            s->server = 0;
126            if (cb != NULL)
127                cb(s, SSL_CB_HANDSHAKE_START, 1);
128
129            /* s->version=TLS1_VERSION; */
130            s->type = SSL_ST_CONNECT;
131
132            if (s->init_buf == NULL) {
133                if ((buf = BUF_MEM_new()) == NULL) {
134                    ret = -1;
135                    goto end;
136                }
137                if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
138                    ret = -1;
139                    goto end;
140                }
141                s->init_buf = buf;
142                buf = NULL;
143            }
144
145            if (!ssl3_setup_buffers(s)) {
146                ret = -1;
147                goto end;
148            }
149
150            ssl3_init_finished_mac(s);
151
152            s->state = SSL23_ST_CW_CLNT_HELLO_A;
153            s->ctx->stats.sess_connect++;
154            s->init_num = 0;
155            break;
156
157        case SSL23_ST_CW_CLNT_HELLO_A:
158        case SSL23_ST_CW_CLNT_HELLO_B:
159
160            s->shutdown = 0;
161            ret = ssl23_client_hello(s);
162            if (ret <= 0)
163                goto end;
164            s->state = SSL23_ST_CR_SRVR_HELLO_A;
165            s->init_num = 0;
166
167            break;
168
169        case SSL23_ST_CR_SRVR_HELLO_A:
170        case SSL23_ST_CR_SRVR_HELLO_B:
171            ret = ssl23_get_server_hello(s);
172            if (ret >= 0)
173                cb = NULL;
174            goto end;
175            /* break; */
176
177        default:
178            SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE);
179            ret = -1;
180            goto end;
181            /* break; */
182        }
183
184        if (s->debug) {
185            (void)BIO_flush(s->wbio);
186        }
187
188        if ((cb != NULL) && (s->state != state)) {
189            new_state = s->state;
190            s->state = state;
191            cb(s, SSL_CB_CONNECT_LOOP, 1);
192            s->state = new_state;
193        }
194    }
195 end:
196    s->in_handshake--;
197    if (buf != NULL)
198        BUF_MEM_free(buf);
199    if (cb != NULL)
200        cb(s, SSL_CB_CONNECT_EXIT, ret);
201    return (ret);
202}
203
204static int ssl23_client_hello(SSL *s)
205{
206    unsigned char *buf;
207    unsigned char *p, *d;
208    int i, ch_len;
209    unsigned long Time, l;
210    int ssl2_compat;
211    int version = 0, version_major, version_minor;
212#ifndef OPENSSL_NO_COMP
213    int j;
214    SSL_COMP *comp;
215#endif
216    int ret;
217
218    ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
219
220    if (!(s->options & SSL_OP_NO_TLSv1)) {
221        version = TLS1_VERSION;
222    } else if (!(s->options & SSL_OP_NO_SSLv3)) {
223        version = SSL3_VERSION;
224    } else if (!(s->options & SSL_OP_NO_SSLv2)) {
225        version = SSL2_VERSION;
226    }
227#ifndef OPENSSL_NO_TLSEXT
228    if (version != SSL2_VERSION) {
229        /*
230         * have to disable SSL 2.0 compatibility if we need TLS extensions
231         */
232
233        if (s->tlsext_hostname != NULL)
234            ssl2_compat = 0;
235        if (s->tlsext_status_type != -1)
236            ssl2_compat = 0;
237    }
238#endif
239
240    buf = (unsigned char *)s->init_buf->data;
241    if (s->state == SSL23_ST_CW_CLNT_HELLO_A) {
242#if 0
243        /* don't reuse session-id's */
244        if (!ssl_get_new_session(s, 0)) {
245            return (-1);
246        }
247#endif
248
249        p = s->s3->client_random;
250        Time = (unsigned long)time(NULL); /* Time */
251        l2n(Time, p);
252        if (RAND_pseudo_bytes(p, SSL3_RANDOM_SIZE - 4) <= 0)
253            return -1;
254
255        if (version == TLS1_VERSION) {
256            version_major = TLS1_VERSION_MAJOR;
257            version_minor = TLS1_VERSION_MINOR;
258        }
259#ifdef OPENSSL_FIPS
260        else if (FIPS_mode()) {
261            SSLerr(SSL_F_SSL23_CLIENT_HELLO,
262                   SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
263            return -1;
264        }
265#endif
266        else if (version == SSL3_VERSION) {
267            version_major = SSL3_VERSION_MAJOR;
268            version_minor = SSL3_VERSION_MINOR;
269        } else if (version == SSL2_VERSION) {
270            version_major = SSL2_VERSION_MAJOR;
271            version_minor = SSL2_VERSION_MINOR;
272        } else {
273            SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE);
274            return (-1);
275        }
276
277        s->client_version = version;
278
279        if (ssl2_compat) {
280            /* create SSL 2.0 compatible Client Hello */
281
282            /* two byte record header will be written last */
283            d = &(buf[2]);
284            p = d + 9;          /* leave space for message type, version,
285                                 * individual length fields */
286
287            *(d++) = SSL2_MT_CLIENT_HELLO;
288            *(d++) = version_major;
289            *(d++) = version_minor;
290
291            /* Ciphers supported */
292            i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0);
293            if (i == 0) {
294                /* no ciphers */
295                SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
296                return -1;
297            }
298            s2n(i, d);
299            p += i;
300
301            /*
302             * put in the session-id length (zero since there is no reuse)
303             */
304#if 0
305            s->session->session_id_length = 0;
306#endif
307            s2n(0, d);
308
309            if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
310                ch_len = SSL2_CHALLENGE_LENGTH;
311            else
312                ch_len = SSL2_MAX_CHALLENGE_LENGTH;
313
314            /* write out sslv2 challenge */
315            if (SSL3_RANDOM_SIZE < ch_len)
316                i = SSL3_RANDOM_SIZE;
317            else
318                i = ch_len;
319            s2n(i, d);
320            memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE);
321            if (RAND_pseudo_bytes
322                (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0)
323                return -1;
324
325            memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i);
326            p += i;
327
328            i = p - &(buf[2]);
329            buf[0] = ((i >> 8) & 0xff) | 0x80;
330            buf[1] = (i & 0xff);
331
332            /* number of bytes to write */
333            s->init_num = i + 2;
334            s->init_off = 0;
335
336            ssl3_finish_mac(s, &(buf[2]), i);
337        } else {
338            /* create Client Hello in SSL 3.0/TLS 1.0 format */
339
340            /*
341             * do the record header (5 bytes) and handshake message header (4
342             * bytes) last
343             */
344            d = p = &(buf[9]);
345
346            *(p++) = version_major;
347            *(p++) = version_minor;
348
349            /* Random stuff */
350            memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
351            p += SSL3_RANDOM_SIZE;
352
353            /* Session ID (zero since there is no reuse) */
354            *(p++) = 0;
355
356            /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */
357            i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]),
358                                         ssl3_put_cipher_by_char);
359            if (i == 0) {
360                SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
361                return -1;
362            }
363            s2n(i, p);
364            p += i;
365#ifdef OPENSSL_NO_COMP
366            *(p++) = 1;
367#else
368            /* COMPRESSION */
369            if (s->ctx->comp_methods == NULL)
370                j = 0;
371            else
372                j = sk_SSL_COMP_num(s->ctx->comp_methods);
373            *(p++) = 1 + j;
374            for (i = 0; i < j; i++) {
375                comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
376                *(p++) = comp->id;
377            }
378#endif
379            *(p++) = 0;         /* Add the NULL method */
380#ifndef OPENSSL_NO_TLSEXT
381            if ((p =
382                 ssl_add_clienthello_tlsext(s, p,
383                                            buf +
384                                            SSL3_RT_MAX_PLAIN_LENGTH)) ==
385                NULL) {
386                SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
387                return -1;
388            }
389#endif
390
391            l = p - d;
392            *p = 42;
393
394            /* fill in 4-byte handshake header */
395            d = &(buf[5]);
396            *(d++) = SSL3_MT_CLIENT_HELLO;
397            l2n3(l, d);
398
399            l += 4;
400
401            if (l > SSL3_RT_MAX_PLAIN_LENGTH) {
402                SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
403                return -1;
404            }
405
406            /* fill in 5-byte record header */
407            d = buf;
408            *(d++) = SSL3_RT_HANDSHAKE;
409            *(d++) = version_major;
410            *(d++) = version_minor; /* arguably we should send the *lowest*
411                                     * suported version here (indicating,
412                                     * e.g., TLS 1.0 in "SSL 3.0 format") */
413            s2n((int)l, d);
414
415            /* number of bytes to write */
416            s->init_num = p - buf;
417            s->init_off = 0;
418
419            ssl3_finish_mac(s, &(buf[5]), s->init_num - 5);
420        }
421
422        s->state = SSL23_ST_CW_CLNT_HELLO_B;
423        s->init_off = 0;
424    }
425
426    /* SSL3_ST_CW_CLNT_HELLO_B */
427    ret = ssl23_write_bytes(s);
428
429    if ((ret >= 2) && s->msg_callback) {
430        /* Client Hello has been sent; tell msg_callback */
431
432        if (ssl2_compat)
433            s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2,
434                            ret - 2, s, s->msg_callback_arg);
435        else
436            s->msg_callback(1, version, SSL3_RT_HANDSHAKE,
437                            s->init_buf->data + 5, ret - 5, s,
438                            s->msg_callback_arg);
439    }
440
441    return ret;
442}
443
444static int ssl23_get_server_hello(SSL *s)
445{
446    char buf[8];
447    unsigned char *p;
448    int i;
449    int n;
450
451    n = ssl23_read_bytes(s, 7);
452
453    if (n != 7)
454        return (n);
455    p = s->packet;
456
457    memcpy(buf, p, n);
458
459    if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) &&
460        (p[5] == 0x00) && (p[6] == 0x02)) {
461#ifdef OPENSSL_NO_SSL2
462        SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
463        goto err;
464#else
465        /* we are talking sslv2 */
466        /*
467         * we need to clean up the SSLv3 setup and put in the sslv2 stuff.
468         */
469        int ch_len;
470
471        if (s->options & SSL_OP_NO_SSLv2) {
472            SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
473            goto err;
474        }
475        if (s->s2 == NULL) {
476            if (!ssl2_new(s))
477                goto err;
478        } else
479            ssl2_clear(s);
480
481        if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
482            ch_len = SSL2_CHALLENGE_LENGTH;
483        else
484            ch_len = SSL2_MAX_CHALLENGE_LENGTH;
485
486        /* write out sslv2 challenge */
487        i = (SSL3_RANDOM_SIZE < ch_len)
488            ? SSL3_RANDOM_SIZE : ch_len;
489        s->s2->challenge_length = i;
490        memcpy(s->s2->challenge,
491               &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i);
492
493        if (s->s3 != NULL)
494            ssl3_free(s);
495
496        if (!BUF_MEM_grow_clean(s->init_buf,
497                                SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) {
498            SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB);
499            goto err;
500        }
501
502        s->state = SSL2_ST_GET_SERVER_HELLO_A;
503        if (!(s->client_version == SSL2_VERSION))
504            /*
505             * use special padding (SSL 3.0 draft/RFC 2246, App. E.2)
506             */
507            s->s2->ssl2_rollback = 1;
508
509        /*
510         * setup the 7 bytes we have read so we get them from the sslv2
511         * buffer
512         */
513        s->rstate = SSL_ST_READ_HEADER;
514        s->packet_length = n;
515        s->packet = &(s->s2->rbuf[0]);
516        memcpy(s->packet, buf, n);
517        s->s2->rbuf_left = n;
518        s->s2->rbuf_offs = 0;
519
520        /* we have already written one */
521        s->s2->write_sequence = 1;
522
523        s->method = SSLv2_client_method();
524        s->handshake_func = s->method->ssl_connect;
525#endif
526    } else if (p[1] == SSL3_VERSION_MAJOR &&
527               ((p[2] == SSL3_VERSION_MINOR) ||
528                (p[2] == TLS1_VERSION_MINOR)) &&
529               ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
530                (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) {
531        /* we have sslv3 or tls1 (server hello or alert) */
532
533#ifndef OPENSSL_NO_SSL3
534        if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) {
535# ifdef OPENSSL_FIPS
536            if (FIPS_mode()) {
537                SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
538                       SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
539                goto err;
540            }
541# endif
542            s->version = SSL3_VERSION;
543            s->method = SSLv3_client_method();
544        } else
545#endif
546        if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) {
547            s->version = TLS1_VERSION;
548            s->method = TLSv1_client_method();
549        } else {
550            SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
551            goto err;
552        }
553
554        /* ensure that TLS_MAX_VERSION is up-to-date */
555        OPENSSL_assert(s->version <= TLS_MAX_VERSION);
556
557        if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) {
558            /* fatal alert */
559
560            void (*cb) (const SSL *ssl, int type, int val) = NULL;
561            int j;
562
563            if (s->info_callback != NULL)
564                cb = s->info_callback;
565            else if (s->ctx->info_callback != NULL)
566                cb = s->ctx->info_callback;
567
568            i = p[5];
569            if (cb != NULL) {
570                j = (i << 8) | p[6];
571                cb(s, SSL_CB_READ_ALERT, j);
572            }
573
574            if (s->msg_callback)
575                s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s,
576                                s->msg_callback_arg);
577
578            s->rwstate = SSL_NOTHING;
579            SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]);
580            goto err;
581        }
582
583        if (!ssl_init_wbio_buffer(s, 1))
584            goto err;
585
586        /* we are in this state */
587        s->state = SSL3_ST_CR_SRVR_HELLO_A;
588
589        /*
590         * put the 7 bytes we have read into the input buffer for SSLv3
591         */
592        s->rstate = SSL_ST_READ_HEADER;
593        s->packet_length = n;
594        if (s->s3->rbuf.buf == NULL)
595            if (!ssl3_setup_buffers(s))
596                goto err;
597        s->packet = &(s->s3->rbuf.buf[0]);
598        memcpy(s->packet, buf, n);
599        s->s3->rbuf.left = n;
600        s->s3->rbuf.offset = 0;
601
602        s->handshake_func = s->method->ssl_connect;
603    } else {
604        SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL);
605        goto err;
606    }
607    s->init_num = 0;
608
609    /*
610     * Since, if we are sending a ssl23 client hello, we are not reusing a
611     * session-id
612     */
613    if (!ssl_get_new_session(s, 0))
614        goto err;
615
616    return (SSL_connect(s));
617 err:
618    return (-1);
619}
620