mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-21 17:00:59 +00:00
Add basic digest logging
handle differing digest name cases
This commit is contained in:
parent
926ed7fc56
commit
aaf8e16db4
6 changed files with 120 additions and 211 deletions
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "http-signature-normalization-actix"
|
||||
description = "An HTTP Signatures library that leaves the signing to you"
|
||||
version = "0.3.0-alpha.1"
|
||||
version = "0.3.0-alpha.2"
|
||||
authors = ["asonix <asonix@asonix.dog>"]
|
||||
license-file = "LICENSE"
|
||||
readme = "README.md"
|
||||
|
@ -12,7 +12,7 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[features]
|
||||
default = ["sha-2", "sha-3"]
|
||||
digest = ["base64"]
|
||||
digest = ["base64", "log"]
|
||||
sha-2 = ["digest", "sha2"]
|
||||
sha-3 = ["digest", "sha3"]
|
||||
|
||||
|
@ -31,6 +31,7 @@ base64 = { version = "0.11", optional = true }
|
|||
bytes = "0.5.4"
|
||||
futures = "0.3"
|
||||
http-signature-normalization = { version = "0.3.0", path = ".." }
|
||||
log = { version = "0.4", optional = true }
|
||||
sha2 = { version = "0.8", optional = true }
|
||||
sha3 = { version = "0.8", optional = true }
|
||||
thiserror = "1.0"
|
||||
|
@ -38,3 +39,4 @@ thiserror = "1.0"
|
|||
[dev-dependencies]
|
||||
actix = "0.10.0-alpha.1"
|
||||
actix-rt = "1.0.0"
|
||||
pretty_env_logger = "0.4"
|
||||
|
|
|
@ -16,7 +16,7 @@ This crate provides extensions the ClientRequest type from Actix Web, and provid
|
|||
actix = "0.10.0-alpha.1"
|
||||
actix-web = "3.0.0-alpha.1"
|
||||
thiserror = "0.1"
|
||||
http-signature-normalization-actix = { version = "0.3.0-alpha.0", default-features = false, features = ["sha-2"] }
|
||||
http-signature-normalization-actix = { version = "0.3.0-alpha.2", default-features = false, features = ["sha-2"] }
|
||||
sha2 = "0.8"
|
||||
```
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ use sha2::{Digest, Sha256};
|
|||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
pretty_env_logger::init();
|
||||
|
||||
let config = Config::default();
|
||||
let mut digest = Sha256::new();
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ async fn index(_: (DigestVerified, SignatureVerified)) -> &'static str {
|
|||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
pretty_env_logger::init();
|
||||
|
||||
let config = Config::default();
|
||||
|
||||
HttpServer::new(move || {
|
||||
|
|
|
@ -1,153 +1,120 @@
|
|||
use sha2::{Digest as _, Sha224, Sha256, Sha384, Sha512, Sha512Trunc224, Sha512Trunc256};
|
||||
use log::{info, warn};
|
||||
use sha2::{Sha224, Sha256, Sha384, Sha512, Sha512Trunc224, Sha512Trunc256};
|
||||
|
||||
use super::{DigestCreate, DigestPart, DigestVerify};
|
||||
|
||||
fn create(digest: &mut impl sha2::Digest, input: &[u8]) -> String {
|
||||
digest.input(input);
|
||||
base64::encode(&digest.result_reset())
|
||||
}
|
||||
|
||||
fn verify(digest: &mut impl sha2::Digest, name: &str, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm.to_lowercase() == name.to_lowercase())
|
||||
{
|
||||
info!("Verifying digest type, {}", name);
|
||||
digest.input(bytes);
|
||||
let encoded = base64::encode(&digest.result_reset());
|
||||
|
||||
return part.digest == encoded;
|
||||
}
|
||||
warn!("No matching digest algorithm found for {}", name);
|
||||
warn!(
|
||||
"Provided: [{}]",
|
||||
parts.iter().fold(String::new(), |mut acc, item| {
|
||||
if acc.is_empty() {
|
||||
} else {
|
||||
acc.extend(", ".chars());
|
||||
}
|
||||
acc.extend(item.algorithm.chars());
|
||||
acc
|
||||
})
|
||||
);
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha224 {
|
||||
const NAME: &'static str = "sha-224";
|
||||
const NAME: &'static str = "SHA-224";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha224 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha256 {
|
||||
const NAME: &'static str = "sha-256";
|
||||
const NAME: &'static str = "SHA-256";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha256 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha384 {
|
||||
const NAME: &'static str = "sha-384";
|
||||
const NAME: &'static str = "SHA-384";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha384 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha512 {
|
||||
const NAME: &'static str = "sha-512";
|
||||
const NAME: &'static str = "SHA-512";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha512 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha512Trunc224 {
|
||||
const NAME: &'static str = "sha-512-224";
|
||||
const NAME: &'static str = "SHA-512-224";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha512Trunc224 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha512Trunc256 {
|
||||
const NAME: &'static str = "sha-512-256";
|
||||
const NAME: &'static str = "SHA-512-256";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha512Trunc256 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,107 +1,96 @@
|
|||
use log::{info, warn};
|
||||
use sha3::{
|
||||
Digest as _, Keccak224, Keccak256, Keccak256Full, Keccak384, Keccak512, Sha3_224, Sha3_256,
|
||||
Sha3_384, Sha3_512,
|
||||
Keccak224, Keccak256, Keccak256Full, Keccak384, Keccak512, Sha3_224, Sha3_256, Sha3_384,
|
||||
Sha3_512,
|
||||
};
|
||||
|
||||
use super::{DigestCreate, DigestPart, DigestVerify};
|
||||
|
||||
fn create(digest: &mut impl sha2::Digest, input: &[u8]) -> String {
|
||||
digest.input(input);
|
||||
base64::encode(&digest.result_reset())
|
||||
}
|
||||
|
||||
fn verify(digest: &mut impl sha2::Digest, name: &str, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm.to_lowercase() == name.to_lowercase())
|
||||
{
|
||||
info!("Verifying digest type, {}", name);
|
||||
digest.input(bytes);
|
||||
let encoded = base64::encode(&digest.result_reset());
|
||||
|
||||
return part.digest == encoded;
|
||||
}
|
||||
warn!("No matching digest algorithm found for {}", name);
|
||||
warn!(
|
||||
"Provided: [{}]",
|
||||
parts.iter().fold(String::new(), |mut acc, item| {
|
||||
if acc.is_empty() {
|
||||
} else {
|
||||
acc.extend(", ".chars());
|
||||
}
|
||||
acc.extend(item.algorithm.chars());
|
||||
acc
|
||||
})
|
||||
);
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha3_224 {
|
||||
const NAME: &'static str = "sha3-224";
|
||||
const NAME: &'static str = "SHA3-224";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha3_224 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha3_256 {
|
||||
const NAME: &'static str = "sha3-256";
|
||||
const NAME: &'static str = "SHA3-256";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha3_256 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha3_384 {
|
||||
const NAME: &'static str = "sha3-384";
|
||||
const NAME: &'static str = "SHA3-384";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha3_384 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestCreate for Sha3_512 {
|
||||
const NAME: &'static str = "sha3-512";
|
||||
const NAME: &'static str = "SHA3-512";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Sha3_512 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,24 +98,13 @@ impl DigestCreate for Keccak224 {
|
|||
const NAME: &'static str = "keccak-224";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Keccak224 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,24 +112,13 @@ impl DigestCreate for Keccak256 {
|
|||
const NAME: &'static str = "keccak-256";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Keccak256 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,24 +126,13 @@ impl DigestCreate for Keccak256Full {
|
|||
const NAME: &'static str = "keccak-256-full";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Keccak256Full {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,24 +140,13 @@ impl DigestCreate for Keccak384 {
|
|||
const NAME: &'static str = "keccak-384";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Keccak384 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,23 +154,12 @@ impl DigestCreate for Keccak512 {
|
|||
const NAME: &'static str = "keccak-512";
|
||||
|
||||
fn compute(&mut self, input: &[u8]) -> String {
|
||||
self.input(input);
|
||||
base64::encode(&self.result_reset())
|
||||
create(self, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl DigestVerify for Keccak512 {
|
||||
fn verify(&mut self, parts: &[DigestPart], bytes: &[u8]) -> bool {
|
||||
if let Some(part) = parts
|
||||
.iter()
|
||||
.find(|p| p.algorithm == <Self as DigestCreate>::NAME)
|
||||
{
|
||||
self.input(bytes);
|
||||
let digest = base64::encode(&self.result_reset());
|
||||
|
||||
return part.digest == digest;
|
||||
}
|
||||
|
||||
false
|
||||
verify(self, <Self as DigestCreate>::NAME, parts, bytes)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue