diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_client.c | 214 | ||||
-rw-r--r-- | src/lib/libssl/tls13_handshake.c | 31 |
2 files changed, 214 insertions, 31 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 6578438c78..d15ab65105 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.5 2019/02/09 15:26:15 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.6 2019/02/11 17:48: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 | * |
@@ -343,3 +343,215 @@ tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx) | |||
343 | 343 | ||
344 | return 0; | 344 | return 0; |
345 | } | 345 | } |
346 | |||
347 | int | ||
348 | tls13_server_certificate_request_recv(struct tls13_ctx *ctx) | ||
349 | { | ||
350 | /* | ||
351 | * Thanks to poor state design in the RFC, this function can be called | ||
352 | * when we actually have a certificate message instead of a certificate | ||
353 | * request... in that case we call the certificate handler after | ||
354 | * switching state, to avoid advancing state. | ||
355 | */ | ||
356 | if (tls13_handshake_msg_type(ctx->hs_msg) == TLS13_MT_CERTIFICATE) { | ||
357 | ctx->handshake_stage.hs_type |= WITHOUT_CR; | ||
358 | return tls13_server_certificate_recv(ctx); | ||
359 | } | ||
360 | |||
361 | /* XXX - unimplemented. */ | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | int | ||
367 | tls13_server_certificate_recv(struct tls13_ctx *ctx) | ||
368 | { | ||
369 | CBS cbs, cert_request_context, cert_list, cert_data, cert_exts; | ||
370 | struct stack_st_X509 *certs = NULL; | ||
371 | SSL *s = ctx->ssl; | ||
372 | X509 *cert = NULL; | ||
373 | EVP_PKEY *pkey; | ||
374 | const uint8_t *p; | ||
375 | int cert_idx; | ||
376 | int ret = 0; | ||
377 | |||
378 | if ((certs = sk_X509_new_null()) == NULL) | ||
379 | goto err; | ||
380 | |||
381 | if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) | ||
382 | goto err; | ||
383 | |||
384 | if (!CBS_get_u8_length_prefixed(&cbs, &cert_request_context)) | ||
385 | goto err; | ||
386 | if (CBS_len(&cert_request_context) != 0) | ||
387 | goto err; | ||
388 | if (!CBS_get_u24_length_prefixed(&cbs, &cert_list)) | ||
389 | goto err; | ||
390 | if (CBS_len(&cbs) != 0) | ||
391 | goto err; | ||
392 | |||
393 | while (CBS_len(&cert_list) > 0) { | ||
394 | if (!CBS_get_u24_length_prefixed(&cert_list, &cert_data)) | ||
395 | goto err; | ||
396 | if (!CBS_get_u16_length_prefixed(&cert_list, &cert_exts)) | ||
397 | goto err; | ||
398 | |||
399 | p = CBS_data(&cert_data); | ||
400 | if ((cert = d2i_X509(NULL, &p, CBS_len(&cert_data))) == NULL) | ||
401 | goto err; | ||
402 | if (p != CBS_data(&cert_data) + CBS_len(&cert_data)) | ||
403 | goto err; | ||
404 | |||
405 | if (!sk_X509_push(certs, cert)) | ||
406 | goto err; | ||
407 | |||
408 | cert = NULL; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * At this stage we still have no proof of possession. As such, it would | ||
413 | * be preferable to keep the chain and verify once we have successfully | ||
414 | * processed the CertificateVerify message. | ||
415 | */ | ||
416 | if (ssl_verify_cert_chain(s, certs) <= 0 && | ||
417 | s->verify_mode != SSL_VERIFY_NONE) { | ||
418 | /* XXX send alert */ | ||
419 | goto err; | ||
420 | } | ||
421 | ERR_clear_error(); | ||
422 | |||
423 | cert = sk_X509_value(certs, 0); | ||
424 | X509_up_ref(cert); | ||
425 | |||
426 | if ((pkey = X509_get0_pubkey(cert)) == NULL) | ||
427 | goto err; | ||
428 | if (EVP_PKEY_missing_parameters(pkey)) | ||
429 | goto err; | ||
430 | if ((cert_idx = ssl_cert_type(cert, pkey)) < 0) | ||
431 | goto err; | ||
432 | |||
433 | ssl_sess_cert_free(SSI(s)->sess_cert); | ||
434 | if ((SSI(s)->sess_cert = ssl_sess_cert_new()) == NULL) | ||
435 | goto err; | ||
436 | |||
437 | SSI(s)->sess_cert->cert_chain = certs; | ||
438 | certs = NULL; | ||
439 | |||
440 | X509_up_ref(cert); | ||
441 | SSI(s)->sess_cert->peer_pkeys[cert_idx].x509 = cert; | ||
442 | SSI(s)->sess_cert->peer_key = &(SSI(s)->sess_cert->peer_pkeys[cert_idx]); | ||
443 | |||
444 | X509_free(s->session->peer); | ||
445 | |||
446 | X509_up_ref(cert); | ||
447 | s->session->peer = cert; | ||
448 | s->session->verify_result = s->verify_result; | ||
449 | |||
450 | ret = 1; | ||
451 | |||
452 | err: | ||
453 | sk_X509_pop_free(certs, X509_free); | ||
454 | X509_free(cert); | ||
455 | |||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Certificate Verify padding - RFC 8446 section 4.4.3. | ||
461 | */ | ||
462 | static uint8_t cert_verify_pad[64] = { | ||
463 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
464 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
465 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
466 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
467 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
468 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
469 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
470 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
471 | }; | ||
472 | |||
473 | static uint8_t server_cert_verify_context[] = "TLS 1.3, server CertificateVerify"; | ||
474 | |||
475 | int | ||
476 | tls13_server_certificate_verify_recv(struct tls13_ctx *ctx) | ||
477 | { | ||
478 | const struct ssl_sigalg *sigalg; | ||
479 | uint16_t signature_scheme; | ||
480 | uint8_t *sig_content = NULL; | ||
481 | size_t sig_content_len; | ||
482 | EVP_MD_CTX *mdctx = NULL; | ||
483 | EVP_PKEY_CTX *pctx; | ||
484 | EVP_PKEY *pkey; | ||
485 | X509 *cert; | ||
486 | CBS cbs, signature; | ||
487 | CBB cbb; | ||
488 | int ret = 0; | ||
489 | |||
490 | memset(&cbb, 0, sizeof(cbb)); | ||
491 | |||
492 | if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) | ||
493 | goto err; | ||
494 | |||
495 | if (!CBS_get_u16(&cbs, &signature_scheme)) | ||
496 | goto err; | ||
497 | if (!CBS_get_u16_length_prefixed(&cbs, &signature)) | ||
498 | goto err; | ||
499 | if (CBS_len(&cbs) != 0) | ||
500 | goto err; | ||
501 | |||
502 | if ((sigalg = ssl_sigalg(signature_scheme, tls13_sigalgs, | ||
503 | tls13_sigalgs_len)) == NULL) | ||
504 | goto err; | ||
505 | |||
506 | if (!CBB_init(&cbb, 0)) | ||
507 | goto err; | ||
508 | if (!CBB_add_bytes(&cbb, cert_verify_pad, sizeof(cert_verify_pad))) | ||
509 | goto err; | ||
510 | if (!CBB_add_bytes(&cbb, server_cert_verify_context, | ||
511 | strlen(server_cert_verify_context))) | ||
512 | goto err; | ||
513 | if (!CBB_add_u8(&cbb, 0)) | ||
514 | goto err; | ||
515 | if (!CBB_add_bytes(&cbb, ctx->hs->transcript_hash, | ||
516 | ctx->hs->transcript_hash_len)) | ||
517 | goto err; | ||
518 | if (!CBB_finish(&cbb, &sig_content, &sig_content_len)) | ||
519 | goto err; | ||
520 | |||
521 | if ((cert = ctx->ssl->session->peer) == NULL) | ||
522 | goto err; | ||
523 | if ((pkey = X509_get0_pubkey(cert)) == NULL) | ||
524 | goto err; | ||
525 | if (!ssl_sigalg_pkey_ok(sigalg, pkey)) | ||
526 | goto err; | ||
527 | |||
528 | if (CBS_len(&signature) > EVP_PKEY_size(pkey)) | ||
529 | goto err; | ||
530 | |||
531 | if ((mdctx = EVP_MD_CTX_new()) == NULL) | ||
532 | goto err; | ||
533 | if (!EVP_DigestVerifyInit(mdctx, &pctx, sigalg->md(), NULL, pkey)) | ||
534 | goto err; | ||
535 | if (sigalg->flags & SIGALG_FLAG_RSA_PSS) { | ||
536 | if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)) | ||
537 | goto err; | ||
538 | if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) | ||
539 | goto err; | ||
540 | } | ||
541 | if (!EVP_DigestVerifyUpdate(mdctx, sig_content, sig_content_len)) | ||
542 | goto err; | ||
543 | if (EVP_DigestVerifyFinal(mdctx, CBS_data(&signature), | ||
544 | CBS_len(&signature)) <= 0) { | ||
545 | /* XXX - send alert. */ | ||
546 | goto err; | ||
547 | } | ||
548 | |||
549 | ret = 1; | ||
550 | |||
551 | err: | ||
552 | CBB_cleanup(&cbb); | ||
553 | EVP_MD_CTX_free(mdctx); | ||
554 | free(sig_content); | ||
555 | |||
556 | return ret; | ||
557 | } | ||
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index 8d5b0e3516..3ebf1e9d73 100644 --- a/src/lib/libssl/tls13_handshake.c +++ b/src/lib/libssl/tls13_handshake.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_handshake.c,v 1.25 2019/02/10 13:04:29 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.26 2019/02/11 17:48:15 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> |
4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
@@ -491,35 +491,12 @@ tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx) | |||
491 | } | 491 | } |
492 | 492 | ||
493 | int | 493 | int |
494 | tls13_server_certificate_recv(struct tls13_ctx *ctx) | ||
495 | { | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | int | ||
500 | tls13_server_certificate_send(struct tls13_ctx *ctx) | 494 | tls13_server_certificate_send(struct tls13_ctx *ctx) |
501 | { | 495 | { |
502 | return 0; | 496 | return 0; |
503 | } | 497 | } |
504 | 498 | ||
505 | int | 499 | int |
506 | tls13_server_certificate_request_recv(struct tls13_ctx *ctx) | ||
507 | { | ||
508 | /* | ||
509 | * Thanks to poor state design in the RFC, this function can be called | ||
510 | * when we actually have a certificate message instead of a certificate | ||
511 | * request... in that case we call the certificate handler after | ||
512 | * switching state, to avoid advancing state. | ||
513 | */ | ||
514 | if (tls13_handshake_msg_type(ctx->hs_msg) == TLS13_MT_CERTIFICATE) { | ||
515 | ctx->handshake_stage.hs_type |= WITHOUT_CR; | ||
516 | return tls13_server_certificate_recv(ctx); | ||
517 | } | ||
518 | |||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | int | ||
523 | tls13_server_certificate_request_send(struct tls13_ctx *ctx) | 500 | tls13_server_certificate_request_send(struct tls13_ctx *ctx) |
524 | { | 501 | { |
525 | return 0; | 502 | return 0; |
@@ -532,12 +509,6 @@ tls13_server_certificate_verify_send(struct tls13_ctx *ctx) | |||
532 | } | 509 | } |
533 | 510 | ||
534 | int | 511 | int |
535 | tls13_server_certificate_verify_recv(struct tls13_ctx *ctx) | ||
536 | { | ||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | int | ||
541 | tls13_server_finished_recv(struct tls13_ctx *ctx) | 512 | tls13_server_finished_recv(struct tls13_ctx *ctx) |
542 | { | 513 | { |
543 | return 0; | 514 | return 0; |