iPXE
tlsfmt.c File Reference

TLS data formats. More...

#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/tls.h>
#include <ipxe/tlsfmt.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static const char * tls_map_name (const uint8_t *map)
 Get data structure descriptor mapping name (for debugging).
static int tls_parse_extensions (const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
 Parse TLS extensions within a data structure.
int tls_parse_map (const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
 Parse TLS data structure.
int tls_parse_opt_map (const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
 Parse optional TLS data structure.
static int tls_build_extensions (const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
 Build TLS extensions within a data structure.
int tls_build_map (const uint8_t *map, unsigned int version, union tls_ptr_len *desc, struct tls_cursor *cursor)
 Build TLS data structure.
 TLS_DESCR_MAPPING (tls_certificate)
 Certificate descriptor mapping.
 TLS_DESCR_MAPPING (tls_certificate_entry)
 CertificateEntry descriptor mapping.
 TLS_DESCR_MAPPING (tls_digitally_signed)
 DigitallySigned descriptor mapping.
 TLS_DESCR_MAPPING (tls_extension)
 Extension descriptor mapping.
 TLS_DESCR_MAPPING (tls_hello_request)
 HelloRequest descriptor mapping.
 TLS_DESCR_MAPPING (tls_key_share_entry)
 KeyShareEntry descriptor mapping.
 TLS_DESCR_MAPPING (tls_new_session_ticket)
 NewSessionTicket descriptor mapping.
 TLS_DESCR_MAPPING (tls_renegotiation_info)
 RenegotiationInfo descriptor mapping.
 TLS_DESCR_MAPPING (tls_server_hello)
 ServerHello descriptor mapping.
 TLS_DESCR_MAPPING (tls_server_hello_done)
 ServerHello descriptor mapping.
 TLS_DESCR_MAPPING (tls_server_key_exchange_dhe)
 ServerKeyExchange descriptor mapping (for DHE).
 TLS_DESCR_MAPPING (tls_server_key_exchange_ecdhe)
 ServerKeyExchange descriptor mapping (for EcDHE).
 TLS_DESCR_MAPPING (tls_supported_version)
 SupportedVersions descriptor mapping (in ServerHello).
 TLS_DESCR_MAPPING (tls_supported_versions)
 SupportedVersions descriptor mapping (in ClientHello).

Detailed Description

TLS data formats.

Definition in file tlsfmt.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ tls_map_name()

const char * tls_map_name ( const uint8_t * map)
static

Get data structure descriptor mapping name (for debugging).

Parameters
mapData structure descriptor mapping
Return values
nameData structure name

Definition at line 45 of file tlsfmt.c.

45 {
46
47 if ( map == tls_certificate_map ) {
48 return "Certificate";
49 } else if ( map == tls_certificate_entry_map ) {
50 return "CertificateEntry";
51 } else if ( map == tls_digitally_signed_map ) {
52 return "DigitallySigned";
53 } else if ( map == tls_extension_map ) {
54 return "Extension";
55 } else if ( map == tls_hello_request_map ) {
56 return "HelloRequest";
57 } else if ( map == tls_key_share_entry_map ) {
58 return "KeyShareEntry";
59 } else if ( map == tls_new_session_ticket_map ) {
60 return "NewSessionTicket";
61 } else if ( map == tls_renegotiation_info_map ) {
62 return "RenegotiationInfo";
63 } else if ( map == tls_server_hello_map ) {
64 return "ServerHello";
65 } else if ( map == tls_server_hello_done_map ) {
66 return "ServerHelloDone";
67 } else if ( ( map == tls_server_key_exchange_dhe_map ) ||
68 ( map == tls_server_key_exchange_ecdhe_map ) ) {
69 return "ServerKeyExchange";
70 } else if ( ( map == tls_supported_versions_map ) ||
71 ( map == tls_supported_version_map ) ) {
72 return "SupportedVersions";
73 } else {
74 return "<UNKNOWN>";
75 }
76}
static __always_inline int struct dma_mapping * map
Definition dma.h:184

References map.

Referenced by tls_build_extensions(), tls_build_map(), tls_parse_extensions(), tls_parse_map(), and tls_parse_opt_map().

◆ tls_parse_extensions()

int tls_parse_extensions ( const uint8_t * map,
unsigned int index,
struct tls_cursor * fields,
unsigned int count )
static

Parse TLS extensions within a data structure.

Parameters
mapData structure descriptor mapping
indexCurrent index within mapping
fieldsExtensions data fields
countNumber of extensions
Return values
rcReturn status code

Definition at line 87 of file tlsfmt.c.

89 {
90 const uint16_t __attribute__ (( aligned ( 1 ) )) *invtypes;
91 const struct tls_cursor *cursor = &fields[0];
92 struct tls_extension extension;
93 unsigned int i;
95 int rc;
96
97 /* Extension types are encoded as inverted */
98 invtypes = ( ( const void * ) &map[index] );
99 for ( i = 1 ; i <= count ; i++ ) {
100 if ( ! invtypes[i] ) {
101 DBGC ( map, "TLSFMT %s #%d mapping missing extension "
102 "%d\n", tls_map_name ( map ), index, i );
103 return -EINVAL;
104 }
105 }
106
107 /* Parse extensions */
108 for ( ; cursor->len ; cursor = &extension.next ) {
109
110 /* Parse next extension */
112 cursor, &extension ) ) != 0 )
113 return rc;
114
115 /* Scan for matching extensions */
116 for ( i = 1 ; i <= count ; i++ ) {
117 type = ~invtypes[i];
118 if ( type != *(extension.type) )
119 continue;
120 if ( fields[i].data ) {
121 DBGC ( map, "TLSFMT %s #%d has duplicate "
122 "extension %#04x\n",
124 ntohs ( type ) );
125 return -EPROTO;
126 }
127 fields[i].data = extension.data.data;
128 fields[i].len = extension.data.len;
129 DBGC2 ( map, "TLSFMT %s #%d extension %#04x len "
130 "%zd\n", tls_map_name ( map ), index,
131 ntohs ( type ), fields[i].len );
132 DBGC2_HDA ( map, 0, fields[i].data, fields[i].len );
133 }
134 }
135
136 return 0;
137}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
long index
Definition bigint.h:30
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EPROTO
Protocol error.
Definition errno.h:668
#define ntohs(value)
Definition byteswap.h:137
#define __attribute__(x)
Definition compiler.h:10
A TLS variable-length data cursor.
Definition tlsfmt.h:186
void * data
Data.
Definition tlsfmt.h:188
size_t len
Length of data.
Definition tlsfmt.h:190
Extension descriptor.
Definition tlsfmt.h:421
static const char * tls_map_name(const uint8_t *map)
Get data structure descriptor mapping name (for debugging).
Definition tlsfmt.c:45
#define tls_parse(type, version, cursor, desc)
Parse TLS data structure.
Definition tlsfmt.h:597
#define TLS_VERSION_BASE
Lowest configurable supported version.
Definition tlsfmt.h:183

References __attribute__, count, data, tls_cursor::data, tls_extension::data, DBGC, DBGC2, DBGC2_HDA, EINVAL, EPROTO, index, len, tls_cursor::len, map, tls_extension::next, ntohs, rc, tls_map_name(), tls_parse, TLS_VERSION_BASE, tls_extension::type, and type.

Referenced by tls_parse_map().

◆ tls_parse_map()

int tls_parse_map ( const uint8_t * map,
unsigned int version,
const struct tls_cursor * cursor,
union tls_ptr_len * desc )

Parse TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 148 of file tlsfmt.c.

150 {
151 struct tls_cursor *field;
152 void *data;
153 size_t remaining;
154 unsigned int count;
155 unsigned int index;
156 unsigned int next;
157 unsigned int byte;
158 unsigned int minimum;
159 unsigned int len_len;
160 unsigned int len;
161 int fixed;
162 int exts;
163 int rc;
164
165 /* Read initial cursor (may overlap output data structure) */
166 data = cursor->data;
167 remaining = cursor->len;
168 DBGC2 ( map, "TLSFMT %s parsing len %zd\n",
169 tls_map_name ( map ), remaining );
170 DBGC2_HDA ( map, 0, data, remaining );
171
172 /* Get mapping length */
173 count = map[0];
174 if ( ! count ) {
175 DBGC ( map, "TLSFMT %s mapping has no count\n",
176 tls_map_name ( map ) );
177 return -EINVAL;
178 }
179
180 /* Clear data structure descriptor */
181 memset ( desc, 0, ( ( count - 1 ) * sizeof ( desc[0] ) ) );
182
183 /* Parse data via mapping */
184 for ( index = 1 ; ( next = index ) < count ; index = next ) {
185
186 /* Prepare to store field description */
187 field = container_of ( &desc[ index - 1 ].data,
188 struct tls_cursor, data );
189
190 /* Interpret byte as `llllllvv` */
191 byte = map[next++];
192 minimum = TLS_MAP_MIN ( byte );
193 fixed = TLS_MAP_FIXED ( byte );
194 if ( fixed < 0 ) {
195 DBGC ( map, "TLSFMT %s #%d mapping missing\n",
196 tls_map_name ( map ), index );
197 return -EINVAL;
198 }
199 assert ( next <= count );
200
201 /* Handle fixed-length fields */
202 if ( fixed ) {
203 if ( version < minimum ) {
204 DBGC2 ( map, "TLSFMT %s #%d not in version "
205 "%d.%d\n", tls_map_name ( map ),
206 index, ( version >> 8 ),
207 ( version & 0xff ) );
208 continue;
209 }
210 if ( ( ( size_t ) fixed ) > remaining ) {
211 DBGC ( map, "TLSFMT %s #%d too short for "
212 "fixed length %d:\n",
213 tls_map_name ( map ), index, fixed );
214 DBGC_HDA ( map, 0, data, remaining );
215 return -EPROTO;
216 }
217 field->data = data;
218 DBGC2 ( map, "TLSFMT %s #%d len %d\n",
219 tls_map_name ( map ), index, fixed );
220 DBGC2_HDA ( map, 0, field->data, fixed );
221 data += fixed;
222 remaining -= fixed;
223 continue;
224 }
225
226 /* Interpret next byte as `xxxxxxnn` */
227 if ( next >= count ) {
228 DBGC ( map, "TLSFMT %s #%d mapping overrun\n",
229 tls_map_name ( map ), index );
230 return -EINVAL;
231 }
232 byte = map[next++];
233 len_len = TLS_MAP_LEN_LEN ( byte );
234 exts = TLS_MAP_EXTENSIONS ( byte );
235 if ( exts >= 0 )
236 next += ( exts * 2 );
237 if ( next > count ) {
238 DBGC ( map, "TLSFMT %s #%d mapping extensions "
239 "overrun\n", tls_map_name ( map ), index );
240 return -EINVAL;
241 }
242 if ( version < minimum ) {
243 DBGC2 ( map, "TLSFMT %s #%d not in version %d.%d\n",
244 tls_map_name ( map ), index, ( version >> 8 ),
245 ( version & 0xff ) );
246 continue;
247 }
248
249 /* Allow for optional extensions fields */
250 if ( ( exts >= 0 ) && ( ! remaining ) &&
252 DBGC2 ( map, "TLSFMT %s #%d optional in version "
253 "%d.%d\n", tls_map_name ( map ), index,
254 ( version >> 8 ), ( version & 0xff ) );
255 continue;
256 }
257
258 /* Handle variable-length fields */
259 if ( remaining < len_len ) {
260 DBGC ( map, "TLSFMT %s #%d too short for %d-byte "
261 "variable length:\n", tls_map_name ( map ),
262 index, len_len );
263 DBGC_HDA ( map, 0, data, remaining );
264 return -EPROTO;
265 }
266 if ( len_len ) {
267 for ( len = 0 ; len_len ; len_len-- ) {
268 len <<= 8;
269 len |= *( ( const uint8_t * ) data++ );
270 remaining--;
271 }
272 } else {
273 len = remaining;
274 }
275 if ( remaining < len ) {
276 DBGC ( map, "TLSFMT %s #%d too short for variable "
277 "length %d:\n",
278 tls_map_name ( map ), index, len );
279 DBGC_HDA ( map, 0, data, remaining );
280 return -EPROTO;
281 }
282 field->data = data;
283 field->len = len;
284 DBGC2 ( map, "TLSFMT %s #%d len %zd\n",
285 tls_map_name ( map ), index, field->len );
286 DBGC2_HDA ( map, 0, field->data, field->len );
287 data += len;
288 remaining -= len;
289 if ( exts < 0 )
290 continue;
291
292 /* Handle fields containing extensions */
293 if ( ( rc = tls_parse_extensions ( map, index, field,
294 exts ) ) != 0 ) {
295 return rc;
296 }
297 }
298
299 /* Check that all data was consumed */
300 if ( remaining ) {
301 DBGC ( map, "TLSFMT %s has excess data:\n",
302 tls_map_name ( map ) );
303 DBGC_HDA ( map, 0, data, remaining );
304 return -EPROTO;
305 }
306
307 return 0;
308}
unsigned char uint8_t
Definition stdint.h:10
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
u32 version
Driver version.
Definition ath9k_hw.c:1985
uint32_t next
Next descriptor address.
Definition dwmac.h:11
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition eltorito.h:1
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define DBGC_HDA(...)
Definition compiler.h:531
void * memset(void *dest, int character, size_t len) __nonnull
unsigned char byte
Definition smc9000.h:38
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
static int tls_parse_extensions(const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
Parse TLS extensions within a data structure.
Definition tlsfmt.c:87
#define TLS_MAP_FIXED(byte)
Interpret fixed length from an llllllvv byte.
Definition tlsfmt.h:370
#define TLS_VERSION_TLS_1_3
TLS version 1.3.
Definition tlsfmt.h:180
#define TLS_MAP_EXTENSIONS(byte)
Interpret number of extensions from an xxxxxxnn byte.
Definition tlsfmt.h:389
#define TLS_MAP_MIN(byte)
Interpret minimum version from an llllllvv byte.
Definition tlsfmt.h:362
#define TLS_MAP_LEN_LEN(byte)
Interpret number of length bytes from an xxxxxxnn byte.
Definition tlsfmt.h:378

References assert, container_of, count, data, tls_cursor::data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, desc, EINVAL, EPROTO, fixed, index, len, tls_cursor::len, map, memset(), next, rc, TLS_MAP_EXTENSIONS, TLS_MAP_FIXED, TLS_MAP_LEN_LEN, TLS_MAP_MIN, tls_map_name(), tls_parse_extensions(), TLS_VERSION_TLS_1_3, and version.

Referenced by tls_parse_opt_map().

◆ tls_parse_opt_map()

int tls_parse_opt_map ( const uint8_t * map,
unsigned int version,
const struct tls_cursor * cursor,
union tls_ptr_len * desc )

Parse optional TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 319 of file tlsfmt.c.

321 {
322 unsigned int count;
323 int rc;
324
325 /* Get mapping length */
326 count = map[0];
327 if ( ! count ) {
328 DBGC ( map, "TLSFMT %s mapping has no count\n",
329 tls_map_name ( map ) );
330 return -EINVAL;
331 }
332
333 /* Clear data structure descriptor */
334 memset ( desc, 0, ( ( count - 1 ) * sizeof ( desc[0] ) ) );
335
336 /* Do nothing if optional data structure is not present */
337 if ( ! cursor->data )
338 return 0;
339
340 /* Parse data structure */
341 if ( ( rc = tls_parse_map ( map, version, cursor, desc ) ) != 0 )
342 return rc;
343
344 return 0;
345}
int tls_parse_map(const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
Parse TLS data structure.
Definition tlsfmt.c:148

References count, tls_cursor::data, DBGC, desc, EINVAL, map, memset(), rc, tls_map_name(), tls_parse_map(), and version.

◆ tls_build_extensions()

int tls_build_extensions ( const uint8_t * map,
unsigned int index,
struct tls_cursor * fields,
unsigned int count )
static

Build TLS extensions within a data structure.

Parameters
mapData structure descriptor mapping
indexCurrent index within mapping
fieldsExtensions data fields
countNumber of extensions
Return values
rcReturn status code

Definition at line 356 of file tlsfmt.c.

358 {
359 const uint16_t __attribute__ (( aligned ( 1 ) )) *invtypes;
360 struct tls_cursor *cursor = &fields[0];
361 struct tls_cursor *subcursor;
362 struct tls_extension extension;
363 unsigned int i;
365 int rc;
366
367 /* Prepare per-extension subcursor */
368 subcursor = &extension.next;
369 subcursor->data = cursor->data;
370 cursor->len = 0;
371
372 /* Extension types are encoded as inverted */
373 invtypes = ( ( const void * ) &map[index] );
374 for ( i = 1 ; i <= count ; i++ ) {
375 if ( ! invtypes[i] ) {
376 DBGC ( map, "TLSFMT %s #%d mapping missing extension "
377 "%d\n", tls_map_name ( map ), index, i );
378 return -EINVAL;
379 }
380 }
381
382 /* Build extensions */
383 for ( i = 1 ; i <= count ; i++ ) {
384
385 /* Skip extensions that will not be included */
386 if ( ! ( fields[i].data || fields[i].len ) )
387 continue;
388
389 /* Build extension */
390 type = ~invtypes[i];
391 extension.type = &type;
392 extension.data = fields[i];
393 extension.next.len = 0;
395 &extension, subcursor ) ) != 0 ) {
396 return rc;
397 }
398 fields[i].len = extension.data.len;
399 DBGC2 ( map, "TLSFMT %s #%d extension %#04x len %zd\n",
400 tls_map_name ( map ), index, ntohs ( type ),
401 fields[i].len );
402 cursor->len += subcursor->len;
403 if ( cursor->data ) {
404 fields[i].data = extension.data.data;
405 DBGC2_HDA ( map, 0, fields[i].data, fields[i].len );
406 }
407 }
408
409 return 0;
410}
#define tls_build(type, version, desc, cursor)
Build TLS data structure.
Definition tlsfmt.h:627

