diff --git a/Cargo.lock b/Cargo.lock index c2c01bd3..305418d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -838,7 +838,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -1233,9 +1233,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "aws-lc-rs", "brotli", @@ -1907,7 +1907,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/librustls/Cargo.toml b/librustls/Cargo.toml index 01a0a5b7..2d3a419c 100644 --- a/librustls/Cargo.toml +++ b/librustls/Cargo.toml @@ -29,7 +29,7 @@ prefer-post-quantum = ["aws-lc-rs", "rustls/prefer-post-quantum"] [dependencies] # Keep in sync with RUSTLS_CRATE_VERSION in build.rs -rustls = { version = "0.23.27", default-features = false, features = ["std", "tls12"] } +rustls = { version = "0.23.28", default-features = false, features = ["std", "tls12"] } webpki = { workspace = true } libc = { workspace = true } log = { workspace = true } diff --git a/librustls/build.rs b/librustls/build.rs index 4af344a0..5a08e248 100644 --- a/librustls/build.rs +++ b/librustls/build.rs @@ -8,7 +8,7 @@ use std::{env, fs, path::PathBuf}; // because doing so would require a heavy-weight deserialization lib dependency // (and it couldn't be a _dev_ dep for use in a build script) or doing brittle // by-hand parsing. -const RUSTLS_CRATE_VERSION: &str = "0.23.27"; +const RUSTLS_CRATE_VERSION: &str = "0.23.28"; fn main() { let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); diff --git a/librustls/src/connection.rs b/librustls/src/connection.rs index 55ff4f27..9b4dba14 100644 --- a/librustls/src/connection.rs +++ b/librustls/src/connection.rs @@ -491,6 +491,21 @@ impl rustls_connection { } } + /// Retrieves the number of TLS 1.3 tickets that have been received by a client connection. + /// + /// This returns 0 if the `conn` is `NULL`, or a server connection. + #[no_mangle] + pub extern "C" fn rustls_connection_get_tls13_tickets_received( + conn: *const rustls_connection, + ) -> u32 { + ffi_panic_boundary! { + try_ref_from_ptr!(conn) + .as_client() + .map(|cc| cc.tls13_tickets_received()) + .unwrap_or_default() + } + } + /// Write up to `count` plaintext bytes from `buf` into the `rustls_connection`. /// This will increase the number of output bytes available to /// `rustls_connection_write_tls`. diff --git a/librustls/src/error.rs b/librustls/src/error.rs index 5832ceff..2ff4416e 100644 --- a/librustls/src/error.rs +++ b/librustls/src/error.rs @@ -106,7 +106,8 @@ u32_enum_builder! { CertApplicationVerificationFailure => 7130, CertOtherError => 7131, CertUnknownRevocationStatus => 7154, - CertExpiredRevocationList => 7156, // Last added. + CertExpiredRevocationList => 7156, + CertUnsupportedSignatureAlgorithm => 7157, // Last added. // From InvalidMessage, with fields that get flattened. // https://docs.rs/rustls/0.21.0/rustls/enum.Error.html#variant.InvalidMessage @@ -198,6 +199,7 @@ u32_enum_builder! { CertRevocationListUnsupportedDeltaCrl => 7408, CertRevocationListUnsupportedIndirectCrl => 7409, CertRevocationListUnsupportedRevocationReason => 7410, + CertRevocationListUnsupportedSignatureAlgorithm => 7411, // From ClientCertVerifierBuilderError, with fields that get flattened. ClientCertVerifierBuilderNoRootAnchors => 7500, @@ -341,6 +343,9 @@ impl Display for rustls_result { } CertUnknownIssuer => Error::InvalidCertificate(CertificateError::UnknownIssuer).fmt(f), CertBadSignature => Error::InvalidCertificate(CertificateError::BadSignature).fmt(f), + CertUnsupportedSignatureAlgorithm => { + Error::InvalidCertificate(CertificateError::UnsupportedSignatureAlgorithm).fmt(f) + } CertNotValidForName => { Error::InvalidCertificate(CertificateError::NotValidForName).fmt(f) } @@ -487,6 +492,10 @@ impl Display for rustls_result { CertRevocationListBadSignature => { Error::InvalidCertRevocationList(CertRevocationListError::BadSignature).fmt(f) } + CertRevocationListUnsupportedSignatureAlgorithm => Error::InvalidCertRevocationList( + CertRevocationListError::UnsupportedSignatureAlgorithm, + ) + .fmt(f), CertRevocationListInvalidCrlNumber => { Error::InvalidCertRevocationList(CertRevocationListError::InvalidCrlNumber).fmt(f) } @@ -675,6 +684,9 @@ fn map_crl_error(err: CertRevocationListError) -> rustls_result { match err { CertRevocationListError::BadSignature => CertRevocationListBadSignature, + CertRevocationListError::UnsupportedSignatureAlgorithm => { + CertRevocationListUnsupportedSignatureAlgorithm + } CertRevocationListError::InvalidCrlNumber => CertRevocationListInvalidCrlNumber, CertRevocationListError::InvalidRevokedCertSerialNumber => { CertRevocationListInvalidRevokedCertSerialNumber @@ -740,6 +752,7 @@ fn map_invalid_certificate_error(err: CertificateError) -> rustls_result { CertificateError::ExpiredRevocationList | CertificateError::ExpiredRevocationListContext { .. } => CertExpiredRevocationList, CertificateError::BadSignature => CertBadSignature, + CertificateError::UnsupportedSignatureAlgorithm => CertUnsupportedSignatureAlgorithm, CertificateError::NotValidForName | CertificateError::NotValidForNameContext { .. } => { CertNotValidForName } diff --git a/librustls/src/panic.rs b/librustls/src/panic.rs index c37f78d0..5c322103 100644 --- a/librustls/src/panic.rs +++ b/librustls/src/panic.rs @@ -30,6 +30,8 @@ pub(crate) trait Defaultable: Default {} impl Defaultable for u16 {} +impl Defaultable for u32 {} + impl Defaultable for usize {} impl Defaultable for bool {} diff --git a/librustls/src/rustls.h b/librustls/src/rustls.h index db54b7d7..42ca974e 100644 --- a/librustls/src/rustls.h +++ b/librustls/src/rustls.h @@ -90,6 +90,7 @@ enum rustls_result { RUSTLS_RESULT_CERT_OTHER_ERROR = 7131, RUSTLS_RESULT_CERT_UNKNOWN_REVOCATION_STATUS = 7154, RUSTLS_RESULT_CERT_EXPIRED_REVOCATION_LIST = 7156, + RUSTLS_RESULT_CERT_UNSUPPORTED_SIGNATURE_ALGORITHM = 7157, RUSTLS_RESULT_MESSAGE_HANDSHAKE_PAYLOAD_TOO_LARGE = 7133, RUSTLS_RESULT_MESSAGE_INVALID_CCS = 7134, RUSTLS_RESULT_MESSAGE_INVALID_CONTENT_TYPE = 7135, @@ -163,6 +164,7 @@ enum rustls_result { RUSTLS_RESULT_CERT_REVOCATION_LIST_UNSUPPORTED_DELTA_CRL = 7408, RUSTLS_RESULT_CERT_REVOCATION_LIST_UNSUPPORTED_INDIRECT_CRL = 7409, RUSTLS_RESULT_CERT_REVOCATION_LIST_UNSUPPORTED_REVOCATION_REASON = 7410, + RUSTLS_RESULT_CERT_REVOCATION_LIST_UNSUPPORTED_SIGNATURE_ALGORITHM = 7411, RUSTLS_RESULT_CLIENT_CERT_VERIFIER_BUILDER_NO_ROOT_ANCHORS = 7500, RUSTLS_RESULT_INCONSISTENT_KEYS_KEYS_MISMATCH = 7600, RUSTLS_RESULT_INCONSISTENT_KEYS_UNKNOWN = 7601, @@ -672,7 +674,13 @@ typedef struct rustls_slice_u16 { * * `signature_schemes` carries the values supplied by the client or, if the * client did not send this TLS extension, the default schemes in the rustls library. See: - * . + * . + * + * `named_groups` carries the values of the `named_groups` extension sent by the + * client. If the client did not send a `named_groups` extension, the length of + * this `rustls_slice_u16` will be 0. The meaning of this extension differ + * based on TLS version. See the Rustls documentation for more information: + * * * `alpn` carries the list of ALPN protocol names that the client proposed to * the server. Again, the length of this list will be 0 if none were supplied. @@ -687,6 +695,7 @@ typedef struct rustls_slice_u16 { typedef struct rustls_client_hello { struct rustls_str server_name; struct rustls_slice_u16 signature_schemes; + struct rustls_slice_u16 named_groups; const struct rustls_slice_slice_bytes *alpn; } rustls_client_hello; @@ -1839,6 +1848,13 @@ uint16_t rustls_connection_get_negotiated_key_exchange_group(const struct rustls */ struct rustls_str rustls_connection_get_negotiated_key_exchange_group_name(const struct rustls_connection *conn); +/** + * Retrieves the number of TLS 1.3 tickets that have been received by a client connection. + * + * This returns 0 if the `conn` is `NULL`, or a server connection. + */ +uint32_t rustls_connection_get_tls13_tickets_received(const struct rustls_connection *conn); + /** * Write up to `count` plaintext bytes from `buf` into the `rustls_connection`. * This will increase the number of output bytes available to diff --git a/librustls/src/server.rs b/librustls/src/server.rs index 3d6804b6..e0df7e97 100644 --- a/librustls/src/server.rs +++ b/librustls/src/server.rs @@ -512,7 +512,13 @@ impl ResolvesServerCert for ResolvesServerCertFromChoices { /// /// `signature_schemes` carries the values supplied by the client or, if the /// client did not send this TLS extension, the default schemes in the rustls library. See: -/// . +/// . +/// +/// `named_groups` carries the values of the `named_groups` extension sent by the +/// client. If the client did not send a `named_groups` extension, the length of +/// this `rustls_slice_u16` will be 0. The meaning of this extension differ +/// based on TLS version. See the Rustls documentation for more information: +/// /// /// `alpn` carries the list of ALPN protocol names that the client proposed to /// the server. Again, the length of this list will be 0 if none were supplied. @@ -527,6 +533,7 @@ impl ResolvesServerCert for ResolvesServerCertFromChoices { pub struct rustls_client_hello<'a> { server_name: rustls_str<'a>, signature_schemes: rustls_slice_u16<'a>, + named_groups: rustls_slice_u16<'a>, alpn: *const rustls_slice_slice_bytes<'a>, } @@ -596,6 +603,10 @@ impl ResolvesServerCert for ClientHelloResolver { .iter() .map(|s| u16::from(*s)) .collect(); + let mapped_groups = match client_hello.named_groups() { + Some(groups) => groups.iter().map(|g| u16::from(*g)).collect(), + None => Vec::new(), + }; // Unwrap the Option. None becomes an empty slice. let alpn = match client_hello.alpn() { Some(iter) => iter.collect(), @@ -604,9 +615,11 @@ impl ResolvesServerCert for ClientHelloResolver { let alpn = rustls_slice_slice_bytes { inner: &alpn }; let signature_schemes = (&*mapped_sigs).into(); + let named_groups = (&*mapped_groups).into(); let hello = rustls_client_hello { server_name, signature_schemes, + named_groups, alpn: &alpn, };