[tls] Handle multiple handshake records

The handshake record in TLS can contain multiple messages.

Originally-fixed-by: Timothy Stack <tstack@vmware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/1/head
Michael Brown 2010-06-23 01:01:32 +01:00
parent 719ba316df
commit 21682afe69
1 changed files with 55 additions and 40 deletions

View File

@ -962,6 +962,10 @@ static int tls_new_finished ( struct tls_session *tls,
*/ */
static int tls_new_handshake ( struct tls_session *tls, static int tls_new_handshake ( struct tls_session *tls,
void *data, size_t len ) { void *data, size_t len ) {
void *end = ( data + len );
int rc;
while ( data != end ) {
struct { struct {
uint8_t type; uint8_t type;
uint8_t length[3]; uint8_t length[3];
@ -969,12 +973,12 @@ static int tls_new_handshake ( struct tls_session *tls,
} __attribute__ (( packed )) *handshake = data; } __attribute__ (( packed )) *handshake = data;
void *payload = &handshake->payload; void *payload = &handshake->payload;
size_t payload_len = tls_uint24 ( handshake->length ); size_t payload_len = tls_uint24 ( handshake->length );
void *end = ( payload + payload_len ); void *next = ( payload + payload_len );
int rc;
/* Sanity check */ /* Sanity check */
if ( end != ( data + len ) ) { if ( next > end ) {
DBGC ( tls, "TLS %p received overlength Handshake\n", tls ); DBGC ( tls, "TLS %p received overlength Handshake\n",
tls );
DBGC_HD ( tls, data, len ); DBGC_HD ( tls, data, len );
return -EINVAL; return -EINVAL;
} }
@ -987,7 +991,8 @@ static int tls_new_handshake ( struct tls_session *tls,
rc = tls_new_certificate ( tls, payload, payload_len ); rc = tls_new_certificate ( tls, payload, payload_len );
break; break;
case TLS_SERVER_HELLO_DONE: case TLS_SERVER_HELLO_DONE:
rc = tls_new_server_hello_done ( tls, payload, payload_len ); rc = tls_new_server_hello_done ( tls, payload,
payload_len );
break; break;
case TLS_FINISHED: case TLS_FINISHED:
rc = tls_new_finished ( tls, payload, payload_len ); rc = tls_new_finished ( tls, payload, payload_len );
@ -999,13 +1004,23 @@ static int tls_new_handshake ( struct tls_session *tls,
break; break;
} }
/* Add to handshake digest (except for Hello Requests, which /* Add to handshake digest (except for Hello Requests,
* are explicitly excluded). * which are explicitly excluded).
*/ */
if ( handshake->type != TLS_HELLO_REQUEST ) if ( handshake->type != TLS_HELLO_REQUEST )
tls_add_handshake ( tls, data, len ); tls_add_handshake ( tls, data,
sizeof ( *handshake ) +
payload_len );
/* Abort on failure */
if ( rc != 0 )
return rc; return rc;
/* Move to next handshake record */
data = next;
}
return 0;
} }
/** /**