References __attribute__, count, data, tls_cursor::data, tls_extension::data, DBGC, DBGC2, DBGC2_HDA, EINVAL, index, len, tls_cursor::len, map, tls_extension::next, ntohs, rc, tls_build, tls_map_name(), TLS_VERSION_BASE, tls_extension::type, and type.

Referenced by tls_build_map().

◆ tls_build_map()

int tls_build_map ( const uint8_t * map,
unsigned int version,
union tls_ptr_len * desc,
struct tls_cursor * cursor )

Build TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
descData structure descriptor
cursorCursor to contain TLS data structure
Return values
rcReturn status code

Build a TLS data structure at the cursor. The cursor's original length will be ignored and will be set to the overall length of the built data structure. The caller must ensure that sufficient space already exists (e.g. by calling tls_size() first to determine the required length).

The overall length will be calculated based on the variable lengths within the descriptor. The output content will be be copied from any non-NULL pointers within the descriptor (with any missing content initialised to zero).

Pointers within the descriptor will be updated to point to the appropriate location within the built data structure.

The caller must therefore fill in any variable lengths within the descriptor beforehand, but may freely choose to either fill in pointers within the descriptor beforehand or to write through the updated pointers afterwards.

A cursor with a NULL data pointer may be used to calculate the required length without copying in any data or updating any pointers within the descriptor.

