#![allow(dead_code)]
use crate::Digest;
use hmac::{self, Mac};
use sha2::{Sha256, Sha512};
#[derive(Debug, Clone)]
pub enum Hmac {
Sha256(Box<hmac::Hmac<Sha256>>),
Sha512(Box<hmac::Hmac<Sha512>>),
}
impl Hmac {
#[inline]
pub fn num_bytes(&self) -> usize {
match *self {
Hmac::Sha256(_) => 32,
Hmac::Sha512(_) => 64,
}
}
pub fn from_key(algorithm: Digest, key: &[u8]) -> Self {
match algorithm {
Digest::Sha256 => Hmac::Sha256(Box::new(
hmac::Hmac::new_from_slice(key).expect("Hmac::new_varkey accepts any key length"),
)),
Digest::Sha512 => Hmac::Sha512(Box::new(
hmac::Hmac::new_from_slice(key).expect("Hmac::new_varkey accepts any key length"),
)),
}
}
pub fn sign(&self, crypted_data: &[u8]) -> Vec<u8> {
match *self {
Hmac::Sha256(ref hmac) => {
let mut hmac = hmac.clone();
hmac.update(crypted_data);
hmac.finalize().into_bytes().to_vec()
}
Hmac::Sha512(ref hmac) => {
let mut hmac = hmac.clone();
hmac.update(crypted_data);
hmac.finalize().into_bytes().to_vec()
}
}
}
pub fn verify(&self, crypted_data: &[u8], expected_hash: &[u8]) -> bool {
match *self {
Hmac::Sha256(ref hmac) => {
let mut hmac = hmac.clone();
hmac.update(crypted_data);
hmac.verify_slice(expected_hash).is_ok()
}
Hmac::Sha512(ref hmac) => {
let mut hmac = hmac.clone();
hmac.update(crypted_data);
hmac.verify_slice(expected_hash).is_ok()
}
}
}
pub fn context(&self) -> Context {
match self {
Hmac::Sha256(hmac) => Context::Sha256(hmac.clone()),
Hmac::Sha512(hmac) => Context::Sha512(hmac.clone()),
}
}
}
pub enum Context {
Sha256(Box<hmac::Hmac<Sha256>>),
Sha512(Box<hmac::Hmac<Sha512>>),
}
impl Context {
pub fn update(&mut self, data: &[u8]) {
match *self {
Context::Sha256(ref mut hmac) => {
hmac.update(data);
}
Context::Sha512(ref mut hmac) => {
hmac.update(data);
}
}
}
pub fn sign(self) -> Vec<u8> {
match self {
Context::Sha256(hmac) => hmac.finalize().into_bytes().to_vec(),
Context::Sha512(hmac) => hmac.finalize().into_bytes().to_vec(),
}
}
}