vss_client_ng/headers/
sigs_auth.rs1use crate::headers::{VssHeaderProvider, VssHeaderProviderError};
4use async_trait::async_trait;
5use bitcoin::hashes::sha256::Hash as Sha256;
6use bitcoin::hashes::Hash as _;
7use bitcoin::secp256k1::{Message, Secp256k1, SecretKey, SignOnly};
8use std::collections::HashMap;
9use std::fmt::Write as _;
10use std::io::Write as _;
11use std::time::SystemTime;
12
13pub const SIGNING_CONSTANT: &'static [u8] =
16 b"VSS Signature Authorizer Signing Salt Constant..................";
17
18fn build_token(secret_key: &SecretKey, secp_ctx: &Secp256k1<SignOnly>) -> String {
19 let pubkey = secret_key.public_key(secp_ctx);
20 let old_time = "System time must be at least Jan 1, 1970";
21 let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect(old_time).as_secs();
22
23 let mut buffer = [0u8; SIGNING_CONSTANT.len() + 33 + 20];
25 let mut stream = &mut buffer[..];
26 stream.write_all(SIGNING_CONSTANT).unwrap();
27 stream.write_all(&pubkey.serialize()).unwrap();
28 write!(stream, "{now}").unwrap();
29 let bytes_remaining = stream.len();
30 let bytes_to_sign = &buffer[..buffer.len() - bytes_remaining];
31
32 let hash = Sha256::hash(&bytes_to_sign);
33 let sig = secp_ctx.sign_ecdsa(&Message::from_digest(hash.to_byte_array()), secret_key);
34 let mut out = String::with_capacity((33 + 64 + 20) * 2);
35 write!(&mut out, "{pubkey:x}").unwrap();
36 for c in sig.serialize_compact() {
37 write!(&mut out, "{:02x}", c).unwrap();
38 }
39 write!(&mut out, "{now}").unwrap();
40 out
41}
42
43pub struct SigsAuthProvider {
49 key: SecretKey,
50 secp_ctx: Secp256k1<SignOnly>,
51 default_headers: HashMap<String, String>,
52}
53
54impl SigsAuthProvider {
55 pub fn new(key: SecretKey, default_headers: HashMap<String, String>) -> Self {
63 SigsAuthProvider { secp_ctx: Secp256k1::signing_only(), key, default_headers }
64 }
65}
66
67#[async_trait]
68impl VssHeaderProvider for SigsAuthProvider {
69 async fn get_headers(
70 &self, _request: &[u8],
71 ) -> Result<HashMap<String, String>, VssHeaderProviderError> {
72 let mut headers = self.default_headers.clone();
75 headers.insert("Authorization".to_owned(), build_token(&self.key, &self.secp_ctx));
76 Ok(headers)
77 }
78}