diff options
| author | jsing <> | 2022-08-21 19:42:15 +0000 |
|---|---|---|
| committer | jsing <> | 2022-08-21 19:42:15 +0000 |
| commit | 98775205fa6daaa784876d020a9f743bbffbf9f7 (patch) | |
| tree | 3f5f311135865c1a6e8755e4b00e7fd5f637f1f5 /src | |
| parent | 7fe8799b48e0b5267eb3138fe5229520af2a9519 (diff) | |
| download | openbsd-98775205fa6daaa784876d020a9f743bbffbf9f7.tar.gz openbsd-98775205fa6daaa784876d020a9f743bbffbf9f7.tar.bz2 openbsd-98775205fa6daaa784876d020a9f743bbffbf9f7.zip | |
Provide the remaining QUIC API.
While more work is still required, this is sufficient to get ngtcp2 to
compile with QUIC and for curl to be able to make HTTP/3 requests.
ok tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/ssl.h | 44 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_lib.c | 107 |
2 files changed, 149 insertions, 2 deletions
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index be116de775..caee3d60d9 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl.h,v 1.226 2022/08/21 19:32:38 jsing Exp $ */ | 1 | /* $OpenBSD: ssl.h,v 1.227 2022/08/21 19:42:15 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -1743,6 +1743,41 @@ int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method); | |||
| 1743 | int SSL_is_quic(const SSL *ssl); | 1743 | int SSL_is_quic(const SSL *ssl); |
| 1744 | 1744 | ||
| 1745 | /* | 1745 | /* |
| 1746 | * SSL_quic_max_handshake_flight_len returns returns the maximum number of bytes | ||
| 1747 | * that may be received at the given encryption level. This function should be | ||
| 1748 | * used to limit buffering in the QUIC implementation. See RFC 9000 section 7.5. | ||
| 1749 | */ | ||
| 1750 | size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, | ||
| 1751 | enum ssl_encryption_level_t level); | ||
| 1752 | |||
| 1753 | /* | ||
| 1754 | * SSL_quic_read_level returns the current read encryption level. | ||
| 1755 | */ | ||
| 1756 | enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl); | ||
| 1757 | |||
| 1758 | /* | ||
| 1759 | * SSL_quic_write_level returns the current write encryption level. | ||
| 1760 | */ | ||
| 1761 | enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl); | ||
| 1762 | |||
| 1763 | /* | ||
| 1764 | * SSL_provide_quic_data provides data from QUIC at a particular encryption | ||
| 1765 | * level |level|. It returns one on success and zero on error. Note this | ||
| 1766 | * function will return zero if the handshake is not expecting data from |level| | ||
| 1767 | * at this time. The QUIC implementation should then close the connection with | ||
| 1768 | * an error. | ||
| 1769 | */ | ||
| 1770 | int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, | ||
| 1771 | const uint8_t *data, size_t len); | ||
| 1772 | |||
| 1773 | /* | ||
| 1774 | * SSL_process_quic_post_handshake processes any data that QUIC has provided | ||
| 1775 | * after the handshake has completed. This includes NewSessionTicket messages | ||
| 1776 | * sent by the server. It returns one on success and zero on error. | ||
| 1777 | */ | ||
| 1778 | int SSL_process_quic_post_handshake(SSL *ssl); | ||
| 1779 | |||
| 1780 | /* | ||
| 1746 | * SSL_set_quic_transport_params configures |ssl| to send |params| (of length | 1781 | * SSL_set_quic_transport_params configures |ssl| to send |params| (of length |
| 1747 | * |params_len|) in the quic_transport_parameters extension in either the | 1782 | * |params_len|) in the quic_transport_parameters extension in either the |
| 1748 | * ClientHello or EncryptedExtensions handshake message. It is an error to set | 1783 | * ClientHello or EncryptedExtensions handshake message. It is an error to set |
| @@ -1763,6 +1798,13 @@ int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, | |||
| 1763 | void SSL_get_peer_quic_transport_params(const SSL *ssl, | 1798 | void SSL_get_peer_quic_transport_params(const SSL *ssl, |
| 1764 | const uint8_t **out_params, size_t *out_params_len); | 1799 | const uint8_t **out_params, size_t *out_params_len); |
| 1765 | 1800 | ||
| 1801 | /* | ||
| 1802 | * SSL_set_quic_use_legacy_codepoint configures whether to use the legacy QUIC | ||
| 1803 | * extension codepoint 0xffa5 as opposed to the official value 57. This is | ||
| 1804 | * unsupported in LibreSSL. | ||
| 1805 | */ | ||
| 1806 | void SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy); | ||
| 1807 | |||
| 1766 | #endif | 1808 | #endif |
| 1767 | 1809 | ||
| 1768 | void ERR_load_SSL_strings(void); | 1810 | void ERR_load_SSL_strings(void); |
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index f0f0150d19..c0ca19c7c1 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_lib.c,v 1.303 2022/08/21 19:32:38 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.304 2022/08/21 19:42:15 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -2607,6 +2607,105 @@ SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) | |||
| 2607 | return 1; | 2607 | return 1; |
| 2608 | } | 2608 | } |
| 2609 | 2609 | ||
| 2610 | size_t | ||
| 2611 | SSL_quic_max_handshake_flight_len(const SSL *ssl, | ||
| 2612 | enum ssl_encryption_level_t level) | ||
| 2613 | { | ||
| 2614 | size_t flight_len; | ||
| 2615 | |||
| 2616 | /* Limit flights to 16K when there are no large certificate messages. */ | ||
| 2617 | flight_len = 16384; | ||
| 2618 | |||
| 2619 | switch (level) { | ||
| 2620 | case ssl_encryption_initial: | ||
| 2621 | return flight_len; | ||
| 2622 | |||
| 2623 | case ssl_encryption_early_data: | ||
| 2624 | /* QUIC does not send EndOfEarlyData. */ | ||
| 2625 | return 0; | ||
| 2626 | |||
| 2627 | case ssl_encryption_handshake: | ||
| 2628 | if (ssl->server) { | ||
| 2629 | /* | ||
| 2630 | * Servers may receive Certificate message if configured | ||
| 2631 | * to request client certificates. | ||
| 2632 | */ | ||
| 2633 | if ((SSL_get_verify_mode(ssl) & SSL_VERIFY_PEER) != 0 && | ||
| 2634 | ssl->internal->max_cert_list > flight_len) | ||
| 2635 | flight_len = ssl->internal->max_cert_list; | ||
| 2636 | } else { | ||
| 2637 | /* | ||
| 2638 | * Clients may receive both Certificate message and a | ||
| 2639 | * CertificateRequest message. | ||
| 2640 | */ | ||
| 2641 | if (ssl->internal->max_cert_list * 2 > flight_len) | ||
| 2642 | flight_len = ssl->internal->max_cert_list * 2; | ||
| 2643 | } | ||
| 2644 | return flight_len; | ||
| 2645 | case ssl_encryption_application: | ||
| 2646 | /* | ||
| 2647 | * Note there is not actually a bound on the number of | ||
| 2648 | * NewSessionTickets one may send in a row. This level may need | ||
| 2649 | * more involved flow control. | ||
| 2650 | */ | ||
| 2651 | return flight_len; | ||
| 2652 | } | ||
| 2653 | |||
| 2654 | return 0; | ||
| 2655 | } | ||
| 2656 | |||
| 2657 | enum ssl_encryption_level_t | ||
| 2658 | SSL_quic_read_level(const SSL *ssl) | ||
| 2659 | { | ||
| 2660 | return ssl->s3->hs.tls13.quic_read_level; | ||
| 2661 | } | ||
| 2662 | |||
| 2663 | enum ssl_encryption_level_t | ||
| 2664 | SSL_quic_write_level(const SSL *ssl) | ||
| 2665 | { | ||
| 2666 | return ssl->s3->hs.tls13.quic_write_level; | ||
| 2667 | } | ||
| 2668 | |||
| 2669 | int | ||
| 2670 | SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, | ||
| 2671 | const uint8_t *data, size_t len) | ||
| 2672 | { | ||
| 2673 | if (!SSL_is_quic(ssl)) { | ||
| 2674 | SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 2675 | return 0; | ||
| 2676 | } | ||
| 2677 | |||
| 2678 | if (level != SSL_quic_read_level(ssl)) { | ||
| 2679 | SSLerror(ssl, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); | ||
| 2680 | return 0; | ||
| 2681 | } | ||
| 2682 | |||
| 2683 | if (ssl->s3->hs.tls13.quic_read_buffer == NULL) { | ||
| 2684 | ssl->s3->hs.tls13.quic_read_buffer = tls_buffer_new(0); | ||
| 2685 | if (ssl->s3->hs.tls13.quic_read_buffer == NULL) { | ||
| 2686 | SSLerror(ssl, ERR_R_MALLOC_FAILURE); | ||
| 2687 | return 0; | ||
| 2688 | } | ||
| 2689 | } | ||
| 2690 | |||
| 2691 | /* XXX - note that this does not currently downsize. */ | ||
| 2692 | tls_buffer_set_capacity_limit(ssl->s3->hs.tls13.quic_read_buffer, | ||
| 2693 | SSL_quic_max_handshake_flight_len(ssl, level)); | ||
| 2694 | |||
| 2695 | /* | ||
| 2696 | * XXX - an append that fails due to exceeding capacity should set | ||
| 2697 | * SSL_R_EXCESSIVE_MESSAGE_SIZE. | ||
| 2698 | */ | ||
| 2699 | return tls_buffer_append(ssl->s3->hs.tls13.quic_read_buffer, data, len); | ||
| 2700 | } | ||
| 2701 | |||
| 2702 | int | ||
| 2703 | SSL_process_quic_post_handshake(SSL *ssl) | ||
| 2704 | { | ||
| 2705 | /* XXX - this needs to run PHH received. */ | ||
| 2706 | return 1; | ||
| 2707 | } | ||
| 2708 | |||
| 2610 | int | 2709 | int |
| 2611 | SSL_do_handshake(SSL *s) | 2710 | SSL_do_handshake(SSL *s) |
| 2612 | { | 2711 | { |
| @@ -3371,6 +3470,12 @@ SSL_get_peer_quic_transport_params(const SSL *ssl, const uint8_t **out_params, | |||
| 3371 | *out_params_len = ssl->s3->peer_quic_transport_params_len; | 3470 | *out_params_len = ssl->s3->peer_quic_transport_params_len; |
| 3372 | } | 3471 | } |
| 3373 | 3472 | ||
| 3473 | void | ||
| 3474 | SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy) | ||
| 3475 | { | ||
| 3476 | /* Not supported. */ | ||
| 3477 | } | ||
| 3478 | |||
| 3374 | static int | 3479 | static int |
| 3375 | ssl_cipher_id_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) | 3480 | ssl_cipher_id_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) |
| 3376 | { | 3481 | { |
