actix-web: add digest verification
This commit is contained in:
parent
36255bfbb4
commit
0db515714e
|
@ -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"] }
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue