1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crypto::mac::{Mac, MacResult};
use crypto::hmac::{Hmac};
use crypto::sha2;
use crate::{error, Error, Headers, HeadersMut, Result, Signer, Verifier};
pub struct HmacVerifier{
key: Vec<u8>,
}
pub struct MacSigner<M>(pub Hmac<M>);
impl HmacVerifier {
pub fn new(key: Vec<u8>) -> Self {
Self{key}
}
}
impl Verifier for HmacVerifier {
fn verify(&mut self, headers: Headers, encoded_header: &[u8], encoded_payload: &[u8], signature: &[u8]) -> Result<()> {
let algorithm : &str = headers.deserialize_required("alg")?;
match algorithm {
"HS256" => verify_mac(encoded_header, encoded_payload, signature, &mut Hmac::new(sha2::Sha256::new(), &self.key)),
"HS384" => verify_mac(encoded_header, encoded_payload, signature, &mut Hmac::new(sha2::Sha384::new(), &self.key)),
"HS512" => verify_mac(encoded_header, encoded_payload, signature, &mut Hmac::new(sha2::Sha512::new(), &self.key)),
_ => Err(Error::from(error::UnsupportedMacAlgorithm(algorithm.to_string()))),
}
}
}
impl Signer for MacSigner<sha2::Sha256> {
fn set_header_params(&mut self, mut headers: HeadersMut) -> Result<()> {
headers.insert("alg".to_string(), "HS256");
Ok(())
}
fn compute_mac(&mut self, encoded_header: &[u8], encoded_payload: &[u8]) -> Result<Vec<u8>> {
Ok(compute_mac(encoded_header, encoded_payload, &mut self.0).code().to_owned())
}
}
impl Signer for MacSigner<sha2::Sha384> {
fn set_header_params(&mut self, mut headers: HeadersMut) -> Result<()> {
headers.insert("alg".to_string(), "HS384");
Ok(())
}
fn compute_mac(&mut self, encoded_header: &[u8], encoded_payload: &[u8]) -> Result<Vec<u8>> {
Ok(compute_mac(encoded_header, encoded_payload, &mut self.0).code().to_owned())
}
}
impl Signer for MacSigner<sha2::Sha512> {
fn set_header_params(&mut self, mut headers: HeadersMut) -> Result<()> {
headers.insert("alg".to_string(), "HS512");
Ok(())
}
fn compute_mac(&mut self, encoded_header: &[u8], encoded_payload: &[u8]) -> Result<Vec<u8>> {
Ok(compute_mac(encoded_header, encoded_payload, &mut self.0).code().to_owned())
}
}
fn compute_mac(encoded_header: &[u8], encoded_payload: &[u8], mac: &mut impl Mac) -> MacResult {
mac.reset();
mac.input(encoded_header);
mac.input(b".");
mac.input(encoded_payload);
mac.result()
}
fn verify_mac(encoded_header: &[u8], encoded_payload: &[u8], signature: &[u8], mac: &mut impl Mac) -> Result<()> {
let digest = compute_mac(encoded_header, encoded_payload, mac);
if digest == MacResult::new(signature) {
Ok(())
} else {
Err(Error::InvalidSignature)
}
}