[tls] Use standalone TLS data structure builder

Define structure descriptors and mappings for every data structure
currently sent by the TLS protocol engine, and use the standalone data
structure builder to remove a large amount of open-coded layout and
assembly logic.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-09-21 00:23:03 +01:00
parent 2e549711c2
commit b36e8472d4
5 changed files with 882 additions and 452 deletions
+104 -2
View File
@@ -48,16 +48,30 @@ static const char * tls_map_name ( const uint8_t *map ) {
return "Certificate";
} else if ( map == tls_certificate_entry_map ) {
return "CertificateEntry";
} else if ( map == tls_client_hello_map ) {
return "ClientHello";
} else if ( ( map == tls_client_key_exchange_dhe_map ) ||
( map == tls_client_key_exchange_ecdhe_map ) ||
( map == tls_client_key_exchange_pubkey_map ) ) {
return "ClientKeyExchange";
} else if ( map == tls_digitally_signed_map ) {
return "DigitallySigned";
} else if ( map == tls_extension_map ) {
return "Extension";
} else if ( map == tls_hello_request_map ) {
return "HelloRequest";
} else if ( map == tls_key_share_client_hello_map ) {
return "KeyShareClientHello";
} else if ( map == tls_key_share_entry_map ) {
return "KeyShareEntry";
} else if ( map == tls_max_fragment_length_map ) {
return "MaxFragmentLength";
} else if ( map == tls_named_group_list_map ) {
return "NamedGroupList";
} else if ( map == tls_new_session_ticket_map ) {
return "NewSessionTicket";
} else if ( map == tls_psk_key_exchange_modes_map ) {
return "PskKeyExchangeModes";
} else if ( map == tls_renegotiation_info_map ) {
return "RenegotiationInfo";
} else if ( map == tls_server_hello_map ) {
@@ -67,6 +81,12 @@ static const char * tls_map_name ( const uint8_t *map ) {
} else if ( ( map == tls_server_key_exchange_dhe_map ) ||
( map == tls_server_key_exchange_ecdhe_map ) ) {
return "ServerKeyExchange";
} else if ( map == tls_server_name_map ) {
return "ServerName";
} else if ( map == tls_server_name_list_map ) {
return "ServerNameList";
} else if ( map == tls_signature_scheme_list_map ) {
return "SignatureSchemeList";
} else if ( ( map == tls_supported_versions_map ) ||
( map == tls_supported_version_map ) ) {
return "SupportedVersions";
@@ -661,6 +681,45 @@ TLS_DESCR_MAPPING ( tls_certificate_entry ) = {
TLS_EXTRA ( tls_certificate_entry, TLS_VERSION_BASE, next ),
};
/** ClientHello descriptor mapping */
TLS_DESCR_MAPPING ( tls_client_hello ) = {
TLS_MAPSZ ( tls_client_hello ),
TLS_FIXED ( tls_client_hello, TLS_VERSION_BASE, a ),
TLS_VAR08 ( tls_client_hello, TLS_VERSION_BASE, session_id ),
TLS_VAR16 ( tls_client_hello, TLS_VERSION_BASE, suites ),
TLS_VAR08 ( tls_client_hello, TLS_VERSION_BASE, compression ),
TLS_EXT16 ( tls_client_hello, TLS_VERSION_BASE, ext ),
TLS_EXTND ( tls_client_hello, TLS_EXTENDED_MASTER_SECRET, ext.ems ),
TLS_EXTND ( tls_client_hello, TLS_MAX_FRAGMENT_LENGTH, ext.frag ),
TLS_EXTND ( tls_client_hello, TLS_NAMED_GROUP, ext.groups ),
TLS_EXTND ( tls_client_hello, TLS_KEY_SHARE, ext.keys ),
TLS_EXTND ( tls_client_hello, TLS_SERVER_NAME, ext.names ),
TLS_EXTND ( tls_client_hello, TLS_PSK_MODES, ext.pskmodes ),
TLS_EXTND ( tls_client_hello, TLS_RECORD_SIZE_LIMIT, ext.record ),
TLS_EXTND ( tls_client_hello, TLS_RENEGOTIATION_INFO, ext.reneg ),
TLS_EXTND ( tls_client_hello, TLS_SIGNATURE_ALGORITHMS, ext.sigs ),
TLS_EXTND ( tls_client_hello, TLS_SUPPORTED_VERSIONS, ext.supvers ),
TLS_EXTND ( tls_client_hello, TLS_SESSION_TICKET, ext.ticket ),
};
/** ClientKeyExchange descriptor mapping (for DHE) */
TLS_DESCR_MAPPING ( tls_client_key_exchange_dhe ) = {
TLS_MAPSZ ( tls_client_key_exchange_dhe ),
TLS_VAR16 ( tls_client_key_exchange_dhe, TLS_VERSION_BASE, dh_yc ),
};
/** ClientKeyExchange descriptor mapping (for ECDHE) */
TLS_DESCR_MAPPING ( tls_client_key_exchange_ecdhe ) = {
TLS_MAPSZ ( tls_client_key_exchange_ecdhe ),
TLS_VAR08 ( tls_client_key_exchange_ecdhe, TLS_VERSION_BASE, point ),
};
/** ClientKeyExchange descriptor mapping (for key transport) */
TLS_DESCR_MAPPING ( tls_client_key_exchange_pubkey ) = {
TLS_MAPSZ ( tls_client_key_exchange_pubkey ),
TLS_VAR16 ( tls_client_key_exchange_pubkey, TLS_VERSION_BASE, enc ),
};
/** DigitallySigned descriptor mapping */
TLS_DESCR_MAPPING ( tls_digitally_signed ) = {
TLS_MAPSZ ( tls_digitally_signed ),
@@ -681,6 +740,12 @@ TLS_DESCR_MAPPING ( tls_hello_request ) = {
TLS_MAPSZ ( tls_hello_request ),
};
/** KeyShareClientHello descriptor mapping */
TLS_DESCR_MAPPING ( tls_key_share_client_hello ) = {
TLS_MAPSZ ( tls_key_share_client_hello ),
TLS_VAR16 ( tls_key_share_client_hello, TLS_VERSION_BASE, list ),
};
/** KeyShareEntry descriptor mapping */
TLS_DESCR_MAPPING ( tls_key_share_entry ) = {
TLS_MAPSZ ( tls_key_share_entry ),
@@ -689,6 +754,18 @@ TLS_DESCR_MAPPING ( tls_key_share_entry ) = {
TLS_EXTRA ( tls_key_share_entry, TLS_VERSION_BASE, next ),
};
/** MaxFragmentLength descriptor mapping */
TLS_DESCR_MAPPING ( tls_max_fragment_length ) = {
TLS_MAPSZ ( tls_max_fragment_length ),
TLS_FIXED ( tls_max_fragment_length, TLS_VERSION_BASE, max ),
};
/** NamedGroupList descriptor mapping */
TLS_DESCR_MAPPING ( tls_named_group_list ) = {
TLS_MAPSZ ( tls_named_group_list ),
TLS_VAR16 ( tls_named_group_list, TLS_VERSION_BASE, list ),
};
/** NewSessionTicket descriptor mapping */
TLS_DESCR_MAPPING ( tls_new_session_ticket ) = {
TLS_MAPSZ ( tls_new_session_ticket ),
@@ -699,6 +776,12 @@ TLS_DESCR_MAPPING ( tls_new_session_ticket ) = {
TLS_EXT16 ( tls_new_session_ticket, TLS_VERSION_TLS_1_3, ext ),
};
/** PskKeyExchangeModes descriptor mapping */
TLS_DESCR_MAPPING ( tls_psk_key_exchange_modes ) = {
TLS_MAPSZ ( tls_psk_key_exchange_modes ),
TLS_VAR08 ( tls_psk_key_exchange_modes, TLS_VERSION_TLS_1_3, list ),
};
/** RenegotiationInfo descriptor mapping */
TLS_DESCR_MAPPING ( tls_renegotiation_info ) = {
TLS_MAPSZ ( tls_renegotiation_info ),
@@ -732,7 +815,7 @@ TLS_DESCR_MAPPING ( tls_server_key_exchange_dhe ) = {
TLS_EXTRA ( tls_server_key_exchange_dhe, TLS_VERSION_BASE, dsig ),
};
/** ServerKeyExchange descriptor mapping (for EcDHE) */
/** ServerKeyExchange descriptor mapping (for ECDHE) */
TLS_DESCR_MAPPING ( tls_server_key_exchange_ecdhe ) = {
TLS_MAPSZ ( tls_server_key_exchange_ecdhe ),
TLS_FIXED ( tls_server_key_exchange_ecdhe, TLS_VERSION_BASE, curve ),
@@ -740,6 +823,25 @@ TLS_DESCR_MAPPING ( tls_server_key_exchange_ecdhe ) = {
TLS_EXTRA ( tls_server_key_exchange_ecdhe, TLS_VERSION_BASE, dsig ),
};
/** ServerName descriptor mapping */
TLS_DESCR_MAPPING ( tls_server_name ) = {
TLS_MAPSZ ( tls_server_name ),
TLS_FIXED ( tls_server_name, TLS_VERSION_BASE, type ),
TLS_VAR16 ( tls_server_name, TLS_VERSION_BASE, name ),
};
/** ServerNameList descriptor mapping */
TLS_DESCR_MAPPING ( tls_server_name_list ) = {
TLS_MAPSZ ( tls_server_name_list ),
TLS_VAR16 ( tls_server_name_list, TLS_VERSION_BASE, list ),
};
/** SignatureSchemeList descriptor mapping */
TLS_DESCR_MAPPING ( tls_signature_scheme_list ) = {
TLS_MAPSZ ( tls_signature_scheme_list ),
TLS_VAR16 ( tls_signature_scheme_list, TLS_VERSION_BASE, list ),
};
/** SupportedVersions descriptor mapping (in ServerHello) */
TLS_DESCR_MAPPING ( tls_supported_version ) = {
TLS_MAPSZ ( tls_supported_version ),
@@ -749,5 +851,5 @@ TLS_DESCR_MAPPING ( tls_supported_version ) = {
/** SupportedVersions descriptor mapping (in ClientHello) */
TLS_DESCR_MAPPING ( tls_supported_versions ) = {
TLS_MAPSZ ( tls_supported_versions ),
TLS_VAR08 ( tls_supported_versions, TLS_VERSION_BASE, versions ),
TLS_VAR08 ( tls_supported_versions, TLS_VERSION_BASE, list ),
};
+8 -2
View File
@@ -179,12 +179,18 @@ union tls_server_random {
/* TLS extended master secret extension */
#define TLS_EXTENDED_MASTER_SECRET 23
/* TLS record size limit extension */
#define TLS_RECORD_SIZE_LIMIT 28
/* TLS session ticket extension */
#define TLS_SESSION_TICKET 35
/* TLS supported versions extension */
#define TLS_SUPPORTED_VERSIONS 43
/* TLS pre-shared key modes extension */
#define TLS_PSK_MODES 45
/* TLS key share extension */
#define TLS_KEY_SHARE 51
@@ -242,8 +248,8 @@ struct tls_key_exchange_algorithm {
int ( * parse ) ( struct tls_connection *tls,
const struct tls_cursor *cursor,
struct tls_key_exchange_parameters *kex );
/** Length of length field in Client Key Exchange record */
uint8_t len_len;
/** ClientKeyExchange descriptor mapping */
const uint8_t *map;
};
/**
+137 -6
View File
@@ -409,6 +409,82 @@ struct tls_certificate_entry {
struct tls_cursor next;
};
/** ClientHello descriptor */
struct tls_client_hello {
/** Fixed portion */
struct {
/** Offered version */
uint16_t version;
/** Client random bytes */
uint8_t random[32];
} __attribute__ (( packed )) *a;
/** Session ID */
struct tls_cursor session_id;
/** Cipher suites */
struct tls_cursor suites;
/** Compression methods */
struct tls_cursor compression;
/** Extensions of interest */
struct {
/** All extensions */
struct tls_cursor all;
/** Extended master secret extension */
struct tls_cursor ems;
/** Maximum fragment length extension */
struct tls_cursor frag;
/** Supported groups extension */
struct tls_cursor groups;
/** Key share extension */
struct tls_cursor keys;
/** Server name indication extension */
struct tls_cursor names;
/** Preshared key modes extension */
struct tls_cursor pskmodes;
/** Record size limit extension */
struct tls_cursor record;
/** Renegotiation information extension */
struct tls_cursor reneg;
/** Signature algorithms extension */
struct tls_cursor sigs;
/** Supported versions extension */
struct tls_cursor supvers;
/** Session ticket extension */
struct tls_cursor ticket;
} ext;
};
/** ClientKeyExchange descriptor (for DHE) */
struct tls_client_key_exchange_dhe {
/** Public key */
struct tls_cursor dh_yc;
};
/** ClientKeyExchange descriptor (for ECDHE) */
struct tls_client_key_exchange_ecdhe {
/** Curve point */
struct tls_cursor point;
};
/** ClientKeyExchange descriptor (for key transport) */
struct tls_client_key_exchange_pubkey {
/** Encrypted pre-master secret */
struct tls_cursor enc;
};
/** ClientKeyExchange descriptor (unified) */
union tls_client_key_exchange {
/** ClientKeyExchange descriptor (common format) */
struct tls_cursor cursor;
/** ClientKeyExchange descriptor (for key transport) */
struct tls_client_key_exchange_pubkey pubkey;
/** ClientKeyExchange descriptor (for DHE) */
struct tls_client_key_exchange_dhe dhe;
/** ClientKeyExchange descriptor (for ECDHE) */
struct tls_client_key_exchange_ecdhe ecdhe;
/** Raw pointer/length array */
union tls_ptr_len desc[0];
};
/** DigitallySigned descriptor */
struct tls_digitally_signed {
/** Signature and hash algorithm */
@@ -430,6 +506,12 @@ struct tls_extension {
/** HelloRequest descriptor */
struct tls_hello_request {};
/** KeyShareClientHello descriptor */
struct tls_key_share_client_hello {
/** Key share list */
struct tls_cursor list;
};
/** KeyShareEntry descriptor */
struct tls_key_share_entry {
/** Named group */
@@ -440,6 +522,18 @@ struct tls_key_share_entry {
struct tls_cursor next;
};
/** MaxFragmentLength descriptor */
struct tls_max_fragment_length {
/** Maximum fragment length */
uint8_t *max;
};
/** NamedGroupList descriptor */
struct tls_named_group_list {
/** Named group list */
struct tls_cursor list;
};
/** NewSessionTicket descriptor */
struct tls_new_session_ticket {
/** Lifetime hint */
@@ -457,6 +551,12 @@ struct tls_new_session_ticket {
} ext;
};
/** PskKeyExchangeModes descriptor */
struct tls_psk_key_exchange_modes {
/** Mode list */
struct tls_cursor list;
};
/** RenegotiationInfo descriptor */
struct tls_renegotiation_info {
/** Verification data from previous Finished */
@@ -477,9 +577,9 @@ struct tls_server_hello {
/** Second fixed-length portion */
struct {
/** Selected cipher suite */
uint16_t cipher_suite;
uint16_t suite;
/** Selected compression method */
uint8_t compression_method;
uint8_t compression;
} __attribute__ (( packed )) *b;
/** Extensions of interest */
struct {
@@ -489,9 +589,9 @@ struct tls_server_hello {
struct tls_cursor reneg;
/** Extended master secret extension */
struct tls_cursor ems;
/** Supported version */
/** Supported versions extension */
struct tls_cursor supver;
/** Key share */
/** Key share extension */
struct tls_cursor key;
} ext;
};
@@ -526,6 +626,26 @@ struct tls_server_key_exchange_ecdhe {
struct tls_cursor dsig;
};
/** ServerName descriptor */
struct tls_server_name {
/** Name type */
uint8_t *type;
/** Host name */
struct tls_cursor name;
};
/** ServerNameList descriptor */
struct tls_server_name_list {
/** Server name list */
struct tls_cursor list;
};
/** SignatureSchemeList descriptor */
struct tls_signature_scheme_list {
/** Supported signature algorithm list */
struct tls_cursor list;
};
/** SupportedVersions descriptor (in ServerHello) */
struct tls_supported_version {
/** Selected version */
@@ -534,8 +654,8 @@ struct tls_supported_version {
/** SupportedVersions descriptor (in ClientHello) */
struct tls_supported_versions {
/** Supported versions */
struct tls_cursor versions;
/** Supported version list */
struct tls_cursor list;
};
/**
@@ -633,16 +753,27 @@ extern int tls_size_map ( const uint8_t *map, unsigned int version,
extern TLS_DESCR_MAPPING ( tls_certificate );
extern TLS_DESCR_MAPPING ( tls_certificate_entry );
extern TLS_DESCR_MAPPING ( tls_client_hello );
extern TLS_DESCR_MAPPING ( tls_client_key_exchange_dhe );
extern TLS_DESCR_MAPPING ( tls_client_key_exchange_ecdhe );
extern TLS_DESCR_MAPPING ( tls_client_key_exchange_pubkey );
extern TLS_DESCR_MAPPING ( tls_digitally_signed );
extern TLS_DESCR_MAPPING ( tls_extension );
extern TLS_DESCR_MAPPING ( tls_hello_request );
extern TLS_DESCR_MAPPING ( tls_key_share_client_hello );
extern TLS_DESCR_MAPPING ( tls_key_share_entry );
extern TLS_DESCR_MAPPING ( tls_max_fragment_length );
extern TLS_DESCR_MAPPING ( tls_named_group_list );
extern TLS_DESCR_MAPPING ( tls_new_session_ticket );
extern TLS_DESCR_MAPPING ( tls_psk_key_exchange_modes );
extern TLS_DESCR_MAPPING ( tls_renegotiation_info );
extern TLS_DESCR_MAPPING ( tls_server_hello );
extern TLS_DESCR_MAPPING ( tls_server_hello_done );
extern TLS_DESCR_MAPPING ( tls_server_key_exchange_dhe );
extern TLS_DESCR_MAPPING ( tls_server_key_exchange_ecdhe );
extern TLS_DESCR_MAPPING ( tls_server_name );
extern TLS_DESCR_MAPPING ( tls_server_name_list );
extern TLS_DESCR_MAPPING ( tls_signature_scheme_list );
extern TLS_DESCR_MAPPING ( tls_supported_version );
extern TLS_DESCR_MAPPING ( tls_supported_versions );
+414 -428
View File
File diff suppressed because it is too large Load Diff
+219 -14
View File
@@ -258,6 +258,66 @@ static uint8_t server_key_exchange_sig[] = {
0x02, 0x07, 0x2e
};
/** Reference TLSv1.3 ClientHello (from RFC 8448) */
static uint8_t tls13_client_hello[] = {
0x03, 0x03, 0xcb, 0x34, 0xec, 0xb1, 0xe7, 0x81, 0x63, 0xba, 0x1c,
0x38, 0xc6, 0xda, 0xcb, 0x19, 0x6a, 0x6d, 0xff, 0xa2, 0x1a, 0x8d,
0x99, 0x12, 0xec, 0x18, 0xa2, 0xef, 0x62, 0x83, 0x02, 0x4d, 0xec,
0xe7, 0x00, 0x00, 0x06, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02, 0x01,
0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x00,
0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0xff, 0x01, 0x00, 0x01,
0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x17,
0x00, 0x18, 0x00, 0x19, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01,
0x03, 0x01, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x33, 0x00, 0x26,
0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x99, 0x38, 0x1d, 0xe5, 0x60,
0xe4, 0xbd, 0x43, 0xd2, 0x3d, 0x8e, 0x43, 0x5a, 0x7d, 0xba, 0xfe,
0xb3, 0xc0, 0x6e, 0x51, 0xc1, 0x3c, 0xae, 0x4d, 0x54, 0x13, 0x69,
0x1e, 0x52, 0x9a, 0xaf, 0x2c, 0x00, 0x2b, 0x00, 0x03, 0x02, 0x03,
0x04, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x1e, 0x04, 0x03, 0x05, 0x03,
0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x04,
0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x05, 0x02,
0x06, 0x02, 0x02, 0x02, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00,
0x1c, 0x00, 0x02, 0x40, 0x01
};
/** TLSv1.3 ClientHello random bytes */
static uint8_t tls13_client_hello_random[] = {
0xcb, 0x34, 0xec, 0xb1, 0xe7, 0x81, 0x63, 0xba, 0x1c, 0x38, 0xc6,
0xda, 0xcb, 0x19, 0x6a, 0x6d, 0xff, 0xa2, 0x1a, 0x8d, 0x99, 0x12,
0xec, 0x18, 0xa2, 0xef, 0x62, 0x83, 0x02, 0x4d, 0xec, 0xe7
};
/** TLSv1.3 ClientHello cipher suites */
static uint8_t tls13_client_hello_suites[] = {
0x13, 0x01, 0x13, 0x03, 0x13, 0x02
};
/** TLSv1.3 ClientHello supported groups */
static uint8_t tls13_client_hello_groups[] = {
0x00, 0x12, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01,
0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04
};
/** TLSv1.3 ClientHello public key */
static uint8_t tls13_client_hello_public[] = {
0x99, 0x38, 0x1d, 0xe5, 0x60, 0xe4, 0xbd, 0x43, 0xd2, 0x3d, 0x8e,
0x43, 0x5a, 0x7d, 0xba, 0xfe, 0xb3, 0xc0, 0x6e, 0x51, 0xc1, 0x3c,
0xae, 0x4d, 0x54, 0x13, 0x69, 0x1e, 0x52, 0x9a, 0xaf, 0x2c
};
/** TLSv1.3 ClientHello signature algorithms */
static uint8_t tls13_client_hello_sigs[] = {
0x00, 0x1e, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08,
0x04, 0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01,
0x02, 0x01, 0x04, 0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02
};
/** TLSv1.3 ClientHello supported version */
static uint8_t tls13_client_hello_supvers[] = { 0x03, 0x04 };
/** TLSv1.3 ClientHello pre-shared key modes */
static uint8_t tls13_client_hello_pskmodes[] = { 0x01 };
/** Space for test data */
union tlsfmt_test_data {
uint8_t tls13_server_hello[ sizeof ( tls13_server_hello ) + 1 ];
@@ -268,8 +328,54 @@ union tlsfmt_test_data {
[ sizeof ( tls12_server_key_exchange_ecdhe ) ];
uint8_t tls11_server_key_exchange_ecdhe
[ sizeof ( tls11_server_key_exchange_ecdhe ) ];
uint8_t tls13_client_hello[ sizeof ( tls13_client_hello ) ];
};
/**
* Report a cursor comparison test result
*
* @v cursor Cursor
* @v reference Reference cursor
* @v file Test code file
* @v line Test code line
*/
static void cursor_okx ( struct tls_cursor *cursor,
struct tls_cursor *reference,
const char *file, unsigned int line ) {
/* Compare cursors */
okx ( cursor->len == reference->len, file, line );
okx ( memcmp ( cursor->data, reference->data, reference->len ) == 0,
file, line );
}
#define cursor_ok( cursor, reference ) \
cursor_okx ( (cursor), (reference), __FILE__, __LINE__ )
/**
* Report a pre-extensions comparison test result
*
* @v data Data
* @v ext Extensions
* @v reference Reference data
* @v reference_ext Reference extensions
* @v file Test code file
* @v line Test code line
*/
static void pre_ext_okx ( const void *data, struct tls_cursor *extensions,
const void *reference,
struct tls_cursor *reference_ext,
const char *file, unsigned int line ) {
size_t reference_len = ( reference_ext->data - reference );
size_t len = ( extensions->data - data );
/* Compare cursors */
okx ( len == reference_len, file, line );
okx ( memcmp ( data, reference, reference_len ) == 0, file, line );
}
#define pre_ext_ok( data, ext, reference, reference_ext ) \
pre_ext_okx ( (data), (ext), (reference), (reference_ext), \
__FILE__, __LINE__ )
/**
* Perform TLS data format self-test
*
@@ -277,19 +383,28 @@ union tlsfmt_test_data {
static void tlsfmt_test_exec ( void ) {
union tlsfmt_test_data u;
struct tls_cursor cursor;
struct tls_client_hello client_hello;
struct tls_client_hello client_hello_ref;
struct tls_server_hello server_hello;
struct tls_server_hello server_hello_ref;
struct tls_supported_version supported_version;
struct tls_supported_versions supported_versions;
struct tls_key_share_entry key_share_entry;
struct tls_key_share_client_hello key_share_client_hello;
struct tls_certificate certificate;
struct tls_certificate_entry certificate_entry;
struct tls_server_key_exchange_ecdhe server_key_exchange_ecdhe;
struct tls_digitally_signed digitally_signed;
struct tls_server_name server_name;
struct tls_server_name_list server_name_list;
struct tls_psk_key_exchange_modes psk_key_exchange_modes;
struct x509_certificate *tls13_cert;
struct x509_certificate *tls12_cert;
unsigned int offset;
uint16_t __attribute__ (( aligned ( 1 ) )) *tmp16;
uint16_t group;
uint16_t record;
uint8_t empty[0];
/* Well-formed TLSv1.3 ServerHello */
memset ( u.tls13_server_hello, 0xaa, sizeof ( u.tls13_server_hello ) );
@@ -302,8 +417,7 @@ static void tlsfmt_test_exec ( void ) {
ok ( server_hello.a->version == htons ( TLS_VERSION_TLS_1_2 ) );
ok ( server_hello.session_id.data != NULL );
ok ( server_hello.session_id.len == 0 );
ok ( server_hello.b->cipher_suite ==
htons ( TLS_AES_128_GCM_SHA256 ) );
ok ( server_hello.b->suite == htons ( TLS_AES_128_GCM_SHA256 ) );
ok ( server_hello.ext.reneg.data == NULL );
ok ( server_hello.ext.ems.data == NULL );
ok ( server_hello.ext.supver.data != NULL );
@@ -512,7 +626,7 @@ static void tlsfmt_test_exec ( void ) {
server_hello.a->version = htons ( TLS_VERSION_TLS_1_2 );
memcpy ( server_hello.a->random, tls13_server_hello_random,
sizeof ( server_hello.a->random ) );
server_hello.b->cipher_suite = htons ( TLS_AES_128_GCM_SHA256 );
server_hello.b->suite = htons ( TLS_AES_128_GCM_SHA256 );
ok ( tls_build ( tls_key_share_entry, TLS_VERSION_TLS_1_3,
&key_share_entry, &server_hello.ext.key ) == 0 );
ok ( tls_build ( tls_supported_version, TLS_VERSION_TLS_1_3,
@@ -527,17 +641,10 @@ static void tlsfmt_test_exec ( void ) {
cursor.len = sizeof ( tls13_server_hello );
ok ( tls_parse ( tls_server_hello, TLS_VERSION_TLS_1_3,
&cursor, &server_hello_ref ) == 0 );
ok ( server_hello.ext.supver.len == server_hello_ref.ext.supver.len );
ok ( server_hello.ext.key.len == server_hello_ref.ext.key.len );
ok ( memcmp ( u.tls13_server_hello, tls13_server_hello,
( server_hello.ext.all.data -
( ( void * ) u.tls13_server_hello ) ) ) == 0 );
ok ( memcmp ( server_hello.ext.supver.data,
server_hello_ref.ext.supver.data,
server_hello_ref.ext.supver.len ) == 0 );
ok ( memcmp ( server_hello.ext.key.data,
server_hello_ref.ext.key.data,
server_hello_ref.ext.key.len ) == 0 );
pre_ext_ok ( u.tls13_server_hello, &server_hello.ext.all,
tls13_server_hello, &server_hello_ref.ext.all );
cursor_ok ( &server_hello.ext.supver, &server_hello_ref.ext.supver );
cursor_ok ( &server_hello.ext.key, &server_hello_ref.ext.key );
/* Build TLSv1.2 ServerKeyExchange */
memset ( &digitally_signed, 0, sizeof ( digitally_signed ) );
@@ -608,6 +715,104 @@ static void tlsfmt_test_exec ( void ) {
tls11_server_key_exchange_ecdhe,
sizeof ( tls11_server_key_exchange_ecdhe ) ) == 0 );
/* Build TLSv1.3 ClientHello */
memset ( &server_name, 0, sizeof ( server_name ) );
memset ( &server_name_list, 0, sizeof ( server_name_list ) );
memset ( &key_share_entry, 0, sizeof ( key_share_entry ) );
memset ( &key_share_client_hello, 0,
sizeof ( key_share_client_hello ) );
memset ( &supported_versions, 0, sizeof ( supported_versions ) );
memset ( &psk_key_exchange_modes, 0,
sizeof ( psk_key_exchange_modes ) );
memset ( &client_hello, 0, sizeof ( client_hello ) );
server_name.name.data = "server";
server_name.name.len = strlen ( server_name.name.data );
ok ( tls_size ( tls_server_name, TLS_VERSION_TLS_1_3,
&server_name, &server_name_list.list ) == 0 );
ok ( tls_size ( tls_server_name_list, TLS_VERSION_TLS_1_3,
&server_name_list, &client_hello.ext.names ) == 0 );
group = htons ( TLS_NAMED_GROUP_X25519 );
key_share_entry.group = &group;
key_share_entry.public.data = tls13_client_hello_public;
key_share_entry.public.len = sizeof ( tls13_client_hello_public );
ok ( tls_size ( tls_key_share_entry, TLS_VERSION_TLS_1_3,
&key_share_entry,
&key_share_client_hello.list ) == 0 );
ok ( tls_size ( tls_key_share_client_hello, TLS_VERSION_TLS_1_3,
&key_share_client_hello,
&client_hello.ext.keys ) == 0 );
supported_versions.list.data = tls13_client_hello_supvers;
supported_versions.list.len = sizeof ( tls13_client_hello_supvers );
ok ( tls_size ( tls_supported_versions, TLS_VERSION_TLS_1_3,
&supported_versions,
&client_hello.ext.supvers ) == 0 );
psk_key_exchange_modes.list.data = tls13_client_hello_pskmodes;
psk_key_exchange_modes.list.len =
sizeof ( tls13_client_hello_pskmodes );
ok ( tls_size ( tls_psk_key_exchange_modes, TLS_VERSION_TLS_1_3,
&psk_key_exchange_modes,
&client_hello.ext.pskmodes ) == 0 );
client_hello.suites.data = tls13_client_hello_suites;
client_hello.suites.len = sizeof ( tls13_client_hello_suites );
client_hello.compression.len = 1;
client_hello.ext.reneg.len = 1;
client_hello.ext.groups.data = tls13_client_hello_groups;
client_hello.ext.groups.len = sizeof ( tls13_client_hello_groups );
client_hello.ext.ticket.data = empty;
client_hello.ext.sigs.data = tls13_client_hello_sigs;
client_hello.ext.sigs.len = sizeof ( tls13_client_hello_sigs );
record = htons ( 0x4001 );
client_hello.ext.record.data = &record;
client_hello.ext.record.len = sizeof ( record );
ok ( tls_size ( tls_client_hello, TLS_VERSION_TLS_1_3,
&client_hello, &cursor ) == 0 );
ok ( cursor.len == sizeof ( tls13_client_hello ) );
cursor.data = u.tls13_client_hello;
ok ( tls_build ( tls_client_hello, TLS_VERSION_TLS_1_3,
&client_hello, &cursor ) == 0 );
client_hello.a->version = htons ( TLS_VERSION_TLS_1_2 );
ok ( tls_build ( tls_server_name_list, TLS_VERSION_TLS_1_3,
&server_name_list, &client_hello.ext.names ) == 0 );
ok ( tls_build ( tls_server_name, TLS_VERSION_TLS_1_3,
&server_name, &server_name_list.list ) == 0 );
ok ( tls_build ( tls_key_share_client_hello, TLS_VERSION_TLS_1_3,
&key_share_client_hello,
&client_hello.ext.keys ) == 0 );
ok ( tls_build ( tls_key_share_entry, TLS_VERSION_TLS_1_3,
&key_share_entry,
&key_share_client_hello.list ) == 0 );
ok ( tls_build ( tls_supported_versions, TLS_VERSION_TLS_1_3,
&supported_versions,
&client_hello.ext.supvers ) == 0 );
ok ( tls_build ( tls_psk_key_exchange_modes, TLS_VERSION_TLS_1_3,
&psk_key_exchange_modes,
&client_hello.ext.pskmodes ) == 0 );
memcpy ( client_hello.a->random, tls13_client_hello_random,
sizeof ( client_hello.a->random ) );
DBGC ( &cursor, "TLSFMT built TLSv1.3 ClientHello:\n" );
DBGC_HDA ( &cursor, 0, cursor.data, cursor.len );
DBGC ( &cursor, "TLSFMT reference TLSv1.3 ClientHello:\n" );
DBGC_HDA ( &cursor, 0, tls13_client_hello,
sizeof ( tls13_client_hello ) );
cursor.data = tls13_client_hello;
cursor.len = sizeof ( tls13_client_hello );
ok ( tls_parse ( tls_client_hello, TLS_VERSION_TLS_1_3,
&cursor, &client_hello_ref ) == 0 );
pre_ext_ok ( u.tls13_client_hello, &client_hello.ext.all,
tls13_client_hello, &client_hello_ref.ext.all );
cursor_ok ( &client_hello.ext.ems, &client_hello_ref.ext.ems );
cursor_ok ( &client_hello.ext.frag, &client_hello_ref.ext.frag );
cursor_ok ( &client_hello.ext.groups, &client_hello_ref.ext.groups );
cursor_ok ( &client_hello.ext.keys, &client_hello_ref.ext.keys );
cursor_ok ( &client_hello.ext.names, &client_hello_ref.ext.names );
cursor_ok ( &client_hello.ext.pskmodes,
&client_hello_ref.ext.pskmodes );
cursor_ok ( &client_hello.ext.record, &client_hello_ref.ext.record );
cursor_ok ( &client_hello.ext.reneg, &client_hello_ref.ext.reneg );
cursor_ok ( &client_hello.ext.sigs, &client_hello_ref.ext.sigs );
cursor_ok ( &client_hello.ext.supvers, &client_hello_ref.ext.supvers );
cursor_ok ( &client_hello.ext.ticket, &client_hello_ref.ext.ticket );
/* Propagation of sizing errors */
memset ( &digitally_signed, 0, sizeof ( digitally_signed ) );
memset ( &server_key_exchange_ecdhe, 0,