Definition at line 444 of file tlsfmt.c.

445 {
446 struct tls_cursor *field;
447 void *data;
448 size_t len;
449 size_t max;
450 unsigned int count;
451 unsigned int index;
452 unsigned int next;
453 unsigned int byte;
454 unsigned int minimum;
455 unsigned int len_len;
456 int fixed;
457 int exts;
458 int rc;
459
460 /* Read initial cursor (may overlap output data structure) */
461 data = cursor->data;
462 len = 0;
463
464 /* Get mapping length */
465 count = map[0];
466 if ( ! count ) {
467 DBGC ( map, "TLSFMT %s mapping has no count\n",
468 tls_map_name ( map ) );
469 return -EINVAL;
470 }
471
472 /* Accumulate total length via mapping */
473 for ( index = 1 ; ( next = index ) < count ; index = next ) {
474
475 /* Prepare to read field description */
476 field = container_of ( &desc[ index - 1 ].data,
477 struct tls_cursor, data );
478
479 /* Interpret byte as `llllllvv` */
480 byte = map[next++];
481 minimum = TLS_MAP_MIN ( byte );
482 fixed = TLS_MAP_FIXED ( byte );
483 if ( fixed < 0 ) {
484 DBGC ( map, "TLSFMT %s #%d mapping missing\n",
485 tls_map_name ( map ), index );
486 return -EINVAL;
487 }
488 assert ( next <= count );
489
490 /* Handle fixed-length fields */
491 if ( fixed ) {
492 if ( version < minimum ) {
493 DBGC2 ( map, "TLSFMT %s #%d not in version "
494 "%d.%d\n", tls_map_name ( map ),
495 index, ( version >> 8 ),
496 ( version & 0xff ) );
497 continue;
498 }
499 DBGC2 ( map, "TLSFMT %s #%d len %d\n",
500 tls_map_name ( map ), index, fixed );
501 len += fixed;
502 if ( data ) {
503 if ( field->data ) {
504 memcpy ( data, field->data, fixed );
505 } else {
506 memset ( data, 0, fixed );
507 }
508 field->data = data;
509 data += fixed;
510 DBGC2_HDA ( map, 0, field->data, fixed );
511 }
512 continue;
513 }
514
515 /* Interpret next byte as `xxxxxxnn` */
516 if ( next >= count ) {
517 DBGC ( map, "TLSFMT %s #%d mapping overrun\n",
518 tls_map_name ( map ), index );
519 return -EINVAL;
520 }
521 byte = map[next++];
522 len_len = TLS_MAP_LEN_LEN ( byte );
523 exts = TLS_MAP_EXTENSIONS ( byte );
524 if ( exts >= 0 )
525 next += ( exts * 2 );
526 if ( next > count ) {
527 DBGC ( map, "TLSFMT %s #%d mapping extensions "
528 "overrun\n", tls_map_name ( map ), index );
529 return -EINVAL;
530 }
531 if ( version < minimum ) {
532 DBGC2 ( map, "TLSFMT %s #%d not in version %d.%d\n",
533 tls_map_name ( map ), index, ( version >> 8 ),
534 ( version & 0xff ) );
535 continue;
536 }
537
538 /* Handle variable-length fields */
539 max = ( len_len ? ( ( 1 << ( 8 * len_len ) ) - 1 ) :
540 ( ( 1 << ( 8 * TLS_MAP_LEN_LEN_MAX ) ) - 1 ) );
541 if ( exts >= 0 ) {
542 field->data = ( data ? ( data + len_len ) : NULL );
543 if ( ( rc = tls_build_extensions ( map, index, field,
544 exts ) ) != 0 ) {
545 return rc;
546 }
547 }
548 if ( field->len > max ) {
549 DBGC ( map, "TLSFMT %s #%d len %zd too long\n",
550 tls_map_name ( map ), index, field->len );
551 return -ERANGE;
552 }
553
554 /* Allow for optional extensions fields */
555 if ( ( exts >= 0 ) && ( ! field->len ) &&
557 DBGC2 ( map, "TLSFMT %s #%d optional in version "
558 "%d.%d\n", tls_map_name ( map ), index,
559 ( version >> 8 ), ( version & 0xff ) );
560 continue;
561 }
562
563 /* Build field */
564 DBGC2 ( map, "TLSFMT %s #%d len %zd\n",
565 tls_map_name ( map ), index, field->len );
566 len += ( len_len + field->len );
567 if ( data ) {
568 while ( len_len-- ) {
569 *( ( uint8_t * ) data++ ) =
570 ( field->len >> ( 8 * len_len ) );
571 }
572 if ( exts < 0 ) {
573 if ( field->data ) {
574 memcpy ( data, field->data,
575 field->len );
576 } else {
577 memset ( data, 0, field->len );
578 }
579 }
580 field->data = data;
581 data += field->len;
582 DBGC2_HDA ( map, 0, field->data, field->len );
583 }
584 }
585
586 /* Update cursor (may overlap output data structure) */
587 cursor->len = len;
588 DBGC2 ( map, "TLSFMT %s built len %zd\n",
589 tls_map_name ( map ), cursor->len );
590 if ( data )
591 DBGC2_HDA ( map, 0, cursor->data, cursor->len );
592
593 return 0;
594}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define max(x, y)
Definition ath.h:41
#define ERANGE
Result too large.
Definition errno.h:683
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int tls_build_extensions(const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
Build TLS extensions within a data structure.
Definition tlsfmt.c:356
#define TLS_MAP_LEN_LEN_MAX
Maximum number of length bytes.
Definition tlsfmt.h:381

References assert, container_of, count, data, tls_cursor::data, DBGC, DBGC2, DBGC2_HDA, desc, EINVAL, ERANGE, fixed, index, len, tls_cursor::len, map, max, memcpy(), memset(), next, NULL, rc, tls_build_extensions(), TLS_MAP_EXTENSIONS, TLS_MAP_FIXED, TLS_MAP_LEN_LEN, TLS_MAP_LEN_LEN_MAX, TLS_MAP_MIN, tls_map_name(), TLS_VERSION_TLS_1_3, and version.

Referenced by tls_size_map().

◆ TLS_DESCR_MAPPING() [1/14]

TLS_DESCR_MAPPING ( tls_certificate )

Certificate descriptor mapping.

References TLS_MAPSZ, TLS_VAR08, TLS_VAR24, TLS_VERSION_BASE, and TLS_VERSION_TLS_1_3.

◆ TLS_DESCR_MAPPING() [2/14]

TLS_DESCR_MAPPING ( tls_certificate_entry )

CertificateEntry descriptor mapping.

References ext, next, TLS_EXT16, TLS_EXTRA, TLS_MAPSZ, TLS_VAR24, TLS_VERSION_BASE, and TLS_VERSION_TLS_1_3.

◆ TLS_DESCR_MAPPING() [3/14]

TLS_DESCR_MAPPING ( tls_digitally_signed )

DigitallySigned descriptor mapping.

References sig, TLS_FIXED, TLS_MAPSZ, TLS_VAR16, TLS_VERSION_BASE, and TLS_VERSION_TLS_1_2.

◆ TLS_DESCR_MAPPING() [4/14]

TLS_DESCR_MAPPING ( tls_extension )

Extension descriptor mapping.

References data, next, TLS_EXTRA, TLS_FIXED, TLS_MAPSZ, TLS_VAR16, TLS_VERSION_BASE, and type.

◆ TLS_DESCR_MAPPING() [5/14]

TLS_DESCR_MAPPING ( tls_hello_request )

HelloRequest descriptor mapping.

References TLS_MAPSZ.

◆ TLS_DESCR_MAPPING() [6/14]

TLS_DESCR_MAPPING ( tls_key_share_entry )

KeyShareEntry descriptor mapping.

References group, next, TLS_EXTRA, TLS_FIXED, TLS_MAPSZ, TLS_VAR16, and TLS_VERSION_BASE.

◆ TLS_DESCR_MAPPING() [7/14]

TLS_DESCR_MAPPING ( tls_new_session_ticket )

NewSessionTicket descriptor mapping.

References age, ext, lifetime, nonce, TLS_EXT16, TLS_FIXED, TLS_MAPSZ, TLS_VAR08, TLS_VAR16, TLS_VERSION_BASE, and TLS_VERSION_TLS_1_3.

◆ TLS_DESCR_MAPPING() [8/14]

TLS_DESCR_MAPPING ( tls_renegotiation_info )

RenegotiationInfo descriptor mapping.

References TLS_MAPSZ, TLS_VAR08, and TLS_VERSION_BASE.

◆ TLS_DESCR_MAPPING() [9/14]

◆ TLS_DESCR_MAPPING() [10/14]

TLS_DESCR_MAPPING ( tls_server_hello_done )

ServerHello descriptor mapping.

References TLS_MAPSZ.

◆ TLS_DESCR_MAPPING() [11/14]

TLS_DESCR_MAPPING ( tls_server_key_exchange_dhe )

ServerKeyExchange descriptor mapping (for DHE).

References TLS_EXTRA, TLS_MAPSZ, TLS_VAR16, and TLS_VERSION_BASE.

◆ TLS_DESCR_MAPPING() [12/14]

TLS_DESCR_MAPPING ( tls_server_key_exchange_ecdhe )

ServerKeyExchange descriptor mapping (for EcDHE).

References TLS_EXTRA, TLS_FIXED, TLS_MAPSZ, TLS_VAR08, and TLS_VERSION_BASE.

◆ TLS_DESCR_MAPPING() [13/14]

TLS_DESCR_MAPPING ( tls_supported_version )

SupportedVersions descriptor mapping (in ServerHello).

References TLS_FIXED, TLS_MAPSZ, and TLS_VERSION_BASE.

◆ TLS_DESCR_MAPPING() [14/14]

TLS_DESCR_MAPPING ( tls_supported_versions )

SupportedVersions descriptor mapping (in ClientHello).

References TLS_MAPSZ, TLS_VAR08, TLS_VERSION_BASE, and versions.