From c6bed25f00a32664942919f8ce2781b0b5f12ef4 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Thu, 29 Jun 2023 15:52:05 -0400 Subject: [PATCH] error: replace num_enum with minimal macro rule. The `num_enum` dependency brings with it a large number of transitive dependencies. Some of those transitive deps now have an aggressive MSRV of 1.64+. The existing usage of `num_enum` is very minimal: just one derived trait for the `rustls_result` enum to provide it with a `From` impl for u32 primitive values. This commit replaces the `num_enum` crate with a small `u32_enum_builder!` macro rule loosely based on the Rustls `enum_builder` macro. Since our use case is narrower, I've simplified the macro and tailored it to the rustls-ffi use-case. This approach adds one complication related to `cbindgen`: it now has to be instructed to expand the `rustls-ffi` crate before generating bindings in order to find the `rustls_result` enum. Doing this requires tweaking the `cbindgen.toml` to add a `parse.expand` configuration setting. Notably this also means `cbindgen` now has to be run with a nightly `rustc`. Since this is a developer only workflow it shouldn't be too onerous a requirement. We're now happily building with Rust 1.60 again and can also breathe easy knowing we have a slimmer dependency profile! --- .github/workflows/test.yaml | 6 + Cargo.toml | 1 - cbindgen.toml | 4 + src/error.rs | 287 ++++++++++++++++++++---------------- src/session.rs | 2 +- 5 files changed, 167 insertions(+), 133 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a216f137..9c240b28 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -106,6 +106,12 @@ jobs: - uses: actions/checkout@v2 with: persist-credentials: false + - name: Install nightly rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + default: true - run: touch src/lib.rs - run: cbindgen --version - run: make src/rustls.h diff --git a/Cargo.toml b/Cargo.toml index 2c7c2535..6202b60d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ libc = "0.2" sct = "0.7" rustls-pemfile = "0.2.1" log = "0.4.17" -num_enum = "0.5.10" [lib] name = "rustls_ffi" diff --git a/cbindgen.toml b/cbindgen.toml index ffcc0fcf..1a1b977a 100644 --- a/cbindgen.toml +++ b/cbindgen.toml @@ -11,3 +11,7 @@ include = ["rustls_tls_version"] [defines] "feature = read_buf" = "DEFINE_READ_BUF" + +[parse.expand] +crates = ["rustls-ffi"] +features = ["read_buf"] diff --git a/src/error.rs b/src/error.rs index 40f43994..7bccf8b5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,7 +5,6 @@ use std::sync::Arc; use crate::ffi_panic_boundary; use libc::{c_char, c_uint, size_t}; -use num_enum::TryFromPrimitive; use rustls::{CertificateError, Error, InvalidMessage}; /// A return value for a function that may return either success (0) or a @@ -16,6 +15,162 @@ use rustls::{CertificateError, Error, InvalidMessage}; #[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, + } + } + } + }; +} + +u32_enum_builder! { + 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, + + // 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, + + // 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, // Last added. + + // 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, + + // https://docs.rs/sct/latest/sct/enum.Error.html + CertSCTMalformed => 7319, + CertSCTInvalidSignature => 7320, + CertSCTTimestampInFuture => 7321, + CertSCTUnsupportedVersion => 7322, + CertSCTUnknownLog => 7323 + } +} + impl rustls_result { /// After a rustls function returns an error, you may call /// this to get a pointer to a buffer containing a detailed error @@ -135,136 +290,6 @@ fn test_rustls_result_is_cert_error() { } } -#[allow(dead_code)] -#[repr(u32)] -#[derive(Debug, TryFromPrimitive, 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, - - // 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, - - // 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, // Last added. - - // 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, - - // https://docs.rs/sct/latest/sct/enum.Error.html - CertSCTMalformed = 7319, - CertSCTInvalidSignature = 7320, - CertSCTTimestampInFuture = 7321, - CertSCTUnsupportedVersion = 7322, - CertSCTUnknownLog = 7323, -} - pub(crate) fn map_error(input: rustls::Error) -> rustls_result { use rustls::AlertDescription as alert; use rustls_result::*; diff --git a/src/session.rs b/src/session.rs index b2780867..79fcff4f 100644 --- a/src/session.rs +++ b/src/session.rs @@ -129,7 +129,7 @@ impl SessionStoreBroker { Err(_) => return false, }; let result = unsafe { cb(userdata, &key, &value) }; - result == rustls_result::Ok as u32 + rustls_result::from(result) == rustls_result::Ok } }