1 use secure::ring::hkdf::expand; 2 use secure::ring::digest::{SHA256, Algorithm}; 3 use secure::ring::hmac::SigningKey; 4 use secure::ring::rand::{SecureRandom, SystemRandom}; 5 6 use secure::private::KEY_LEN as PRIVATE_KEY_LEN; 7 use secure::signed::KEY_LEN as SIGNED_KEY_LEN; 8 9 static HKDF_DIGEST: &'static Algorithm = &SHA256; 10 const KEYS_INFO: &'static str = "COOKIE;SIGNED:HMAC-SHA256;PRIVATE:AEAD-AES-256-GCM"; 11 12 /// A cryptographic master key for use with `Signed` and/or `Private` jars. 13 /// 14 /// This structure encapsulates secure, cryptographic keys for use with both 15 /// [PrivateJar](struct.PrivateJar.html) and [SignedJar](struct.SignedJar.html). 16 /// It can be derived from a single master key via 17 /// [from_master](#method.from_master) or generated from a secure random source 18 /// via [generate](#method.generate). A single instance of `Key` can be used for 19 /// both a `PrivateJar` and a `SignedJar`. 20 /// 21 /// This type is only available when the `secure` feature is enabled. 22 #[derive(Clone)] 23 pub struct Key { 24 signing_key: [u8; SIGNED_KEY_LEN], 25 encryption_key: [u8; PRIVATE_KEY_LEN] 26 } 27 28 impl Key { 29 /// Derives new signing/encryption keys from a master key. 30 /// 31 /// The master key must be at least 256-bits (32 bytes). For security, the 32 /// master key _must_ be cryptographically random. The keys are derived 33 /// deterministically from the master key. 34 /// 35 /// # Panics 36 /// 37 /// Panics if `key` is less than 32 bytes in length. 38 /// 39 /// # Example 40 /// 41 /// ```rust 42 /// use cookie::Key; 43 /// 44 /// # /* 45 /// let master_key = { /* a cryptographically random key >= 32 bytes */ }; 46 /// # */ 47 /// # let master_key: &Vec<u8> = &(0..32).collect(); 48 /// 49 /// let key = Key::from_master(master_key); 50 /// ``` from_master(key: &[u8]) -> Key51 pub fn from_master(key: &[u8]) -> Key { 52 if key.len() < 32 { 53 panic!("bad master key length: expected at least 32 bytes, found {}", key.len()); 54 } 55 56 // Expand the user's key into two. 57 let prk = SigningKey::new(HKDF_DIGEST, key); 58 let mut both_keys = [0; SIGNED_KEY_LEN + PRIVATE_KEY_LEN]; 59 expand(&prk, KEYS_INFO.as_bytes(), &mut both_keys); 60 61 // Copy the keys into their respective arrays. 62 let mut signing_key = [0; SIGNED_KEY_LEN]; 63 let mut encryption_key = [0; PRIVATE_KEY_LEN]; 64 signing_key.copy_from_slice(&both_keys[..SIGNED_KEY_LEN]); 65 encryption_key.copy_from_slice(&both_keys[SIGNED_KEY_LEN..]); 66 67 Key { 68 signing_key: signing_key, 69 encryption_key: encryption_key 70 } 71 } 72 73 /// Generates signing/encryption keys from a secure, random source. Keys are 74 /// generated nondeterministically. 75 /// 76 /// # Panics 77 /// 78 /// Panics if randomness cannot be retrieved from the operating system. See 79 /// [try_generate](#method.try_generate) for a non-panicking version. 80 /// 81 /// # Example 82 /// 83 /// ```rust 84 /// use cookie::Key; 85 /// 86 /// let key = Key::generate(); 87 /// ``` generate() -> Key88 pub fn generate() -> Key { 89 Self::try_generate().expect("failed to generate `Key` from randomness") 90 } 91 92 /// Attempts to generate signing/encryption keys from a secure, random 93 /// source. Keys are generated nondeterministically. If randomness cannot be 94 /// retrieved from the underlying operating system, returns `None`. 95 /// 96 /// # Example 97 /// 98 /// ```rust 99 /// use cookie::Key; 100 /// 101 /// let key = Key::try_generate(); 102 /// ``` try_generate() -> Option<Key>103 pub fn try_generate() -> Option<Key> { 104 let mut sign_key = [0; SIGNED_KEY_LEN]; 105 let mut enc_key = [0; PRIVATE_KEY_LEN]; 106 107 let rng = SystemRandom::new(); 108 if rng.fill(&mut sign_key).is_err() || rng.fill(&mut enc_key).is_err() { 109 return None 110 } 111 112 Some(Key { signing_key: sign_key, encryption_key: enc_key }) 113 } 114 115 /// Returns the raw bytes of a key suitable for signing cookies. 116 /// 117 /// # Example 118 /// 119 /// ```rust 120 /// use cookie::Key; 121 /// 122 /// let key = Key::generate(); 123 /// let signing_key = key.signing(); 124 /// ``` signing(&self) -> &[u8]125 pub fn signing(&self) -> &[u8] { 126 &self.signing_key[..] 127 } 128 129 /// Returns the raw bytes of a key suitable for encrypting cookies. 130 /// 131 /// # Example 132 /// 133 /// ```rust 134 /// use cookie::Key; 135 /// 136 /// let key = Key::generate(); 137 /// let encryption_key = key.encryption(); 138 /// ``` encryption(&self) -> &[u8]139 pub fn encryption(&self) -> &[u8] { 140 &self.encryption_key[..] 141 } 142 } 143 144 #[cfg(test)] 145 mod test { 146 use super::Key; 147 148 #[test] deterministic_from_master()149 fn deterministic_from_master() { 150 let master_key: Vec<u8> = (0..32).collect(); 151 152 let key_a = Key::from_master(&master_key); 153 let key_b = Key::from_master(&master_key); 154 155 assert_eq!(key_a.signing(), key_b.signing()); 156 assert_eq!(key_a.encryption(), key_b.encryption()); 157 assert_ne!(key_a.encryption(), key_a.signing()); 158 159 let master_key_2: Vec<u8> = (32..64).collect(); 160 let key_2 = Key::from_master(&master_key_2); 161 162 assert_ne!(key_2.signing(), key_a.signing()); 163 assert_ne!(key_2.encryption(), key_a.encryption()); 164 } 165 166 #[test] non_deterministic_generate()167 fn non_deterministic_generate() { 168 let key_a = Key::generate(); 169 let key_b = Key::generate(); 170 171 assert_ne!(key_a.signing(), key_b.signing()); 172 assert_ne!(key_a.encryption(), key_b.encryption()); 173 } 174 } 175