pub fn format_endpoint(template: &str, params: &[(&str, &str)]) -> String {
let mut result = template.to_string();
for (key, val) in params {
result = result.replace(&format!("{{{}}}", key), val);
}
result
}
use std::time::{SystemTime, UNIX_EPOCH};
pub fn get_timestamp_in_milliseconds() -> Result<u128, std::time::SystemTimeError> {
let current_system_time = SystemTime::now();
let duration_since_epoch = current_system_time.duration_since(UNIX_EPOCH)?;
let milliseconds_timestamp = duration_since_epoch.as_millis();
Ok(milliseconds_timestamp)
}
use base64::{engine::general_purpose, Engine as _};
use rsa::{pkcs1::DecodeRsaPrivateKey, Pss, RsaPrivateKey};
pub fn sign_pss_text(private_key: &RsaPrivateKey, text: &str) -> Result<String, String> {
use rand::rngs::OsRng;
use sha2::Digest;
use sha2::Sha256;
let message = text.as_bytes();
let mut rng = OsRng;
let pss = Pss::new::<Sha256>();
let mut hasher = Sha256::new();
hasher.update(message);
let message = hasher.finalize();
match private_key.sign_with_rng(&mut rng, pss, &message) {
Ok(signature) => Ok(general_purpose::STANDARD.encode(signature)),
Err(e) => Err(format!("RSA sign PSS failed: {}", e)),
}
}
fn load_private_key_from_pem(pem: &str) -> Result<RsaPrivateKey, String> {
RsaPrivateKey::from_pkcs1_pem(pem)
.map_err(|e| format!("Failed to parse RSA private key from PEM: {}", e))
}
pub fn load_private_key_from_file(file_path: &str) -> Result<RsaPrivateKey, String> {
let pem = std::fs::read_to_string(file_path)
.map_err(|e| format!("Failed to read private key file: {}", e))?;
load_private_key_from_pem(&pem)
}
pub fn load_and_sign_with_private_key(file_path: &str, text: &str) -> Result<String, String> {
let private_key = load_private_key_from_file(file_path)?;
sign_pss_text(&private_key, text)
}