diff --git a/CHANGES b/CHANGES index 5d129a825a..df2d24ddd6 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,15 @@ *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7 +) applies to 0.9.7 only + +) Change ssl3_get_message (ssl/s3_both.c) and the functions using it + so that complete 'Handshake' protocol structures are kept in memory + instead of overwriting 'msg_type' and 'length' with 'body' data. + [Bodo Moeller] + + *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation + correctly. + [Bodo Moeller] + +) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32. [Massimo Santin via Richard Levitte] diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c index e0abbaf834..342d145c23 100644 --- a/ssl/s23_srvr.c +++ b/ssl/s23_srvr.c @@ -202,7 +202,7 @@ int ssl23_get_client_hello(SSL *s) * 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; @@ -365,6 +365,14 @@ int ssl23_get_client_hello(SSL *s) 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]; @@ -396,6 +404,7 @@ int ssl23_get_client_hello(SSL *s) *(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; diff --git a/ssl/s3_both.c b/ssl/s3_both.c index cd97280374..409120bade 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -109,6 +109,7 @@ * */ +#include #include #include #include @@ -205,7 +206,7 @@ int ssl3_get_finished(SSL *s, int a, int b) } s->s3->change_cipher_spec=0; - p = (unsigned char *)s->init_buf->data; + p = (unsigned char *)s->init_msg; i = s->s3->tmp.peer_finish_md_len; if (i != n) @@ -355,6 +356,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) goto f_err; } *ok=1; + s->init_msg = s->init_buf->data + 4; return((int)s->s3->tmp.message_size); } @@ -415,8 +417,6 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) ssl3_init_finished_mac(s); } - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, 4); - s->s3->tmp.message_type= *(p++); n2l3(p,l); @@ -426,7 +426,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l && !BUF_MEM_grow(s->init_buf,(int)l)) + if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */ + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto f_err; + } + if (l && !BUF_MEM_grow(s->init_buf,(int)l+4)) { SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB); goto err; @@ -434,13 +440,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->s3->tmp.message_size=l; s->state=stn; - s->init_num=0; + s->init_msg = s->init_buf->data + 4; + s->init_num = 0; } /* next state (stn) */ - p=(unsigned char *)s->init_buf->data; - n=s->s3->tmp.message_size; - n -= s->init_num; + p = s->init_msg; + n = s->s3->tmp.message_size - s->init_num; while (n > 0) { i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0); @@ -453,7 +459,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_num += i; n -= i; } - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num); + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); *ok=1; return s->init_num; f_err: diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 67dc5b05d5..9791a0d8e8 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -554,7 +554,7 @@ static int ssl3_get_server_hello(SSL *s) &ok); if (!ok) return((int)n); - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff))) { @@ -710,7 +710,7 @@ static int ssl3_get_server_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE); goto f_err; } - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; if ((sk=sk_X509_new_null()) == NULL) { @@ -895,7 +895,7 @@ static int ssl3_get_key_exchange(SSL *s) return(1); } - param=p=(unsigned char *)s->init_buf->data; + param=p=(unsigned char *)s->init_msg; if (s->session->sess_cert != NULL) { @@ -1218,7 +1218,7 @@ static int ssl3_get_certificate_request(SSL *s) } } - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL) { diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 001b37bf1c..ab2478d01c 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -663,7 +663,7 @@ static int ssl3_get_client_hello(SSL *s) &ok); if (!ok) return((int)n); - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; /* use version from inside client hello, not from record header * (may differ: see RFC 2246, Appendix E, second paragraph) */ @@ -1355,7 +1355,7 @@ static int ssl3_get_client_key_exchange(SSL *s) &ok); if (!ok) return((int)n); - p=(unsigned char *)s->init_buf->data; + p=(unsigned char *)s->init_msg; l=s->s3->tmp.new_cipher->algorithms; @@ -1756,7 +1756,7 @@ static int ssl3_get_cert_verify(SSL *s) } /* we now have a signature that we need to verify */ - p=(unsigned char *)s->init_buf->data; + p=(unsigned char *)s->init_msg; n2s(p,i); n-=2; if (i > n) @@ -1872,7 +1872,7 @@ static int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; if ((sk=sk_X509_new_null()) == NULL) { diff --git a/ssl/ssl.h b/ssl/ssl.h index c1c467480d..eab1317ab8 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -652,6 +652,7 @@ struct ssl_st int rstate; /* where we are when reading */ BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by ssl3_get_message() */ int init_num; /* amount read/written */ int init_off; /* amount read/written */