biscuit/
jwa.rs

1//! JSON Web Algorithms
2//!
3//! Code for implementing JWA according to [RFC 7518](https://tools.ietf.org/html/rfc7518).
4//!
5//! Typically, you will not use these directly, but as part of a JWS or JWE.
6
7use std::fmt;
8
9use once_cell::sync::Lazy;
10use ring::constant_time::verify_slices_are_equal;
11use ring::rand::SystemRandom;
12use ring::signature::KeyPair;
13use ring::{aead, hmac, rand, signature};
14use serde::de::DeserializeOwned;
15use serde::{Deserialize, Serialize};
16
17use crate::errors::Error;
18use crate::jwk;
19use crate::jws::Secret;
20use crate::Empty;
21
22pub use ring::rand::SecureRandom;
23
24/// AES GCM Tag Size, in bytes
25const AES_GCM_TAG_SIZE: usize = 128 / 8;
26/// AES GCM Nonce length, in bytes
27const AES_GCM_NONCE_LENGTH: usize = 96 / 8;
28
29/// A zeroed AES GCM Nonce EncryptionOptions
30static AES_GCM_ZEROED_NONCE: Lazy<EncryptionOptions> = Lazy::new(|| EncryptionOptions::AES_GCM {
31    nonce: vec![0; AES_GCM_NONCE_LENGTH],
32});
33
34/// A default `None` `EncryptionOptions`
35pub(crate) const NONE_ENCRYPTION_OPTIONS: &EncryptionOptions = &EncryptionOptions::None;
36
37/// Options to be passed in while performing an encryption operation, if required by the algorithm.
38#[derive(Clone, Debug, Eq, PartialEq)]
39#[allow(non_camel_case_types)]
40#[derive(Default)]
41pub enum EncryptionOptions {
42    /// No options are required. Most algorithms do not require additional parameters
43    #[default]
44    None,
45    /// Options for AES GCM encryption.
46    AES_GCM {
47        /// Initialization vector, or nonce for the AES GCM encryption. _MUST BE_ 96 bits long.
48        ///
49        /// AES GCM encryption operations should not reuse the nonce, or initialization vector.
50        /// Users should keep track of previously used
51        /// nonces and not reuse them. A simple way to keep track is to simply increment the nonce
52        /// as a 96 bit counter.
53        nonce: Vec<u8>,
54    },
55}
56
57#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
58/// Algorithms described by [RFC 7518](https://tools.ietf.org/html/rfc7518).
59/// This enum is serialized `untagged`.
60#[serde(untagged)]
61pub enum Algorithm {
62    /// Algorithms meant for Digital signature or MACs
63    /// See [RFC7518#3](https://tools.ietf.org/html/rfc7518#section-3)
64    Signature(SignatureAlgorithm),
65    /// Algorithms meant for key management. The algorithms are either meant to
66    /// encrypt a content encryption key or determine the content encryption key.
67    /// See [RFC7518#4](https://tools.ietf.org/html/rfc7518#section-4)
68    KeyManagement(KeyManagementAlgorithm),
69    /// Algorithms meant for content encryption.
70    /// See [RFC7518#5](https://tools.ietf.org/html/rfc7518#section-5)
71    ContentEncryption(ContentEncryptionAlgorithm),
72}
73
74#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
75/// The algorithms supported for digital signature and MACs, defined by
76/// [RFC7518#3](https://tools.ietf.org/html/rfc7518#section-3).
77#[derive(Default)]
78pub enum SignatureAlgorithm {
79    /// No encryption/signature is included for the JWT.
80    /// During verification, the signature _MUST BE_ empty or verification  will fail.
81    #[serde(rename = "none")]
82    None,
83    /// HMAC using SHA-256
84    #[default]
85    HS256,
86    /// HMAC using SHA-384
87    HS384,
88    /// HMAC using SHA-512
89    HS512,
90    /// RSASSA-PKCS1-v1_5 using SHA-256
91    RS256,
92    /// RSASSA-PKCS1-v1_5 using SHA-384
93    RS384,
94    /// RSASSA-PKCS1-v1_5 using SHA-512
95    RS512,
96    /// ECDSA using P-256 and SHA-256
97    ES256,
98    /// ECDSA using P-384 and SHA-384
99    ES384,
100    /// ECDSA using P-521 and SHA-512 --
101    /// This variant is [unsupported](https://github.com/briansmith/ring/issues/268) and will probably never be.
102    ES512,
103    /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256.
104    /// The size of the salt value is the same size as the hash function output.
105    PS256,
106    /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
107    /// The size of the salt value is the same size as the hash function output.
108    PS384,
109    /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
110    /// The size of the salt value is the same size as the hash function output.
111    PS512,
112}
113
114/// Algorithms for key management as defined in [RFC7518#4](https://tools.ietf.org/html/rfc7518#section-4)
115#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
116#[allow(non_camel_case_types)]
117#[derive(Default)]
118pub enum KeyManagementAlgorithm {
119    /// RSAES-PKCS1-v1_5
120    RSA1_5,
121    /// RSAES OAEP using default parameters
122    #[serde(rename = "RSA-OAEP")]
123    RSA_OAEP,
124    /// RSAES OAEP using SHA-256 and MGF1 with SHA-256
125    #[serde(rename = "RSA-OAEP-256")]
126    RSA_OAEP_256,
127    /// AES Key Wrap using 128-bit key. _Unsupported_
128    A128KW,
129    /// AES Key Wrap using 192-bit key. _Unsupported_.
130    /// This is [not supported](https://github.com/briansmith/ring/issues/112) by `ring`.
131    A192KW,
132    /// AES Key Wrap using 256-bit key. _Unsupported_
133    A256KW,
134    /// Direct use of a shared symmetric key
135    #[serde(rename = "dir")]
136    #[default]
137    DirectSymmetricKey,
138    /// ECDH-ES using Concat KDF
139    #[serde(rename = "ECDH-ES")]
140    ECDH_ES,
141    /// ECDH-ES using Concat KDF and "A128KW" wrapping
142    #[serde(rename = "ECDH-ES+A128KW")]
143    ECDH_ES_A128KW,
144    /// ECDH-ES using Concat KDF and "A192KW" wrapping
145    #[serde(rename = "ECDH-ES+A192KW")]
146    ECDH_ES_A192KW,
147    /// ECDH-ES using Concat KDF and "A256KW" wrapping
148    #[serde(rename = "ECDH-ES+A256KW")]
149    ECDH_ES_A256KW,
150    /// Key wrapping with AES GCM using 128-bit key alg
151    A128GCMKW,
152    /// Key wrapping with AES GCM using 192-bit key alg.
153    /// This is [not supported](https://github.com/briansmith/ring/issues/112) by `ring`.
154    A192GCMKW,
155    /// Key wrapping with AES GCM using 256-bit key alg
156    A256GCMKW,
157    /// PBES2 with HMAC SHA-256 and "A128KW" wrapping
158    #[serde(rename = "PBES2-HS256+A128KW")]
159    PBES2_HS256_A128KW,
160    /// PBES2 with HMAC SHA-384 and "A192KW" wrapping
161    #[serde(rename = "PBES2-HS384+A192KW")]
162    PBES2_HS384_A192KW,
163    /// PBES2 with HMAC SHA-512 and "A256KW" wrapping
164    #[serde(rename = "PBES2-HS512+A256KW")]
165    PBES2_HS512_A256KW,
166}
167
168/// Describes the type of operations that the key management algorithm
169/// supports with respect to a Content Encryption Key (CEK)
170#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
171pub enum KeyManagementAlgorithmType {
172    /// Wraps a randomly generated CEK using a symmetric encryption algorithm
173    SymmetricKeyWrapping,
174    /// Encrypt a randomly generated CEK using an asymmetric encryption algorithm,
175    AsymmetricKeyEncryption,
176    /// A key agreement algorithm to pick a CEK
177    DirectKeyAgreement,
178    /// A key agreement algorithm used to pick a symmetric CEK and wrap the CEK with a symmetric encryption algorithm
179    KeyAgreementWithKeyWrapping,
180    /// A user defined symmetric shared key is the CEK
181    DirectEncryption,
182}
183
184/// Algorithms meant for content encryption.
185/// See [RFC7518#5](https://tools.ietf.org/html/rfc7518#section-5)
186#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
187#[allow(non_camel_case_types)]
188#[derive(Default)]
189pub enum ContentEncryptionAlgorithm {
190    /// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm enc
191    #[serde(rename = "A128CBC-HS256")]
192    A128CBC_HS256,
193    /// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm enc
194    #[serde(rename = "A192CBC-HS384")]
195    A192CBC_HS384,
196    /// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm enc
197    #[serde(rename = "A256CBC-HS512")]
198    A256CBC_HS512,
199    /// AES GCM using 128-bit key
200    #[default]
201    A128GCM,
202    /// AES GCM using 192-bit key
203    /// This is [not supported](https://github.com/briansmith/ring/issues/112) by `ring`.
204    A192GCM,
205    /// AES GCM using 256-bit key
206    A256GCM,
207}
208
209/// The result returned from an encryption operation
210// TODO: Might have to turn this into an enum
211#[derive(Clone, Debug, Eq, PartialEq, Default)]
212pub struct EncryptionResult {
213    /// The initialization vector, or nonce used in the encryption
214    pub nonce: Vec<u8>,
215    /// The encrypted payload
216    pub encrypted: Vec<u8>,
217    /// The authentication tag
218    pub tag: Vec<u8>,
219    /// Additional authenticated data that is integrity protected but not encrypted
220    pub additional_data: Vec<u8>,
221}
222
223impl EncryptionOptions {
224    /// Description of the type of key
225    pub fn description(&self) -> &'static str {
226        match self {
227            EncryptionOptions::None => "None",
228            EncryptionOptions::AES_GCM { .. } => "AES GCM Nonce/Initialization Vector",
229        }
230    }
231}
232
233impl fmt::Display for EncryptionOptions {
234    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235        write!(f, "{}", self.description())
236    }
237}
238
239impl SignatureAlgorithm {
240    /// Take some bytes and sign it according to the algorithm and secret provided.
241    pub fn sign(self, data: &[u8], secret: &Secret) -> Result<Vec<u8>, Error> {
242        use self::SignatureAlgorithm::*;
243
244        match self {
245            None => Self::sign_none(secret),
246            HS256 | HS384 | HS512 => Self::sign_hmac(data, secret, self),
247            RS256 | RS384 | RS512 | PS256 | PS384 | PS512 => Self::sign_rsa(data, secret, self),
248            ES256 | ES384 | ES512 => Self::sign_ecdsa(data, secret, self),
249        }
250    }
251
252    /// Verify signature based on the algorithm and secret provided.
253    pub fn verify(
254        self,
255        expected_signature: &[u8],
256        data: &[u8],
257        secret: &Secret,
258    ) -> Result<(), Error> {
259        use self::SignatureAlgorithm::*;
260
261        match self {
262            None => Self::verify_none(expected_signature, secret),
263            HS256 | HS384 | HS512 => Self::verify_hmac(expected_signature, data, secret, self),
264            RS256 | RS384 | RS512 | PS256 | PS384 | PS512 | ES256 | ES384 | ES512 => {
265                Self::verify_public_key(expected_signature, data, secret, self)
266            }
267        }
268    }
269
270    /// Returns the type of operations the key is meant for
271    fn sign_none(secret: &Secret) -> Result<Vec<u8>, Error> {
272        match *secret {
273            Secret::None => {}
274            _ => Err("Invalid secret type. `None` should be provided".to_string())?,
275        };
276        Ok(vec![])
277    }
278
279    fn sign_hmac(
280        data: &[u8],
281        secret: &Secret,
282        algorithm: SignatureAlgorithm,
283    ) -> Result<Vec<u8>, Error> {
284        let secret = match *secret {
285            Secret::Bytes(ref secret) => secret,
286            _ => Err("Invalid secret type. A byte array is required".to_string())?,
287        };
288
289        let algorithm = match algorithm {
290            SignatureAlgorithm::HS256 => &hmac::HMAC_SHA256,
291            SignatureAlgorithm::HS384 => &hmac::HMAC_SHA384,
292            SignatureAlgorithm::HS512 => &hmac::HMAC_SHA512,
293            _ => unreachable!("Should not happen"),
294        };
295        let key = hmac::Key::new(*algorithm, secret);
296        Ok(hmac::sign(&key, data).as_ref().to_vec())
297    }
298
299    fn sign_rsa(
300        data: &[u8],
301        secret: &Secret,
302        algorithm: SignatureAlgorithm,
303    ) -> Result<Vec<u8>, Error> {
304        let key_pair = match *secret {
305            Secret::RsaKeyPair(ref key_pair) => key_pair,
306            _ => Err("Invalid secret type. A RsaKeyPair is required".to_string())?,
307        };
308
309        let rng = rand::SystemRandom::new();
310        let mut signature = vec![0; key_pair.public().modulus_len()];
311        let padding_algorithm: &dyn signature::RsaEncoding = match algorithm {
312            SignatureAlgorithm::RS256 => &signature::RSA_PKCS1_SHA256,
313            SignatureAlgorithm::RS384 => &signature::RSA_PKCS1_SHA384,
314            SignatureAlgorithm::RS512 => &signature::RSA_PKCS1_SHA512,
315            SignatureAlgorithm::PS256 => &signature::RSA_PSS_SHA256,
316            SignatureAlgorithm::PS384 => &signature::RSA_PSS_SHA384,
317            SignatureAlgorithm::PS512 => &signature::RSA_PSS_SHA512,
318            _ => unreachable!("Should not happen"),
319        };
320
321        key_pair.sign(padding_algorithm, &rng, data, &mut signature)?;
322        Ok(signature)
323    }
324
325    fn sign_ecdsa(
326        data: &[u8],
327        secret: &Secret,
328        algorithm: SignatureAlgorithm,
329    ) -> Result<Vec<u8>, Error> {
330        let key_pair = match *secret {
331            Secret::EcdsaKeyPair(ref key_pair) => key_pair,
332            _ => Err("Invalid secret type. An EcdsaKeyPair is required".to_string())?,
333        };
334        if let SignatureAlgorithm::ES512 = algorithm {
335            // See https://github.com/briansmith/ring/issues/268
336            Err(Error::UnsupportedOperation)
337        } else {
338            let rng = rand::SystemRandom::new();
339            let sig = key_pair.as_ref().sign(&rng, data)?;
340            Ok(sig.as_ref().to_vec())
341        }
342    }
343
344    fn verify_none(expected_signature: &[u8], secret: &Secret) -> Result<(), Error> {
345        match *secret {
346            Secret::None => {}
347            _ => Err("Invalid secret type. `None` should be provided".to_string())?,
348        };
349
350        if expected_signature.is_empty() {
351            Ok(())
352        } else {
353            Err(Error::UnspecifiedCryptographicError)
354        }
355    }
356
357    fn verify_hmac(
358        expected_signature: &[u8],
359        data: &[u8],
360        secret: &Secret,
361        algorithm: SignatureAlgorithm,
362    ) -> Result<(), Error> {
363        let actual_signature = Self::sign_hmac(data, secret, algorithm)?;
364        verify_slices_are_equal(expected_signature, actual_signature.as_ref())?;
365        Ok(())
366    }
367
368    fn verify_public_key(
369        expected_signature: &[u8],
370        data: &[u8],
371        secret: &Secret,
372        algorithm: SignatureAlgorithm,
373    ) -> Result<(), Error> {
374        match *secret {
375            Secret::PublicKey(ref public_key) => {
376                let verification_algorithm: &dyn signature::VerificationAlgorithm = match algorithm
377                {
378                    SignatureAlgorithm::RS256 => &signature::RSA_PKCS1_2048_8192_SHA256,
379                    SignatureAlgorithm::RS384 => &signature::RSA_PKCS1_2048_8192_SHA384,
380                    SignatureAlgorithm::RS512 => &signature::RSA_PKCS1_2048_8192_SHA512,
381                    SignatureAlgorithm::PS256 => &signature::RSA_PSS_2048_8192_SHA256,
382                    SignatureAlgorithm::PS384 => &signature::RSA_PSS_2048_8192_SHA384,
383                    SignatureAlgorithm::PS512 => &signature::RSA_PSS_2048_8192_SHA512,
384                    SignatureAlgorithm::ES256 => &signature::ECDSA_P256_SHA256_FIXED,
385                    SignatureAlgorithm::ES384 => &signature::ECDSA_P384_SHA384_FIXED,
386                    SignatureAlgorithm::ES512 => Err(Error::UnsupportedOperation)?,
387                    _ => unreachable!("Should not happen"),
388                };
389
390                let public_key = signature::UnparsedPublicKey::new(
391                    verification_algorithm,
392                    public_key.as_slice(),
393                );
394                public_key.verify(data, expected_signature)?;
395                Ok(())
396            }
397            Secret::RsaKeyPair(ref keypair) => {
398                let verification_algorithm: &dyn signature::VerificationAlgorithm = match algorithm
399                {
400                    SignatureAlgorithm::RS256 => &signature::RSA_PKCS1_2048_8192_SHA256,
401                    SignatureAlgorithm::RS384 => &signature::RSA_PKCS1_2048_8192_SHA384,
402                    SignatureAlgorithm::RS512 => &signature::RSA_PKCS1_2048_8192_SHA512,
403                    SignatureAlgorithm::PS256 => &signature::RSA_PSS_2048_8192_SHA256,
404                    SignatureAlgorithm::PS384 => &signature::RSA_PSS_2048_8192_SHA384,
405                    SignatureAlgorithm::PS512 => &signature::RSA_PSS_2048_8192_SHA512,
406                    _ => unreachable!("Should not happen"),
407                };
408
409                let public_key =
410                    signature::UnparsedPublicKey::new(verification_algorithm, keypair.public_key());
411                public_key.verify(data, expected_signature)?;
412                Ok(())
413            }
414            Secret::RSAModulusExponent { ref n, ref e } => {
415                let params = match algorithm {
416                    SignatureAlgorithm::RS256 => &signature::RSA_PKCS1_2048_8192_SHA256,
417                    SignatureAlgorithm::RS384 => &signature::RSA_PKCS1_2048_8192_SHA384,
418                    SignatureAlgorithm::RS512 => &signature::RSA_PKCS1_2048_8192_SHA512,
419                    SignatureAlgorithm::PS256 => &signature::RSA_PSS_2048_8192_SHA256,
420                    SignatureAlgorithm::PS384 => &signature::RSA_PSS_2048_8192_SHA384,
421                    SignatureAlgorithm::PS512 => &signature::RSA_PSS_2048_8192_SHA512,
422                    _ => unreachable!("(n,e) secret with a non-rsa algorithm should not happen"),
423                };
424
425                let n_big_endian = n.to_bytes_be();
426                let e_big_endian = e.to_bytes_be();
427                let public_key = signature::RsaPublicKeyComponents {
428                    n: n_big_endian,
429                    e: e_big_endian,
430                };
431                public_key.verify(params, data, expected_signature)?;
432                Ok(())
433            }
434            Secret::EcdsaKeyPair(ref keypair) => {
435                let verification_algorithm: &dyn signature::VerificationAlgorithm = match algorithm
436                {
437                    SignatureAlgorithm::ES256 => &signature::ECDSA_P256_SHA256_FIXED,
438                    SignatureAlgorithm::ES384 => &signature::ECDSA_P384_SHA384_FIXED,
439                    SignatureAlgorithm::ES512 => Err(Error::UnsupportedOperation)?,
440                    _ => unreachable!("Should not happen"),
441                };
442
443                let public_key =
444                    signature::UnparsedPublicKey::new(verification_algorithm, keypair.public_key());
445                public_key.verify(data, expected_signature)?;
446                Ok(())
447            }
448            _ => unreachable!("This is a private method and should not be called erroneously."),
449        }
450    }
451}
452
453impl KeyManagementAlgorithm {
454    /// Returns the type of operations that the algorithm is intended to support
455    pub fn algorithm_type(self) -> KeyManagementAlgorithmType {
456        use self::KeyManagementAlgorithm::*;
457
458        match self {
459            A128KW | A192KW | A256KW | A128GCMKW | A192GCMKW | A256GCMKW | PBES2_HS256_A128KW
460            | PBES2_HS384_A192KW | PBES2_HS512_A256KW => {
461                KeyManagementAlgorithmType::SymmetricKeyWrapping
462            }
463            RSA1_5 | RSA_OAEP | RSA_OAEP_256 => KeyManagementAlgorithmType::AsymmetricKeyEncryption,
464            DirectSymmetricKey => KeyManagementAlgorithmType::DirectEncryption,
465            ECDH_ES => KeyManagementAlgorithmType::DirectKeyAgreement,
466            ECDH_ES_A128KW | ECDH_ES_A192KW | ECDH_ES_A256KW => {
467                KeyManagementAlgorithmType::KeyAgreementWithKeyWrapping
468            }
469        }
470    }
471
472    /// Return the Content Encryption Key (CEK) based on the key management algorithm
473    ///
474    /// If the algorithm is `dir` or `DirectSymmetricKey`, the key provided is the CEK.
475    /// Otherwise, the appropriate algorithm will be used to derive or generate the required CEK
476    /// using the provided key.
477    pub fn cek<T>(
478        self,
479        content_alg: ContentEncryptionAlgorithm,
480        key: &jwk::JWK<T>,
481    ) -> Result<jwk::JWK<Empty>, Error>
482    where
483        T: Serialize + DeserializeOwned,
484    {
485        use self::KeyManagementAlgorithm::*;
486
487        match self {
488            DirectSymmetricKey => self.cek_direct(key),
489            A128GCMKW | A256GCMKW => self.cek_aes_gcm(content_alg),
490            _ => Err(Error::UnsupportedOperation),
491        }
492    }
493
494    fn cek_direct<T>(self, key: &jwk::JWK<T>) -> Result<jwk::JWK<Empty>, Error>
495    where
496        T: Serialize + DeserializeOwned,
497    {
498        match key.key_type() {
499            jwk::KeyType::Octet => Ok(key.clone_without_additional()),
500            others => Err(unexpected_key_type_error!(jwk::KeyType::Octet, others)),
501        }
502    }
503
504    fn cek_aes_gcm(
505        self,
506        content_alg: ContentEncryptionAlgorithm,
507    ) -> Result<jwk::JWK<Empty>, Error> {
508        let key = content_alg.generate_key()?;
509        Ok(jwk::JWK {
510            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
511                value: key,
512                key_type: Default::default(),
513            }),
514            common: jwk::CommonParameters {
515                public_key_use: Some(jwk::PublicKeyUse::Encryption),
516                algorithm: Some(Algorithm::ContentEncryption(content_alg)),
517                ..Default::default()
518            },
519            additional: Default::default(),
520        })
521    }
522
523    /// Encrypt or wrap a Content Encryption Key with the provided algorithm
524    pub fn wrap_key<T: Serialize + DeserializeOwned>(
525        self,
526        payload: &[u8],
527        key: &jwk::JWK<T>,
528        options: &EncryptionOptions,
529    ) -> Result<EncryptionResult, Error> {
530        use self::KeyManagementAlgorithm::*;
531
532        match self {
533            A128GCMKW | A192GCMKW | A256GCMKW => self.aes_gcm_encrypt(payload, key, options),
534            DirectSymmetricKey => match *options {
535                EncryptionOptions::None => Ok(Default::default()),
536                ref other => Err(unexpected_encryption_options_error!(
537                    EncryptionOptions::None,
538                    other
539                )),
540            },
541            _ => Err(Error::UnsupportedOperation),
542        }
543    }
544
545    /// Decrypt or unwrap a CEK with the provided algorithm
546    pub fn unwrap_key<T: Serialize + DeserializeOwned>(
547        self,
548        encrypted: &EncryptionResult,
549        content_alg: ContentEncryptionAlgorithm,
550        key: &jwk::JWK<T>,
551    ) -> Result<jwk::JWK<Empty>, Error> {
552        use self::KeyManagementAlgorithm::*;
553
554        match self {
555            A128GCMKW | A192GCMKW | A256GCMKW => self.aes_gcm_decrypt(encrypted, content_alg, key),
556            DirectSymmetricKey => Ok(key.clone_without_additional()),
557            _ => Err(Error::UnsupportedOperation),
558        }
559    }
560
561    fn aes_gcm_encrypt<T: Serialize + DeserializeOwned>(
562        self,
563        payload: &[u8],
564        key: &jwk::JWK<T>,
565        options: &EncryptionOptions,
566    ) -> Result<EncryptionResult, Error> {
567        use self::KeyManagementAlgorithm::*;
568
569        let algorithm = match self {
570            A128GCMKW => &aead::AES_128_GCM,
571            A256GCMKW => &aead::AES_256_GCM,
572            _ => Err(Error::UnsupportedOperation)?,
573        };
574
575        let nonce = match *options {
576            EncryptionOptions::AES_GCM { ref nonce } => Ok(nonce),
577            ref others => Err(unexpected_encryption_options_error!(
578                AES_GCM_ZEROED_NONCE,
579                others
580            )),
581        }?;
582        // FIXME: Should we check the nonce length here or leave it to ring?
583
584        aes_gcm_encrypt(algorithm, payload, nonce.as_slice(), &[], key)
585    }
586
587    fn aes_gcm_decrypt<T: Serialize + DeserializeOwned>(
588        self,
589        encrypted: &EncryptionResult,
590        content_alg: ContentEncryptionAlgorithm,
591        key: &jwk::JWK<T>,
592    ) -> Result<jwk::JWK<Empty>, Error> {
593        use self::KeyManagementAlgorithm::*;
594
595        let algorithm = match self {
596            A128GCMKW => &aead::AES_128_GCM,
597            A256GCMKW => &aead::AES_256_GCM,
598            _ => Err(Error::UnsupportedOperation)?,
599        };
600
601        let cek = aes_gcm_decrypt(algorithm, encrypted, key)?;
602        Ok(jwk::JWK {
603            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
604                value: cek,
605                key_type: Default::default(),
606            }),
607            common: jwk::CommonParameters {
608                public_key_use: Some(jwk::PublicKeyUse::Encryption),
609                algorithm: Some(Algorithm::ContentEncryption(content_alg)),
610                ..Default::default()
611            },
612            additional: Default::default(),
613        })
614    }
615}
616
617impl ContentEncryptionAlgorithm {
618    /// Convenience function to generate a new random key with the required length
619    pub fn generate_key(self) -> Result<Vec<u8>, Error> {
620        use self::ContentEncryptionAlgorithm::*;
621
622        let length: usize = match self {
623            A128GCM => 128 / 8,
624            A256GCM => 256 / 8,
625            _ => Err(Error::UnsupportedOperation)?,
626        };
627
628        let mut key: Vec<u8> = vec![0; length];
629        rng().fill(&mut key)?;
630        Ok(key)
631    }
632
633    /// Encrypt some payload with the provided algorithm
634    pub fn encrypt<T: Serialize + DeserializeOwned>(
635        self,
636        payload: &[u8],
637        aad: &[u8],
638        key: &jwk::JWK<T>,
639        options: &EncryptionOptions,
640    ) -> Result<EncryptionResult, Error> {
641        use self::ContentEncryptionAlgorithm::*;
642
643        match self {
644            A128GCM | A192GCM | A256GCM => self.aes_gcm_encrypt(payload, aad, key, options),
645            _ => Err(Error::UnsupportedOperation),
646        }
647    }
648
649    /// Decrypt some payload with the provided algorithm
650    pub fn decrypt<T: Serialize + DeserializeOwned>(
651        self,
652        encrypted: &EncryptionResult,
653        key: &jwk::JWK<T>,
654    ) -> Result<Vec<u8>, Error> {
655        use self::ContentEncryptionAlgorithm::*;
656
657        match self {
658            A128GCM | A192GCM | A256GCM => self.aes_gcm_decrypt(encrypted, key),
659            _ => Err(Error::UnsupportedOperation),
660        }
661    }
662
663    /// Generate a new random `EncryptionOptions` based on the algorithm
664    pub(crate) fn random_encryption_options(self) -> Result<EncryptionOptions, Error> {
665        use self::ContentEncryptionAlgorithm::*;
666        match self {
667            A128GCM | A192GCM | A256GCM => Ok(EncryptionOptions::AES_GCM {
668                nonce: random_aes_gcm_nonce()?,
669            }),
670            _ => Err(Error::UnsupportedOperation),
671        }
672    }
673
674    fn aes_gcm_encrypt<T: Serialize + DeserializeOwned>(
675        self,
676        payload: &[u8],
677        aad: &[u8],
678        key: &jwk::JWK<T>,
679        options: &EncryptionOptions,
680    ) -> Result<EncryptionResult, Error> {
681        use self::ContentEncryptionAlgorithm::*;
682
683        let algorithm = match self {
684            A128GCM => &aead::AES_128_GCM,
685            A256GCM => &aead::AES_256_GCM,
686            _ => Err(Error::UnsupportedOperation)?,
687        };
688
689        let nonce = match *options {
690            EncryptionOptions::AES_GCM { ref nonce } => Ok(nonce),
691            ref others => Err(unexpected_encryption_options_error!(
692                AES_GCM_ZEROED_NONCE,
693                others
694            )),
695        }?;
696        // FIXME: Should we check the nonce length here or leave it to ring?
697
698        aes_gcm_encrypt(algorithm, payload, nonce.as_slice(), aad, key)
699    }
700
701    fn aes_gcm_decrypt<T: Serialize + DeserializeOwned>(
702        self,
703        encrypted: &EncryptionResult,
704        key: &jwk::JWK<T>,
705    ) -> Result<Vec<u8>, Error> {
706        use self::ContentEncryptionAlgorithm::*;
707
708        let algorithm = match self {
709            A128GCM => &aead::AES_128_GCM,
710            A256GCM => &aead::AES_256_GCM,
711            _ => Err(Error::UnsupportedOperation)?,
712        };
713        aes_gcm_decrypt(algorithm, encrypted, key)
714    }
715}
716
717/// Return a pseudo random number generator
718pub(crate) fn rng() -> &'static SystemRandom {
719    use std::ops::Deref;
720
721    static RANDOM: Lazy<SystemRandom> = Lazy::new(SystemRandom::new);
722
723    RANDOM.deref()
724}
725
726/// Encrypt a payload with AES GCM
727fn aes_gcm_encrypt<T: Serialize + DeserializeOwned>(
728    algorithm: &'static aead::Algorithm,
729    payload: &[u8],
730    nonce: &[u8],
731    aad: &[u8],
732    key: &jwk::JWK<T>,
733) -> Result<EncryptionResult, Error> {
734    // JWA needs a 128 bit tag length. We need to assert that the algorithm has 128 bit tag length
735    assert_eq!(algorithm.tag_len(), AES_GCM_TAG_SIZE);
736    // Also the nonce (or initialization vector) needs to be 96 bits
737    assert_eq!(algorithm.nonce_len(), AES_GCM_NONCE_LENGTH);
738
739    let key = key.algorithm.octet_key()?;
740    let key = aead::UnboundKey::new(algorithm, key)?;
741    let sealing_key = aead::LessSafeKey::new(key);
742
743    let mut in_out: Vec<u8> = payload.to_vec();
744    let tag = sealing_key.seal_in_place_separate_tag(
745        aead::Nonce::try_assume_unique_for_key(nonce)?,
746        aead::Aad::from(aad),
747        &mut in_out,
748    )?;
749
750    Ok(EncryptionResult {
751        nonce: nonce.to_vec(),
752        encrypted: in_out,
753        tag: tag.as_ref().to_vec(),
754        additional_data: aad.to_vec(),
755    })
756}
757
758/// Decrypts a payload with AES GCM
759fn aes_gcm_decrypt<T: Serialize + DeserializeOwned>(
760    algorithm: &'static aead::Algorithm,
761    encrypted: &EncryptionResult,
762    key: &jwk::JWK<T>,
763) -> Result<Vec<u8>, Error> {
764    // JWA needs a 128 bit tag length. We need to assert that the algorithm has 128 bit tag length
765    assert_eq!(algorithm.tag_len(), AES_GCM_TAG_SIZE);
766    // Also the nonce (or initialization vector) needs to be 96 bits
767    assert_eq!(algorithm.nonce_len(), AES_GCM_NONCE_LENGTH);
768
769    let key = key.algorithm.octet_key()?;
770    let key = aead::UnboundKey::new(algorithm, key)?;
771    let opening_key = aead::LessSafeKey::new(key);
772
773    let mut in_out = encrypted.encrypted.to_vec();
774    in_out.append(&mut encrypted.tag.to_vec());
775
776    let plaintext = opening_key.open_in_place(
777        aead::Nonce::try_assume_unique_for_key(&encrypted.nonce)?,
778        aead::Aad::from(&encrypted.additional_data),
779        &mut in_out,
780    )?;
781    Ok(plaintext.to_vec())
782}
783
784pub(crate) fn random_aes_gcm_nonce() -> Result<Vec<u8>, Error> {
785    let mut nonce: Vec<u8> = vec![0; AES_GCM_NONCE_LENGTH];
786    rng().fill(&mut nonce)?;
787    Ok(nonce)
788}
789
790#[cfg(test)]
791mod tests {
792    use ring::constant_time::verify_slices_are_equal;
793
794    use super::*;
795    use crate::jwa;
796    use crate::CompactPart;
797
798    #[test]
799    fn sign_and_verify_none() {
800        let expected_signature: Vec<u8> = vec![];
801        let actual_signature = not_err!(
802            SignatureAlgorithm::None.sign("payload".to_string().as_bytes(), &Secret::None,)
803        );
804        assert_eq!(expected_signature, actual_signature);
805
806        not_err!(SignatureAlgorithm::None.verify(
807            vec![].as_slice(),
808            "payload".to_string().as_bytes(),
809            &Secret::None
810        ));
811    }
812
813    #[test]
814    fn sign_and_verify_hs256() {
815        let expected_base64 = "uC_LeRrOxXhZuYm0MKgmSIzi5Hn9-SMmvQoug3WkK6Q";
816        let expected_bytes: Vec<u8> = not_err!(CompactPart::from_base64(&expected_base64));
817
818        let actual_signature = not_err!(SignatureAlgorithm::HS256.sign(
819            "payload".to_string().as_bytes(),
820            &Secret::bytes_from_str("secret"),
821        ));
822        assert_eq!(&*not_err!(actual_signature.to_base64()), expected_base64);
823
824        not_err!(SignatureAlgorithm::HS256.verify(
825            expected_bytes.as_slice(),
826            "payload".to_string().as_bytes(),
827            &Secret::bytes_from_str("secret"),
828        ));
829    }
830
831    /// To generate the signature, use
832    ///
833    /// ```sh
834    /// echo -n "payload" | openssl dgst -sha256 -sign test/fixtures/rsa_private_key.pem | base64
835    /// ```
836    ///
837    /// The base64 encoding from this command will be in `STANDARD` form and not URL_SAFE.
838    #[test]
839    fn sign_and_verify_rs256() {
840        let private_key =
841            Secret::rsa_keypair_from_file("test/fixtures/rsa_private_key.der").unwrap();
842        let payload = "payload".to_string();
843        let payload_bytes = payload.as_bytes();
844        // This is standard base64
845        let expected_signature =
846            "JIHqiBfUknrFPDLT0gxyoufD06S43ZqWN_PzQqHZqQ-met7kZmkSTYB_rUyotLMxlKkuXdnvKmWm\
847             dwGAHWEwDvb5392pCmAAtmUIl6LormxJptWYb2PoF5jmtX_lwV8y4RYIh54Ai51162VARQCKAsxL\
848             uH772MEChkcpjd31NWzaePWoi_IIk11iqy6uFWmbLLwzD_Vbpl2C6aHR3vQjkXZi05gA3zksjYAh\
849             j-m7GgBt0UFOE56A4USjhQwpb4g3NEamgp51_kZ2ULi4Aoo_KJC6ynIm_pR6rEzBgwZjlCUnE-6o\
850             5RPQZ8Oau03UDVH2EwZe-Q91LaWRvkKjGg5Tcw";
851        let expected_signature_bytes: Vec<u8> =
852            not_err!(CompactPart::from_base64(&expected_signature));
853
854        let actual_signature =
855            not_err!(SignatureAlgorithm::RS256.sign(payload_bytes, &private_key));
856        assert_eq!(&*not_err!(actual_signature.to_base64()), expected_signature);
857
858        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
859        not_err!(SignatureAlgorithm::RS256.verify(
860            expected_signature_bytes.as_slice(),
861            payload_bytes,
862            &public_key,
863        ));
864    }
865
866    #[test]
867    fn sign_and_verify_rs256_key_params() {
868        use num_bigint::BigUint;
869        // There is no way in Ring right now to get these values from the key
870        let params = Secret::RSAModulusExponent {
871            n: BigUint::parse_bytes(
872                b"D57336432EDB91A0A98E3BC2959C08D79017CBDF7AEA6EDCDEC611DA746E1\
873                                      DBD144FB4391163E797FB392C438CC70AEA89796D8FCFF69646655AD02E00\
874                                      169B5F1C4C9150D3399D80DCE6D8F6F057B105F5FC5EE774B0A8FF20A67D8\
875                                      0E6707D380462D2CDCB913E6EE9EA7585CD504AE45B6930BC713D02999E36\
876                                      BF449CFFA2385374F3850819056207880A2E8BA47EE8A86CBE4C361D6D54B\
877                                      95F2E1668262F79C2774D4234B8D5C6D15A0E95493E308AA98F002A78BB92\
878                                      8CB78F1E7E06243AB6D7EAFAB59F6446774B0479F6593F88F763978F14EFB\
879                                      7F422B4C66E8EB53FF5E6DC4D3C92952D8413E06E2D9EB1DF50D8224FF3BD\
880                                      319FF5E4258D06C578B9527B",
881                16,
882            )
883            .unwrap(),
884            e: BigUint::from(65537u32),
885        };
886        let payload = "payload".to_string();
887        let payload_bytes = payload.as_bytes();
888        let expected_signature =
889            "JIHqiBfUknrFPDLT0gxyoufD06S43ZqWN_PzQqHZqQ-met7kZmkSTYB_rUyotLMxlKkuXdnvKmWm\
890             dwGAHWEwDvb5392pCmAAtmUIl6LormxJptWYb2PoF5jmtX_lwV8y4RYIh54Ai51162VARQCKAsxL\
891             uH772MEChkcpjd31NWzaePWoi_IIk11iqy6uFWmbLLwzD_Vbpl2C6aHR3vQjkXZi05gA3zksjYAh\
892             j-m7GgBt0UFOE56A4USjhQwpb4g3NEamgp51_kZ2ULi4Aoo_KJC6ynIm_pR6rEzBgwZjlCUnE-6o\
893             5RPQZ8Oau03UDVH2EwZe-Q91LaWRvkKjGg5Tcw";
894        let expected_signature_bytes: Vec<u8> =
895            not_err!(CompactPart::from_base64(&expected_signature));
896        not_err!(SignatureAlgorithm::RS256.verify(
897            expected_signature_bytes.as_slice(),
898            payload_bytes,
899            &params,
900        ));
901    }
902
903    /// This signature is non-deterministic.
904    #[test]
905    fn sign_and_verify_ps256_round_trip() {
906        let private_key =
907            Secret::rsa_keypair_from_file("test/fixtures/rsa_private_key.der").unwrap();
908        let payload = "payload".to_string();
909        let payload_bytes = payload.as_bytes();
910
911        let actual_signature =
912            not_err!(SignatureAlgorithm::PS256.sign(payload_bytes, &private_key));
913
914        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
915        not_err!(SignatureAlgorithm::PS256.verify(
916            actual_signature.as_slice(),
917            payload_bytes,
918            &public_key,
919        ));
920    }
921
922    /// This signature is non-deterministic.
923    #[test]
924    fn sign_and_verify_ps256_round_trip_with_keypair() {
925        let key = Secret::rsa_keypair_from_file("test/fixtures/rsa_private_key.der").unwrap();
926        let payload = "payload".to_string();
927        let payload_bytes = payload.as_bytes();
928
929        let actual_signature = not_err!(SignatureAlgorithm::PS256.sign(payload_bytes, &key));
930
931        not_err!(SignatureAlgorithm::PS256.verify(
932            actual_signature.as_slice(),
933            payload_bytes,
934            &key,
935        ));
936    }
937
938    /// To generate a (non-deterministic) signature:
939    ///
940    /// ```sh
941    /// echo -n "payload" | openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \
942    ///    -sign test/fixtures/rsa_private_key.pem | base64
943    /// ```
944    ///
945    /// The base64 encoding from this command will be in `STANDARD` form and not URL_SAFE.
946    #[test]
947    fn verify_ps256() {
948        use data_encoding::BASE64;
949
950        let payload = "payload".to_string();
951        let payload_bytes = payload.as_bytes();
952        let signature =
953            "TiMXtt3Wmv/a/tbLWuJPDlFYMfuKsD7U5lbBUn2mBu8DLMLj1EplEZNmkB8w65BgUijnu9hxmhwv\
954             ET2k7RrsYamEst6BHZf20hIK1yE/YWaktbVmAZwUDdIpXYaZn8ukTsMT06CDrVk6RXF0EPMaSL33\
955             tFNPZpz4/3pYQdxco/n6DpaR5206wsur/8H0FwoyiFKanhqLb1SgZqyc+SXRPepjKc28wzBnfWl4\
956             mmlZcJ2xk8O2/t1Y1/m/4G7drBwOItNl7EadbMVCetYnc9EILv39hjcL9JvaA9q0M2RB75DIu8SF\
957             9Kr/l+wzUJjWAHthgqSBpe15jLkpO8tvqR89fw==";
958        let signature_bytes: Vec<u8> = not_err!(BASE64.decode(signature.as_bytes()));
959        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
960        not_err!(SignatureAlgorithm::PS256.verify(
961            signature_bytes.as_slice(),
962            payload_bytes,
963            &public_key,
964        ));
965    }
966
967    /// This signature is non-deterministic.
968    #[test]
969    fn sign_and_verify_es256_round_trip() {
970        let private_key = Secret::ecdsa_keypair_from_file(
971            SignatureAlgorithm::ES256,
972            "test/fixtures/ecdsa_private_key.p8",
973        )
974        .unwrap();
975        let payload = "payload".to_string();
976        let payload_bytes = payload.as_bytes();
977
978        let actual_signature =
979            not_err!(SignatureAlgorithm::ES256.sign(payload_bytes, &private_key));
980
981        let public_key =
982            Secret::public_key_from_file("test/fixtures/ecdsa_public_key.der").unwrap();
983        not_err!(SignatureAlgorithm::ES256.verify(
984            actual_signature.as_slice(),
985            payload_bytes,
986            &public_key,
987        ));
988    }
989
990    /// This signature is non-deterministic.
991    #[test]
992    fn sign_and_verify_es256_round_trip_with_keypair() {
993        let key = Secret::ecdsa_keypair_from_file(
994            SignatureAlgorithm::ES256,
995            "test/fixtures/ecdsa_private_key.p8",
996        )
997        .unwrap();
998        let payload = "payload".to_string();
999        let payload_bytes = payload.as_bytes();
1000
1001        let actual_signature = not_err!(SignatureAlgorithm::ES256.sign(payload_bytes, &key));
1002
1003        not_err!(SignatureAlgorithm::ES256.verify(
1004            actual_signature.as_slice(),
1005            payload_bytes,
1006            &key,
1007        ));
1008    }
1009
1010    /// Test case from https://github.com/briansmith/ring/blob/a13b8e2/src/ec/suite_b/ecdsa_verify_fixed_tests.txt
1011    #[test]
1012    fn verify_es256() {
1013        use data_encoding::HEXUPPER;
1014
1015        let payload_bytes = Vec::<u8>::new();
1016        let public_key = "0430345FD47EA21A11129BE651B0884BFAC698377611ACC9F689458E13B9ED7D4B9D7599\
1017                          A68DCF125E7F31055CCB374CD04F6D6FD2B217438A63F6F667D50EF2F0";
1018        let public_key = Secret::PublicKey(not_err!(HEXUPPER.decode(public_key.as_bytes())));
1019        let signature = "341F6779B75E98BB42E01095DD48356CBF9002DC704AC8BD2A8240B88D3796C6555843B1B\
1020                         4E264FE6FFE6E2B705A376C05C09404303FFE5D2711F3E3B3A010A1";
1021        let signature_bytes: Vec<u8> = not_err!(HEXUPPER.decode(signature.as_bytes()));
1022        not_err!(SignatureAlgorithm::ES256.verify(
1023            signature_bytes.as_slice(),
1024            &payload_bytes,
1025            &public_key,
1026        ));
1027    }
1028
1029    /// Test case from https://github.com/briansmith/ring/blob/a13b8e2/src/ec/suite_b/ecdsa_verify_fixed_tests.txt
1030    #[test]
1031    fn verify_es384() {
1032        use data_encoding::HEXUPPER;
1033
1034        let payload_bytes = Vec::<u8>::new();
1035        let public_key = "045C5E788A805C77D34128B8401CB59B2373B8B468336C9318252BF39FD31D2507557987\
1036                          A5180A9435F9FB8EB971C426F1C485170DCB18FB688A257F89387A09FC4C5B8BD4B320616\
1037                          B54A0A7B1D1D7C6A0C59F6DFF78C78AD4E3D6FCA9C9A17B96";
1038        let public_key = Secret::PublicKey(not_err!(HEXUPPER.decode(public_key.as_bytes())));
1039        let signature = "85AC708D4B0126BAC1F5EEEBDF911409070A286FDDE5649582611B60046DE353761660DD0\
1040                         3903F58B44148F25142EEF8183475EC1F1392F3D6838ABC0C01724709C446888BED7F2CE4\
1041                         642C6839DC18044A2A6AB9DDC960BFAC79F6988E62D452";
1042        let signature_bytes: Vec<u8> = not_err!(HEXUPPER.decode(signature.as_bytes()));
1043        not_err!(SignatureAlgorithm::ES384.verify(
1044            signature_bytes.as_slice(),
1045            &payload_bytes,
1046            &public_key,
1047        ));
1048    }
1049
1050    #[test]
1051    #[should_panic(expected = "UnsupportedOperation")]
1052    fn verify_es512() {
1053        let payload: Vec<u8> = vec![];
1054        let signature: Vec<u8> = vec![];
1055        let public_key = Secret::PublicKey(vec![]);
1056        SignatureAlgorithm::ES512
1057            .verify(signature.as_slice(), payload.as_slice(), &public_key)
1058            .unwrap();
1059    }
1060
1061    #[test]
1062    #[should_panic(expected = "UnspecifiedCryptographicError")]
1063    fn invalid_none() {
1064        let invalid_signature = "broken".to_string();
1065        let signature_bytes = invalid_signature.as_bytes();
1066        SignatureAlgorithm::None
1067            .verify(
1068                signature_bytes,
1069                "payload".to_string().as_bytes(),
1070                &Secret::None,
1071            )
1072            .unwrap();
1073    }
1074
1075    #[test]
1076    #[should_panic(expected = "UnspecifiedCryptographicError")]
1077    fn invalid_hs256() {
1078        let invalid_signature = "broken".to_string();
1079        let signature_bytes = invalid_signature.as_bytes();
1080        SignatureAlgorithm::HS256
1081            .verify(
1082                signature_bytes,
1083                "payload".to_string().as_bytes(),
1084                &Secret::Bytes("secret".to_string().into_bytes()),
1085            )
1086            .unwrap();
1087    }
1088
1089    #[test]
1090    #[should_panic(expected = "UnspecifiedCryptographicError")]
1091    fn invalid_rs256() {
1092        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
1093        let invalid_signature = "broken".to_string();
1094        let signature_bytes = invalid_signature.as_bytes();
1095        SignatureAlgorithm::RS256
1096            .verify(
1097                signature_bytes,
1098                "payload".to_string().as_bytes(),
1099                &public_key,
1100            )
1101            .unwrap();
1102    }
1103
1104    #[test]
1105    #[should_panic(expected = "UnspecifiedCryptographicError")]
1106    fn invalid_ps256() {
1107        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
1108        let invalid_signature = "broken".to_string();
1109        let signature_bytes = invalid_signature.as_bytes();
1110        SignatureAlgorithm::PS256
1111            .verify(
1112                signature_bytes,
1113                "payload".to_string().as_bytes(),
1114                &public_key,
1115            )
1116            .unwrap();
1117    }
1118
1119    #[test]
1120    #[should_panic(expected = "UnspecifiedCryptographicError")]
1121    fn invalid_es256() {
1122        let public_key = Secret::public_key_from_file("test/fixtures/rsa_public_key.der").unwrap();
1123        let invalid_signature = "broken".to_string();
1124        let signature_bytes = invalid_signature.as_bytes();
1125        SignatureAlgorithm::ES256
1126            .verify(
1127                signature_bytes,
1128                "payload".to_string().as_bytes(),
1129                &public_key,
1130            )
1131            .unwrap();
1132    }
1133
1134    #[test]
1135    fn rng_is_created() {
1136        let rng = rng();
1137        let mut random: Vec<u8> = vec![0; 8];
1138        rng.fill(&mut random).unwrap();
1139    }
1140
1141    #[test]
1142    fn aes_gcm_128_encryption_round_trip_fixed_key_nonce() {
1143        const PAYLOAD: &str = "这个世界值得我们奋战!";
1144        let key: Vec<u8> = vec![0; 128 / 8];
1145
1146        let key = jwk::JWK::<Empty> {
1147            common: Default::default(),
1148            additional: Default::default(),
1149            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1150                key_type: Default::default(),
1151                value: key,
1152            }),
1153        };
1154
1155        let encrypted = not_err!(aes_gcm_encrypt(
1156            &aead::AES_128_GCM,
1157            PAYLOAD.as_bytes(),
1158            &[0; AES_GCM_NONCE_LENGTH],
1159            &[],
1160            &key,
1161        ));
1162        let decrypted = not_err!(aes_gcm_decrypt(&aead::AES_128_GCM, &encrypted, &key));
1163
1164        let payload = not_err!(String::from_utf8(decrypted));
1165        assert_eq!(payload, PAYLOAD);
1166    }
1167
1168    #[test]
1169    fn aes_gcm_128_encryption_round_trip() {
1170        const PAYLOAD: &str = "这个世界值得我们奋战!";
1171        let mut key: Vec<u8> = vec![0; 128 / 8];
1172        not_err!(rng().fill(&mut key));
1173
1174        let key = jwk::JWK::<Empty> {
1175            common: Default::default(),
1176            additional: Default::default(),
1177            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1178                key_type: Default::default(),
1179                value: key,
1180            }),
1181        };
1182
1183        let encrypted = not_err!(aes_gcm_encrypt(
1184            &aead::AES_128_GCM,
1185            PAYLOAD.as_bytes(),
1186            &random_aes_gcm_nonce().unwrap(),
1187            &[],
1188            &key,
1189        ));
1190        let decrypted = not_err!(aes_gcm_decrypt(&aead::AES_128_GCM, &encrypted, &key));
1191
1192        let payload = not_err!(String::from_utf8(decrypted));
1193        assert_eq!(payload, PAYLOAD);
1194    }
1195
1196    #[test]
1197    fn aes_gcm_256_encryption_round_trip() {
1198        const PAYLOAD: &str = "这个世界值得我们奋战!";
1199        let mut key: Vec<u8> = vec![0; 256 / 8];
1200        not_err!(rng().fill(&mut key));
1201
1202        let key = jwk::JWK::<Empty> {
1203            common: Default::default(),
1204            additional: Default::default(),
1205            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1206                key_type: Default::default(),
1207                value: key,
1208            }),
1209        };
1210
1211        let encrypted = not_err!(aes_gcm_encrypt(
1212            &aead::AES_256_GCM,
1213            PAYLOAD.as_bytes(),
1214            &random_aes_gcm_nonce().unwrap(),
1215            &[],
1216            &key,
1217        ));
1218        let decrypted = not_err!(aes_gcm_decrypt(&aead::AES_256_GCM, &encrypted, &key));
1219
1220        let payload = not_err!(String::from_utf8(decrypted));
1221        assert_eq!(payload, PAYLOAD);
1222    }
1223
1224    #[test]
1225    fn aes_gcm_256_encryption_round_trip_fixed_key_nonce() {
1226        const PAYLOAD: &str = "这个世界值得我们奋战!";
1227        let key: Vec<u8> = vec![0; 256 / 8];
1228
1229        let key = jwk::JWK::<Empty> {
1230            common: Default::default(),
1231            additional: Default::default(),
1232            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1233                key_type: Default::default(),
1234                value: key,
1235            }),
1236        };
1237
1238        let encrypted = not_err!(aes_gcm_encrypt(
1239            &aead::AES_256_GCM,
1240            PAYLOAD.as_bytes(),
1241            &[0; AES_GCM_NONCE_LENGTH],
1242            &[],
1243            &key,
1244        ));
1245        let decrypted = not_err!(aes_gcm_decrypt(&aead::AES_256_GCM, &encrypted, &key));
1246
1247        let payload = not_err!(String::from_utf8(decrypted));
1248        assert_eq!(payload, PAYLOAD);
1249    }
1250
1251    /// `KeyManagementAlgorithm::DirectSymmetricKey` returns the same key when CEK is requested
1252    #[test]
1253    fn dir_cek_returns_provided_key() {
1254        let mut key: Vec<u8> = vec![0; 256 / 8];
1255        not_err!(rng().fill(&mut key));
1256
1257        let key = jwk::JWK::<Empty> {
1258            common: Default::default(),
1259            additional: Default::default(),
1260            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1261                key_type: Default::default(),
1262                value: key,
1263            }),
1264        };
1265
1266        let cek_alg = KeyManagementAlgorithm::DirectSymmetricKey;
1267        let cek = not_err!(cek_alg.cek(jwa::ContentEncryptionAlgorithm::A256GCM, &key));
1268
1269        assert!(
1270            verify_slices_are_equal(cek.octet_key().unwrap(), key.octet_key().unwrap()).is_ok()
1271        );
1272    }
1273
1274    /// `KeyManagementAlgorithm::A128GCMKW` returns a random key with the right length when CEK is requested
1275    #[test]
1276    fn cek_aes128gcmkw_returns_right_key_length() {
1277        let mut key: Vec<u8> = vec![0; 128 / 8];
1278        not_err!(rng().fill(&mut key));
1279
1280        let key = jwk::JWK::<Empty> {
1281            common: Default::default(),
1282            additional: Default::default(),
1283            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1284                key_type: Default::default(),
1285                value: key,
1286            }),
1287        };
1288
1289        let cek_alg = KeyManagementAlgorithm::A128GCMKW;
1290        let cek = not_err!(cek_alg.cek(jwa::ContentEncryptionAlgorithm::A128GCM, &key));
1291        assert_eq!(cek.octet_key().unwrap().len(), 128 / 8);
1292        assert!(
1293            verify_slices_are_equal(cek.octet_key().unwrap(), key.octet_key().unwrap()).is_err()
1294        );
1295
1296        let cek = not_err!(cek_alg.cek(jwa::ContentEncryptionAlgorithm::A256GCM, &key));
1297        assert_eq!(cek.octet_key().unwrap().len(), 256 / 8);
1298        assert!(
1299            verify_slices_are_equal(cek.octet_key().unwrap(), key.octet_key().unwrap()).is_err()
1300        );
1301    }
1302
1303    /// `KeyManagementAlgorithm::A256GCMKW` returns a random key with the right length when CEK is requested
1304    #[test]
1305    fn cek_aes256gcmkw_returns_right_key_length() {
1306        let mut key: Vec<u8> = vec![0; 256 / 8];
1307        not_err!(rng().fill(&mut key));
1308
1309        let key = jwk::JWK::<Empty> {
1310            common: Default::default(),
1311            additional: Default::default(),
1312            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1313                key_type: Default::default(),
1314                value: key,
1315            }),
1316        };
1317
1318        let cek_alg = KeyManagementAlgorithm::A256GCMKW;
1319        let cek = not_err!(cek_alg.cek(jwa::ContentEncryptionAlgorithm::A128GCM, &key));
1320        assert_eq!(cek.octet_key().unwrap().len(), 128 / 8);
1321        assert!(
1322            verify_slices_are_equal(cek.octet_key().unwrap(), key.octet_key().unwrap()).is_err()
1323        );
1324
1325        let cek = not_err!(cek_alg.cek(jwa::ContentEncryptionAlgorithm::A256GCM, &key));
1326        assert_eq!(cek.octet_key().unwrap().len(), 256 / 8);
1327        assert!(
1328            verify_slices_are_equal(cek.octet_key().unwrap(), key.octet_key().unwrap()).is_err()
1329        );
1330    }
1331
1332    #[test]
1333    fn aes128gcmkw_key_encryption_round_trip() {
1334        let mut key: Vec<u8> = vec![0; 128 / 8];
1335        not_err!(rng().fill(&mut key));
1336
1337        let key = jwk::JWK::<Empty> {
1338            common: Default::default(),
1339            additional: Default::default(),
1340            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1341                key_type: Default::default(),
1342                value: key,
1343            }),
1344        };
1345
1346        let options = EncryptionOptions::AES_GCM {
1347            nonce: random_aes_gcm_nonce().unwrap(),
1348        };
1349
1350        let cek_alg = KeyManagementAlgorithm::A128GCMKW;
1351        let enc_alg = jwa::ContentEncryptionAlgorithm::A128GCM; // determines the CEK
1352        let cek = not_err!(cek_alg.cek(enc_alg, &key));
1353
1354        let encrypted_cek = not_err!(cek_alg.wrap_key(cek.octet_key().unwrap(), &key, &options));
1355        let decrypted_cek = not_err!(cek_alg.unwrap_key(&encrypted_cek, enc_alg, &key));
1356
1357        assert!(verify_slices_are_equal(
1358            cek.octet_key().unwrap(),
1359            decrypted_cek.octet_key().unwrap(),
1360        )
1361        .is_ok());
1362    }
1363
1364    #[test]
1365    fn aes256gcmkw_key_encryption_round_trip() {
1366        let mut key: Vec<u8> = vec![0; 256 / 8];
1367        not_err!(rng().fill(&mut key));
1368
1369        let key = jwk::JWK::<Empty> {
1370            common: Default::default(),
1371            additional: Default::default(),
1372            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1373                key_type: Default::default(),
1374                value: key,
1375            }),
1376        };
1377
1378        let options = EncryptionOptions::AES_GCM {
1379            nonce: random_aes_gcm_nonce().unwrap(),
1380        };
1381
1382        let cek_alg = KeyManagementAlgorithm::A256GCMKW;
1383        let enc_alg = jwa::ContentEncryptionAlgorithm::A128GCM; // determines the CEK
1384        let cek = not_err!(cek_alg.cek(enc_alg, &key));
1385
1386        let encrypted_cek = not_err!(cek_alg.wrap_key(cek.octet_key().unwrap(), &key, &options));
1387        let decrypted_cek = not_err!(cek_alg.unwrap_key(&encrypted_cek, enc_alg, &key));
1388
1389        assert!(verify_slices_are_equal(
1390            cek.octet_key().unwrap(),
1391            decrypted_cek.octet_key().unwrap(),
1392        )
1393        .is_ok());
1394    }
1395
1396    /// `ContentEncryptionAlgorithm::A128GCM` generates CEK of the right length
1397    #[test]
1398    fn aes128gcm_key_length() {
1399        let enc_alg = jwa::ContentEncryptionAlgorithm::A128GCM;
1400        let cek = not_err!(enc_alg.generate_key());
1401        assert_eq!(cek.len(), 128 / 8);
1402    }
1403
1404    /// `ContentEncryptionAlgorithm::A256GCM` generates CEK of the right length
1405    #[test]
1406    fn aes256gcm_key_length() {
1407        let enc_alg = jwa::ContentEncryptionAlgorithm::A256GCM;
1408        let cek = not_err!(enc_alg.generate_key());
1409        assert_eq!(cek.len(), 256 / 8);
1410    }
1411
1412    #[test]
1413    fn aes128gcm_encryption_round_trip() {
1414        let mut key: Vec<u8> = vec![0; 128 / 8];
1415        not_err!(rng().fill(&mut key));
1416
1417        let key = jwk::JWK::<Empty> {
1418            common: Default::default(),
1419            additional: Default::default(),
1420            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1421                key_type: Default::default(),
1422                value: key,
1423            }),
1424        };
1425
1426        let options = EncryptionOptions::AES_GCM {
1427            nonce: random_aes_gcm_nonce().unwrap(),
1428        };
1429
1430        let payload = "狼よ、我が敵を食らえ!";
1431        let aad = "My servants never die!";
1432        let enc_alg = jwa::ContentEncryptionAlgorithm::A128GCM;
1433        let encrypted_payload =
1434            not_err!(enc_alg.encrypt(payload.as_bytes(), aad.as_bytes(), &key, &options,));
1435
1436        let decrypted_payload = not_err!(enc_alg.decrypt(&encrypted_payload, &key));
1437        assert!(verify_slices_are_equal(payload.as_bytes(), &decrypted_payload).is_ok());
1438    }
1439
1440    #[test]
1441    fn aes1256gcm_encryption_round_trip() {
1442        let mut key: Vec<u8> = vec![0; 256 / 8];
1443        not_err!(rng().fill(&mut key));
1444
1445        let key = jwk::JWK::<Empty> {
1446            common: Default::default(),
1447            additional: Default::default(),
1448            algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
1449                key_type: Default::default(),
1450                value: key,
1451            }),
1452        };
1453
1454        let options = EncryptionOptions::AES_GCM {
1455            nonce: random_aes_gcm_nonce().unwrap(),
1456        };
1457
1458        let payload = "狼よ、我が敵を食らえ!";
1459        let aad = "My servants never die!";
1460        let enc_alg = jwa::ContentEncryptionAlgorithm::A256GCM;
1461        let encrypted_payload =
1462            not_err!(enc_alg.encrypt(payload.as_bytes(), aad.as_bytes(), &key, &options,));
1463
1464        let decrypted_payload = not_err!(enc_alg.decrypt(&encrypted_payload, &key));
1465        assert!(verify_slices_are_equal(payload.as_bytes(), &decrypted_payload).is_ok());
1466    }
1467}