jwt_simple_legacy/
common.rs1use std::collections::HashSet;
2
3use coarsetime::{Duration, UnixTimeStamp};
4use ct_codecs::{Base64UrlSafeNoPadding, Decoder, Encoder, Hex};
5
6use crate::{claims::DEFAULT_TIME_TOLERANCE_SECS, error::*};
7
8pub const DEFAULT_MAX_TOKEN_LENGTH: usize = 1_000_000;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct VerificationOptions {
14 pub reject_before: Option<UnixTimeStamp>,
20
21 pub accept_future: bool,
23
24 pub required_subject: Option<String>,
26
27 pub required_key_id: Option<String>,
29
30 pub required_public_key: Option<String>,
32
33 pub required_nonce: Option<String>,
35
36 pub allowed_issuers: Option<HashSet<String>>,
38
39 pub allowed_audiences: Option<HashSet<String>>,
41
42 pub time_tolerance: Option<Duration>,
44
45 pub max_validity: Option<Duration>,
47
48 pub max_token_length: Option<usize>,
50
51 pub max_header_length: Option<usize>,
53}
54
55impl Default for VerificationOptions {
56 fn default() -> Self {
57 Self {
58 reject_before: None,
59 accept_future: false,
60 required_subject: None,
61 required_key_id: None,
62 required_public_key: None,
63 required_nonce: None,
64 allowed_issuers: None,
65 allowed_audiences: None,
66 time_tolerance: Some(Duration::from_secs(DEFAULT_TIME_TOLERANCE_SECS)),
67 max_validity: None,
68 max_token_length: Some(DEFAULT_MAX_TOKEN_LENGTH),
69 max_header_length: None,
70 }
71 }
72}
73
74#[derive(Debug, Clone, Default)]
78pub struct KeyMetadata {
79 pub(crate) key_set_url: Option<String>,
80 pub(crate) public_key: Option<String>,
81 pub(crate) certificate_url: Option<String>,
82 pub(crate) certificate_sha1_thumbprint: Option<String>,
83 pub(crate) certificate_sha256_thumbprint: Option<String>,
84}
85
86impl KeyMetadata {
87 pub fn with_key_set_url(mut self, key_set_url: impl ToString) -> Self {
89 self.key_set_url = Some(key_set_url.to_string());
90 self
91 }
92
93 pub fn with_public_key(mut self, public_key: impl ToString) -> Self {
95 self.public_key = Some(public_key.to_string());
96 self
97 }
98
99 pub fn with_certificate_url(mut self, certificate_url: impl ToString) -> Self {
101 self.certificate_url = Some(certificate_url.to_string());
102 self
103 }
104
105 pub fn with_certificate_sha1_thumbprint(
107 mut self,
108 certificate_sha1_thumbprint: impl ToString,
109 ) -> Result<Self, Error> {
110 let thumbprint = certificate_sha1_thumbprint.to_string();
111 let mut bin = [0u8; 20];
112 if thumbprint.len() == 40 {
113 ensure!(
114 Hex::decode(&mut bin, &thumbprint, None)?.len() == bin.len(),
115 JWTError::InvalidCertThumprint
116 );
117 let thumbprint = Base64UrlSafeNoPadding::encode_to_string(bin)?;
118 self.certificate_sha1_thumbprint = Some(thumbprint);
119 return Ok(self);
120 }
121 ensure!(
122 Base64UrlSafeNoPadding::decode(&mut bin, &thumbprint, None)?.len() == bin.len(),
123 JWTError::InvalidCertThumprint
124 );
125 self.certificate_sha1_thumbprint = Some(thumbprint);
126 Ok(self)
127 }
128
129 pub fn with_certificate_sha256_thumbprint(
131 mut self,
132 certificate_sha256_thumbprint: impl ToString,
133 ) -> Result<Self, Error> {
134 let thumbprint = certificate_sha256_thumbprint.to_string();
135 let mut bin = [0u8; 32];
136 if thumbprint.len() == 64 {
137 ensure!(
138 Hex::decode(&mut bin, &thumbprint, None)?.len() == bin.len(),
139 JWTError::InvalidCertThumprint
140 );
141 let thumbprint = Base64UrlSafeNoPadding::encode_to_string(bin)?;
142 self.certificate_sha256_thumbprint = Some(thumbprint);
143 return Ok(self);
144 }
145 ensure!(
146 Base64UrlSafeNoPadding::decode(&mut bin, &thumbprint, None)?.len() == bin.len(),
147 JWTError::InvalidCertThumprint
148 );
149 self.certificate_sha256_thumbprint = Some(thumbprint);
150 Ok(self)
151 }
152}
153
154#[inline(never)]
155pub(crate) fn timingsafe_eq(a: &[u8], b: &[u8]) -> bool {
156 if a.len() != b.len() {
157 return false;
158 }
159 a.iter().zip(b.iter()).fold(0, |c, (x, y)| c | (x ^ y)) == 0
160}