From 0db515714ea4cf5ab93ceae2ba4ee1505d1ce2a3 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Fri, 19 Nov 2021 17:55:13 -0600 Subject: [PATCH] actix-web: add digest verification --- apub-actix-web/Cargo.toml | 2 +- apub-actix-web/src/lib.rs | 50 +++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/apub-actix-web/Cargo.toml b/apub-actix-web/Cargo.toml index 7c7c60f..167dcd9 100644 --- a/apub-actix-web/Cargo.toml +++ b/apub-actix-web/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] apub-core = { version = "0.1.0", path = "../apub-core/" } actix-web = { version = "4.0.0-beta.11", default-features = false } -http-signature-normalization-actix = { version = "0.5.0-beta.12", default-features = false, features = ["server"] } +http-signature-normalization-actix = { version = "0.5.0-beta.12", default-features = false, features = ["server", "digest"] } serde = { version = "1", features = ["derive"] } thiserror = "1" url = { version = "2", features = ["serde"] } diff --git a/apub-actix-web/src/lib.rs b/apub-actix-web/src/lib.rs index 8f9a6ce..099affc 100644 --- a/apub-actix-web/src/lib.rs +++ b/apub-actix-web/src/lib.rs @@ -5,11 +5,16 @@ use actix_web::{ }; use apub_core::{ deref::{Dereference, Repo}, + digest::Digest, ingest::Ingest, signature::Verify, }; -use http_signature_normalization_actix::prelude::{ - Algorithm, DeprecatedAlgorithm, SignatureVerified, SignatureVerify, VerifySignature, +use http_signature_normalization_actix::{ + digest::DigestName, + prelude::{ + Algorithm, DeprecatedAlgorithm, DigestPart, DigestVerify, SignatureVerified, + SignatureVerify, VerifyDigest, VerifySignature, + }, }; use std::{future::Future, marker::PhantomData, pin::Pin}; use url::Url; @@ -41,6 +46,7 @@ pub trait VerifierFactory { type Error: ResponseError + From + From + 'static; type VerifyError: Send + 'static; type Verifier: for<'a> Verifier<'a, D, Error = Self::VerifyError> + 'static; + type Digest: Digest + Clone + Send; fn verifier(&self) -> Self::Verifier; } @@ -93,21 +99,24 @@ where V: VerifierFactory> + Clone + 'static, { move |service_config: &mut ServiceConfig| { - let verifier = VerifySignature::new( + let signature = VerifySignature::new( VerifyMiddleware::>::new(verifier_factory), config, ); - let verifier = if require_signature { - verifier + let digest = VerifyDigest::new(DigestWrapper(V::Digest::build())); + + let (signature, digest) = if require_signature { + (signature, digest) } else { - verifier.optional() + (signature.optional(), digest.optional()) }; service_config.service( web::scope("") .app_data(web::Data::new(ingest)) - .wrap(verifier) + .wrap(digest) + .wrap(signature) .route("", web::post().to(inbox_handler::)), ); } @@ -225,6 +234,33 @@ where } } +#[derive(Clone)] +struct DigestWrapper(D); + +impl DigestName for DigestWrapper +where + D: Digest, +{ + const NAME: &'static str = D::NAME; +} + +impl DigestVerify for DigestWrapper +where + D: Digest + Clone, +{ + fn update(&mut self, part: &[u8]) { + self.0.update(part); + } + + fn verify(&mut self, digests: &[DigestPart]) -> bool { + if let Some(part) = digests.iter().find(|part| part.algorithm == D::NAME) { + return self.0.clone().verify(&part.digest); + } + + false + } +} + struct ServeInfo { local_host: String, repo_factory: R,