aws_signer 0.0.4

A Rust library for AWS Signature Version 4 signing
Documentation
use std::collections::HashMap;
use chrono::Utc;
use hmac::{Hmac, Mac};
use sha2::Sha256;

pub struct Signature {
    datetime: String,
    secret_access_key: String,
    region: String,
    service: String,
    cache: HashMap<String, Vec<u8>>,
}

impl Signature {
    pub fn new(secret_access_key: String, region: String, service: String) -> Self {
        Self {
            datetime: Utc::now().format("%Y%m%dT%H%M%SZ").to_string(),
            secret_access_key,
            region,
            service,
            cache: HashMap::new(),
        }
    }
    pub fn signature(&mut self) -> String {
        let date = &self.datetime[0..8];
        let cache_key = format!("{},{},{},{}", self.secret_access_key, date, self.region, self.service);

        // if let Some(k_credentials) = self.cache.get(&cache_key) {
        //     return buf2hex(k_credentials.as_slice());
        // }

        let k_date = hmac_sha256(format!("AWS4{}", self.secret_access_key).as_bytes(), date.as_bytes());
        let k_region = hmac_sha256(&k_date, self.region.as_bytes());
        let k_service = hmac_sha256(&k_region, self.service.as_bytes());
        let k_signing = hmac_sha256(&k_service, b"aws4_request");

        self.cache.insert(cache_key.clone(), k_signing.clone());
        buf2hex(k_signing.as_slice())
    }
}


// Type alias for HMAC-SHA256
type HmacSha256 = Hmac<Sha256>;

// Updated hmac function in Rust
fn hmac_sha256(key: &[u8], data: &[u8]) -> Vec<u8> {
    // Create a new HMAC object with the provided key
    let mut mac = HmacSha256::new_from_slice(key).expect("HMAC can take key of any size");
    // Process the data to be signed
    mac.update(data);
    // Return the resulting HMAC as bytes
    mac.finalize().into_bytes().to_vec()
}


pub fn buf2hex(array_buffer: &[u8]) -> String {
    const HEX_CHARS: [char; 16] = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
    ];

    let mut out = String::with_capacity(array_buffer.len() * 2);
    for &byte in array_buffer {
        out.push(HEX_CHARS[(byte >> 4) as usize]);
        out.push(HEX_CHARS[(byte & 0xf) as usize]);
    }
    out
}