diff options
| author | jsing <> | 2019-02-04 16:18:15 +0000 |
|---|---|---|
| committer | jsing <> | 2019-02-04 16:18:15 +0000 |
| commit | a463a4af03e850a8f1e34eca25a31e6b653e8c0e (patch) | |
| tree | 4b4a3650a0532f0cb29f66755c86aa47e29f60c6 /src/lib/libssl/tls13_client.c | |
| parent | c8529befa0a8588be484dd03bbc4c6b6d8490f05 (diff) | |
| download | openbsd-a463a4af03e850a8f1e34eca25a31e6b653e8c0e.tar.gz openbsd-a463a4af03e850a8f1e34eca25a31e6b653e8c0e.tar.bz2 openbsd-a463a4af03e850a8f1e34eca25a31e6b653e8c0e.zip | |
Implement parsing and processing of TLSv1.3 ServerHello messages.
ok tb@
Diffstat (limited to 'src/lib/libssl/tls13_client.c')
| -rw-r--r-- | src/lib/libssl/tls13_client.c | 179 |
1 files changed, 178 insertions, 1 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 1a2529be6a..4d34cf9943 100644 --- a/src/lib/libssl/tls13_client.c +++ b/src/lib/libssl/tls13_client.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_client.c,v 1.1 2019/01/21 13:45:57 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.2 2019/02/04 16:18:15 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include "bytestring.h" | 23 | #include "bytestring.h" |
| 24 | #include "ssl_tlsext.h" | 24 | #include "ssl_tlsext.h" |
| 25 | #include "tls13_handshake.h" | ||
| 25 | #include "tls13_internal.h" | 26 | #include "tls13_internal.h" |
| 26 | 27 | ||
| 27 | int | 28 | int |
| @@ -137,3 +138,179 @@ tls13_client_hello_send(struct tls13_ctx *ctx) | |||
| 137 | 138 | ||
| 138 | return 1; | 139 | return 1; |
| 139 | } | 140 | } |
| 141 | |||
| 142 | /* | ||
| 143 | * HelloRetryRequest hash - RFC 8446 section 4.1.3. | ||
| 144 | */ | ||
| 145 | static const uint8_t tls13_hello_retry_request_hash[] = { | ||
| 146 | 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, | ||
| 147 | 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, | ||
| 148 | 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, | ||
| 149 | 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static int | ||
| 153 | tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | ||
| 154 | { | ||
| 155 | CBS server_random, session_id; | ||
| 156 | uint16_t cipher_suite, legacy_version; | ||
| 157 | uint8_t compression_method; | ||
| 158 | const SSL_CIPHER *cipher; | ||
| 159 | SSL *s = ctx->ssl; | ||
| 160 | int alert; | ||
| 161 | |||
| 162 | if (!CBS_get_u16(cbs, &legacy_version)) | ||
| 163 | goto err; | ||
| 164 | if (!CBS_get_bytes(cbs, &server_random, SSL3_RANDOM_SIZE)) | ||
| 165 | goto err; | ||
| 166 | if (!CBS_get_u8_length_prefixed(cbs, &session_id)) | ||
| 167 | goto err; | ||
| 168 | if (!CBS_get_u16(cbs, &cipher_suite)) | ||
| 169 | goto err; | ||
| 170 | if (!CBS_get_u8(cbs, &compression_method)) | ||
| 171 | goto err; | ||
| 172 | |||
| 173 | if (!tlsext_client_parse(s, cbs, &alert, SSL_TLSEXT_MSG_SH)) | ||
| 174 | goto err; | ||
| 175 | |||
| 176 | if (CBS_len(cbs) != 0) | ||
| 177 | goto err; | ||
| 178 | |||
| 179 | /* | ||
| 180 | * See if a supported versions extension was returned. If it was then | ||
| 181 | * the legacy version must be set to 0x0303 (RFC 8446 section 4.1.3). | ||
| 182 | * Otherwise, fallback to the legacy version, ensuring that it is both | ||
| 183 | * within range and not TLS 1.3 or greater (which must use the | ||
| 184 | * supported version extension. | ||
| 185 | */ | ||
| 186 | if (S3I(s)->hs_tls13.server_version != 0) { | ||
| 187 | if (legacy_version != TLS1_2_VERSION) { | ||
| 188 | /* XXX - alert. */ | ||
| 189 | goto err; | ||
| 190 | } | ||
| 191 | } else { | ||
| 192 | if (legacy_version < S3I(s)->hs_tls13.min_version || | ||
| 193 | legacy_version > S3I(s)->hs_tls13.max_version || | ||
| 194 | legacy_version > TLS1_2_VERSION) { | ||
| 195 | /* XXX - alert. */ | ||
| 196 | goto err; | ||
| 197 | } | ||
| 198 | S3I(s)->hs_tls13.server_version = legacy_version; | ||
| 199 | } | ||
| 200 | |||
| 201 | /* XXX - session_id must match. */ | ||
| 202 | |||
| 203 | /* | ||
| 204 | * Ensure that the cipher suite is one that we offered in the client | ||
| 205 | * hello and that it matches the TLS version selected. | ||
| 206 | */ | ||
| 207 | cipher = ssl3_get_cipher_by_value(cipher_suite); | ||
| 208 | if (cipher == NULL || | ||
| 209 | sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(s), cipher) < 0) { | ||
| 210 | /* XXX - alert. */ | ||
| 211 | goto err; | ||
| 212 | } | ||
| 213 | if (S3I(s)->hs_tls13.server_version == TLS1_3_VERSION && | ||
| 214 | cipher->algorithm_ssl != SSL_TLSV1_3) { | ||
| 215 | /* XXX - alert. */ | ||
| 216 | goto err; | ||
| 217 | } | ||
| 218 | /* XXX - move this to hs_tls13? */ | ||
| 219 | S3I(s)->hs.new_cipher = cipher; | ||
| 220 | |||
| 221 | if (compression_method != 0) { | ||
| 222 | /* XXX - alert. */ | ||
| 223 | goto err; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash, | ||
| 227 | sizeof(tls13_hello_retry_request_hash))) | ||
| 228 | ctx->handshake_stage.hs_type |= WITH_HRR; | ||
| 229 | |||
| 230 | return 1; | ||
| 231 | |||
| 232 | err: | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | int | ||
| 237 | tls13_server_hello_recv(struct tls13_ctx *ctx) | ||
| 238 | { | ||
| 239 | struct tls13_secrets *secrets; | ||
| 240 | struct tls13_secret context; | ||
| 241 | unsigned char buf[EVP_MAX_MD_SIZE]; | ||
| 242 | uint8_t *shared_key = NULL; | ||
| 243 | size_t hash_len; | ||
| 244 | SSL *s = ctx->ssl; | ||
| 245 | int ret = 0; | ||
| 246 | CBS cbs; | ||
| 247 | |||
| 248 | if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) | ||
| 249 | goto err; | ||
| 250 | |||
| 251 | if (!tls13_server_hello_process(ctx, &cbs)) | ||
| 252 | goto err; | ||
| 253 | |||
| 254 | if (S3I(s)->hs_tls13.server_version < TLS1_3_VERSION) { | ||
| 255 | /* XXX - switch back to legacy client. */ | ||
| 256 | } | ||
| 257 | |||
| 258 | if (ctx->handshake_stage.hs_type & WITH_HRR) | ||
| 259 | return 1; | ||
| 260 | |||
| 261 | /* XXX - handle other key share types. */ | ||
| 262 | if (S3I(s)->hs_tls13.x25519_peer_public == NULL) { | ||
| 263 | /* XXX - alert. */ | ||
| 264 | goto err; | ||
| 265 | } | ||
| 266 | if ((shared_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
| 267 | goto err; | ||
| 268 | if (!X25519(shared_key, S3I(s)->hs_tls13.x25519_private, | ||
| 269 | S3I(s)->hs_tls13.x25519_peer_public)) | ||
| 270 | goto err; | ||
| 271 | |||
| 272 | s->session->cipher = S3I(s)->hs.new_cipher; | ||
| 273 | s->session->ssl_version = S3I(s)->hs_tls13.server_version; | ||
| 274 | |||
| 275 | if ((ctx->aead = tls13_cipher_aead(S3I(s)->hs.new_cipher)) == NULL) | ||
| 276 | goto err; | ||
| 277 | if ((ctx->hash = tls13_cipher_hash(S3I(s)->hs.new_cipher)) == NULL) | ||
| 278 | goto err; | ||
| 279 | |||
| 280 | if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL) | ||
| 281 | goto err; | ||
| 282 | S3I(ctx->ssl)->hs_tls13.secrets = secrets; | ||
| 283 | |||
| 284 | /* XXX - pass in hash. */ | ||
| 285 | if (!tls1_handshake_hash_init(s)) | ||
| 286 | goto err; | ||
| 287 | if (!tls1_handshake_hash_value(s, buf, sizeof(buf), &hash_len)) | ||
| 288 | goto err; | ||
| 289 | context.data = buf; | ||
| 290 | context.len = hash_len; | ||
| 291 | |||
| 292 | /* Early secrets. */ | ||
| 293 | if (!tls13_derive_early_secrets(secrets, secrets->zeros.data, | ||
| 294 | secrets->zeros.len, &context)) | ||
| 295 | goto err; | ||
| 296 | |||
| 297 | /* Handshake secrets. */ | ||
| 298 | if (!tls13_derive_handshake_secrets(S3I(s)->hs_tls13.secrets, | ||
| 299 | shared_key, X25519_KEY_LENGTH, &context)) | ||
| 300 | goto err; | ||
| 301 | |||
| 302 | tls13_record_layer_set_aead(ctx->rl, ctx->aead); | ||
| 303 | tls13_record_layer_set_hash(ctx->rl, ctx->hash); | ||
| 304 | |||
| 305 | if (!tls13_record_layer_set_traffic_keys(ctx->rl, | ||
| 306 | &secrets->server_handshake_traffic, | ||
| 307 | &secrets->client_handshake_traffic)) | ||
| 308 | goto err; | ||
| 309 | |||
| 310 | ctx->handshake_stage.hs_type |= NEGOTIATED; | ||
| 311 | ret = 1; | ||
| 312 | |||
| 313 | err: | ||
| 314 | freezero(shared_key, X25519_KEY_LENGTH); | ||
| 315 | return ret; | ||
| 316 | } | ||
