2018-05-04 17:18:00 +02:00
|
|
|
use base64;
|
|
|
|
use openssl::hash::{Hasher, MessageDigest};
|
2018-06-23 13:23:37 +02:00
|
|
|
use reqwest::{
|
|
|
|
mime::Mime,
|
2018-07-18 16:58:28 +02:00
|
|
|
header::{Accept, Date, Headers, UserAgent, qitem}
|
2018-06-23 13:23:37 +02:00
|
|
|
};
|
|
|
|
use std::{
|
|
|
|
str::FromStr,
|
|
|
|
time::SystemTime
|
|
|
|
};
|
2018-05-04 17:18:00 +02:00
|
|
|
|
2018-07-18 16:58:28 +02:00
|
|
|
use activity_pub::ap_accept_header;
|
2018-05-04 17:18:00 +02:00
|
|
|
use activity_pub::sign::Signer;
|
|
|
|
|
|
|
|
const USER_AGENT: &'static str = "Plume/0.1.0";
|
|
|
|
|
|
|
|
header! {
|
|
|
|
(Signature, "Signature") => [String]
|
|
|
|
}
|
|
|
|
|
|
|
|
header! {
|
|
|
|
(Digest, "Digest") => [String]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn headers() -> Headers {
|
|
|
|
let mut headers = Headers::new();
|
|
|
|
headers.set(UserAgent::new(USER_AGENT));
|
|
|
|
headers.set(Date(SystemTime::now().into()));
|
2018-07-18 16:58:28 +02:00
|
|
|
headers.set(Accept(ap_accept_header().into_iter().map(|h| qitem(h.parse::<Mime>().expect("Invalid Content-Type"))).collect()));
|
2018-05-04 17:18:00 +02:00
|
|
|
headers
|
|
|
|
}
|
|
|
|
|
2018-06-21 17:31:42 +02:00
|
|
|
pub fn signature<S: Signer>(signer: &S, headers: Headers) -> Signature {
|
2018-05-04 17:18:00 +02:00
|
|
|
let signed_string = headers.iter().map(|h| format!("{}: {}", h.name().to_lowercase(), h.value_string())).collect::<Vec<String>>().join("\n");
|
|
|
|
let signed_headers = headers.iter().map(|h| h.name().to_string()).collect::<Vec<String>>().join(" ").to_lowercase();
|
|
|
|
|
|
|
|
let data = signer.sign(signed_string);
|
2018-05-08 21:38:37 +02:00
|
|
|
let sign = base64::encode(&data[..]);
|
2018-05-04 17:18:00 +02:00
|
|
|
|
|
|
|
Signature(format!(
|
2018-05-08 21:38:37 +02:00
|
|
|
"keyId=\"{key_id}\",algorithm=\"rsa-sha256\",headers=\"{signed_headers}\",signature=\"{signature}\"",
|
2018-06-21 17:31:42 +02:00
|
|
|
key_id = signer.get_key_id(),
|
2018-05-04 17:18:00 +02:00
|
|
|
signed_headers = signed_headers,
|
|
|
|
signature = sign
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn digest(body: String) -> Digest {
|
|
|
|
let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap();
|
2018-05-09 22:35:50 +02:00
|
|
|
hasher.update(&body.into_bytes()[..]).unwrap();
|
2018-05-04 17:18:00 +02:00
|
|
|
let res = base64::encode(&hasher.finish().unwrap());
|
|
|
|
Digest(format!("SHA-256={}", res))
|
|
|
|
}
|