pub(crate) mod rustcrypto;
use crate::Result;
use rustcrypto::RustCryptoBackend;
use std::borrow::Borrow;
use subtle::ConstantTimeEq;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
pub struct MacaroonKey([u8; 32]);
impl std::fmt::Debug for MacaroonKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("MacaroonKey([REDACTED])")
}
}
impl PartialEq for MacaroonKey {
fn eq(&self, other: &Self) -> bool {
self.0.ct_eq(&other.0).into()
}
}
impl Eq for MacaroonKey {}
impl AsRef<[u8; 32]> for MacaroonKey {
fn as_ref(&self) -> &[u8; 32] {
&self.0
}
}
impl AsRef<[u8]> for MacaroonKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Borrow<[u8; 32]> for MacaroonKey {
fn borrow(&self) -> &[u8; 32] {
&self.0
}
}
impl From<[u8; 32]> for MacaroonKey {
fn from(b: [u8; 32]) -> Self {
MacaroonKey(b)
}
}
impl From<&[u8; 32]> for MacaroonKey {
fn from(b: &[u8; 32]) -> Self {
MacaroonKey(*b)
}
}
impl MacaroonKey {
pub fn generate_random() -> Result<Self> {
RustCryptoBackend::generate_random_key()
}
pub fn generate(seed: &[u8]) -> Self {
generate_derived_key(seed)
}
}
const KEY_GENERATOR: MacaroonKey = MacaroonKey(*b"macaroons-key-generator\0\0\0\0\0\0\0\0\0");
fn generate_derived_key(key: &[u8]) -> MacaroonKey {
hmac(&KEY_GENERATOR, key)
}
pub fn hmac<T, U>(key: &T, text: &U) -> MacaroonKey
where
T: AsRef<[u8; 32]> + ?Sized,
U: AsRef<[u8]> + ?Sized,
{
RustCryptoBackend::hmac(key, text)
}
pub fn hmac2<T, U>(key: &T, text1: &U, text2: &U) -> MacaroonKey
where
T: AsRef<[u8; 32]> + ?Sized,
U: AsRef<[u8]> + ?Sized,
{
RustCryptoBackend::hmac2(key, text1, text2)
}
pub fn encrypt_key<T>(key: &T, plaintext: &T) -> Result<Vec<u8>>
where
T: AsRef<[u8; 32]> + ?Sized,
{
RustCryptoBackend::encrypt_key(key, plaintext)
}
pub fn decrypt_key<T, U>(key: &T, data: &U) -> Result<MacaroonKey>
where
T: AsRef<[u8; 32]> + ?Sized,
U: AsRef<[u8]> + ?Sized,
{
RustCryptoBackend::decrypt_key(key, data)
}