actix-web: add digest verification
This commit is contained in:
parent
36255bfbb4
commit
0db515714e
2 changed files with 44 additions and 8 deletions
|
@ -8,7 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
apub-core = { version = "0.1.0", path = "../apub-core/" }
|
apub-core = { version = "0.1.0", path = "../apub-core/" }
|
||||||
actix-web = { version = "4.0.0-beta.11", default-features = false }
|
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"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
url = { version = "2", features = ["serde"] }
|
url = { version = "2", features = ["serde"] }
|
||||||
|
|
|
@ -5,11 +5,16 @@ use actix_web::{
|
||||||
};
|
};
|
||||||
use apub_core::{
|
use apub_core::{
|
||||||
deref::{Dereference, Repo},
|
deref::{Dereference, Repo},
|
||||||
|
digest::Digest,
|
||||||
ingest::Ingest,
|
ingest::Ingest,
|
||||||
signature::Verify,
|
signature::Verify,
|
||||||
};
|
};
|
||||||
use http_signature_normalization_actix::prelude::{
|
use http_signature_normalization_actix::{
|
||||||
Algorithm, DeprecatedAlgorithm, SignatureVerified, SignatureVerify, VerifySignature,
|
digest::DigestName,
|
||||||
|
prelude::{
|
||||||
|
Algorithm, DeprecatedAlgorithm, DigestPart, DigestVerify, SignatureVerified,
|
||||||
|
SignatureVerify, VerifyDigest, VerifySignature,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::{future::Future, marker::PhantomData, pin::Pin};
|
use std::{future::Future, marker::PhantomData, pin::Pin};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -41,6 +46,7 @@ pub trait VerifierFactory<D: Dereference> {
|
||||||
type Error: ResponseError + From<VerifyError> + From<Self::VerifyError> + 'static;
|
type Error: ResponseError + From<VerifyError> + From<Self::VerifyError> + 'static;
|
||||||
type VerifyError: Send + 'static;
|
type VerifyError: Send + 'static;
|
||||||
type Verifier: for<'a> Verifier<'a, D, Error = Self::VerifyError> + 'static;
|
type Verifier: for<'a> Verifier<'a, D, Error = Self::VerifyError> + 'static;
|
||||||
|
type Digest: Digest + Clone + Send;
|
||||||
|
|
||||||
fn verifier(&self) -> Self::Verifier;
|
fn verifier(&self) -> Self::Verifier;
|
||||||
}
|
}
|
||||||
|
@ -93,21 +99,24 @@ where
|
||||||
V: VerifierFactory<ObjectId<PublicKeyType>> + Clone + 'static,
|
V: VerifierFactory<ObjectId<PublicKeyType>> + Clone + 'static,
|
||||||
{
|
{
|
||||||
move |service_config: &mut ServiceConfig| {
|
move |service_config: &mut ServiceConfig| {
|
||||||
let verifier = VerifySignature::new(
|
let signature = VerifySignature::new(
|
||||||
VerifyMiddleware::<V, ObjectId<PublicKeyType>>::new(verifier_factory),
|
VerifyMiddleware::<V, ObjectId<PublicKeyType>>::new(verifier_factory),
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
|
|
||||||
let verifier = if require_signature {
|
let digest = VerifyDigest::new(DigestWrapper(V::Digest::build()));
|
||||||
verifier
|
|
||||||
|
let (signature, digest) = if require_signature {
|
||||||
|
(signature, digest)
|
||||||
} else {
|
} else {
|
||||||
verifier.optional()
|
(signature.optional(), digest.optional())
|
||||||
};
|
};
|
||||||
|
|
||||||
service_config.service(
|
service_config.service(
|
||||||
web::scope("")
|
web::scope("")
|
||||||
.app_data(web::Data::new(ingest))
|
.app_data(web::Data::new(ingest))
|
||||||
.wrap(verifier)
|
.wrap(digest)
|
||||||
|
.wrap(signature)
|
||||||
.route("", web::post().to(inbox_handler::<Activity, Metadata, I>)),
|
.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> {
|
struct ServeInfo<R> {
|
||||||
local_host: String,
|
local_host: String,
|
||||||
repo_factory: R,
|
repo_factory: R,
|
||||||
|
|
Loading…
Reference in a new issue