From a9c8fc4dbc74de19bd247178cb6ca4f89b009e7a Mon Sep 17 00:00:00 2001 From: "Sajjad (Sage) Pourali" Date: Tue, 16 Jul 2024 03:39:53 -0400 Subject: [PATCH] Add aws_lc_rs feature and set it as default (#56) --- .github/workflows/rust.yml | 7 ++++++- Cargo.toml | 14 +++++++++----- src/lib.rs | 27 +++++++++++++++++++-------- src/types.rs | 12 ++++++++---- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4ede9a0..056e6c4 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -21,12 +21,17 @@ jobs: runs-on: ${{ matrix.os }} + env: + AWS_LC_SYS_NO_ASM: 1 + steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - - run: cargo test --all-features --all-targets + - run: cargo check + - run: cargo test + - run: cargo test --no-default-features --features hyper-rustls,aws-lc-rs msrv: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index aaee19c..fc31712 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,15 +12,19 @@ keywords = ["letsencrypt", "acme"] categories = ["web-programming", "api-bindings"] [features] -default = ["hyper-rustls"] +default = ["hyper-rustls", "ring"] +ring = ["dep:ring", "hyper-rustls?/ring", "rcgen/ring"] +aws-lc-rs = ["dep:aws-lc-rs", "hyper-rustls?/aws-lc-rs", "rcgen/aws_lc_rs"] +fips = ["aws-lc-rs", "aws-lc-rs?/fips"] [dependencies] +aws-lc-rs = { version = "1.8.0", optional = true } base64 = "0.21.0" hyper = { version = "1.3.1", features = ["client", "http1", "http2"] } -hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "tls12", "rustls-native-certs", "ring"], optional = true } -hyper-util = { version = "0.1.5", features = ["client", "client-legacy", "http1", "http2", "tokio"]} +hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "tls12", "rustls-native-certs"], optional = true } +hyper-util = { version = "0.1.5", features = ["client", "client-legacy", "http1", "http2", "tokio"] } http-body-util = "0.1.2" -ring = { version = "0.17", features = ["std"] } +ring = { version = "0.17", features = ["std"], optional = true } rustls-pki-types = "1.1.0" serde = { version = "1.0.104", features = ["derive"] } serde_json = "1.0.78" @@ -29,7 +33,7 @@ thiserror = "1.0.30" [dev-dependencies] anyhow = "1.0.66" clap = { version = "4.0.29", features = ["derive"] } -rcgen = "0.12" +rcgen = { version = "0.12", default-features = false, features = ["pem"] } tokio = { version = "1.22.0", features = ["macros", "rt", "rt-multi-thread", "time"] } tracing = "0.1.37" tracing-subscriber = "0.3.16" diff --git a/src/lib.rs b/src/lib.rs index 25b01aa..cdf91c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,10 @@ #![warn(unreachable_pub)] #![warn(missing_docs)] +#[cfg(feature = "aws-lc-rs")] +pub(crate) use aws_lc_rs as ring_like; +#[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))] +pub(crate) use ring as ring_like; use std::fmt; use std::future::Future; use std::pin::Pin; @@ -13,14 +17,14 @@ use http_body_util::{BodyExt, Full}; use hyper::body::{Bytes, Incoming}; use hyper::header::{CONTENT_TYPE, LOCATION}; use hyper::{Method, Request, Response, StatusCode}; -#[cfg(feature = "hyper-rustls")] -use hyper_util::client::legacy::connect::{Connect, HttpConnector}; +use hyper_util::client::legacy::connect::Connect; use hyper_util::client::legacy::Client as HyperClient; -use hyper_util::rt::TokioExecutor; -use ring::digest::{digest, SHA256}; -use ring::rand::SystemRandom; -use ring::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING}; -use ring::{hmac, pkcs8}; +#[cfg(feature = "hyper-rustls")] +use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor}; +use ring_like::digest::{digest, SHA256}; +use ring_like::rand::SystemRandom; +use ring_like::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING}; +use ring_like::{hmac, pkcs8}; use serde::de::DeserializeOwned; use serde::Serialize; @@ -555,7 +559,10 @@ impl Key { fn generate() -> Result<(Self, pkcs8::Document), Error> { let rng = SystemRandom::new(); let pkcs8 = EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng)?; + #[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))] let key = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8.as_ref(), &rng)?; + #[cfg(feature = "aws-lc-rs")] + let key = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8.as_ref())?; let thumb = BASE64_URL_SAFE_NO_PAD.encode(Jwk::thumb_sha256(&key)?); Ok(( @@ -571,7 +578,11 @@ impl Key { fn from_pkcs8_der(pkcs8_der: &[u8]) -> Result { let rng = SystemRandom::new(); + #[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))] let key = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8_der, &rng)?; + #[cfg(feature = "aws-lc-rs")] + let key = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8_der)?; + let thumb = BASE64_URL_SAFE_NO_PAD.encode(Jwk::thumb_sha256(&key)?); Ok(Self { @@ -584,7 +595,7 @@ impl Key { } impl Signer for Key { - type Signature = ring::signature::Signature; + type Signature = ring_like::signature::Signature; fn header<'n, 'u: 'n, 's: 'u>(&'s self, nonce: Option<&'n str>, url: &'u str) -> Header<'n> { debug_assert!(nonce.is_some()); diff --git a/src/types.rs b/src/types.rs index 41da9b0..3e276aa 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,11 +1,15 @@ use std::fmt; +#[cfg(feature = "aws-lc-rs")] +pub(crate) use aws_lc_rs as ring_like; use base64::prelude::{Engine, BASE64_URL_SAFE_NO_PAD}; use http_body_util::BodyExt; use hyper::body::Incoming; use hyper::Response; -use ring::digest::{digest, Digest, SHA256}; -use ring::signature::{EcdsaKeyPair, KeyPair}; +#[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))] +pub(crate) use ring as ring_like; +use ring_like::digest::{digest, Digest, SHA256}; +use ring_like::signature::{EcdsaKeyPair, KeyPair}; use rustls_pki_types::CertificateDer; use serde::de::DeserializeOwned; use serde::ser::SerializeMap; @@ -25,10 +29,10 @@ pub enum Error { Base64(#[from] base64::DecodeError), /// Failed from cryptographic operations #[error("cryptographic operation failed: {0}")] - Crypto(#[from] ring::error::Unspecified), + Crypto(#[from] ring_like::error::Unspecified), /// Failed to instantiate a private key #[error("invalid key bytes: {0}")] - CryptoKey(#[from] ring::error::KeyRejected), + CryptoKey(#[from] ring_like::error::KeyRejected), /// HTTP failure #[error("HTTP request failure: {0}")] Http(#[from] hyper::http::Error),