jwt_simple/algorithms/jwe/
aes_kw.rs1#[cfg(any(feature = "pure-rust", target_arch = "wasm32", target_arch = "wasm64"))]
6use superboring as boring;
7
8use boring::aes::{unwrap_key, wrap_key, AesKey};
9use rand::Rng;
10use serde::{de::DeserializeOwned, Serialize};
11use zeroize::Zeroize;
12
13use crate::claims::*;
14use crate::error::*;
15use crate::jwe_header::JWEHeader;
16use crate::jwe_token::{DecryptionOptions, EncryptionOptions, JWEToken, JWETokenMetadata};
17
18#[derive(Clone)]
22pub struct A256KWKey {
23 key: Vec<u8>,
24 key_id: Option<String>,
25}
26
27impl std::fmt::Debug for A256KWKey {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("A256KWKey")
30 .field("key_id", &self.key_id)
31 .finish_non_exhaustive()
32 }
33}
34
35impl Drop for A256KWKey {
36 fn drop(&mut self) {
37 self.key.zeroize();
38 }
39}
40
41impl A256KWKey {
42 const KEY_SIZE: usize = 32;
43 const ALG_NAME: &'static str = "A256KW";
44
45 pub fn from_bytes(key: &[u8]) -> Result<Self, Error> {
49 ensure!(key.len() == Self::KEY_SIZE, JWTError::InvalidEncryptionKey);
50 Ok(A256KWKey {
51 key: key.to_vec(),
52 key_id: None,
53 })
54 }
55
56 pub fn generate() -> Self {
58 let mut key = vec![0u8; Self::KEY_SIZE];
59 rand::rng().fill_bytes(&mut key);
60 A256KWKey { key, key_id: None }
61 }
62
63 pub fn to_bytes(&self) -> Vec<u8> {
65 self.key.clone()
66 }
67
68 pub fn with_key_id(mut self, key_id: impl Into<String>) -> Self {
70 self.key_id = Some(key_id.into());
71 self
72 }
73
74 pub fn key_id(&self) -> Option<&str> {
76 self.key_id.as_deref()
77 }
78
79 pub(crate) fn wrap_key(&self, cek: &[u8]) -> Result<Vec<u8>, Error> {
80 let aes_key = AesKey::new_encrypt(&self.key).map_err(|_| JWTError::InvalidEncryptionKey)?;
81
82 let mut wrapped = vec![0u8; cek.len() + 8];
84 wrap_key(&aes_key, None, &mut wrapped, cek).map_err(|_| JWTError::InvalidEncryptionKey)?;
85
86 Ok(wrapped)
87 }
88
89 pub(crate) fn unwrap_key(&self, wrapped: &[u8]) -> Result<Vec<u8>, Error> {
90 ensure!(wrapped.len() >= 16, JWTError::KeyUnwrapFailed);
91
92 let aes_key = AesKey::new_decrypt(&self.key).map_err(|_| JWTError::InvalidEncryptionKey)?;
93
94 let mut cek = vec![0u8; wrapped.len() - 8];
96 unwrap_key(&aes_key, None, &mut cek, wrapped).map_err(|_| JWTError::KeyUnwrapFailed)?;
97
98 Ok(cek)
99 }
100
101 pub fn encrypt<CustomClaims: Serialize>(
103 &self,
104 claims: JWTClaims<CustomClaims>,
105 ) -> Result<String, Error> {
106 self.encrypt_with_options(claims, &EncryptionOptions::default())
107 }
108
109 pub fn encrypt_with_options<CustomClaims: Serialize>(
111 &self,
112 claims: JWTClaims<CustomClaims>,
113 options: &EncryptionOptions,
114 ) -> Result<String, Error> {
115 let content_encryption = options.content_encryption;
116 let mut header = JWEHeader::new(Self::ALG_NAME, content_encryption.alg_name());
117
118 if let Some(key_id) = &self.key_id {
119 header.key_id = Some(key_id.clone());
120 }
121 if let Some(key_id) = &options.key_id {
122 header.key_id = Some(key_id.clone());
123 }
124 if let Some(cty) = &options.content_type {
125 header.content_type = Some(cty.clone());
126 }
127
128 JWEToken::build_from_claims(&header, &claims, content_encryption, |cek| {
129 self.wrap_key(cek)
130 })
131 }
132
133 pub fn decrypt_token<CustomClaims: DeserializeOwned>(
135 &self,
136 token: &str,
137 options: Option<DecryptionOptions>,
138 ) -> Result<JWTClaims<CustomClaims>, Error> {
139 JWEToken::decrypt(Self::ALG_NAME, token, options, |_header, encrypted_key| {
140 self.unwrap_key(encrypted_key)
141 })
142 }
143
144 pub fn decode_metadata(token: &str) -> Result<JWETokenMetadata, Error> {
146 JWEToken::decode_metadata(token)
147 }
148}
149
150#[derive(Clone)]
155pub struct A128KWKey {
156 key: Vec<u8>,
157 key_id: Option<String>,
158}
159
160impl std::fmt::Debug for A128KWKey {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 f.debug_struct("A128KWKey")
163 .field("key_id", &self.key_id)
164 .finish_non_exhaustive()
165 }
166}
167
168impl Drop for A128KWKey {
169 fn drop(&mut self) {
170 self.key.zeroize();
171 }
172}
173
174impl A128KWKey {
175 const KEY_SIZE: usize = 16;
176 const ALG_NAME: &'static str = "A128KW";
177
178 pub fn from_bytes(key: &[u8]) -> Result<Self, Error> {
182 ensure!(key.len() == Self::KEY_SIZE, JWTError::InvalidEncryptionKey);
183 Ok(A128KWKey {
184 key: key.to_vec(),
185 key_id: None,
186 })
187 }
188
189 pub fn generate() -> Self {
191 let mut key = vec![0u8; Self::KEY_SIZE];
192 rand::rng().fill_bytes(&mut key);
193 A128KWKey { key, key_id: None }
194 }
195
196 pub fn to_bytes(&self) -> Vec<u8> {
198 self.key.clone()
199 }
200
201 pub fn with_key_id(mut self, key_id: impl Into<String>) -> Self {
203 self.key_id = Some(key_id.into());
204 self
205 }
206
207 pub fn key_id(&self) -> Option<&str> {
209 self.key_id.as_deref()
210 }
211
212 pub(crate) fn wrap_key(&self, cek: &[u8]) -> Result<Vec<u8>, Error> {
213 let aes_key = AesKey::new_encrypt(&self.key).map_err(|_| JWTError::InvalidEncryptionKey)?;
214
215 let mut wrapped = vec![0u8; cek.len() + 8];
217 wrap_key(&aes_key, None, &mut wrapped, cek).map_err(|_| JWTError::InvalidEncryptionKey)?;
218
219 Ok(wrapped)
220 }
221
222 pub(crate) fn unwrap_key(&self, wrapped: &[u8]) -> Result<Vec<u8>, Error> {
223 ensure!(wrapped.len() >= 16, JWTError::KeyUnwrapFailed);
224
225 let aes_key = AesKey::new_decrypt(&self.key).map_err(|_| JWTError::InvalidEncryptionKey)?;
226
227 let mut cek = vec![0u8; wrapped.len() - 8];
229 unwrap_key(&aes_key, None, &mut cek, wrapped).map_err(|_| JWTError::KeyUnwrapFailed)?;
230
231 Ok(cek)
232 }
233
234 pub fn encrypt<CustomClaims: Serialize>(
236 &self,
237 claims: JWTClaims<CustomClaims>,
238 ) -> Result<String, Error> {
239 self.encrypt_with_options(claims, &EncryptionOptions::default())
240 }
241
242 pub fn encrypt_with_options<CustomClaims: Serialize>(
244 &self,
245 claims: JWTClaims<CustomClaims>,
246 options: &EncryptionOptions,
247 ) -> Result<String, Error> {
248 let content_encryption = options.content_encryption;
249 let mut header = JWEHeader::new(Self::ALG_NAME, content_encryption.alg_name());
250
251 if let Some(key_id) = &self.key_id {
252 header.key_id = Some(key_id.clone());
253 }
254 if let Some(key_id) = &options.key_id {
255 header.key_id = Some(key_id.clone());
256 }
257 if let Some(cty) = &options.content_type {
258 header.content_type = Some(cty.clone());
259 }
260
261 JWEToken::build_from_claims(&header, &claims, content_encryption, |cek| {
262 self.wrap_key(cek)
263 })
264 }
265
266 pub fn decrypt_token<CustomClaims: DeserializeOwned>(
268 &self,
269 token: &str,
270 options: Option<DecryptionOptions>,
271 ) -> Result<JWTClaims<CustomClaims>, Error> {
272 JWEToken::decrypt(Self::ALG_NAME, token, options, |_header, encrypted_key| {
273 self.unwrap_key(encrypted_key)
274 })
275 }
276
277 pub fn decode_metadata(token: &str) -> Result<JWETokenMetadata, Error> {
279 JWEToken::decode_metadata(token)
280 }
281}