| 
					
				 | 
			
			
				@@ -6,11 +6,16 @@ use std::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         raw::c_char, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         unix::fs::PermissionsExt, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ffi::CStr, path::{Path}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ffi::CStr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    path::Path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fs::{File, OpenOptions}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sync::{Arc, Mutex}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use openssl::{bn::BigNum, hash::Hasher, nid::Nid}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use openssl::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bn::BigNum, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    hash::Hasher, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nid::Nid, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use tss_esapi_sys::{TSS2_RC, TPMT_TK_HASHCHECK }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use tss_esapi::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Context, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -38,6 +43,8 @@ use tss_esapi::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         HashcheckTicket, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Ticket, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SignatureScheme, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RsaDecryptionScheme, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Data, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     attributes::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         object::ObjectAttributes, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -45,7 +52,7 @@ use tss_esapi::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     handles::KeyHandle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const COOKIE_LEN: usize = RSA_SIG_LEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const COOKIE_LEN: usize = RSA_KEY_BYTES; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct Cookie([u8; COOKIE_LEN]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -108,6 +115,11 @@ pub(crate) struct TpmCredStore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl TpmCredStore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// The public exponent to use for generated RSA keys. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const RSA_EXPONENT: u32 = 65537; // 2**16 + 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const RSA_KEY_BITS: RsaKeyBits = RsaKeyBits::Rsa3072; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub(crate) fn new<P: AsRef<Path>>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         mut context: Context, cookie_path: P 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ) -> Result<TpmCredStore> { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -128,7 +140,6 @@ impl TpmCredStore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn gen_node_creds(&self) -> Result<TpmCreds> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const RSA_EXPONENT: u32 = 65537; // 2**16 + 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let template = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let object_attributes = ObjectAttributes::builder() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 .with_fixed_tpm(true) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -146,8 +157,8 @@ impl TpmCredStore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let parameters = PublicRsaParameters::new( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 SymmetricDefinitionObject::Null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 RsaScheme::Null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                RsaKeyBits::Rsa3072, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                RsaExponent::try_from(RSA_EXPONENT).map_err(Error::from)?,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                TpmCredStore::RSA_KEY_BITS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                RsaExponent::try_from(TpmCredStore::RSA_EXPONENT).map_err(Error::from)?,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let unique = PublicKeyRsa::try_from(self.cookie.as_slice()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 .map_err(|e| Error::Message(e.to_string()))?; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -307,7 +318,7 @@ impl Signer for TpmCreds { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let buf = match sig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             tss_esapi::structures::Signature::RsaSsa(inner) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let mut buf = [0u8; RSA_SIG_LEN]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let mut buf = [0u8; RSA_KEY_BYTES]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let slice: &[u8] = inner.signature(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 buf.as_mut_slice().write_all(slice).map_err(Error::from)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 buf 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -320,8 +331,16 @@ impl Signer for TpmCreds { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl Decrypter for TpmCreds { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fn decrypt(&self, _slice: &[u8]) -> Result<Vec<u8>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      unimplemented!()   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let cipher_text = PublicKeyRsa::try_from(slice).map_err(|e| Error::Message(e.to_string()))?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let in_scheme = RsaDecryptionScheme::RsaEs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let empty = [0u8; 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let label = Data::try_from(empty.as_slice()).map_err(|e| Error::Message(e.to_string()))?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let plain_text = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let mut lock = self.context.lock().map_err(|e| Error::Message(e.to_string()))?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lock.rsa_decrypt(self.handle, cipher_text, in_scheme, label)? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Ok(Vec::from(plain_text.value())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -413,6 +432,7 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             PublicEccParameters, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    use ctor::ctor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     trait ContextExt { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn for_test() -> Result<Context>; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -425,6 +445,11 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[ctor] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn ctor() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        env_logger::init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /// Displays the message associated with a TSS2 return code. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     //#[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn print_error_message() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -558,18 +583,33 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq(MessageDigest::sha3_512(), Nid::sha3_512()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fn tpm_sign_verify() -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        env_logger::init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn test_store() -> Result<TpmCredStore> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let dir = TempDir::new("btnode").map_err(Error::from)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let cookie_path = dir.path().join("cookie.bin"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let store = TpmCredStore::new(Context::for_test()?, &cookie_path)?;        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dir.close()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Ok(store) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn tpm_sign_verify() -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let store = test_store()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let handle = store.gen_node_creds()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let data: [u8; 1024] = rand_array()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let parts = [data.as_slice()]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let sig = handle.sign(parts.into_iter())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert!(handle.verify(parts.into_iter(), sig.as_slice())?); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dir.close()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Ok(()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn tpm_encrypt_decrypt() -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let store = test_store()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let handle = store.gen_node_creds()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expected: [u8; RSA_KEY_BYTES / 2] = rand_array()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let ct = handle.encrypt(expected.as_slice())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let actual = handle.decrypt(&ct)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!(expected.as_slice(), actual); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Ok(()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -578,4 +618,16 @@ mod test { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn hashcheck_null() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         HashcheckTicket::null(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Checks that the value of `TpmCredStore::RSA_KEY_BITS` matches the value of `RSA_KEY_BYTES`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn rsa_key_bits_and_key_bytes_compatible() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let bytes = match TpmCredStore::RSA_KEY_BITS { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RsaKeyBits::Rsa1024 => 128, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RsaKeyBits::Rsa2048 => 256, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RsaKeyBits::Rsa3072 => 384, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RsaKeyBits::Rsa4096 => 512, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!(RSA_KEY_BYTES, bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |