@ -1979,6 +1979,16 @@ ssl_is_ocspreq(const unsigned char *buf, size_t sz)
return 1 ;
}
static uint16_t
len2 ( uint8_t p0 , uint8_t p1 ) {
return ( uint16_t ) p1 + ( ( uint16_t ) p0 < < 8 ) ;
}
static uint32_t
len3 ( uint8_t p0 , uint8_t p1 , uint8_t p2 ) {
return ( uint32_t ) p2 + ( ( uint32_t ) p1 < < 8 ) + ( ( uint32_t ) p0 < < 16 ) ;
}
/*
* Ugly hack to manually parse a clientHello message from a memory buffer .
* This is needed in order to be able to support SNI and STARTTLS .
@ -2037,13 +2047,13 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
# endif /* !DEBUG_CLIENTHELLO_PARSER */
const unsigned char * p = buf ;
ssize_t n = sz ;
char * sn = NULL ;
* clienthello = NULL ;
DBG_printf ( " parsing buffer of sz %zd \n " , sz ) ;
do {
char * sn = NULL ;
if ( * clienthello ) {
/*
* Rewind after skipping an invalid ClientHello by
@ -2052,10 +2062,6 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
*/
p = ( * clienthello ) + 1 ;
n = sz - ( p - buf ) ;
if ( sn ) {
free ( sn ) ;
sn = NULL ;
}
}
if ( search ) {
@ -2114,15 +2120,15 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
p + = 2 ; n - = 2 ;
DBG_printf ( " cipher-spec-len: %02x %02x \n " , p [ 0 ] , p [ 1 ] ) ;
ssize_t cipherspec_len = p [ 0 ] < < 8 | p [ 1 ] ;
ssize_t cipherspec_len = len2 ( p [ 0 ] , p [ 1 ] ) ;
p + = 2 ; n - = 2 ;
DBG_printf ( " session-id-len: %02x %02x \n " , p [ 0 ] , p [ 1 ] ) ;
ssize_t sessionid_len = p [ 0 ] < < 8 | p [ 1 ] ;
ssize_t sessionid_len = len2 ( p [ 0 ] , p [ 1 ] ) ;
p + = 2 ; n - = 2 ;
DBG_printf ( " challenge-len: %02x %02x \n " , p [ 0 ] , p [ 1 ] ) ;
ssize_t challenge_len = p [ 0 ] < < 8 | p [ 1 ] ;
ssize_t challenge_len = len2 ( p [ 0 ] , p [ 1 ] ) ;
p + = 2 ; n - = 2 ;
if ( challenge_len < 16 | | challenge_len > 32 )
continue ;
@ -2165,7 +2171,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
return 1 ;
}
DBG_printf ( " length: %02x %02x \n " , p [ 0 ] , p [ 1 ] ) ;
ssize_t recordlen = p [ 1 ] + ( p [ 0 ] < < 8 ) ;
ssize_t recordlen = len2 ( p [ 0 ] , p [ 1 ] ) ;
DBG_printf ( " recordlen=%zd \n " , recordlen ) ;
p + = 2 ; n - = 2 ;
if ( recordlen < 36 ) /* arbitrary size too small for a c-h */
@ -2190,7 +2196,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
if ( n < 3 )
continue ;
DBG_printf ( " message len: %02x %02x %02x \n " , p [ 0 ] , p [ 1 ] , p [ 2 ] ) ;
ssize_t msglen = p [ 2 ] + ( p [ 1 ] < < 8 ) + ( p [ 0 ] < < 16 ) ;
ssize_t msglen = len3 ( p [ 0 ] , p [ 1 ] , p [ 2 ] ) ;
DBG_printf ( " msglen=%zd \n " , msglen ) ;
p + = 3 ; n - = 3 ;
if ( msglen < 32 ) /* arbitrary size too small for a c-h */
@ -2232,7 +2239,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
continue ;
DBG_printf ( " clienthello cipher suites length %02x %02x \n " ,
p [ 0 ] , p [ 1 ] ) ;
ssize_t suiteslen = p [ 1 ] + ( p [ 0 ] < < 8 ) ;
ssize_t suiteslen = len2 ( p [ 0 ] , p [ 1 ] ) ;
p + = 2 ; n - = 2 ;
if ( n < suiteslen )
continue ;
@ -2261,7 +2269,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
if ( n < 2 )
continue ;
DBG_printf ( " tlsexts length %02x %02x \n " , p [ 0 ] , p [ 1 ] ) ;
ssize_t tlsextslen = p [ 1 ] + ( p [ 0 ] < < 8 ) ;
ssize_t tlsextslen = len2 ( p [ 0 ] , p [ 1 ] ) ;
DBG_printf ( " tlsextslen %zd \n " , tlsextslen ) ;
p + = 2 ; n - = 2 ;
if ( n < tlsextslen )
@ -2273,8 +2281,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
goto continue_search ;
DBG_printf ( " tlsext type %02x %02x len %02x %02x \n " ,
p [ 0 ] , p [ 1 ] , p [ 2 ] , p [ 3 ] ) ;
unsigned short exttype = p [ 1 ] + ( p [ 0 ] < < 8 ) ;
ssize_t extlen = p [ 3 ] + ( p [ 2 ] < < 8 ) ;
unsigned short exttype = len2 ( p [ 0 ] , p [ 1 ] ) ;
ssize_t extlen = len2 ( p [ 2 ] , p [ 3 ] ) ;
p + = 4 ; n - = 4 ;
if ( n < extlen )
goto continue_search ;
@ -2287,7 +2295,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
goto continue_search ;
DBG_printf ( " list length %02x %02x \n " ,
extp [ 0 ] , extp [ 1 ] ) ;
ssize_t namelistlen = extp [ 1 ] + ( extp [ 0 ] < < 8 ) ;
ssize_t namelistlen = len2 ( extp [ 0 ] , extp [ 1 ] ) ;
DBG_printf ( " namelistlen = %zd \n " , namelistlen ) ;
extp + = 2 ;
extn - = 2 ;
@ -2302,7 +2310,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search,
" len %02x %02x \n " ,
extp [ 0 ] , extp [ 1 ] , extp [ 2 ] ) ;
unsigned char sntype = extp [ 0 ] ;
ssize_t snlen = extp [ 2 ] + ( extp [ 1 ] < < 8 ) ;
ssize_t snlen = len2 ( extp [ 1 ] , extp [ 2 ] ) ;
extp + = 3 ;
extn - = 3 ;
if ( snlen > extn )
@ -2353,16 +2361,13 @@ done_parsing:
* servername = sn ;
return 0 ;
continue_search :
;
if ( sn )
free ( sn ) ;
} while ( search & & n > 0 ) ;
/* No valid ClientHello messages found, not even a truncated one */
DBG_printf ( " ===> No match: rv 1, *clienthello NULL \n " ) ;
* clienthello = NULL ;
if ( sn ) {
free ( sn ) ;
sn = NULL ;
}
return 1 ;
}