diff options
Diffstat (limited to 'lib/libssl/ssl_tlsext.c')
| -rw-r--r-- | lib/libssl/ssl_tlsext.c | 348 |
1 files changed, 22 insertions, 326 deletions
diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c index 06105f976d1..d5c30c4e736 100644 --- a/lib/libssl/ssl_tlsext.c +++ b/lib/libssl/ssl_tlsext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_tlsext.c,v 1.32 2019/01/23 16:46:04 beck Exp $ */ +/* $OpenBSD: ssl_tlsext.c,v 1.33 2019/01/23 18:24:40 beck Exp $ */ /* * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> @@ -536,26 +536,9 @@ tlsext_sigalgs_client_build(SSL *s, CBB *cbb) if (!CBB_add_u16_length_prefixed(cbb, &sigalgs)) return 0; - switch (TLS1_get_client_version(s)) { - case TLS1_2_VERSION: - if (!ssl_sigalgs_build(&sigalgs, tls12_sigalgs, tls12_sigalgs_len)) - return 0; - break; - case TLS1_3_VERSION: - if (S3I(s)->hs_tls13.min_version < TLS1_3_VERSION) { - if (!ssl_sigalgs_build(&sigalgs, tls12_sigalgs, - tls12_sigalgs_len)) - return 0; - } else { - if (!ssl_sigalgs_build(&sigalgs, tls13_sigalgs, - tls13_sigalgs_len)) - return 0; } - - break; - default: - /* Should not happen */ + if (!ssl_sigalgs_build(&sigalgs, tls12_sigalgs, tls12_sigalgs_len)) return 0; - } + if (!CBB_flush(cbb)) return 0; @@ -570,17 +553,7 @@ tlsext_sigalgs_server_parse(SSL *s, CBS *cbs, int *alert) if (!CBS_get_u16_length_prefixed(cbs, &sigalgs)) return 0; - switch (s->version) { - case TLS1_3_VERSION: - return tls1_process_sigalgs(s, &sigalgs, tls13_sigalgs, - tls13_sigalgs_len); - case TLS1_2_VERSION: - return tls1_process_sigalgs(s, &sigalgs, tls12_sigalgs, - tls12_sigalgs_len); - default: - /* Fail if we get a version > what we recognize */ - return 0; - } + return tls1_process_sigalgs(s, &sigalgs); } int @@ -1270,7 +1243,7 @@ tlsext_keyshare_client_build(SSL *s, CBB *cbb) return 1; - err: +err: freezero(public_key, X25519_KEY_LENGTH); freezero(private_key, X25519_KEY_LENGTH); @@ -1280,100 +1253,24 @@ tlsext_keyshare_client_build(SSL *s, CBB *cbb) int tlsext_keyshare_server_parse(SSL *s, CBS *cbs, int *alert) { - CBS client_shares; - CBS key_exchange; - uint16_t group; - size_t out_len; - int ret = 0; - - if (!CBS_get_u16_length_prefixed(cbs, &client_shares)) - goto err; - - if (CBS_len(cbs) != 0) - goto err; - - while (CBS_len(&client_shares) > 0) { - - /* Unpack client share. */ - if (!CBS_get_u16(&client_shares, &group)) - goto err; - - if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange)) - goto err; - - /* - * Skip this client share if not X25519 - * XXX support other groups later. - */ - if (ret || group != tls1_ec_nid2curve_id(NID_X25519)) - continue; - - if (CBS_len(&key_exchange) != X25519_KEY_LENGTH) - goto err; - - if (!CBS_stow(&key_exchange, &S3I(s)->hs_tls13.x25519_peer_public, - &out_len)) - goto err; - - ret = 1; + /* XXX we accept this but currently ignore it */ + if (!CBS_skip(cbs, CBS_len(cbs))) { + *alert = TLS1_AD_INTERNAL_ERROR; + return 0; } - return ret; - - err: - *alert = SSL_AD_DECODE_ERROR; - return 0; + return 1; } int tlsext_keyshare_server_needs(SSL *s) { - size_t idx; - - if (SSL_IS_DTLS(s) || s->version < TLS1_3_VERSION) - return 0; - if (tls_extension_find(TLSEXT_TYPE_key_share, &idx) == NULL) - return 0; - return ((S3I(s)->hs.extensions_seen & (1 << idx)) != 0); + return (!SSL_IS_DTLS(s) && s->version >= TLS1_3_VERSION); } int tlsext_keyshare_server_build(SSL *s, CBB *cbb) { - uint8_t *public_key = NULL, *private_key = NULL; - CBB key_exchange; - - /* X25519 */ - if (S3I(s)->hs_tls13.x25519_peer_public == NULL) - return 0; - - /* Generate X25519 key pair. */ - if ((public_key = malloc(X25519_KEY_LENGTH)) == NULL) - goto err; - if ((private_key = malloc(X25519_KEY_LENGTH)) == NULL) - goto err; - X25519_keypair(public_key, private_key); - - /* Add the group and serialize the public key. */ - if (!CBB_add_u16(cbb, tls1_ec_nid2curve_id(NID_X25519))) - goto err; - if (!CBB_add_u16_length_prefixed(cbb, &key_exchange)) - goto err; - if (!CBB_add_bytes(&key_exchange, public_key, X25519_KEY_LENGTH)) - goto err; - - if (!CBB_flush(cbb)) - goto err; - - S3I(s)->hs_tls13.x25519_public = public_key; - S3I(s)->hs_tls13.x25519_private = private_key; - - return 1; - - err: - freezero(public_key, X25519_KEY_LENGTH); - freezero(private_key, X25519_KEY_LENGTH); - return 0; } @@ -1394,10 +1291,6 @@ tlsext_keyshare_client_parse(SSL *s, CBS *cbs, int *alert) if (!CBS_get_u16_length_prefixed(cbs, &key_exchange)) goto err; - - if (CBS_len(cbs) != 0) - goto err; - if (CBS_len(&key_exchange) != X25519_KEY_LENGTH) goto err; if (!CBS_stow(&key_exchange, &S3I(s)->hs_tls13.x25519_peer_public, @@ -1420,9 +1313,8 @@ tlsext_versions_client_needs(SSL *s) /* XXX once this gets initialized when we get tls13_client.c */ if (S3I(s)->hs_tls13.max_version == 0) return 0; - if (SSL_IS_DTLS(s)) - return 0; - return (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION); + return (!SSL_IS_DTLS(s) && S3I(s)->hs_tls13.max_version >= + TLS1_3_VERSION); } int @@ -1456,41 +1348,13 @@ tlsext_versions_client_build(SSL *s, CBB *cbb) int tlsext_versions_server_parse(SSL *s, CBS *cbs, int *alert) { - CBS versions; - uint16_t version; - uint16_t max, min; - uint16_t matched_version = 0; - - max = S3I(s)->hs_tls13.max_version; - min = S3I(s)->hs_tls13.min_version; - - if (!CBS_get_u8_length_prefixed(cbs, &versions)) - goto err; - - if (CBS_len(cbs) != 0) - goto err; - - if (CBS_len(&versions) < 2) - goto err; - - while(CBS_len(&versions) > 0) { - if (!CBS_get_u16(&versions, &version)) - goto err; - /* - * XXX What is below implements client preference, and - * ignores any server preference entirely. - */ - if (matched_version == 0 && version >= min && version <= max) - matched_version = version; + /* XXX we accept this but currently ignore it */ + if (!CBS_skip(cbs, CBS_len(cbs))) { + *alert = TLS1_AD_INTERNAL_ERROR; + return 0; } - if (matched_version != 0) - s->version = matched_version; return 1; - - err: - *alert = SSL_AD_DECODE_ERROR; - return 0; } int @@ -1502,11 +1366,7 @@ tlsext_versions_server_needs(SSL *s) int tlsext_versions_server_build(SSL *s, CBB *cbb) { - if (!CBB_add_u16(cbb, TLS1_3_VERSION)) - return 0; - /* XXX set 1.2 in legacy version? */ - - return 1; + return 0; } int @@ -1519,161 +1379,12 @@ tlsext_versions_client_parse(SSL *s, CBS *cbs, int *alert) return 0; } - if (CBS_len(cbs) != 0) { - *alert = SSL_AD_DECODE_ERROR; - return 0; - } - - if (selected_version < TLS1_3_VERSION) { - *alert = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - /* XXX test between min and max once initialization code goes in */ S3I(s)->hs_tls13.server_version = selected_version; return 1; } - -/* - * Cookie - RFC 8446 section 4.2.2. - */ - -int -tlsext_cookie_client_needs(SSL *s) -{ - /* XXX once this gets initialized when we get tls13_client.c */ - if (S3I(s)->hs_tls13.max_version == 0) - return 0; - if (SSL_IS_DTLS(s)) - return 0; - if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION) - return 0; - return ((S3I(s)->hs_tls13.cookie_len > 0) && - (S3I(s)->hs_tls13.cookie != NULL)); -} - -int -tlsext_cookie_client_build(SSL *s, CBB *cbb) -{ - CBB cookie; - - if (!CBB_add_u16_length_prefixed(cbb, &cookie)) - return 0; - - if (!CBB_add_bytes(&cookie, S3I(s)->hs_tls13.cookie, - S3I(s)->hs_tls13.cookie_len)) - return 0; - - if (!CBB_flush(cbb)) - return 0; - - return 1; -} - -int -tlsext_cookie_server_parse(SSL *s, CBS *cbs, int *alert) -{ - CBS cookie; - - if (!CBS_get_u16_length_prefixed(cbs, &cookie)) - goto err; - - if (CBS_len(cbs) != 0) - goto err; - - if (CBS_len(&cookie) != S3I(s)->hs_tls13.cookie_len) - goto err; - - /* - * Check provided cookie value against what server previously - * sent - client *MUST* send the same cookie with new CR after - * a cookie is sent by the server with an HRR - */ - if (memcmp(CBS_data(&cookie), S3I(s)->hs_tls13.cookie, - S3I(s)->hs_tls13.cookie_len) != 0) { - /* XXX special cookie mismatch alert? */ - *alert = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - return 1; - - err: - *alert = SSL_AD_DECODE_ERROR; - return 0; -} - -int -tlsext_cookie_server_needs(SSL *s) -{ - /* XXX once this gets initialized when we get tls13_client.c */ - if (S3I(s)->hs_tls13.max_version == 0) - return 0; - if (SSL_IS_DTLS(s)) - return 0; - if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION) - return 0; - /* - * Server needs to set cookie value in tls13 handshake - * in order to send one, should only be sent with HRR. - */ - return ((S3I(s)->hs_tls13.cookie_len > 0) && - (S3I(s)->hs_tls13.cookie != NULL)); -} - -int -tlsext_cookie_server_build(SSL *s, CBB *cbb) -{ - CBB cookie; - - if (!CBB_add_u16_length_prefixed(cbb, &cookie)) - return 0; - if (!CBB_add_bytes(&cookie, S3I(s)->hs_tls13.cookie, - S3I(s)->hs_tls13.cookie_len)) - return 0; - if (!CBB_flush(cbb)) - return 0; - - return 1; -} - -int -tlsext_cookie_client_parse(SSL *s, CBS *cbs, int *alert) -{ - CBS cookie; - - /* - * XXX This currently assumes we will not get a second - * HRR from a server with a cookie to process after accepting - * one from the server in the same handshake - */ - if ((S3I(s)->hs_tls13.cookie != NULL) || - S3I(s)->hs_tls13.cookie_len != 0) { - *alert = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - if (!CBS_get_u16_length_prefixed(cbs, &cookie)) - goto err; - - if (CBS_len(cbs) != 0) - goto err; - - if ((S3I(s)->hs_tls13.cookie = malloc(CBS_len(&cookie))) == NULL) - goto err; - - memcpy(S3I(s)->hs_tls13.cookie, CBS_data(&cookie), CBS_len(&cookie)); - S3I(s)->hs_tls13.cookie_len = CBS_len(&cookie); - - return 1; - - err: - *alert = SSL_AD_DECODE_ERROR; - return 0; -} - struct tls_extension_funcs { int (*needs)(SSL *s); int (*build)(SSL *s, CBB *cbb); @@ -1831,20 +1542,6 @@ static struct tls_extension tls_extensions[] = { .parse = tlsext_alpn_client_parse, }, }, - { - .type = TLSEXT_TYPE_cookie, - .messages = SSL_TLSEXT_MSG_CH | SSL_TLSEXT_MSG_HRR, - .client = { - .needs = tlsext_cookie_client_needs, - .build = tlsext_cookie_client_build, - .parse = tlsext_cookie_server_parse, - }, - .server = { - .needs = tlsext_cookie_server_needs, - .build = tlsext_cookie_server_build, - .parse = tlsext_cookie_client_parse, - }, - }, #ifndef OPENSSL_NO_SRTP { .type = TLSEXT_TYPE_use_srtp, @@ -1868,7 +1565,7 @@ static struct tls_extension tls_extensions[] = { /* Ensure that extensions fit in a uint32_t bitmask. */ CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8)); -struct tls_extension * +static struct tls_extension * tls_extension_find(uint16_t type, size_t *tls_extensions_idx) { size_t i; @@ -1948,12 +1645,11 @@ tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) struct tls_extension_funcs *ext; struct tls_extension *tlsext; CBS extensions, extension_data; + uint32_t extensions_seen = 0; uint16_t type; size_t idx; uint16_t version; - S3I(s)->hs.extensions_seen = 0; - if (is_server) version = s->version; else @@ -1992,9 +1688,9 @@ tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) } /* Check for duplicate known extensions. */ - if ((S3I(s)->hs.extensions_seen & (1 << idx)) != 0) + if ((extensions_seen & (1 << idx)) != 0) return 0; - S3I(s)->hs.extensions_seen |= (1 << idx); + extensions_seen |= (1 << idx); ext = tlsext_funcs(tlsext, is_server); if (!ext->parse(s, &extension_data, alert)) |
