use base64::prelude::*; use httpdate::fmt_http_date; use openssl::hash::MessageDigest; use openssl::pkey::PKey; use openssl::sign::Signer; use serde::{Deserialize, Serialize}; use sha2::Digest; use std::time::SystemTime; #[derive(Serialize, Deserialize)] struct CreateActivity { street: String, city: String, } fn sha256sum(bytes: &[u8]) -> String { let mut hasher = sha2::Sha256::new(); hasher.update(bytes); return BASE64_STANDARD.encode(hasher.finalize()); } fn main() { let host = "estradiol.city"; let path = "/users/ity/inbox"; let url = format!("https://{}{}", host, path); let key_id = "https://testing4host.com/users/test71/#main-key"; let json = include_bytes!("note.json"); let digest = format!("SHA-256={}", sha256sum(json)); println!("digest: {}", digest); let date = fmt_http_date(SystemTime::now()); let mut headers = String::new(); headers.push_str(format!("(request-target): post {}\n", path).as_str()); headers.push_str(format!("host: {}\n", host).as_str()); headers.push_str(format!("date: {}\n", date).as_str()); headers.push_str(format!("digest: {}", digest).as_str()); println!("signed_string: {:?}", headers); let privkey_file = include_str!("private.pem"); let pubkey_file = include_str!("public.pem"); let privkey = PKey::private_key_from_pem(privkey_file.as_bytes()).expect("Failed decoding private.pem"); let _pubkey = PKey::public_key_from_pem(pubkey_file.as_bytes()).expect("Failed decoding public.pem"); let mut signer = Signer::new(MessageDigest::sha256(), &privkey).unwrap(); signer.update(headers.as_bytes()).unwrap(); let signature = BASE64_STANDARD.encode(signer.sign_to_vec().unwrap()); let header = format!( "keyId=\"{}\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"{}\"", key_id, signature ); println!("header: {}", header); let response = ureq::post(url) .header("Content-Type", "application/activity+json") .header("Signature", header) .header("host", host) .header("date", date) .header("digest", digest) .send(json); match response { Err(v) => println!("{:#?}", v), Ok(v) => { println!("Status: {}", v.status()); println!( "Response: {}", v.into_body() .read_to_string() .expect("Invalid response: decode error") ); } } }