From c5de3995a666778fc58dd90aaa9194bcd458db2b Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sun, 28 Sep 2025 13:44:27 -0400 Subject: [PATCH 1/4] librustls: replace u32_enum_builder macro We only used this for `rustls_result`, and in practice it only saved us having to implement `From` by hand. That's handy, but comes at the cost of needing to use the nightly toolchain w/ cbindgen so it can expand the macro before generating the `.h`. That wasn't the worst, but a nighty regression that has remained unfixed for months broke this workflow. In sum: life will be easier without the macro. RIP. --- librustls/src/error.rs | 489 +++++++++++++++++++++++++---------------- 1 file changed, 299 insertions(+), 190 deletions(-) diff --git a/librustls/src/error.rs b/librustls/src/error.rs index 333525dc..db730cdd 100644 --- a/librustls/src/error.rs +++ b/librustls/src/error.rs @@ -20,198 +20,307 @@ use crate::panic::ffi_panic_boundary; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct rustls_io_result(pub libc::c_int); -macro_rules! u32_enum_builder { - ( - $(#[$comment:meta])* - EnumName: $enum_name: ident; - EnumDefault: $enum_default: ident; - EnumVal { $( $enum_var: ident => $enum_val: expr ),* } - ) => { - $(#[$comment])* - #[allow(dead_code)] - #[repr(u32)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub enum $enum_name { - $( $enum_var = $enum_val),* - } - impl From for $enum_name { - fn from(x: u32) -> Self { - match x { - $($enum_val => $enum_name::$enum_var),* - , _ => $enum_name::$enum_default, - } - } - } - }; +/// Numeric error codes returned from rustls-ffi API functions. +#[allow(dead_code)] +#[repr(u32)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum rustls_result { + Ok = 7000, + Io = 7001, + NullParameter = 7002, + InvalidDnsNameError = 7003, + Panic = 7004, + CertificateParseError = 7005, + PrivateKeyParseError = 7006, + InsufficientSize = 7007, + NotFound = 7008, + InvalidParameter = 7009, + UnexpectedEof = 7010, + PlaintextEmpty = 7011, + AcceptorNotReady = 7012, + AlreadyUsed = 7013, + CertificateRevocationListParseError = 7014, + NoServerCertVerifier = 7015, + NoDefaultCryptoProvider = 7016, + GetRandomFailed = 7017, + NoCertResolver = 7018, + HpkeError = 7019, + BuilderIncompatibleTlsVersions = 7020, + + // From https://docs.rs/rustls/latest/rustls/enum.Error.html + NoCertificatesPresented = 7101, + DecryptError = 7102, + FailedToGetCurrentTime = 7103, + FailedToGetRandomBytes = 7113, + HandshakeNotComplete = 7104, + PeerSentOversizedRecord = 7105, + NoApplicationProtocol = 7106, + BadMaxFragmentSize = 7114, + UnsupportedNameType = 7115, + EncryptError = 7116, + + // Reserved from previous use pre rustls-ffi <0.21.0 + // CorruptMessage => 7100, + // CorruptMessagePayload => 7111, + // CertInvalidEncoding => 7117, + // CertInvalidSignatureType => 7118, + // CertInvalidSignature => 7119, + // CertInvalidData => 7120, + + // From InvalidCertificate, with fields that get flattened. + // https://docs.rs/rustls/0.21.0/rustls/enum.Error.html#variant.InvalidCertificate + CertEncodingBad = 7121, + CertExpired = 7122, + CertNotYetValid = 7123, + CertRevoked = 7124, + CertUnhandledCriticalExtension = 7125, + CertUnknownIssuer = 7126, + CertBadSignature = 7127, + CertNotValidForName = 7128, + CertInvalidPurpose = 7129, + CertApplicationVerificationFailure = 7130, + CertOtherError = 7131, + CertUnknownRevocationStatus = 7154, + 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 + MessageHandshakePayloadTooLarge = 7133, + MessageInvalidCcs = 7134, + MessageInvalidContentType = 7135, + MessageInvalidCertStatusType = 7136, + MessageInvalidCertRequest = 7137, + MessageInvalidDhParams = 7138, + MessageInvalidEmptyPayload = 7139, + MessageInvalidKeyUpdate = 7140, + MessageInvalidServerName = 7141, + MessageTooLarge = 7142, + MessageTooShort = 7143, + MessageMissingData = 7144, + MessageMissingKeyExchange = 7145, + MessageNoSignatureSchemes = 7146, + MessageTrailingData = 7147, + MessageUnexpectedMessage = 7148, + MessageUnknownProtocolVersion = 7149, + MessageUnsupportedCompression = 7150, + MessageUnsupportedCurveType = 7151, + MessageUnsupportedKeyExchangeAlgorithm = 7152, + MessageInvalidOther = 7153, + MessageCertificatePayloadTooLarge = 7155, + + // From Error, with fields that get dropped. + PeerIncompatibleError = 7107, + PeerMisbehavedError = 7108, + InappropriateMessage = 7109, + InappropriateHandshakeMessage = 7110, + General = 7112, + + // From Error, with fields that get flattened. + // https://docs.rs/rustls/latest/rustls/internal/msgs/enums/enum.AlertDescription.html + AlertCloseNotify = 7200, + AlertUnexpectedMessage = 7201, + AlertBadRecordMac = 7202, + AlertDecryptionFailed = 7203, + AlertRecordOverflow = 7204, + AlertDecompressionFailure = 7205, + AlertHandshakeFailure = 7206, + AlertNoCertificate = 7207, + AlertBadCertificate = 7208, + AlertUnsupportedCertificate = 7209, + AlertCertificateRevoked = 7210, + AlertCertificateExpired = 7211, + AlertCertificateUnknown = 7212, + AlertIllegalParameter = 7213, + AlertUnknownCA = 7214, + AlertAccessDenied = 7215, + AlertDecodeError = 7216, + AlertDecryptError = 7217, + AlertExportRestriction = 7218, + AlertProtocolVersion = 7219, + AlertInsufficientSecurity = 7220, + AlertInternalError = 7221, + AlertInappropriateFallback = 7222, + AlertUserCanceled = 7223, + AlertNoRenegotiation = 7224, + AlertMissingExtension = 7225, + AlertUnsupportedExtension = 7226, + AlertCertificateUnobtainable = 7227, + AlertUnrecognisedName = 7228, + AlertBadCertificateStatusResponse = 7229, + AlertBadCertificateHashValue = 7230, + AlertUnknownPSKIdentity = 7231, + AlertCertificateRequired = 7232, + AlertNoApplicationProtocol = 7233, + AlertUnknown = 7234, + + // Reserved from previous use pre rustls-ffi <0.22.0 + // CertSCTMalformed => 7319, + // CertSCTInvalidSignature => 7320, + // CertSCTTimestampInFuture => 7321, + // CertSCTUnsupportedVersion => 7322, + // CertSCTUnknownLog => 7323, + + // From InvalidCertRevocationList, with fields that get flattened. + // https://docs.rs/rustls/0.21.6/rustls/enum.Error.html#variant.InvalidCertRevocationList + CertRevocationListBadSignature = 7400, + CertRevocationListInvalidCrlNumber = 7401, + CertRevocationListInvalidRevokedCertSerialNumber = 7402, + CertRevocationListIssuerInvalidForCrl = 7403, + CertRevocationListOtherError = 7404, + CertRevocationListParseError = 7405, + CertRevocationListUnsupportedCrlVersion = 7406, + CertRevocationListUnsupportedCriticalExtension = 7407, + CertRevocationListUnsupportedDeltaCrl = 7408, + CertRevocationListUnsupportedIndirectCrl = 7409, + CertRevocationListUnsupportedRevocationReason = 7410, + CertRevocationListUnsupportedSignatureAlgorithm = 7411, + + // From ClientCertVerifierBuilderError, with fields that get flattened. + ClientCertVerifierBuilderNoRootAnchors = 7500, + + // From InconsistentKeys, with fields that get flattened. + InconsistentKeysKeysMismatch = 7600, + InconsistentKeysUnknown = 7601, + + // From InvalidEncryptedClientHello, with fields that get flattened. + InvalidEncryptedClientHelloInvalidConfigList = 7700, + InvalidEncryptedClientHelloNoCompatibleConfig = 7701, + InvalidEncryptedClientHelloSniRequired = 7702, } -u32_enum_builder! { - /// Numeric error codes returned from rustls-ffi API functions. - EnumName: rustls_result; - EnumDefault: InvalidParameter; - EnumVal{ - Ok => 7000, - Io => 7001, - NullParameter => 7002, - InvalidDnsNameError => 7003, - Panic => 7004, - CertificateParseError => 7005, - PrivateKeyParseError => 7006, - InsufficientSize => 7007, - NotFound => 7008, - InvalidParameter => 7009, - UnexpectedEof => 7010, - PlaintextEmpty => 7011, - AcceptorNotReady => 7012, - AlreadyUsed => 7013, - CertificateRevocationListParseError => 7014, - NoServerCertVerifier => 7015, - NoDefaultCryptoProvider => 7016, - GetRandomFailed => 7017, - NoCertResolver => 7018, - HpkeError => 7019, - BuilderIncompatibleTlsVersions => 7020, - - // From https://docs.rs/rustls/latest/rustls/enum.Error.html - NoCertificatesPresented => 7101, - DecryptError => 7102, - FailedToGetCurrentTime => 7103, - FailedToGetRandomBytes => 7113, - HandshakeNotComplete => 7104, - PeerSentOversizedRecord => 7105, - NoApplicationProtocol => 7106, - BadMaxFragmentSize => 7114, - UnsupportedNameType => 7115, - EncryptError => 7116, - - // Reserved from previous use pre rustls-ffi <0.21.0 - // CorruptMessage => 7100, - // CorruptMessagePayload => 7111, - // CertInvalidEncoding => 7117, - // CertInvalidSignatureType => 7118, - // CertInvalidSignature => 7119, - // CertInvalidData => 7120, - - // From InvalidCertificate, with fields that get flattened. - // https://docs.rs/rustls/0.21.0/rustls/enum.Error.html#variant.InvalidCertificate - CertEncodingBad => 7121, - CertExpired => 7122, - CertNotYetValid => 7123, - CertRevoked => 7124, - CertUnhandledCriticalExtension => 7125, - CertUnknownIssuer => 7126, - CertBadSignature => 7127, - CertNotValidForName => 7128, - CertInvalidPurpose => 7129, - CertApplicationVerificationFailure => 7130, - CertOtherError => 7131, - CertUnknownRevocationStatus => 7154, - 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 - MessageHandshakePayloadTooLarge => 7133, - MessageInvalidCcs => 7134, - MessageInvalidContentType => 7135, - MessageInvalidCertStatusType => 7136, - MessageInvalidCertRequest => 7137, - MessageInvalidDhParams => 7138, - MessageInvalidEmptyPayload => 7139, - MessageInvalidKeyUpdate => 7140, - MessageInvalidServerName => 7141, - MessageTooLarge => 7142, - MessageTooShort => 7143, - MessageMissingData => 7144, - MessageMissingKeyExchange => 7145, - MessageNoSignatureSchemes => 7146, - MessageTrailingData => 7147, - MessageUnexpectedMessage => 7148, - MessageUnknownProtocolVersion => 7149, - MessageUnsupportedCompression => 7150, - MessageUnsupportedCurveType => 7151, - MessageUnsupportedKeyExchangeAlgorithm => 7152, - MessageInvalidOther => 7153, - MessageCertificatePayloadTooLarge => 7155, - - // From Error, with fields that get dropped. - PeerIncompatibleError => 7107, - PeerMisbehavedError => 7108, - InappropriateMessage => 7109, - InappropriateHandshakeMessage => 7110, - General => 7112, - - // From Error, with fields that get flattened. - // https://docs.rs/rustls/latest/rustls/internal/msgs/enums/enum.AlertDescription.html - AlertCloseNotify => 7200, - AlertUnexpectedMessage => 7201, - AlertBadRecordMac => 7202, - AlertDecryptionFailed => 7203, - AlertRecordOverflow => 7204, - AlertDecompressionFailure => 7205, - AlertHandshakeFailure => 7206, - AlertNoCertificate => 7207, - AlertBadCertificate => 7208, - AlertUnsupportedCertificate => 7209, - AlertCertificateRevoked => 7210, - AlertCertificateExpired => 7211, - AlertCertificateUnknown => 7212, - AlertIllegalParameter => 7213, - AlertUnknownCA => 7214, - AlertAccessDenied => 7215, - AlertDecodeError => 7216, - AlertDecryptError => 7217, - AlertExportRestriction => 7218, - AlertProtocolVersion => 7219, - AlertInsufficientSecurity => 7220, - AlertInternalError => 7221, - AlertInappropriateFallback => 7222, - AlertUserCanceled => 7223, - AlertNoRenegotiation => 7224, - AlertMissingExtension => 7225, - AlertUnsupportedExtension => 7226, - AlertCertificateUnobtainable => 7227, - AlertUnrecognisedName => 7228, - AlertBadCertificateStatusResponse => 7229, - AlertBadCertificateHashValue => 7230, - AlertUnknownPSKIdentity => 7231, - AlertCertificateRequired => 7232, - AlertNoApplicationProtocol => 7233, - AlertUnknown => 7234, - - // Reserved from previous use pre rustls-ffi <0.22.0 - // CertSCTMalformed => 7319, - // CertSCTInvalidSignature => 7320, - // CertSCTTimestampInFuture => 7321, - // CertSCTUnsupportedVersion => 7322, - // CertSCTUnknownLog => 7323, - - // From InvalidCertRevocationList, with fields that get flattened. - // https://docs.rs/rustls/0.21.6/rustls/enum.Error.html#variant.InvalidCertRevocationList - CertRevocationListBadSignature => 7400, - CertRevocationListInvalidCrlNumber => 7401, - CertRevocationListInvalidRevokedCertSerialNumber => 7402, - CertRevocationListIssuerInvalidForCrl => 7403, - CertRevocationListOtherError => 7404, - CertRevocationListParseError => 7405, - CertRevocationListUnsupportedCrlVersion => 7406, - CertRevocationListUnsupportedCriticalExtension => 7407, - CertRevocationListUnsupportedDeltaCrl => 7408, - CertRevocationListUnsupportedIndirectCrl => 7409, - CertRevocationListUnsupportedRevocationReason => 7410, - CertRevocationListUnsupportedSignatureAlgorithm => 7411, - - // From ClientCertVerifierBuilderError, with fields that get flattened. - ClientCertVerifierBuilderNoRootAnchors => 7500, - - // From InconsistentKeys, with fields that get flattened. - InconsistentKeysKeysMismatch => 7600, - InconsistentKeysUnknown => 7601, - - // From InvalidEncryptedClientHello, with fields that get flattened. - InvalidEncryptedClientHelloInvalidConfigList => 7700, - InvalidEncryptedClientHelloNoCompatibleConfig => 7701, - InvalidEncryptedClientHelloSniRequired => 7702 +impl From for rustls_result { + fn from(x: u32) -> Self { + use rustls_result::*; + + match x { + 7000 => Ok, + 7001 => Io, + 7002 => NullParameter, + 7003 => InvalidDnsNameError, + 7004 => Panic, + 7005 => CertificateParseError, + 7006 => PrivateKeyParseError, + 7007 => InsufficientSize, + 7008 => NotFound, + 7009 => InvalidParameter, + 7010 => UnexpectedEof, + 7011 => PlaintextEmpty, + 7012 => AcceptorNotReady, + 7013 => AlreadyUsed, + 7014 => CertificateRevocationListParseError, + 7015 => NoServerCertVerifier, + 7016 => NoDefaultCryptoProvider, + 7017 => GetRandomFailed, + 7018 => NoCertResolver, + 7019 => HpkeError, + 7020 => BuilderIncompatibleTlsVersions, + 7101 => NoCertificatesPresented, + 7102 => DecryptError, + 7103 => FailedToGetCurrentTime, + 7113 => FailedToGetRandomBytes, + 7104 => HandshakeNotComplete, + 7105 => PeerSentOversizedRecord, + 7106 => NoApplicationProtocol, + 7114 => BadMaxFragmentSize, + 7115 => UnsupportedNameType, + 7116 => EncryptError, + 7121 => CertEncodingBad, + 7122 => CertExpired, + 7123 => CertNotYetValid, + 7124 => CertRevoked, + 7125 => CertUnhandledCriticalExtension, + 7126 => CertUnknownIssuer, + 7127 => CertBadSignature, + 7128 => CertNotValidForName, + 7129 => CertInvalidPurpose, + 7130 => CertApplicationVerificationFailure, + 7131 => CertOtherError, + 7154 => CertUnknownRevocationStatus, + 7156 => CertExpiredRevocationList, + 7157 => CertUnsupportedSignatureAlgorithm, + 7133 => MessageHandshakePayloadTooLarge, + 7134 => MessageInvalidCcs, + 7135 => MessageInvalidContentType, + 7136 => MessageInvalidCertStatusType, + 7137 => MessageInvalidCertRequest, + 7138 => MessageInvalidDhParams, + 7139 => MessageInvalidEmptyPayload, + 7140 => MessageInvalidKeyUpdate, + 7141 => MessageInvalidServerName, + 7142 => MessageTooLarge, + 7143 => MessageTooShort, + 7144 => MessageMissingData, + 7145 => MessageMissingKeyExchange, + 7146 => MessageNoSignatureSchemes, + 7147 => MessageTrailingData, + 7148 => MessageUnexpectedMessage, + 7149 => MessageUnknownProtocolVersion, + 7150 => MessageUnsupportedCompression, + 7151 => MessageUnsupportedCurveType, + 7152 => MessageUnsupportedKeyExchangeAlgorithm, + 7153 => MessageInvalidOther, + 7155 => MessageCertificatePayloadTooLarge, + 7107 => PeerIncompatibleError, + 7108 => PeerMisbehavedError, + 7109 => InappropriateMessage, + 7110 => InappropriateHandshakeMessage, + 7112 => General, + 7200 => AlertCloseNotify, + 7201 => AlertUnexpectedMessage, + 7202 => AlertBadRecordMac, + 7203 => AlertDecryptionFailed, + 7204 => AlertRecordOverflow, + 7205 => AlertDecompressionFailure, + 7206 => AlertHandshakeFailure, + 7207 => AlertNoCertificate, + 7208 => AlertBadCertificate, + 7209 => AlertUnsupportedCertificate, + 7210 => AlertCertificateRevoked, + 7211 => AlertCertificateExpired, + 7212 => AlertCertificateUnknown, + 7213 => AlertIllegalParameter, + 7214 => AlertUnknownCA, + 7215 => AlertAccessDenied, + 7216 => AlertDecodeError, + 7217 => AlertDecryptError, + 7218 => AlertExportRestriction, + 7219 => AlertProtocolVersion, + 7220 => AlertInsufficientSecurity, + 7221 => AlertInternalError, + 7222 => AlertInappropriateFallback, + 7223 => AlertUserCanceled, + 7224 => AlertNoRenegotiation, + 7225 => AlertMissingExtension, + 7226 => AlertUnsupportedExtension, + 7227 => AlertCertificateUnobtainable, + 7228 => AlertUnrecognisedName, + 7229 => AlertBadCertificateStatusResponse, + 7230 => AlertBadCertificateHashValue, + 7231 => AlertUnknownPSKIdentity, + 7232 => AlertCertificateRequired, + 7233 => AlertNoApplicationProtocol, + 7234 => AlertUnknown, + 7400 => CertRevocationListBadSignature, + 7401 => CertRevocationListInvalidCrlNumber, + 7402 => CertRevocationListInvalidRevokedCertSerialNumber, + 7403 => CertRevocationListIssuerInvalidForCrl, + 7404 => CertRevocationListOtherError, + 7405 => CertRevocationListParseError, + 7406 => CertRevocationListUnsupportedCrlVersion, + 7407 => CertRevocationListUnsupportedCriticalExtension, + 7408 => CertRevocationListUnsupportedDeltaCrl, + 7409 => CertRevocationListUnsupportedIndirectCrl, + 7410 => CertRevocationListUnsupportedRevocationReason, + 7411 => CertRevocationListUnsupportedSignatureAlgorithm, + 7500 => ClientCertVerifierBuilderNoRootAnchors, + 7600 => InconsistentKeysKeysMismatch, + 7601 => InconsistentKeysUnknown, + 7700 => InvalidEncryptedClientHelloInvalidConfigList, + 7701 => InvalidEncryptedClientHelloNoCompatibleConfig, + 7702 => InvalidEncryptedClientHelloSniRequired, + _ => InvalidParameter, + } } } From 42d81bb3d2b7b0a9b046832dc11defd68e4f97b2 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sun, 28 Sep 2025 14:14:09 -0400 Subject: [PATCH 2/4] librustls: replace castable macros They're helpful, but require us to use cbindgen's parse.expand feature which in turn requires nightly, and is broken with nightly since ~April. --- librustls/src/acceptor.rs | 93 +++++++++++++++----------- librustls/src/certificate.rs | 71 +++++++++++++------- librustls/src/cipher.rs | 13 ++-- librustls/src/client.rs | 52 +++++++++------ librustls/src/connection.rs | 13 ++-- librustls/src/crypto_provider.rs | 60 +++++++++++------ librustls/src/ffi.rs | 94 --------------------------- librustls/src/server.rs | 52 +++++++++------ librustls/src/verifier.rs | 108 ++++++++++++++++++------------- 9 files changed, 284 insertions(+), 272 deletions(-) diff --git a/librustls/src/acceptor.rs b/librustls/src/acceptor.rs index 1c609c9b..bc4504c7 100644 --- a/librustls/src/acceptor.rs +++ b/librustls/src/acceptor.rs @@ -4,7 +4,7 @@ use rustls::server::{Accepted, AcceptedAlert, Acceptor}; use crate::connection::rustls_connection; use crate::error::{map_error, rustls_io_result, rustls_result}; use crate::ffi::{ - box_castable, free_box, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr, try_callback, + Castable, OwnershipBox, free_box, set_boxed_mut_ptr, to_box, to_boxed_mut_ptr, try_callback, try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr, try_ref_from_ptr, try_take, }; use crate::io::{CallbackReader, CallbackWriter, rustls_read_callback, rustls_write_callback}; @@ -12,43 +12,53 @@ use crate::panic::ffi_panic_boundary; use crate::rslice::{rustls_slice_bytes, rustls_str}; use crate::server::rustls_server_config; -box_castable! { - /// A buffer and parser for ClientHello bytes. - /// - /// This allows reading ClientHello before choosing a rustls_server_config. - /// - /// It's useful when the server config will be based on parameters in the - /// ClientHello: server name indication (SNI), ALPN protocols, signature - /// schemes, and cipher suites. - /// - /// In particular, if a server wants to do some potentially expensive work - /// to load a certificate for a given hostname, rustls_acceptor allows doing - /// that asynchronously, as opposed to rustls_server_config_builder_set_hello_callback(), - /// which doesn't work well for asynchronous I/O. - /// - /// The general flow is: - /// - rustls_acceptor_new() - /// - Loop: - /// - Read bytes from the network it with rustls_acceptor_read_tls(). - /// - If successful, parse those bytes with rustls_acceptor_accept(). - /// - If that returns RUSTLS_RESULT_ACCEPTOR_NOT_READY, continue. - /// - Otherwise, break. - /// - If rustls_acceptor_accept() returned RUSTLS_RESULT_OK: - /// - Examine the resulting rustls_accepted. - /// - Create or select a rustls_server_config. - /// - Call rustls_accepted_into_connection(). - /// - Otherwise, there was a problem with the ClientHello data and the - /// connection should be rejected. - pub struct rustls_acceptor(Acceptor); +/// A buffer and parser for ClientHello bytes. +/// +/// This allows reading ClientHello before choosing a rustls_server_config. +/// +/// It's useful when the server config will be based on parameters in the +/// ClientHello: server name indication (SNI), ALPN protocols, signature +/// schemes, and cipher suites. +/// +/// In particular, if a server wants to do some potentially expensive work +/// to load a certificate for a given hostname, rustls_acceptor allows doing +/// that asynchronously, as opposed to rustls_server_config_builder_set_hello_callback(), +/// which doesn't work well for asynchronous I/O. +/// +/// The general flow is: +/// - rustls_acceptor_new() +/// - Loop: +/// - Read bytes from the network it with rustls_acceptor_read_tls(). +/// - If successful, parse those bytes with rustls_acceptor_accept(). +/// - If that returns RUSTLS_RESULT_ACCEPTOR_NOT_READY, continue. +/// - Otherwise, break. +/// - If rustls_acceptor_accept() returned RUSTLS_RESULT_OK: +/// - Examine the resulting rustls_accepted. +/// - Create or select a rustls_server_config. +/// - Call rustls_accepted_into_connection(). +/// - Otherwise, there was a problem with the ClientHello data and the +/// connection should be rejected. +pub struct rustls_acceptor { + _private: [u8; 0], } -box_castable! { - /// A parsed ClientHello produced by a rustls_acceptor. - /// - /// It is used to check server name indication (SNI), ALPN protocols, - /// signature schemes, and cipher suites. It can be combined with a - /// `rustls_server_config` to build a `rustls_connection`. - pub struct rustls_accepted(Option); +impl Castable for rustls_acceptor { + type Ownership = OwnershipBox; + type RustType = Acceptor; +} + +/// A parsed ClientHello produced by a rustls_acceptor. +/// +/// It is used to check server name indication (SNI), ALPN protocols, +/// signature schemes, and cipher suites. It can be combined with a +/// `rustls_server_config` to build a `rustls_connection`. +pub struct rustls_accepted { + _private: [u8; 0], +} + +impl Castable for rustls_accepted { + type Ownership = OwnershipBox; + type RustType = Option; } impl rustls_acceptor { @@ -446,9 +456,14 @@ impl rustls_accepted { } } -box_castable! { - /// Represents a TLS alert resulting from accepting a client. - pub struct rustls_accepted_alert(AcceptedAlert); +/// Represents a TLS alert resulting from accepting a client. +pub struct rustls_accepted_alert { + _private: [u8; 0], +} + +impl Castable for rustls_accepted_alert { + type Ownership = OwnershipBox; + type RustType = AcceptedAlert; } impl rustls_accepted_alert { diff --git a/librustls/src/certificate.rs b/librustls/src/certificate.rs index 1f76e783..0e164423 100644 --- a/librustls/src/certificate.rs +++ b/librustls/src/certificate.rs @@ -12,18 +12,24 @@ use rustls::sign::CertifiedKey; use crate::crypto_provider::{self, rustls_signing_key}; use crate::error::{map_error, rustls_result}; use crate::ffi::{ - arc_castable, box_castable, free_arc, free_box, ref_castable, set_arc_mut_ptr, + Castable, OwnershipArc, OwnershipBox, OwnershipRef, free_arc, free_box, set_arc_mut_ptr, to_arc_const_ptr, to_boxed_mut_ptr, try_box_from_ptr, try_mut_from_ptr, try_ref_from_ptr, try_ref_from_ptr_ptr, try_slice, try_take, }; use crate::panic::ffi_panic_boundary; use crate::rslice::rustls_slice_bytes; -ref_castable! { - /// An X.509 certificate, as used in rustls. - /// Corresponds to `CertificateDer` in the Rust pki-types API. - /// - pub struct rustls_certificate(CertificateDer<'a>); +/// An X.509 certificate, as used in rustls. +/// Corresponds to `CertificateDer` in the Rust pki-types API. +/// +pub struct rustls_certificate<'a> { + _private: [u8; 0], + _marker: PhantomData<&'a ()>, +} + +impl<'a> Castable for rustls_certificate<'a> { + type Ownership = OwnershipRef; + type RustType = CertificateDer<'a>; } /// Get the DER data of the certificate itself. @@ -48,13 +54,18 @@ pub extern "C" fn rustls_certificate_get_der( } } -arc_castable! { - /// The complete chain of certificates to send during a TLS handshake, - /// plus a private key that matches the end-entity (leaf) certificate. - /// - /// Corresponds to `CertifiedKey` in the Rust API. - /// - pub struct rustls_certified_key(CertifiedKey); +/// The complete chain of certificates to send during a TLS handshake, +/// plus a private key that matches the end-entity (leaf) certificate. +/// +/// Corresponds to `CertifiedKey` in the Rust API. +/// +pub struct rustls_certified_key { + _private: [u8; 0], +} + +impl Castable for rustls_certified_key { + type Ownership = OwnershipArc; + type RustType = CertifiedKey; } impl rustls_certified_key { @@ -270,14 +281,19 @@ impl rustls_certified_key { } } -box_castable! { - /// A `rustls_root_cert_store` being constructed. - /// - /// A builder can be modified by adding trust anchor root certificates with - /// `rustls_root_cert_store_builder_add_pem`. Once you're done adding root certificates, - /// call `rustls_root_cert_store_builder_build` to turn it into a `rustls_root_cert_store`. - /// This object is not safe for concurrent mutation. - pub struct rustls_root_cert_store_builder(Option); +/// A `rustls_root_cert_store` being constructed. +/// +/// A builder can be modified by adding trust anchor root certificates with +/// `rustls_root_cert_store_builder_add_pem`. Once you're done adding root certificates, +/// call `rustls_root_cert_store_builder_build` to turn it into a `rustls_root_cert_store`. +/// This object is not safe for concurrent mutation. +pub struct rustls_root_cert_store_builder { + _private: [u8; 0], +} + +impl Castable for rustls_root_cert_store_builder { + type Ownership = OwnershipBox; + type RustType = Option; } pub(crate) struct RootCertStoreBuilder { @@ -440,10 +456,15 @@ impl rustls_root_cert_store_builder { } } -arc_castable! { - /// A root certificate store. - /// - pub struct rustls_root_cert_store(RootCertStore); +/// A root certificate store. +/// +pub struct rustls_root_cert_store { + _private: [u8; 0], +} + +impl Castable for rustls_root_cert_store { + type Ownership = OwnershipArc; + type RustType = RootCertStore; } impl rustls_root_cert_store { diff --git a/librustls/src/cipher.rs b/librustls/src/cipher.rs index 625911ca..66526731 100644 --- a/librustls/src/cipher.rs +++ b/librustls/src/cipher.rs @@ -1,13 +1,18 @@ use rustls::SupportedCipherSuite; use crate::enums::rustls_tls_version; -use crate::ffi::{ref_castable, try_ref_from_ptr}; +use crate::ffi::{Castable, OwnershipRef, try_ref_from_ptr}; use crate::panic::ffi_panic_boundary; use crate::rslice::rustls_str; -ref_castable! { - /// A cipher suite supported by rustls. - pub struct rustls_supported_ciphersuite(SupportedCipherSuite); +/// A cipher suite supported by rustls. +pub struct rustls_supported_ciphersuite { + _private: [u8; 0], +} + +impl Castable for rustls_supported_ciphersuite { + type Ownership = OwnershipRef; + type RustType = SupportedCipherSuite; } impl rustls_supported_ciphersuite { diff --git a/librustls/src/client.rs b/librustls/src/client.rs index 8e18ae15..7a0838b8 100644 --- a/librustls/src/client.rs +++ b/librustls/src/client.rs @@ -18,7 +18,7 @@ use crate::connection::{Connection, rustls_connection}; use crate::crypto_provider::{self, rustls_crypto_provider, rustls_hpke}; use crate::error::{self, map_error, rustls_result}; use crate::ffi::{ - arc_castable, box_castable, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr, + Castable, OwnershipArc, OwnershipBox, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr, to_boxed_mut_ptr, try_box_from_ptr, try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr, try_ref_from_ptr, try_ref_from_ptr_ptr, try_slice, }; @@ -29,20 +29,25 @@ use crate::rslice::{rustls_slice_bytes, rustls_slice_slice_bytes, rustls_str}; use crate::userdata::userdata_get; use crate::verifier::rustls_server_cert_verifier; -box_castable! { - /// A client config being constructed. - /// - /// A builder can be modified by, e.g. `rustls_client_config_builder_load_roots_from_file`. - /// Once you're done configuring settings, call `rustls_client_config_builder_build` - /// to turn it into a *rustls_client_config. - /// - /// Alternatively, if an error occurs or, you don't wish to build a config, - /// call `rustls_client_config_builder_free` to free the builder directly. - /// - /// This object is not safe for concurrent mutation. Under the hood, - /// it corresponds to a `Box`. - /// - pub struct rustls_client_config_builder(ClientConfigBuilder); +/// A client config being constructed. +/// +/// A builder can be modified by, e.g. `rustls_client_config_builder_load_roots_from_file`. +/// Once you're done configuring settings, call `rustls_client_config_builder_build` +/// to turn it into a *rustls_client_config. +/// +/// Alternatively, if an error occurs or, you don't wish to build a config, +/// call `rustls_client_config_builder_free` to free the builder directly. +/// +/// This object is not safe for concurrent mutation. Under the hood, +/// it corresponds to a `Box`. +/// +pub struct rustls_client_config_builder { + _private: [u8; 0], +} + +impl Castable for rustls_client_config_builder { + type Ownership = OwnershipBox; + type RustType = ClientConfigBuilder; } pub(crate) struct ClientConfigBuilder { @@ -76,12 +81,17 @@ impl Default for ClientConfigBuilder { } } -arc_castable! { - /// A client config that is done being constructed and is now read-only. - /// - /// Under the hood, this object corresponds to an `Arc`. - /// - pub struct rustls_client_config(ClientConfig); +/// A client config that is done being constructed and is now read-only. +/// +/// Under the hood, this object corresponds to an `Arc`. +/// +pub struct rustls_client_config { + _private: [u8; 0], +} + +impl Castable for rustls_client_config { + type Ownership = OwnershipArc; + type RustType = ClientConfig; } impl rustls_client_config_builder { diff --git a/librustls/src/connection.rs b/librustls/src/connection.rs index 9b4dba14..c267ed75 100644 --- a/librustls/src/connection.rs +++ b/librustls/src/connection.rs @@ -11,7 +11,7 @@ use crate::certificate::rustls_certificate; use crate::enums::rustls_handshake_kind; use crate::error::{map_error, rustls_io_result, rustls_result}; use crate::ffi::{ - box_castable, free_box, try_callback, try_mut_from_ptr, try_ref_from_ptr, try_slice, + Castable, OwnershipBox, free_box, try_callback, try_mut_from_ptr, try_ref_from_ptr, try_slice, try_slice_mut, }; use crate::io::{ @@ -92,9 +92,14 @@ impl std::ops::DerefMut for Connection { } } -box_castable! { - /// A C representation of a Rustls `Connection`. - pub struct rustls_connection(Connection); +/// A C representation of a Rustls `Connection`. +pub struct rustls_connection { + _private: [u8; 0], +} + +impl Castable for rustls_connection { + type Ownership = OwnershipBox; + type RustType = Connection; } impl rustls_connection { diff --git a/librustls/src/crypto_provider.rs b/librustls/src/crypto_provider.rs index c3eced79..b45ecd08 100644 --- a/librustls/src/crypto_provider.rs +++ b/librustls/src/crypto_provider.rs @@ -16,15 +16,20 @@ use rustls::sign::SigningKey; use crate::cipher::rustls_supported_ciphersuite; use crate::error::{map_error, rustls_result}; use crate::ffi::{ - arc_castable, box_castable, free_arc, free_box, ref_castable, set_arc_mut_ptr, + Castable, OwnershipArc, OwnershipBox, OwnershipRef, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr, to_boxed_mut_ptr, try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr, try_ref_from_ptr, try_ref_from_ptr_ptr, try_slice, try_slice_mut, try_take, }; use crate::panic::ffi_panic_boundary; -box_castable! { - /// A `rustls_crypto_provider` builder. - pub struct rustls_crypto_provider_builder(Option); +/// A `rustls_crypto_provider` builder. +pub struct rustls_crypto_provider_builder { + _private: [u8; 0], +} + +impl Castable for rustls_crypto_provider_builder { + type Ownership = OwnershipBox; + type RustType = Option; } /// A builder for customizing a `CryptoProvider`. Can be used to install a process-wide default. @@ -284,9 +289,14 @@ pub extern "C" fn rustls_crypto_provider_default() -> *const rustls_crypto_provi } } -arc_castable! { - /// A C representation of a Rustls [`CryptoProvider`]. - pub struct rustls_crypto_provider(CryptoProvider); +/// A C representation of a Rustls [`CryptoProvider`]. +pub struct rustls_crypto_provider { + _private: [u8; 0], +} + +impl Castable for rustls_crypto_provider { + type Ownership = OwnershipArc; + type RustType = CryptoProvider; } /// Returns the number of ciphersuites the `rustls_crypto_provider` supports. @@ -471,12 +481,17 @@ pub extern "C" fn rustls_default_crypto_provider_random( } } -box_castable! { - /// A signing key that can be used to construct a certified key. - // NOTE: we box cast an arc over the dyn trait per the pattern described - // in our docs[0] for dynamically sized types. - // [0]: - pub struct rustls_signing_key(Arc); +/// A signing key that can be used to construct a certified key. +// NOTE: we box cast an arc over the dyn trait per the pattern described +// in our docs[0] for dynamically sized types. +// [0]: +pub struct rustls_signing_key { + _private: [u8; 0], +} + +impl Castable for rustls_signing_key { + type Ownership = OwnershipBox; + type RustType = Arc; } impl rustls_signing_key { @@ -490,13 +505,18 @@ impl rustls_signing_key { } } -ref_castable! { - /// A collection of supported Hybrid Public Key Encryption (HPKE) suites. - /// - /// `rustls_hpke` can be provided to `rustls_client_config_builder_enable_ech` and - /// `rustls_client_config_builder_enable_ech_grease()` to customize a - /// `rustls_client_config_builder` to use Encrypted Client Hello (ECH). - pub struct rustls_hpke(Hpke); +/// A collection of supported Hybrid Public Key Encryption (HPKE) suites. +/// +/// `rustls_hpke` can be provided to `rustls_client_config_builder_enable_ech` and +/// `rustls_client_config_builder_enable_ech_grease()` to customize a +/// `rustls_client_config_builder` to use Encrypted Client Hello (ECH). +pub struct rustls_hpke { + _private: [u8; 0], +} + +impl Castable for rustls_hpke { + type Ownership = OwnershipRef; + type RustType = Hpke; } pub(crate) struct Hpke { diff --git a/librustls/src/ffi.rs b/librustls/src/ffi.rs index 743f4566..07c72f9e 100644 --- a/librustls/src/ffi.rs +++ b/librustls/src/ffi.rs @@ -59,100 +59,6 @@ pub(crate) trait Castable { type RustType; } -/// Defines a new [`Castable`] opaque struct with [`OwnershipBox`] ownership. -/// -/// Expects to be invoked with a visibility specifier, the struct keyword, a struct name, and -/// in parens, the Rust type pointed to by raw pointers of the opaque struct's type. -/// Similar to a [newtype] with `#[repr(transparent)]`, but only allows conversions -/// between `Box` and raw pointers. -/// -/// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction -macro_rules! box_castable { - ( - $(#[$comment:meta])* - pub struct $name:ident($rust_type:ty); - ) => { - crate::ffi::castable!(OwnershipBox $(#[$comment])* $name $rust_type); - }; -} - -pub(crate) use box_castable; - -/// Defines a new [`Castable`] opaque struct with [`OwnershipArc`] ownership. -/// -/// Expects to be invoked with a visibility specifier, the struct keyword, a struct name, and -/// in parens, the Rust type pointed to by raw pointers of the opaque struct's type. -/// Similar to a [newtype] with `#[repr(transparent)]`, but only allows conversions -/// between `Arc` and raw pointers. -/// -/// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction -macro_rules! arc_castable { - ( - $(#[$comment:meta])* - pub struct $name:ident($rust_type:ty); - ) => { - crate::ffi::castable!(OwnershipArc $(#[$comment])* $name $rust_type); - }; -} - -pub(crate) use arc_castable; - -/// Defines a new [`Castable`] opaque struct with [`OwnershipRef`] ownership. -/// -/// Expects to be invoked with a visibility specifier, the struct keyword, a struct name, and -/// in parens, the Rust type pointed to by raw pointers of the opaque struct's type. -/// Similar to a [newtype] with `#[repr(transparent)]`, but only allows conversions -/// between a reference and raw pointers. -/// -/// If a lifetime parameter is specified, the opaque struct will be parameterized by it, -/// and a `PhantomData` field referencing the lifetime is added to the struct. -/// -/// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction -macro_rules! ref_castable { - ( - $(#[$comment:meta])* - pub struct $name:ident ($rust_type:ident $(<$lt:tt>)?); - ) => { - $(#[$comment])* - pub struct $name $(<$lt>)? { - _private: [u8; 0], - $( _marker: PhantomData<&$lt ()>, )? - } - - impl $(<$lt>)? crate::ffi::Castable for $name $(<$lt>)? { - type Ownership = crate::ffi::OwnershipRef; - type RustType = $rust_type $(<$lt>)?; - } - }; -} - -pub(crate) use ref_castable; - -/// Defines a new [`Castable`] opaque struct with the specified ownership. -/// -/// In general you should prefer using `box_castable!`, `arc_castable!`, or `ref_castable!` -/// instead of this macro. -macro_rules! castable { - ( - $ownership:ident - $(#[$comment:meta])* - $name:ident - $rust_type:ty - ) => { - $(#[$comment])* - pub struct $name { - _private: [u8; 0], - } - - impl crate::ffi::Castable for $name { - type Ownership = crate::ffi::$ownership; - type RustType = $rust_type; - } - }; -} - -pub(crate) use castable; - /// Convert a const pointer to a [`Castable`] to a const pointer to its underlying /// [`Castable::RustType`]. /// diff --git a/librustls/src/server.rs b/librustls/src/server.rs index e0df7e97..fac04994 100644 --- a/librustls/src/server.rs +++ b/librustls/src/server.rs @@ -18,7 +18,7 @@ use crate::connection::{Connection, rustls_connection}; use crate::crypto_provider::{self, rustls_crypto_provider}; use crate::error::{map_error, rustls_result}; use crate::ffi::{ - Castable, OwnershipRef, arc_castable, box_castable, free_arc, free_box, set_arc_mut_ptr, + Castable, OwnershipArc, OwnershipBox, OwnershipRef, free_arc, free_box, set_arc_mut_ptr, set_boxed_mut_ptr, to_boxed_mut_ptr, try_box_from_ptr, try_clone_arc, try_mut_from_ptr, try_mut_from_ptr_ptr, try_ref_from_ptr, try_ref_from_ptr_ptr, try_slice, }; @@ -31,20 +31,25 @@ use crate::session::{ use crate::userdata::userdata_get; use crate::verifier::rustls_client_cert_verifier; -box_castable! { - /// A server config being constructed. - /// - /// A builder can be modified by, - /// e.g. rustls_server_config_builder_load_native_roots. Once you're - /// done configuring settings, call rustls_server_config_builder_build - /// to turn it into a *const rustls_server_config. - /// - /// Alternatively, if an error occurs or, you don't wish to build a config, - /// call `rustls_server_config_builder_free` to free the builder directly. - /// - /// This object is not safe for concurrent mutation. - /// - pub struct rustls_server_config_builder(ServerConfigBuilder); +/// A server config being constructed. +/// +/// A builder can be modified by, +/// e.g. rustls_server_config_builder_load_native_roots. Once you're +/// done configuring settings, call rustls_server_config_builder_build +/// to turn it into a *const rustls_server_config. +/// +/// Alternatively, if an error occurs or, you don't wish to build a config, +/// call `rustls_server_config_builder_free` to free the builder directly. +/// +/// This object is not safe for concurrent mutation. +/// +pub struct rustls_server_config_builder { + _private: [u8; 0], +} + +impl Castable for rustls_server_config_builder { + type Ownership = OwnershipBox; + type RustType = ServerConfigBuilder; } pub(crate) struct ServerConfigBuilder { @@ -58,12 +63,17 @@ pub(crate) struct ServerConfigBuilder { key_log: Option>, } -arc_castable! { - /// A server config that is done being constructed and is now read-only. - /// - /// Under the hood, this object corresponds to an `Arc`. - /// - pub struct rustls_server_config(ServerConfig); +/// A server config that is done being constructed and is now read-only. +/// +/// Under the hood, this object corresponds to an `Arc`. +/// +pub struct rustls_server_config { + _private: [u8; 0], +} + +impl Castable for rustls_server_config { + type Ownership = OwnershipArc; + type RustType = ServerConfig; } impl rustls_server_config_builder { diff --git a/librustls/src/verifier.rs b/librustls/src/verifier.rs index 5ddad9c3..52db5509 100644 --- a/librustls/src/verifier.rs +++ b/librustls/src/verifier.rs @@ -16,20 +16,25 @@ use crate::certificate::rustls_root_cert_store; use crate::crypto_provider::{self, rustls_crypto_provider}; use crate::error::{self, rustls_result}; use crate::ffi::{ - box_castable, free_box, set_boxed_mut_ptr, to_boxed_mut_ptr, try_clone_arc, try_mut_from_ptr, - try_mut_from_ptr_ptr, try_slice, try_take, + Castable, OwnershipBox, free_box, set_boxed_mut_ptr, to_boxed_mut_ptr, try_clone_arc, + try_mut_from_ptr, try_mut_from_ptr_ptr, try_slice, try_take, }; use crate::panic::ffi_panic_boundary; -box_castable! { - /// A built client certificate verifier that can be provided to a `rustls_server_config_builder` - /// with `rustls_server_config_builder_set_client_verifier`. - // - // Rustls' ConfigBuilder requires an `Arc` here, meaning we - // must follow the pattern described in CONTRIBUTING.md[^0] for handling dynamically sized - // types (DSTs) across the FFI boundary. - // [^0]: - pub struct rustls_client_cert_verifier(Arc); +/// A built client certificate verifier that can be provided to a `rustls_server_config_builder` +/// with `rustls_server_config_builder_set_client_verifier`. +// +// Rustls' ConfigBuilder requires an `Arc` here, meaning we +// must follow the pattern described in CONTRIBUTING.md[^0] for handling dynamically sized +// types (DSTs) across the FFI boundary. +// [^0]: +pub struct rustls_client_cert_verifier { + _private: [u8; 0], +} + +impl Castable for rustls_client_cert_verifier { + type Ownership = OwnershipBox; + type RustType = Arc; } impl rustls_client_cert_verifier { @@ -54,19 +59,24 @@ pub(crate) struct ClientCertVerifierBuilder { allow_unauthenticated: bool, } -box_castable! { - /// A client certificate verifier being constructed. - /// - /// A builder can be modified by, e.g. `rustls_web_pki_client_cert_verifier_builder_add_crl`. - /// - /// Once you're done configuring settings, call `rustls_web_pki_client_cert_verifier_builder_build` - /// to turn it into a `rustls_client_cert_verifier`. - /// - /// This object is not safe for concurrent mutation. - /// - /// See - /// for more information. - pub struct rustls_web_pki_client_cert_verifier_builder(Option); +/// A client certificate verifier being constructed. +/// +/// A builder can be modified by, e.g. `rustls_web_pki_client_cert_verifier_builder_add_crl`. +/// +/// Once you're done configuring settings, call `rustls_web_pki_client_cert_verifier_builder_build` +/// to turn it into a `rustls_client_cert_verifier`. +/// +/// This object is not safe for concurrent mutation. +/// +/// See +/// for more information. +pub struct rustls_web_pki_client_cert_verifier_builder { + _private: [u8; 0], +} + +impl Castable for rustls_web_pki_client_cert_verifier_builder { + type Ownership = OwnershipBox; + type RustType = Option; } impl rustls_web_pki_client_cert_verifier_builder { @@ -370,17 +380,22 @@ impl rustls_web_pki_client_cert_verifier_builder { } } -box_castable! { - /// A server certificate verifier being constructed. - /// - /// A builder can be modified by, e.g. `rustls_web_pki_server_cert_verifier_builder_add_crl`. - /// - /// Once you're done configuring settings, call `rustls_web_pki_server_cert_verifier_builder_build` - /// to turn it into a `rustls_server_cert_verifier`. This object is not safe for concurrent mutation. - /// - /// See - /// for more information. - pub struct rustls_web_pki_server_cert_verifier_builder(Option); +/// A server certificate verifier being constructed. +/// +/// A builder can be modified by, e.g. `rustls_web_pki_server_cert_verifier_builder_add_crl`. +/// +/// Once you're done configuring settings, call `rustls_web_pki_server_cert_verifier_builder_build` +/// to turn it into a `rustls_server_cert_verifier`. This object is not safe for concurrent mutation. +/// +/// See +/// for more information. +pub struct rustls_web_pki_server_cert_verifier_builder { + _private: [u8; 0], +} + +impl Castable for rustls_web_pki_server_cert_verifier_builder { + type Ownership = OwnershipBox; + type RustType = Option; } pub(crate) struct ServerCertVerifierBuilder { @@ -636,15 +651,20 @@ impl ServerCertVerifierBuilder { } } -box_castable! { - /// A built server certificate verifier that can be provided to a `rustls_client_config_builder` - /// with `rustls_client_config_builder_set_server_verifier`. - // - // Rustls' ConfigBuilder requires an `Arc` here, meaning we - // must follow the pattern described in CONTRIBUTING.md[^0] for handling dynamically sized - // types (DSTs) across the FFI boundary. - // [^0]: - pub struct rustls_server_cert_verifier(Arc); +/// A built server certificate verifier that can be provided to a `rustls_client_config_builder` +/// with `rustls_client_config_builder_set_server_verifier`. +// +// Rustls' ConfigBuilder requires an `Arc` here, meaning we +// must follow the pattern described in CONTRIBUTING.md[^0] for handling dynamically sized +// types (DSTs) across the FFI boundary. +// [^0]: +pub struct rustls_server_cert_verifier { + _private: [u8; 0], +} + +impl Castable for rustls_server_cert_verifier { + type Ownership = OwnershipBox; + type RustType = Arc; } impl rustls_server_cert_verifier { From 16976e2a3d7c725777a5b8963b8755abbe3e8af6 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sun, 28 Sep 2025 13:51:34 -0400 Subject: [PATCH 3/4] librustls: stop using parse.expand Since we have no macros anymore, it's not needed. --- librustls/cbindgen.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/librustls/cbindgen.toml b/librustls/cbindgen.toml index 5f500d06..0b3783eb 100644 --- a/librustls/cbindgen.toml +++ b/librustls/cbindgen.toml @@ -41,7 +41,3 @@ include = ["rustls_tls_version"] "feature = aws-lc-rs" = "DEFINE_AWS_LC_RS" "feature = ring" = "DEFINE_RING" "feature = fips" = "DEFINE_FIPS" - -[parse.expand] -crates = ["rustls-ffi"] -features = ["read_buf", "aws-lc-rs", "ring", "fips"] From b62f8474bd0034966bfa32ba6bd7c83bc733ce72 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Sun, 28 Sep 2025 13:46:34 -0400 Subject: [PATCH 4/4] ci: use stable for cbindgen/ensure-header-updated task --- .github/workflows/test.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8a87be89..8c17656d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -271,12 +271,8 @@ jobs: with: persist-credentials: false - - name: Install nightly rust toolchain - uses: dtolnay/rust-toolchain@nightly - with: - # TODO(XXX): remove toolchain pinning once upstream issue is resolved: - # https://github.com/rust-lang/rust/issues/139715 - toolchain: nightly-2025-03-25 + - name: Install stable rust toolchain + uses: dtolnay/rust-toolchain@stable - name: Install cbindgen # Pin the installed version of cbindgen so that local usage can be