summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2022-08-21 19:32:38 +0000
committerjsing <>2022-08-21 19:32:38 +0000
commit3c351e711595523526ff652c526430c9865244a9 (patch)
treef5484c592e752999edfb43ac5fd4dba1a5e88914 /src
parent14c1d07ebeba51e7c5d52a7a218214dcd39548d4 (diff)
downloadopenbsd-3c351e711595523526ff652c526430c9865244a9.tar.gz
openbsd-3c351e711595523526ff652c526430c9865244a9.tar.bz2
openbsd-3c351e711595523526ff652c526430c9865244a9.zip
Provide SSL_QUIC_METHOD.
This provides SSL_QUIC_METHOD (aka ssl_quic_method_st), which allows for QUIC callback hooks to be passed to an SSL_CTX or SSL. This is largely ported/adapted from BoringSSL. It is worth noting that this struct is not opaque and the original interface exposed by BoringSSL differs to the one they now use. The original interface was copied by quictls and it appears that this API will not be updated to match BoringSSL. To make things even more challenging, at least one consumer does not use named initialisers, making code completely dependent on the order in which the function pointers are defined as struct members. In order to try to support both variants, the set_read_secret/set_write_secret functions are included, however they have to go at the end. ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/ssl.h151
-rw-r--r--src/lib/libssl/ssl_lib.c25
-rw-r--r--src/lib/libssl/ssl_locl.h5
3 files changed, 172 insertions, 9 deletions
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 359b554ecc..be116de775 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl.h,v 1.225 2022/08/21 19:18:57 jsing Exp $ */ 1/* $OpenBSD: ssl.h,v 1.226 2022/08/21 19:32:38 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 *
@@ -361,6 +361,10 @@ typedef struct ssl_method_st SSL_METHOD;
361typedef struct ssl_cipher_st SSL_CIPHER; 361typedef struct ssl_cipher_st SSL_CIPHER;
362typedef struct ssl_session_st SSL_SESSION; 362typedef struct ssl_session_st SSL_SESSION;
363 363
364#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL)
365typedef struct ssl_quic_method_st SSL_QUIC_METHOD;
366#endif
367
364DECLARE_STACK_OF(SSL_CIPHER) 368DECLARE_STACK_OF(SSL_CIPHER)
365 369
366/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ 370/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
@@ -1591,6 +1595,36 @@ int SSL_CTX_get_security_level(const SSL_CTX *ctx);
1591 1595
1592#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL) 1596#if defined(LIBRESSL_HAS_QUIC) || defined(LIBRESSL_INTERNAL)
1593/* 1597/*
1598 * QUIC integration.
1599 *
1600 * QUIC acts as an underlying transport for the TLS 1.3 handshake. The following
1601 * functions allow a QUIC implementation to serve as the underlying transport as
1602 * described in RFC 9001.
1603 *
1604 * When configured for QUIC, |SSL_do_handshake| will drive the handshake as
1605 * before, but it will not use the configured |BIO|. It will call functions on
1606 * |SSL_QUIC_METHOD| to configure secrets and send data. If data is needed from
1607 * the peer, it will return |SSL_ERROR_WANT_READ|. As the caller receives data
1608 * it can decrypt, it calls |SSL_provide_quic_data|. Subsequent
1609 * |SSL_do_handshake| calls will then consume that data and progress the
1610 * handshake. After the handshake is complete, the caller should continue to
1611 * call |SSL_provide_quic_data| for any post-handshake data, followed by
1612 * |SSL_process_quic_post_handshake| to process it. It is an error to call
1613 * |SSL_peek|, |SSL_read| and |SSL_write| in QUIC.
1614 *
1615 * To avoid DoS attacks, the QUIC implementation must limit the amount of data
1616 * being queued up. The implementation can call
1617 * |SSL_quic_max_handshake_flight_len| to get the maximum buffer length at each
1618 * encryption level.
1619 *
1620 * QUIC implementations must additionally configure transport parameters with
1621 * |SSL_set_quic_transport_params|. |SSL_get_peer_quic_transport_params| may be
1622 * used to query the value received from the peer. This extension is handled
1623 * as an opaque byte string, which the caller is responsible for serializing
1624 * and parsing. See RFC 9000 section 7.4 for further details.
1625 */
1626
1627/*
1594 * ssl_encryption_level_t specifies the QUIC encryption level used to transmit 1628 * ssl_encryption_level_t specifies the QUIC encryption level used to transmit
1595 * handshake messages. 1629 * handshake messages.
1596 */ 1630 */
@@ -1601,16 +1635,120 @@ typedef enum ssl_encryption_level_t {
1601 ssl_encryption_application, 1635 ssl_encryption_application,
1602} OSSL_ENCRYPTION_LEVEL; 1636} OSSL_ENCRYPTION_LEVEL;
1603 1637
1638/*
1639 * ssl_quic_method_st (aka |SSL_QUIC_METHOD|) describes custom QUIC hooks.
1640 *
1641 * Note that we provide both the new (BoringSSL) secrets interface
1642 * (set_read_secret/set_write_secret) along with the old interface
1643 * (set_encryption_secrets), which quictls is still using.
1644 *
1645 * Since some consumers fail to use named initialisers, the order of these
1646 * functions is important. Hopefully all of these consumers use the old version.
1647 */
1648struct ssl_quic_method_st {
1649 /*
1650 * set_encryption_secrets configures the read and write secrets for the
1651 * given encryption level. This function will always be called before an
1652 * encryption level other than |ssl_encryption_initial| is used.
1653 *
1654 * When reading packets at a given level, the QUIC implementation must
1655 * send ACKs at the same level, so this function provides read and write
1656 * secrets together. The exception is |ssl_encryption_early_data|, where
1657 * secrets are only available in the client to server direction. The
1658 * other secret will be NULL. The server acknowledges such data at
1659 * |ssl_encryption_application|, which will be configured in the same
1660 * |SSL_do_handshake| call.
1661 *
1662 * This function should use |SSL_get_current_cipher| to determine the TLS
1663 * cipher suite.
1664 */
1665 int (*set_encryption_secrets)(SSL *ssl, enum ssl_encryption_level_t level,
1666 const uint8_t *read_secret, const uint8_t *write_secret,
1667 size_t secret_len);
1668
1669 /*
1670 * add_handshake_data adds handshake data to the current flight at the
1671 * given encryption level. It returns one on success and zero on error.
1672 * Callers should defer writing data to the network until |flush_flight|
1673 * to better pack QUIC packets into transport datagrams.
1674 *
1675 * If |level| is not |ssl_encryption_initial|, this function will not be
1676 * called before |level| is initialized with |set_write_secret|.
1677 */
1678 int (*add_handshake_data)(SSL *ssl, enum ssl_encryption_level_t level,
1679 const uint8_t *data, size_t len);
1680
1681 /*
1682 * flush_flight is called when the current flight is complete and should
1683 * be written to the transport. Note a flight may contain data at
1684 * several encryption levels. It returns one on success and zero on
1685 * error.
1686 */
1687 int (*flush_flight)(SSL *ssl);
1688
1689 /*
1690 * send_alert sends a fatal alert at the specified encryption level. It
1691 * returns one on success and zero on error.
1692 *
1693 * If |level| is not |ssl_encryption_initial|, this function will not be
1694 * called before |level| is initialized with |set_write_secret|.
1695 */
1696 int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level,
1697 uint8_t alert);
1698
1699 /*
1700 * set_read_secret configures the read secret and cipher suite for the
1701 * given encryption level. It returns one on success and zero to
1702 * terminate the handshake with an error. It will be called at most once
1703 * per encryption level.
1704 *
1705 * Read keys will not be released before QUIC may use them. Once a level
1706 * has been initialized, QUIC may begin processing data from it.
1707 * Handshake data should be passed to |SSL_provide_quic_data| and
1708 * application data (if |level| is |ssl_encryption_early_data| or
1709 * |ssl_encryption_application|) may be processed according to the rules
1710 * of the QUIC protocol.
1711 */
1712 int (*set_read_secret)(SSL *ssl, enum ssl_encryption_level_t level,
1713 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len);
1714
1715 /*
1716 * set_write_secret behaves like |set_read_secret| but configures the
1717 * write secret and cipher suite for the given encryption level. It will
1718 * be called at most once per encryption level.
1719 *
1720 * Write keys will not be released before QUIC may use them. If |level|
1721 * is |ssl_encryption_early_data| or |ssl_encryption_application|, QUIC
1722 * may begin sending application data at |level|.
1723 */
1724 int (*set_write_secret)(SSL *ssl, enum ssl_encryption_level_t level,
1725 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len);
1726};
1727
1728/*
1729 * SSL_CTX_set_quic_method configures the QUIC hooks. This should only be
1730 * configured with a minimum version of TLS 1.3. |quic_method| must remain valid
1731 * for the lifetime of |ctx|. It returns one on success and zero on error.
1732 */
1733int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method);
1734
1735/*
1736 * SSL_set_quic_method configures the QUIC hooks. This should only be
1737 * configured with a minimum version of TLS 1.3. |quic_method| must remain valid
1738 * for the lifetime of |ssl|. It returns one on success and zero on error.
1739 */
1740int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method);
1741
1742/* SSL_is_quic returns true if an SSL has been configured for use with QUIC. */
1604int SSL_is_quic(const SSL *ssl); 1743int SSL_is_quic(const SSL *ssl);
1605 1744
1606/* 1745/*
1607 * SSL_set_quic_transport_params configures |ssl| to send |params| (of length 1746 * SSL_set_quic_transport_params configures |ssl| to send |params| (of length
1608 * |params_len|) in the quic_transport_parameters extension in either the 1747 * |params_len|) in the quic_transport_parameters extension in either the
1609 * ClientHello or EncryptedExtensions handshake message. This extension will 1748 * ClientHello or EncryptedExtensions handshake message. It is an error to set
1610 * only be sent if the TLS version is at least 1.3, and for a server, only if 1749 * transport parameters if |ssl| is not configured for QUIC. The buffer pointed
1611 * the client sent the extension. The buffer pointed to by |params| only need be 1750 * to by |params| only need be valid for the duration of the call to this
1612 * valid for the duration of the call to this function. This function returns 1 1751 * function. This function returns 1 on success and 0 on failure.
1613 *on success and 0 on failure.
1614 */ 1752 */
1615int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, 1753int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
1616 size_t params_len); 1754 size_t params_len);
@@ -1624,6 +1762,7 @@ int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
1624 */ 1762 */
1625void SSL_get_peer_quic_transport_params(const SSL *ssl, 1763void SSL_get_peer_quic_transport_params(const SSL *ssl,
1626 const uint8_t **out_params, size_t *out_params_len); 1764 const uint8_t **out_params, size_t *out_params_len);
1765
1627#endif 1766#endif
1628 1767
1629void ERR_load_SSL_strings(void); 1768void ERR_load_SSL_strings(void);
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index 515065de6c..f0f0150d19 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.302 2022/08/21 18:17:11 jsing Exp $ */ 1/* $OpenBSD: ssl_lib.c,v 1.303 2022/08/21 19:32:38 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 *
@@ -339,6 +339,7 @@ SSL_new(SSL_CTX *ctx)
339 s->verify_result = X509_V_OK; 339 s->verify_result = X509_V_OK;
340 340
341 s->method = ctx->method; 341 s->method = ctx->method;
342 s->quic_method = ctx->quic_method;
342 343
343 if (!s->method->ssl_new(s)) 344 if (!s->method->ssl_new(s))
344 goto err; 345 goto err;
@@ -2585,6 +2586,28 @@ SSL_get_error(const SSL *s, int i)
2585} 2586}
2586 2587
2587int 2588int
2589SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method)
2590{
2591 if (ctx->method->dtls)
2592 return 0;
2593
2594 ctx->quic_method = quic_method;
2595
2596 return 1;
2597}
2598
2599int
2600SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method)
2601{
2602 if (ssl->method->dtls)
2603 return 0;
2604
2605 ssl->quic_method = quic_method;
2606
2607 return 1;
2608}
2609
2610int
2588SSL_do_handshake(SSL *s) 2611SSL_do_handshake(SSL *s)
2589{ 2612{
2590 if (s->internal->handshake_func == NULL) { 2613 if (s->internal->handshake_func == NULL) {
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 6a4f14d281..d45983ac1e 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.422 2022/08/18 07:00:59 tb Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.423 2022/08/21 19:32:38 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 *
@@ -882,6 +882,7 @@ typedef struct ssl_ctx_internal_st {
882 882
883struct ssl_ctx_st { 883struct ssl_ctx_st {
884 const SSL_METHOD *method; 884 const SSL_METHOD *method;
885 const SSL_QUIC_METHOD *quic_method;
885 886
886 STACK_OF(SSL_CIPHER) *cipher_list; 887 STACK_OF(SSL_CIPHER) *cipher_list;
887 888
@@ -1073,7 +1074,7 @@ struct ssl_st {
1073 int version; 1074 int version;
1074 1075
1075 const SSL_METHOD *method; 1076 const SSL_METHOD *method;
1076 const void *quic_method; /* XXX */ 1077 const SSL_QUIC_METHOD *quic_method;
1077 1078
1078 /* There are 2 BIO's even though they are normally both the 1079 /* There are 2 BIO's even though they are normally both the
1079 * same. This is so data can be read and written to different 1080 * same. This is so data can be read and written to different