From ec73fe55c951ec092da2fa6c6cc99651c8f277ac Mon Sep 17 00:00:00 2001 From: asonix Date: Thu, 17 Aug 2023 12:03:38 -0500 Subject: [PATCH] Add ring --- reqwest/Cargo.toml | 2 + reqwest/src/digest/mod.rs | 2 + reqwest/src/digest/ring.rs | 115 +++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 reqwest/src/digest/ring.rs diff --git a/reqwest/Cargo.toml b/reqwest/Cargo.toml index 9fc8996..67ec9e6 100644 --- a/reqwest/Cargo.toml +++ b/reqwest/Cargo.toml @@ -15,6 +15,7 @@ default = ["sha-2", "default-spawner"] middleware = ["dep:reqwest-middleware"] default-spawner = ["dep:tokio"] digest = ["dep:base64"] +ring = ["digest", "dep:ring"] sha-2 = ["digest", "dep:sha2"] sha-3 = ["digest", "dep:sha3"] @@ -29,6 +30,7 @@ http-signature-normalization = { version = "0.7.0", path = ".." } httpdate = "1.0.2" reqwest = { version = "0.11", default-features = false, features = ["json"] } reqwest-middleware = { version = "0.2.0", optional = true } +ring = { version = "0.16.20", optional = true } sha2 = { version = "0.10", optional = true } sha3 = { version = "0.10", optional = true } thiserror = "1.0" diff --git a/reqwest/src/digest/mod.rs b/reqwest/src/digest/mod.rs index 4342d05..034e015 100644 --- a/reqwest/src/digest/mod.rs +++ b/reqwest/src/digest/mod.rs @@ -2,6 +2,8 @@ use crate::{Config, Sign, SignError, Spawn}; use reqwest::{Body, Request, RequestBuilder}; use std::fmt::Display; +#[cfg(feature = "ring")] +pub mod ring; #[cfg(feature = "sha-2")] mod sha2; #[cfg(feature = "sha-3")] diff --git a/reqwest/src/digest/ring.rs b/reqwest/src/digest/ring.rs new file mode 100644 index 0000000..691c5a0 --- /dev/null +++ b/reqwest/src/digest/ring.rs @@ -0,0 +1,115 @@ +//! Types for creating digests with the `ring` cryptography library + +/// A Sha256 digest backed by ring +#[derive(Clone)] +pub struct Sha256 { + ctx: ring::digest::Context, +} + +/// A Sha384 digest backed by ring +#[derive(Clone)] +pub struct Sha384 { + ctx: ring::digest::Context, +} + +/// A Sha512 digest backed by ring +#[derive(Clone)] +pub struct Sha512 { + ctx: ring::digest::Context, +} + +impl Sha256 { + /// Create a new empty digest + pub fn new() -> Self { + Self::default() + } + + /// Extract the context + pub fn into_inner(self) -> ring::digest::Context { + self.ctx + } +} + +impl Default for Sha256 { + fn default() -> Self { + Sha256 { + ctx: ring::digest::Context::new(&ring::digest::SHA256), + } + } +} + +impl Sha384 { + /// Create a new empty digest + pub fn new() -> Self { + Self::default() + } + + /// Extract the context + pub fn into_inner(self) -> ring::digest::Context { + self.ctx + } +} + +impl Default for Sha384 { + fn default() -> Self { + Sha384 { + ctx: ring::digest::Context::new(&ring::digest::SHA384), + } + } +} + +impl Sha512 { + /// Create a new empty digest + pub fn new() -> Self { + Self::default() + } + + /// Extract the context + pub fn into_inner(self) -> ring::digest::Context { + self.ctx + } +} + +impl Default for Sha512 { + fn default() -> Self { + Sha512 { + ctx: ring::digest::Context::new(&ring::digest::SHA512), + } + } +} + +#[cfg(feature = "client")] +mod client { + use super::*; + use crate::digest::DigestCreate; + + fn create(mut context: ring::digest::Context, input: &[u8]) -> String { + context.update(input); + let digest = context.finish(); + base64::encode(digest.as_ref()) + } + + impl DigestCreate for Sha256 { + const NAME: &'static str = "SHA-256"; + + fn compute(&mut self, input: &[u8]) -> String { + create(self.ctx.clone(), input) + } + } + + impl DigestCreate for Sha384 { + const NAME: &'static str = "SHA-384"; + + fn compute(&mut self, input: &[u8]) -> String { + create(self.ctx.clone(), input) + } + } + + impl DigestCreate for Sha512 { + const NAME: &'static str = "SHA-512"; + + fn compute(&mut self, input: &[u8]) -> String { + create(self.ctx.clone(), input) + } + } +}