1use crate::{Error, JsonObject, Result, Verifier};
4
5#[derive(Clone, Debug)]
6pub struct OrVerifier<Left, Right> {
7 pub left : Left,
8 pub right : Right,
9}
10
11#[derive(Clone, Debug)]
12pub struct AndVerifier<Left, Right> {
13 pub left : Left,
14 pub right : Right,
15}
16
17impl<Left, Right> OrVerifier<Left, Right> {
19 pub fn new(left: Left, right: Right) -> Self {
20 Self{left, right}
21 }
22
23 pub fn into_inner(self) -> (Left, Right) {
24 (self.left, self.right)
25 }
26
27 pub fn left(&self) -> &Left {
28 &self.left
29 }
30
31 pub fn right(&self) -> &Right {
32 &self.right
33 }
34}
35
36impl<Left, Right> AndVerifier<Left, Right> {
38 pub fn new(left: Left, right: Right) -> Self {
39 Self{left, right}
40 }
41
42 pub fn into_inner(self) -> (Left, Right) {
43 (self.left, self.right)
44 }
45
46 pub fn left(&self) -> &Left {
47 &self.left
48 }
49
50 pub fn right(&self) -> &Right {
51 &self.right
52 }
53}
54
55impl<Left: Verifier, Right: Verifier> Verifier for OrVerifier<Left, Right> {
56 fn verify(&self, protected_header: Option<&JsonObject>, unprotected_header: Option<&JsonObject>, encoded_header: &[u8], encoded_payload: &[u8], signature: &[u8]) -> Result<()> {
57 let error_a = match self.left.verify(protected_header, unprotected_header, encoded_header, encoded_payload, signature) {
59 Ok(()) => return Ok(()),
60 Err(x) => x,
61 };
62
63 let error_b = match self.right.verify(protected_header, unprotected_header, encoded_header, encoded_payload, signature) {
65 Ok(()) => return Ok(()),
66 Err(x) => x,
67 };
68
69 Err(match (error_a.kind(), error_b.kind()) {
71 (_, Error::UnsupportedMacAlgorithm) => error_a,
72 (Error::UnsupportedMacAlgorithm, _) => error_b,
73 (_, _) => error_a
74 })
75 }
76}
77
78impl<Left: Verifier, Right: Verifier> Verifier for AndVerifier<Left, Right> {
79 fn verify(&self, protected_header: Option<&JsonObject>, unprotected_header: Option<&JsonObject>, encoded_header: &[u8], encoded_payload: &[u8], signature: &[u8]) -> Result<()> {
80 self.left.verify(protected_header, unprotected_header, encoded_header, encoded_payload, signature)?;
82 self.right.verify(protected_header, unprotected_header, encoded_header, encoded_payload, signature)?;
83 Ok(())
84 }
85}
86
87#[cfg(test)]
88mod test {
89 use super::*;
90 use crate::{compact, json_object};
91 use crate::hmac::{HmacVerifier, Hs256Signer};
92
93 use assert2::assert;
94
95 #[test]
96 fn test_encode_sign_hmac_sha2() {
97 let header = json_object!{"typ": "JWT"};
98 let signed = compact::encode_sign(header, b"foo", &Hs256Signer::new(b"secretkey")).expect("sign HS256 failed");
99
100 let verifier_wrong = HmacVerifier::new(b"wrong-key");
101 let verifier_right = HmacVerifier::new(b"secretkey");
102
103 let wrong_or_right = verifier_wrong.clone().or(verifier_right.clone());
104 let wrong_or_wrong = verifier_wrong.clone().or(verifier_wrong.clone());
105 let wrong_and_right = verifier_wrong.clone().and(verifier_right.clone());
106 let right_and_right = verifier_right.clone().and(verifier_right.clone());
107
108 assert!(let Ok(_) = compact::decode_verify(signed.as_bytes(), &verifier_right));
110 assert!(let Ok(_) = compact::decode_verify(signed.as_bytes(), &wrong_or_right));
111 assert!(let Ok(_) = compact::decode_verify(signed.as_bytes(), &right_and_right));
112
113 assert!(let Err(Error { kind: Error::InvalidSignature, .. }) = compact::decode_verify(signed.as_bytes(), &verifier_wrong));
114 assert!(let Err(Error { kind: Error::InvalidSignature, .. }) = compact::decode_verify(signed.as_bytes(), &wrong_or_wrong));
115 assert!(let Err(Error { kind: Error::InvalidSignature, .. }) = compact::decode_verify(signed.as_bytes(), &wrong_and_right));
116 }
117}