relay/src/verifier.rs

57 lines
1.8 KiB
Rust
Raw Normal View History

use crate::{error::MyError, requests::fetch_actor, state::State};
2020-03-16 04:15:50 +00:00
use actix_web::client::Client;
2020-03-17 01:41:00 +00:00
use http_signature_normalization_actix::{prelude::*, verify::DeprecatedAlgorithm};
2020-03-16 04:15:50 +00:00
use rsa::{hash::Hashes, padding::PaddingScheme, PublicKey, RSAPublicKey};
use rsa_pem::KeyExt;
2020-03-17 01:41:00 +00:00
use sha2::{Digest, Sha256};
2020-03-16 04:15:50 +00:00
use std::{future::Future, pin::Pin, sync::Arc};
#[derive(Clone)]
pub struct MyVerify(pub State, pub Client);
impl SignatureVerify for MyVerify {
type Error = MyError;
type Future = Pin<Box<dyn Future<Output = Result<bool, Self::Error>>>>;
fn signature_verify(
&mut self,
algorithm: Option<Algorithm>,
key_id: &str,
signature: &str,
signing_string: &str,
) -> Self::Future {
let key_id = key_id.to_owned();
let signature = signature.to_owned();
let signing_string = signing_string.to_owned();
let state = Arc::new(self.0.clone());
let client = Arc::new(self.1.clone());
Box::pin(async move {
let actor = fetch_actor(state, client, &key_id.parse()?).await?;
2020-03-16 04:15:50 +00:00
let public_key = actor.public_key.ok_or(MyError::MissingKey)?;
let public_key = RSAPublicKey::from_pem_pkcs8(&public_key.public_key_pem)?;
match algorithm {
Some(Algorithm::Hs2019) => (),
2020-03-17 01:41:00 +00:00
Some(Algorithm::Deprecated(DeprecatedAlgorithm::RsaSha256)) => (),
2020-03-16 04:15:50 +00:00
_ => return Err(MyError::Algorithm),
};
let decoded = base64::decode(signature)?;
2020-03-17 01:41:00 +00:00
let hashed = Sha256::digest(signing_string.as_bytes());
2020-03-16 04:15:50 +00:00
public_key.verify(
PaddingScheme::PKCS1v15,
Some(&Hashes::SHA2_256),
2020-03-17 01:41:00 +00:00
&hashed,
2020-03-16 04:15:50 +00:00
&decoded,
)?;
Ok(true)
})
}
}