Skip to content

Commit 0a4b58b

Browse files
committed
hoist extension decode into common routine
1 parent 033fd90 commit 0a4b58b

1 file changed

Lines changed: 76 additions & 29 deletions

File tree

src/lib/tls/pairs.c

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ static bool tls_session_pairs_from_crl(fr_pair_list_t *pair_list, TALLOC_CTX *ct
124124

125125
for (i = 0; i < sk_DIST_POINT_num(dps); i++) {
126126
dp = sk_DIST_POINT_value(dps, i);
127+
128+
/*
129+
* RFC 5280 Section 4.2.1.13 says that the distpoint is optional.
130+
*/
131+
if (!dp->distpoint) return false;
132+
127133
names = dp->distpoint->name.fullname;
128134

129135
/*
@@ -461,6 +467,56 @@ int fr_tls_session_pairs_from_x509_cert(fr_pair_list_t *pair_list, TALLOC_CTX *c
461467
return 0;
462468
}
463469

470+
static int fr_tls_extension_decode(request_t *request, fr_pair_t *container, uint8_t const *extension,
471+
size_t hlen, size_t dlen, size_t total_len, fr_dict_attr_t const *da)
472+
{
473+
size_t i,extension_len;
474+
uint8_t const *data;
475+
476+
fr_assert((hlen == 1) || (hlen == 2));
477+
fr_assert((dlen == 1) || (dlen == 2));
478+
479+
if (total_len < hlen) {
480+
REDEBUG("Missing length in %s extension", da->name);
481+
return -1;
482+
}
483+
484+
if (hlen == 1) {
485+
fr_assert(da->type == FR_TYPE_UINT8);
486+
extension_len = extension[0];
487+
} else {
488+
fr_assert(da->type == FR_TYPE_UINT16);
489+
extension_len = (extension[0] << 8) + extension[1];
490+
}
491+
492+
if (extension_len * dlen + hlen > total_len) {
493+
REDEBUG("Invalid length in %s extension", da->name);
494+
return -1;
495+
}
496+
497+
data = extension + hlen;
498+
499+
for (i = 0; i < extension_len; i += dlen) {
500+
fr_pair_t *vp;
501+
502+
MEM(fr_pair_append_by_da(container, &vp, &container->vp_group, da) >= 0);
503+
504+
switch (dlen) {
505+
case 1:
506+
vp->vp_uint8= data[0];
507+
break;
508+
509+
case 2:
510+
vp->vp_uint16 = (data[0] << 8) + data[1];
511+
break;
512+
}
513+
514+
data += dlen;
515+
}
516+
517+
return 0;
518+
}
519+
464520
/** Callback to extract pairs from a Client Hello
465521
*
466522
*/
@@ -469,7 +525,7 @@ int fr_tls_session_client_hello_cb(SSL *ssl, UNUSED int *al, UNUSED void *arg)
469525
request_t *request = SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_REQUEST);
470526
request_t *parent = request->parent;
471527
uint8_t const *ciphers, *extension;
472-
int *extensions, extension_len, i;
528+
int *extensions, i;
473529
size_t data_size, j;
474530
STACK_OF(SSL_CIPHER) *sk;
475531
SSL_CIPHER const *cipher;
@@ -510,49 +566,40 @@ int fr_tls_session_client_hello_cb(SSL *ssl, UNUSED int *al, UNUSED void *arg)
510566
RPEDEBUG("Failed to fetch client hello extensions");
511567
goto fail;
512568
}
569+
513570
for (j = 0; j < data_size; j++) {
514-
if (SSL_client_hello_get0_ext(ssl, extensions[j], &extension, NULL) == 0) {
571+
size_t total_len;
572+
573+
if (SSL_client_hello_get0_ext(ssl, extensions[j], &extension, &total_len) == 0) {
515574
RPDEBUG("Failed getting client hello extension %d", extensions[j]);
516575
OPENSSL_free(extensions);
517576
goto fail;
518577
}
519578

520579
switch (extensions[j]) {
521-
case TLSEXT_TYPE_supported_groups:
522-
extension_len = (extension[0] << 8) + extension[1];
523-
for (i = 0; i < extension_len; i += 2) {
524-
fr_pair_append_by_da(container, &vp, &container->vp_group, attr_tls_client_hello_supported_group);
525-
vp->vp_uint16 = (extension[i + 2] << 8) + extension[i + 3];
526-
}
580+
case TLSEXT_TYPE_supported_groups: /* length[2] + 2*data */
581+
if (fr_tls_extension_decode(request, container, extension, 2, 2, total_len,
582+
attr_tls_client_hello_supported_group) < 0) goto fail;
527583
break;
528584

529-
case TLSEXT_TYPE_ec_point_formats:
530-
for (i = 0; i < extension[0]; i += 1) {
531-
fr_pair_append_by_da(container, &vp, &container->vp_group, attr_tls_client_hello_ec_point_format);
532-
vp->vp_uint8 = extension[i + 1];
533-
}
585+
case TLSEXT_TYPE_ec_point_formats: /* length[1] + data */
586+
if (fr_tls_extension_decode(request, container, extension, 1, 1, total_len,
587+
attr_tls_client_hello_ec_point_format) < 0) goto fail;
534588
break;
535589

536-
case TLSEXT_TYPE_signature_algorithms:
537-
extension_len = (extension[0] << 8) + extension[1];
538-
for (i = 0; i < extension_len; i += 2) {
539-
fr_pair_append_by_da(container, &vp, &container->vp_group, attr_tls_client_hello_sig_algo);
540-
vp->vp_uint16 = (extension[i + 2] << 8) + extension[i + 3];
541-
}
590+
case TLSEXT_TYPE_signature_algorithms: /* length[2] + 2*data */
591+
if (fr_tls_extension_decode(request, container, extension, 2, 2, total_len,
592+
attr_tls_client_hello_sig_algo) < 0) goto fail;
542593
break;
543594

544-
case TLSEXT_TYPE_supported_versions:
545-
for (i = 0; i < extension[0]; i += 2) {
546-
fr_pair_append_by_da(container, &vp, &container->vp_group, attr_tls_client_hello_tls_version);
547-
tls_version = vp->vp_uint16 = (extension[i + 1] << 8) + extension[i + 2];
548-
}
595+
case TLSEXT_TYPE_supported_versions: /* length[1] + 2*data */
596+
if (fr_tls_extension_decode(request, container, extension, 1, 2, total_len,
597+
attr_tls_client_hello_tls_version) < 0) goto fail;
549598
break;
550599

551-
case TLSEXT_TYPE_psk_kex_modes:
552-
for (i = 0; i < extension[0]; i += 1) {
553-
fr_pair_append_by_da(container, &vp, &container->vp_group, attr_tls_client_hello_psk_key_mode);
554-
vp->vp_uint8 = extension[i + 1];
555-
}
600+
case TLSEXT_TYPE_psk_kex_modes: /* length[1] + data */
601+
if (fr_tls_extension_decode(request, container, extension, 1, 1, total_len,
602+
attr_tls_client_hello_psk_key_mode) < 0) goto fail;
556603
break;
557604
}
558605
}

0 commit comments

Comments
 (0)