int ssl23_get_client_hello(SSL *s);
static SSL_METHOD *ssl23_get_server_method(int ver)
{
-#ifndef NO_SSL2
+#ifndef OPENSSL_NO_SSL2
if (ver == SSL2_VERSION)
return(SSLv2_server_method());
#endif
* 9/10 client_version /
*/
char *buf= &(buf_space[0]);
- unsigned char *p,*d,*dd;
+ 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];
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
int use_sslv2_strong=0;
#endif
else if (!(s->options & SSL_OP_NO_SSLv2))
type=1;
- if (s->options & SSL_OP_NON_EXPORT_FIRST)
- /* Not only utterly confusing, but broken
- * ('fractured programming'?) -- the details
- * of this block nearly make it work
- * as intended in this environment, but on one
- * of the fine points (w.r.t. restarts) it fails.
- * The obvious fix would be even more devastating
- * to program structure; if you want the functionality,
- * throw this away and implement it in a way
- * that makes sense */
- {
-#if 0
- STACK_OF(SSL_CIPHER) *sk;
- SSL_CIPHER *c;
- int ne2,ne3;
-
- j=((p[0]&0x7f)<<8)|p[1];
- if (j > (1024*4))
- {
- SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
- goto err;
- }
-
- n=ssl23_read_bytes(s,j+2);
- if (n <= 0) return(n);
- p=s->packet;
-
- if ((buf=OPENSSL_malloc(n)) == NULL)
- {
- SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memcpy(buf,p,n);
-
- p+=5;
- n2s(p,csl);
- p+=4;
-
- sk=ssl_bytes_to_cipher_list(
- s,p,csl,NULL);
- if (sk != NULL)
- {
- ne2=ne3=0;
- for (j=0; j<sk_SSL_CIPHER_num(sk); j++)
- {
- c=sk_SSL_CIPHER_value(sk,j);
- if (!SSL_C_IS_EXPORT(c))
- {
- if ((c->id>>24L) == 2L)
- ne2=1;
- else
- ne3=1;
- }
- }
- if (ne2 && !ne3)
- {
- type=1;
- use_sslv2_strong=1;
- goto next_bit;
- }
- }
-#else
- SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_OPTION);
- goto err;
-#endif
- }
}
}
else if ((p[0] == SSL3_RT_HANDSHAKE) &&
* SSLv3 or tls1 header
*/
- v[0]=p[1]; /* major version */
+ 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: */
- v[1]=p[10];
- /* However if we have only a pathologically small fragment of the
- * Client Hello message, we simply use the version from the
- * record header -- this is incorrect but unlikely to fail in
- * practice */
+ * to get the correct minor version.
+ * However if we have only a pathologically small fragment of the
+ * Client Hello message, this would be difficult, we'd have
+ * to read at least one additional record to find out.
+ * This doesn't usually happen in real life, so we just complain
+ * for now.
+ */
if (p[3] == 0 && p[4] < 6)
- v[1]=p[2];
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
+ goto err;
+ }
+ v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
{
if (!(s->options & SSL_OP_NO_TLSv1))
goto err;
}
+ /* record header: version ... */
+ *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
+ *(d++) = v[1];
+ /* ... and length (actual value will be written later) */
+ d_len = d++;
+ d++;
+
+ /* client_version */
*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
*(d++) = v[1];
*(d++)=0;
i=(d-(unsigned char *)s->init_buf->data);
+ s2n(i, d_len);
/* get the data reused from the init_buf */
s->s3->tmp.reuse_message=1;
if (type == 1)
{
-#ifdef NO_SSL2
+#ifdef OPENSSL_NO_SSL2
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
goto err;
#else
s->state=SSL2_ST_GET_CLIENT_HELLO_A;
if ((s->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) ||
- use_sslv2_strong)
+ use_sslv2_strong ||
+ (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3))
s->s2->ssl2_rollback=0;
else
+ /* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0
+ * (SSL 3.0 draft/RFC 2246, App. E.2) */
s->s2->ssl2_rollback=1;
/* setup the n bytes we have read so we get them from