actix-web: add digest verification

This commit is contained in:
Aode (lion) 2021-11-19 17:55:13 -06:00
parent 36255bfbb4
commit 0db515714e
2 changed files with 44 additions and 8 deletions

View file

@ -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"] }

View file

@ -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<D: Dereference> {
type Error: ResponseError + From<VerifyError> + From<Self::VerifyError> + '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<ObjectId<PublicKeyType>> + Clone + 'static,
{
move |service_config: &mut ServiceConfig| {
let verifier = VerifySignature::new(
let signature = VerifySignature::new(
VerifyMiddleware::<V, ObjectId<PublicKeyType>>::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::<Activity, Metadata, I>)),
);
}
@ -225,6 +234,33 @@ where
}
}
#[derive(Clone)]
struct DigestWrapper<D>(D);
impl<D> DigestName for DigestWrapper<D>
where
D: Digest,
{
const NAME: &'static str = D::NAME;
}
impl<D> DigestVerify for DigestWrapper<D>
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<R> {
local_host: String,
repo_factory: R,