* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <assert.h>
#include <stdio.h>
#include <openssl/buf.h>
#include "ssl_locl.h"
static const SSL_METHOD *ssl23_get_server_method(int ver);
-int ssl23_get_client_hello(SSL *s);
+static int ssl23_get_client_hello(SSL *s);
+static int ssl23_get_v2_client_hello(SSL *s);
+
static const SSL_METHOD *ssl23_get_server_method(int ver)
{
if (ver == SSL3_VERSION)
ssl3_init_finished_mac(s);
- s->state=SSL23_ST_SR_CLNT_HELLO_A;
+ s->state=SSL23_ST_SR_CLNT_HELLO;
s->ctx->stats.sess_accept++;
s->init_num=0;
break;
- case SSL23_ST_SR_CLNT_HELLO_A:
- case SSL23_ST_SR_CLNT_HELLO_B:
+ case SSL23_ST_SR_CLNT_HELLO:
+ s->shutdown = 0;
+ ret = ssl23_get_client_hello(s);
+ if (ret <= 0) goto end;
+ break;
+
+ case SSL23_ST_SR_V2_CLNT_HELLO:
+ ret = ssl23_get_v2_client_hello(s);
+ if (ret <= 0) goto end;
+ break;
+
+ case SSL23_ST_SR_SWITCH_VERSION:
+ if (!ssl_init_wbio_buffer(s, 1))
+ {
+ ret = -1;
+ goto end;
+ }
+
+ s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ s->method = ssl23_get_server_method(s->version);
+ assert(s->method != NULL);
+ s->handshake_func = s->method->ssl_accept;
+ s->init_num = 0;
- s->shutdown=0;
- ret=ssl23_get_client_hello(s);
- if (ret >= 0) cb=NULL;
+ /* NULL the callback; SSL_accept will call it instead. */
+ cb = NULL;
+ ret = SSL_accept(s);
goto end;
/* break; */
return(ret);
}
-
-int ssl23_get_client_hello(SSL *s)
+/* ssl23_get_mutual_version determines the highest supported version for a
+ * client which reports a highest version of |client_version|. On success, it
+ * returns 1 and sets |*out_version| to the negotiated version. Otherwise, it
+ * returns 0. */
+static int ssl23_get_mutual_version(SSL *s, int *out_version, uint16_t client_version)
{
- char buf_space[11]; /* Request this many bytes in initial read.
- * We can detect SSL 3.0/TLS 1.0 Client Hellos
- * ('type == 3') correctly only when the following
- * is in a single record, which is not guaranteed by
- * the protocol specification:
- * Byte Content
- * 0 type \
- * 1/2 version > record header
- * 3/4 length /
- * 5 msg_type \
- * 6-8 length > Client Hello message
- * 9/10 client_version /
- */
- char *buf= &(buf_space[0]);
- unsigned char *p,*d,*d_len,*dd;
- unsigned int i;
- unsigned int csl,sil,cl;
- int n=0,j;
- int type=0;
- int v[2];
-
- if (s->state == SSL23_ST_SR_CLNT_HELLO_A)
+ if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2))
{
- /* read the initial header */
- v[0]=v[1]=0;
-
- if (!ssl3_setup_buffers(s)) goto err;
-
- n=ssl23_read_bytes(s, sizeof buf_space);
- if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */
-
- p=s->packet;
-
- memcpy(buf,p,n);
-
- if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO))
- {
- /*
- * SSLv2 header
- */
- if ((p[3] == 0x00) && (p[4] == 0x02))
- {
- v[0]=p[3]; v[1]=p[4];
- /* SSLv2 */
- if (!(s->options & SSL_OP_NO_SSLv2))
- type=1;
- }
- else if (p[3] == SSL3_VERSION_MAJOR)
- {
- v[0]=p[3]; v[1]=p[4];
- /* SSLv3/TLSv1 */
- if (p[4] >= TLS1_VERSION_MINOR)
- {
- if (p[4] >= TLS1_2_VERSION_MINOR &&
- !(s->options & SSL_OP_NO_TLSv1_2))
- {
- s->version=TLS1_2_VERSION;
- s->state=SSL23_ST_SR_CLNT_HELLO_B;
- }
- else if (p[4] >= TLS1_1_VERSION_MINOR &&
- !(s->options & SSL_OP_NO_TLSv1_1))
- {
- s->version=TLS1_1_VERSION;
- /* type=2; */ /* done later to survive restarts */
- s->state=SSL23_ST_SR_CLNT_HELLO_B;
- }
- else if (!(s->options & SSL_OP_NO_TLSv1))
- {
- s->version=TLS1_VERSION;
- /* type=2; */ /* done later to survive restarts */
- s->state=SSL23_ST_SR_CLNT_HELLO_B;
- }
- else if (!(s->options & SSL_OP_NO_SSLv3))
- {
- s->version=SSL3_VERSION;
- /* type=2; */
- s->state=SSL23_ST_SR_CLNT_HELLO_B;
- }
- else if (!(s->options & SSL_OP_NO_SSLv2))
- {
- type=1;
- }
- }
- else if (!(s->options & SSL_OP_NO_SSLv3))
- {
- s->version=SSL3_VERSION;
- /* type=2; */
- s->state=SSL23_ST_SR_CLNT_HELLO_B;
- }
- else if (!(s->options & SSL_OP_NO_SSLv2))
- type=1;
-
- }
- }
- else if ((p[0] == SSL3_RT_HANDSHAKE) &&
- (p[1] == SSL3_VERSION_MAJOR) &&
- (p[5] == SSL3_MT_CLIENT_HELLO) &&
- ((p[3] == 0 && p[4] < 5 /* silly record length? */)
- || (p[9] >= p[1])))
- {
- /*
- * SSLv3 or tls1 header
- */
-
- v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */
- /* We must look at client_version inside the Client Hello message
- * to get the correct minor version.
- * However if we have only a pathologically small fragment of the
- * Client Hello message, this would be difficult, and we'd have
- * to read more records to find out.
- * No known SSL 3.0 client fragments ClientHello like this,
- * so we simply assume TLS 1.0 to avoid protocol version downgrade
- * attacks. */
- if (p[3] == 0 && p[4] < 6)
- {
-#if 0
- OPENSSL_PUT_ERROR(SSL, XXX, SSL_R_RECORD_TOO_SMALL);
- goto err;
-#else
- v[1] = TLS1_VERSION_MINOR;
-#endif
- }
- /* if major version number > 3 set minor to a value
- * which will use the highest version 3 we support.
- * If TLS 2.0 ever appears we will need to revise
- * this....
- */
- else if (p[9] > SSL3_VERSION_MAJOR)
- v[1]=0xff;
- else
- v[1]=p[10]; /* minor version according to client_version */
- if (v[1] >= TLS1_VERSION_MINOR)
- {
- if (v[1] >= TLS1_2_VERSION_MINOR &&
- !(s->options & SSL_OP_NO_TLSv1_2))
- {
- s->version=TLS1_2_VERSION;
- type=3;
- }
- else if (v[1] >= TLS1_1_VERSION_MINOR &&
- !(s->options & SSL_OP_NO_TLSv1_1))
- {
- s->version=TLS1_1_VERSION;
- type=3;
- }
- else if (!(s->options & SSL_OP_NO_TLSv1))
- {
- s->version=TLS1_VERSION;
- type=3;
- }
- else if (!(s->options & SSL_OP_NO_SSLv3))
- {
- s->version=SSL3_VERSION;
- type=3;
- }
- }
- else
- {
- /* client requests SSL 3.0 */
- if (!(s->options & SSL_OP_NO_SSLv3))
- {
- s->version=SSL3_VERSION;
- type=3;
- }
- else if (!(s->options & SSL_OP_NO_TLSv1))
- {
- /* we won't be able to use TLS of course,
- * but this will send an appropriate alert */
- s->version=TLS1_VERSION;
- type=3;
- }
- }
- }
- else if ((strncmp("GET ", (char *)p,4) == 0) ||
- (strncmp("POST ",(char *)p,5) == 0) ||
- (strncmp("HEAD ",(char *)p,5) == 0) ||
- (strncmp("PUT ", (char *)p,4) == 0))
- {
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTP_REQUEST);
- goto err;
- }
- else if (strncmp("CONNECT",(char *)p,7) == 0)
- {
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTPS_PROXY_REQUEST);
- goto err;
- }
+ *out_version = TLS1_2_VERSION;
+ return 1;
+ }
+ if (client_version >= TLS1_1_VERSION && !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ *out_version = TLS1_1_VERSION;
+ return 1;
+ }
+ if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1))
+ {
+ *out_version = TLS1_VERSION;
+ return 1;
}
+ if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3))
+ {
+ *out_version = SSL3_VERSION;
+ return 1;
+ }
+ return 0;
+ }
- if (s->version < TLS1_2_VERSION && tls1_suiteb(s))
+static int ssl23_get_client_hello(SSL *s)
+ {
+ uint8_t *p;
+ int n = 0;
+
+ /* Sniff enough of the input to determine ClientHello type and the
+ * client version. */
+ if (!ssl3_setup_buffers(s)) goto err;
+
+ /* Read the initial 11 bytes of the input. This is sufficient to
+ * determine the client version for a ClientHello or a
+ * V2ClientHello.
+ *
+ * ClientHello (assuming client_version is unfragmented):
+ * Byte Content
+ * 0 type \
+ * 1-2 version > record header
+ * 3-4 length /
+ * 5 msg_type \
+ * 6-8 length > Client Hello message
+ * 9-10 client_version /
+ *
+ * V2ClientHello:
+ * Byte Content
+ * 0-1 msg_length
+ * 2 msg_type
+ * 3-4 version
+ * 5-6 cipher_spec_length
+ * 7-8 session_id_length
+ * 9-10 challenge_length
+ */
+ n = ssl23_read_bytes(s, 11);
+ if (n <= 0)
+ return n;
+ assert(n == 11);
+
+ p = s->packet;
+
+ /* Some dedicated error codes for protocol mixups should the application
+ * wish to interpret them differently. (These do not overlap with
+ * ClientHello or V2ClientHello.) */
+ if ((strncmp("GET ", (char *)p, 4) == 0) ||
+ (strncmp("POST ",(char *)p, 5) == 0) ||
+ (strncmp("HEAD ",(char *)p, 5) == 0) ||
+ (strncmp("PUT ", (char *)p, 4) == 0))
{
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTP_REQUEST);
goto err;
}
-
- if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
+ if (strncmp("CONNECT",(char *)p, 7) == 0)
{
- /* we have SSLv3/TLSv1 in an SSLv2 header
- * (other cases skip this state) */
-
- type=2;
- p=s->packet;
- v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
- v[1] = p[4];
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_HTTPS_PROXY_REQUEST);
+ goto err;
+ }
- n=((p[0]&0x7f)<<8)|p[1];
- if (n > (1024*4))
+ /* Determine if this is a ClientHello or V2ClientHello. */
+ if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO))
+ {
+ /* This is a V2ClientHello. Determine the version to
+ * use. */
+ uint16_t client_version = (p[3] << 8) | p[4];
+ if (!ssl23_get_mutual_version(s, &s->version, client_version))
{
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_RECORD_TOO_LARGE);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL);
goto err;
}
-
- j=ssl23_read_bytes(s,n+2);
- if (j <= 0) return(j);
-
- ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
- if (s->msg_callback)
- s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */
-
- p=s->packet;
- p+=5;
- n2s(p,csl);
- n2s(p,sil);
- n2s(p,cl);
- d=(unsigned char *)s->init_buf->data;
- if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format
- * Client Hello, can we? Error condition should be
- * '>' otherweise */
+ /* Parse the entire V2ClientHello. */
+ s->state = SSL23_ST_SR_V2_CLNT_HELLO;
+ }
+ else if ((p[0] == SSL3_RT_HANDSHAKE) &&
+ (p[1] >= SSL3_VERSION_MAJOR) &&
+ (p[5] == SSL3_MT_CLIENT_HELLO))
+ {
+ /* This is a fragment of a ClientHello. We look at the
+ * client_hello to negotiate the version. However, this
+ * is difficult if we have only a pathologically small
+ * fragment. No known client fragments ClientHello like
+ * this, so we simply reject such connections to avoid
+ * protocol version downgrade attacks. */
+ uint16_t record_length = (p[3] << 8) | p[4];
+ uint16_t client_version;
+ if (record_length < 6)
{
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_RECORD_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_RECORD_TOO_SMALL);
goto err;
}
- /* record header: msg_type ... */
- *(d++) = SSL3_MT_CLIENT_HELLO;
- /* ... and length (actual value will be written later) */
- d_len = d;
- d += 3;
-
- /* client_version */
- *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
- *(d++) = v[1];
-
- /* lets populate the random area */
- /* get the challenge_length */
- i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl;
- memset(d,0,SSL3_RANDOM_SIZE);
- memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i);
- d+=SSL3_RANDOM_SIZE;
-
- /* no session-id reuse */
- *(d++)=0;
-
- /* ciphers */
- j=0;
- dd=d;
- d+=2;
- for (i=0; i<csl; i+=3)
- {
- if (p[i] != 0) continue;
- *(d++)=p[i+1];
- *(d++)=p[i+2];
- j+=2;
- }
- s2n(j,dd);
-
- /* COMPRESSION */
- *(d++)=1;
- *(d++)=0;
-
-#if 0
- /* copy any remaining data with may be extensions */
- p = p+csl+sil+cl;
- while (p < s->packet+s->packet_length)
+ client_version = (p[9] << 8) | p[10];
+ if (!ssl23_get_mutual_version(s, &s->version, client_version))
{
- *(d++)=*(p++);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL);
+ goto err;
}
-#endif
- i = (d-(unsigned char *)s->init_buf->data) - 4;
- l2n3((long)i, d_len);
+ /* Reset the record-layer state for SSL3. */
+ assert(s->rstate == SSL_ST_READ_HEADER);
+ s->s3->rbuf.left = s->packet_length;
+ s->s3->rbuf.offset = 0;
+ s->packet_length = 0;
- /* get the data reused from the init_buf */
- s->s3->tmp.reuse_message=1;
- s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO;
- s->s3->tmp.message_size=i;
+ /* Ready to switch versions. */
+ s->state = SSL23_ST_SR_SWITCH_VERSION;
}
- /* imaginary new state (for program structure): */
- /* s->state = SSL23_SR_CLNT_HELLO_C */
+ return 1;
+err:
+ return -1;
+ }
- if (type == 1)
+static int ssl23_get_v2_client_hello(SSL *s)
+ {
+ uint8_t *p;
+ size_t i;
+ int n = 0;
+
+ CBS v2_client_hello, cipher_specs, session_id, challenge;
+ size_t msg_length, len;
+ uint8_t msg_type;
+ uint16_t version, cipher_spec_length, session_id_length, challenge_length;
+ CBB client_hello, hello_body, cipher_suites;
+ uint8_t random[SSL3_RANDOM_SIZE];
+
+ /* Read the remainder of the V2ClientHello. We have previously read 11
+ * bytes in ssl23_get_client_hello. */
+ p = s->packet;
+ msg_length = ((p[0] & 0x7f) << 8) | p[1];
+ if (msg_length > (1024 * 4))
{
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE);
goto err;
}
-
- if ((type == 2) || (type == 3))
+ if (msg_length < 11 - 2)
+ {
+ /* Reject lengths that are too short early. We have already read
+ * 11 bytes, so we should not attempt to process an (invalid)
+ * V2ClientHello which would be shorter than that. */
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_RECORD_LENGTH_MISMATCH);
+ goto err;
+ }
+ n = ssl23_read_bytes(s, msg_length + 2);
+ if (n <= 0)
+ return n;
+ assert(n == s->packet_length);
+
+ /* The V2ClientHello without the length is incorporated into the
+ * Finished hash. */
+ ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2);
+ if (s->msg_callback)
+ s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */
+
+ CBS_init(&v2_client_hello, s->packet + 2, s->packet_length - 2);
+ if (!CBS_get_u8(&v2_client_hello, &msg_type) ||
+ !CBS_get_u16(&v2_client_hello, &version) ||
+ !CBS_get_u16(&v2_client_hello, &cipher_spec_length) ||
+ !CBS_get_u16(&v2_client_hello, &session_id_length) ||
+ !CBS_get_u16(&v2_client_hello, &challenge_length) ||
+ !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) ||
+ !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
+ !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
+ CBS_len(&v2_client_hello) != 0)
{
- /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ goto err;
+ }
- if (!ssl_init_wbio_buffer(s,1)) goto err;
+ /* msg_type has already been checked. */
+ assert(msg_type == SSL2_MT_CLIENT_HELLO);
- /* we are in this state */
- s->state=SSL3_ST_SR_CLNT_HELLO_A;
+ /* The client_random is the V2ClientHello challenge. Truncate or
+ * left-pad with zeros as needed. */
+ memset(random, 0, SSL3_RANDOM_SIZE);
+ i = (CBS_len(&challenge) > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : CBS_len(&challenge);
+ memcpy(random, CBS_data(&challenge), i);
- if (type == 3)
+ /* Write out an equivalent SSLv3 ClientHello. */
+ if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data, s->init_buf->max))
+ {
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
+ !CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
+ !CBB_add_u16(&hello_body, version) ||
+ !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
+ /* No session id. */
+ !CBB_add_u8(&hello_body, 0) ||
+ !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites))
+ {
+ CBB_cleanup(&client_hello);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ /* Copy the cipher suites. */
+ while (CBS_len(&cipher_specs) > 0)
+ {
+ uint32_t cipher_spec;
+ if (!CBS_get_u24(&cipher_specs, &cipher_spec))
{
- /* put the 'n' bytes we have read into the input buffer
- * for SSLv3 */
- s->rstate=SSL_ST_READ_HEADER;
- s->packet_length=n;
- if (s->s3->rbuf.buf == NULL)
- if (!ssl3_setup_read_buffer(s))
- goto err;
-
- s->packet= &(s->s3->rbuf.buf[0]);
- memcpy(s->packet,buf,n);
- s->s3->rbuf.left=n;
- s->s3->rbuf.offset=0;
+ CBB_cleanup(&client_hello);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ goto err;
}
- else
+
+ /* Skip SSLv2 ciphers. */
+ if ((cipher_spec & 0xff0000) != 0)
+ continue;
+ if (!CBB_add_u16(&cipher_suites, cipher_spec))
{
- s->packet_length=0;
- s->s3->rbuf.left=0;
- s->s3->rbuf.offset=0;
+ CBB_cleanup(&client_hello);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ goto err;
}
- if (s->version == TLS1_2_VERSION)
- s->method = TLSv1_2_server_method();
- else if (s->version == TLS1_1_VERSION)
- s->method = TLSv1_1_server_method();
- else if (s->version == TLS1_VERSION)
- s->method = TLSv1_server_method();
- else
- s->method = SSLv3_server_method();
-#if 0 /* ssl3_get_client_hello does this */
- s->client_version=(v[0]<<8)|v[1];
-#endif
- s->handshake_func=s->method->ssl_accept;
}
-
- if ((type < 1) || (type > 3))
+
+ /* Add the null compression scheme and finish. */
+ if (!CBB_add_u8(&hello_body, 1) ||
+ !CBB_add_u8(&hello_body, 0) ||
+ !CBB_finish(&client_hello, NULL, &len))
{
- /* bad, very bad */
- OPENSSL_PUT_ERROR(SSL, ssl23_get_client_hello, SSL_R_UNKNOWN_PROTOCOL);
+ CBB_cleanup(&client_hello);
+ OPENSSL_PUT_ERROR(SSL, ssl23_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
goto err;
}
- s->init_num=0;
- if (buf != buf_space) OPENSSL_free(buf);
- return(SSL_accept(s));
+ /* Mark the message for "re"-use by the version-specific
+ * method. */
+ s->s3->tmp.reuse_message = 1;
+ s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO;
+ /* The handshake message header is 4 bytes. */
+ s->s3->tmp.message_size = len - 4;
+
+ /* Reset the record layer for SSL3. */
+ assert(s->rstate == SSL_ST_READ_HEADER);
+ s->packet_length = 0;
+ s->s3->rbuf.left = 0;
+ s->s3->rbuf.offset = 0;
+
+ s->state = SSL23_ST_SR_SWITCH_VERSION;
+ return 1;
err:
- if (buf != buf_space) OPENSSL_free(buf);
- return(-1);
+ return -1;
}