ffsend_api/crypto/
sig.rs

1#[cfg(feature = "crypto-openssl")]
2use openssl::{error::ErrorStack, hash::MessageDigest, pkey::PKey, sign::Signer};
3#[cfg(feature = "crypto-ring")]
4use ring::hmac;
5
6use super::b64;
7
8/// Compute the signature for the given data and key.
9/// This is done using an HMAC key using the SHA256 digest.
10///
11/// If computing the signature failed, an error is returned.
12#[cfg(feature = "crypto-openssl")]
13fn signature_openssl(key: &[u8], data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
14    // Build the key, and signer
15    let pkey = PKey::hmac(&key)?;
16    let mut signer = Signer::new(MessageDigest::sha256(), &pkey)?;
17
18    // Feed the data
19    signer.update(&data)?;
20
21    // Compute the signature
22    Ok(signer.sign_to_vec()?)
23}
24
25/// Compute the signature for the given data and key.
26/// This is done using an HMAC key using the SHA256 digest.
27#[cfg(feature = "crypto-ring")]
28fn signature_ring(key: &[u8], data: &[u8]) -> Vec<u8> {
29    let skey = hmac::Key::new(hmac::HMAC_SHA256, key);
30    hmac::sign(&skey, data).as_ref().to_owned()
31}
32
33/// Compute the signature for the given data and key.
34/// This is done using an HMAC key using the SHA256 digest.
35///
36/// The resulting signature is encoded as base64 string in an URL-safe manner.
37///
38/// If computing the signature failed, an error is returned.
39pub fn signature_encoded(key: &[u8], data: &[u8]) -> Result<String, ()> {
40    #[cfg(feature = "crypto-openssl")]
41    {
42        signature_openssl(key, data)
43            .map(|sig| b64::encode(&sig))
44            .map_err(|_| ())
45    }
46
47    #[cfg(feature = "crypto-ring")]
48    {
49        Ok(b64::encode(&signature_ring(key, data)))
50    }
51}