diff options
Diffstat (limited to 'src/lib/libssl/tls13_legacy.c')
-rw-r--r-- | src/lib/libssl/tls13_legacy.c | 191 |
1 files changed, 190 insertions, 1 deletions
diff --git a/src/lib/libssl/tls13_legacy.c b/src/lib/libssl/tls13_legacy.c index 747bdc2728..1e18a8258c 100644 --- a/src/lib/libssl/tls13_legacy.c +++ b/src/lib/libssl/tls13_legacy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_legacy.c,v 1.2 2020/03/10 17:02:21 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_legacy.c,v 1.3 2020/04/28 20:37:22 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 | * |
@@ -277,6 +277,195 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | int | 279 | int |
280 | tls13_use_legacy_client(struct tls13_ctx *ctx) | ||
281 | { | ||
282 | SSL *s = ctx->ssl; | ||
283 | CBS cbs; | ||
284 | |||
285 | s->method = tls_legacy_client_method(); | ||
286 | s->internal->handshake_func = s->method->internal->ssl_connect; | ||
287 | s->client_version = s->version = s->method->internal->max_version; | ||
288 | |||
289 | if (!ssl3_setup_init_buffer(s)) | ||
290 | goto err; | ||
291 | if (!ssl3_setup_buffers(s)) | ||
292 | goto err; | ||
293 | if (!ssl_init_wbio_buffer(s, 0)) | ||
294 | goto err; | ||
295 | |||
296 | if (s->bbio != s->wbio) | ||
297 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
298 | |||
299 | /* Stash any unprocessed data from the last record. */ | ||
300 | tls13_record_layer_rbuf(ctx->rl, &cbs); | ||
301 | if (CBS_len(&cbs) > 0) { | ||
302 | if (!CBS_write_bytes(&cbs, | ||
303 | S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH, | ||
304 | S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL)) | ||
305 | goto err; | ||
306 | |||
307 | S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH; | ||
308 | S3I(s)->rbuf.left = CBS_len(&cbs); | ||
309 | S3I(s)->rrec.type = SSL3_RT_HANDSHAKE; | ||
310 | S3I(s)->rrec.length = CBS_len(&cbs); | ||
311 | s->internal->rstate = SSL_ST_READ_BODY; | ||
312 | s->internal->packet = S3I(s)->rbuf.buf; | ||
313 | s->internal->packet_length = SSL3_RT_HEADER_LENGTH; | ||
314 | s->internal->mac_packet = 1; | ||
315 | } | ||
316 | |||
317 | /* Stash the current handshake message. */ | ||
318 | tls13_handshake_msg_data(ctx->hs_msg, &cbs); | ||
319 | if (!CBS_write_bytes(&cbs, s->internal->init_buf->data, | ||
320 | s->internal->init_buf->length, NULL)) | ||
321 | goto err; | ||
322 | |||
323 | S3I(s)->tmp.reuse_message = 1; | ||
324 | S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg); | ||
325 | S3I(s)->tmp.message_size = CBS_len(&cbs); | ||
326 | |||
327 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | ||
328 | |||
329 | return 1; | ||
330 | |||
331 | err: | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | int | ||
336 | tls13_use_legacy_server(struct tls13_ctx *ctx) | ||
337 | { | ||
338 | SSL *s = ctx->ssl; | ||
339 | CBS cbs; | ||
340 | |||
341 | s->method = tls_legacy_server_method(); | ||
342 | s->internal->handshake_func = s->method->internal->ssl_accept; | ||
343 | s->client_version = s->version = s->method->internal->max_version; | ||
344 | s->server = 1; | ||
345 | |||
346 | if (!ssl3_setup_init_buffer(s)) | ||
347 | goto err; | ||
348 | if (!ssl3_setup_buffers(s)) | ||
349 | goto err; | ||
350 | if (!ssl_init_wbio_buffer(s, 0)) | ||
351 | goto err; | ||
352 | |||
353 | if (s->bbio != s->wbio) | ||
354 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
355 | |||
356 | /* Stash any unprocessed data from the last record. */ | ||
357 | tls13_record_layer_rbuf(ctx->rl, &cbs); | ||
358 | if (CBS_len(&cbs) > 0) { | ||
359 | if (!CBS_write_bytes(&cbs, | ||
360 | S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH, | ||
361 | S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL)) | ||
362 | goto err; | ||
363 | |||
364 | S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH; | ||
365 | S3I(s)->rbuf.left = CBS_len(&cbs); | ||
366 | S3I(s)->rrec.type = SSL3_RT_HANDSHAKE; | ||
367 | S3I(s)->rrec.length = CBS_len(&cbs); | ||
368 | s->internal->rstate = SSL_ST_READ_BODY; | ||
369 | s->internal->packet = S3I(s)->rbuf.buf; | ||
370 | s->internal->packet_length = SSL3_RT_HEADER_LENGTH; | ||
371 | s->internal->mac_packet = 1; | ||
372 | } | ||
373 | |||
374 | /* Stash the current handshake message. */ | ||
375 | tls13_handshake_msg_data(ctx->hs_msg, &cbs); | ||
376 | if (!CBS_write_bytes(&cbs, s->internal->init_buf->data, | ||
377 | s->internal->init_buf->length, NULL)) | ||
378 | goto err; | ||
379 | |||
380 | S3I(s)->tmp.reuse_message = 1; | ||
381 | S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg); | ||
382 | S3I(s)->tmp.message_size = CBS_len(&cbs); | ||
383 | |||
384 | S3I(s)->hs.state = SSL3_ST_SR_CLNT_HELLO_A; | ||
385 | |||
386 | return 1; | ||
387 | |||
388 | err: | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | int | ||
393 | tls13_legacy_accept(SSL *ssl) | ||
394 | { | ||
395 | struct tls13_ctx *ctx = ssl->internal->tls13; | ||
396 | int ret; | ||
397 | |||
398 | if (ctx == NULL) { | ||
399 | if ((ctx = tls13_ctx_new(TLS13_HS_SERVER)) == NULL) { | ||
400 | SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ | ||
401 | return -1; | ||
402 | } | ||
403 | ssl->internal->tls13 = ctx; | ||
404 | ctx->ssl = ssl; | ||
405 | ctx->hs = &S3I(ssl)->hs_tls13; | ||
406 | |||
407 | if (!tls13_server_init(ctx)) { | ||
408 | if (ERR_peek_error() == 0) | ||
409 | SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ | ||
410 | return -1; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | ERR_clear_error(); | ||
415 | S3I(ssl)->hs.state = SSL_ST_ACCEPT; | ||
416 | |||
417 | ret = tls13_server_accept(ctx); | ||
418 | if (ret == TLS13_IO_USE_LEGACY) | ||
419 | return ssl->method->internal->ssl_accept(ssl); | ||
420 | if (ret == TLS13_IO_SUCCESS) | ||
421 | S3I(ssl)->hs.state = SSL_ST_OK; | ||
422 | |||
423 | return tls13_legacy_return_code(ssl, ret); | ||
424 | } | ||
425 | |||
426 | int | ||
427 | tls13_legacy_connect(SSL *ssl) | ||
428 | { | ||
429 | struct tls13_ctx *ctx = ssl->internal->tls13; | ||
430 | int ret; | ||
431 | |||
432 | #ifdef TLS13_USE_LEGACY_CLIENT_AUTH | ||
433 | /* XXX drop back to legacy for client auth for now */ | ||
434 | if (ssl->cert->key->privatekey != NULL) { | ||
435 | ssl->method = tls_legacy_client_method(); | ||
436 | return ssl->method->internal->ssl_connect(ssl); | ||
437 | } | ||
438 | #endif | ||
439 | |||
440 | if (ctx == NULL) { | ||
441 | if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) { | ||
442 | SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ | ||
443 | return -1; | ||
444 | } | ||
445 | ssl->internal->tls13 = ctx; | ||
446 | ctx->ssl = ssl; | ||
447 | ctx->hs = &S3I(ssl)->hs_tls13; | ||
448 | |||
449 | if (!tls13_client_init(ctx)) { | ||
450 | if (ERR_peek_error() == 0) | ||
451 | SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */ | ||
452 | return -1; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | ERR_clear_error(); | ||
457 | S3I(ssl)->hs.state = SSL_ST_CONNECT; | ||
458 | |||
459 | ret = tls13_client_connect(ctx); | ||
460 | if (ret == TLS13_IO_USE_LEGACY) | ||
461 | return ssl->method->internal->ssl_connect(ssl); | ||
462 | if (ret == TLS13_IO_SUCCESS) | ||
463 | S3I(ssl)->hs.state = SSL_ST_OK; | ||
464 | |||
465 | return tls13_legacy_return_code(ssl, ret); | ||
466 | } | ||
467 | |||
468 | int | ||
280 | tls13_legacy_shutdown(SSL *ssl) | 469 | tls13_legacy_shutdown(SSL *ssl) |
281 | { | 470 | { |
282 | struct tls13_ctx *ctx = ssl->internal->tls13; | 471 | struct tls13_ctx *ctx = ssl->internal->tls13; |