diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index bb367ce9d..5e44870b6 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -382,14 +382,6 @@ struct tls_session_id { uint8_t len; }; -/** A TLS session ticket */ -struct tls_session_ticket { - /** Ticket data */ - void *data; - /** Length of ticket data */ - size_t len; -}; - /** A TLS session */ struct tls_session { /** Reference counter */ @@ -411,7 +403,7 @@ struct tls_session { /** Session ID */ struct tls_session_id id; /** Session ticket */ - struct tls_session_ticket ticket; + struct tls_cursor ticket; /** List of connections */ struct list_head conn; @@ -489,7 +481,7 @@ struct tls_connection { /** New session ID (if any) */ struct tls_session_id new_id; /** New session ticket (if any) */ - struct tls_session_ticket new_ticket; + struct tls_cursor new_ticket; /** Plaintext stream */ struct interface plainstream; diff --git a/src/net/tls.c b/src/net/tls.c index c429e8dae..dd9fb4cd2 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -295,6 +295,49 @@ tls_has_inner ( struct tls_connection *tls, struct cipher_algorithm *cipher ) { ( cipher != &cipher_null ) ); } +/** + * Duplicate content of a TLS cursor + * + * @v src Source cursor + * @v dst Destination cursor + * + * The content of the source cursor (if any) will be copied. + * + * If the source cursor is not present (e.g. because it represents an + * extension that was not present, rather than being present but + * empty) then the destination cursor will also become not present. + * + * If the source cursor is present but empty (e.g. because it + * represents an extension that was present but empty) then the + * destination cursor will also become present but empty (with its + * pointer being the sentinel value as returned by malloc(0)). + * + * If the source cursor is either empty or not present, then this + * function is guaranteed to succeed. + */ +static int tls_copy ( const struct tls_cursor *src, struct tls_cursor *dst ) { + + /* Free any existing content */ + zfree ( dst->data ); + dst->data = NULL; + dst->len = 0; + + /* Do nothing if source cursor is not present */ + if ( ! src->data ) { + assert ( src->len == 0 ); + return 0; + } + + /* Duplicate cursor */ + dst->data = malloc ( src->len ); + if ( ! dst->data ) + return -ENOMEM; + memcpy ( dst->data, src->data, src->len ); + dst->len = src->len; + + return 0; +} + /** * Get pipe name (for debugging) * @@ -2782,17 +2825,9 @@ static int tls_new_session_ticket ( struct tls_connection *tls, return 0; } - /* Free any unapplied new session ticket */ - zfree ( tls->new_ticket.data ); - tls->new_ticket.data = NULL; - tls->new_ticket.len = 0; - /* Record ticket */ - tls->new_ticket.data = malloc ( ticket.ticket.len ); - if ( ! tls->new_ticket.data ) - return -ENOMEM; - memcpy ( tls->new_ticket.data, ticket.ticket.data, ticket.ticket.len ); - tls->new_ticket.len = ticket.ticket.len; + if ( ( rc = tls_copy ( &ticket.ticket, &tls->new_ticket ) ) != 0 ) + return rc; return 0; }