@@ -6,13 +6,12 @@ use crate::{
66        Attest ,  AttestBuffer ,  CreationTicket ,  Data ,  Digest ,  PcrSelectionList ,  Signature , 
77        SignatureScheme , 
88    } , 
9-     tss2_esys:: { Esys_Certify ,  Esys_Quote } , 
9+     tss2_esys:: { Esys_Certify ,  Esys_CertifyCreation ,   Esys_GetTime ,   Esys_Quote } , 
1010    Context ,  Result ,  ReturnCode , 
1111} ; 
1212use  log:: error; 
1313use  std:: convert:: TryFrom ; 
1414use  std:: ptr:: null_mut; 
15- use  tss_esapi_sys:: Esys_CertifyCreation ; 
1615
1716impl  Context  { 
1817    /// Prove that an object is loaded in the TPM 
@@ -322,8 +321,120 @@ impl Context {
322321        ) ) 
323322    } 
324323
324+     /// Get the current time and clock from the TPM 
325+      /// 
326+      /// # Arguments 
327+      /// * `signing_key_handle` - Handle of the key used to sign the attestation buffer 
328+      /// * `qualifying_data` - Qualifying data 
329+      /// * `signing_scheme` - Signing scheme to use if the scheme for `signing_key_handle` is `Null`. 
330+      /// 
331+      /// The `signing_key_handle` must be usable for signing. 
332+      /// 
333+      /// If `signing_key_handle` has the Restricted attribute set to `true` then `signing_scheme` must be 
334+      /// [SignatureScheme::Null]. 
335+      /// 
336+      /// # Returns 
337+      /// The command returns a tuple consisting of: 
338+      /// * `attest_data` - TPM-generated attestation data. 
339+      /// * `signature` - Signature for the attestation data. 
340+      /// 
341+      /// # Errors 
342+      /// * if the qualifying data provided is too long, a `WrongParamSize` wrapper error will be returned 
343+      /// 
344+      /// # Examples 
345+      /// 
346+      /// ```rust 
347+      /// # use tss_esapi::{Context, TctiNameConf}; 
348+      /// # use std::convert::TryFrom; 
349+      /// # use tss_esapi::{ 
350+      /// #     abstraction::cipher::Cipher, 
351+      /// #     interface_types::{ 
352+      /// #         algorithm::{HashingAlgorithm, RsaSchemeAlgorithm}, 
353+      /// #         key_bits::RsaKeyBits, 
354+      /// #         reserved_handles::Hierarchy, 
355+      /// #     }, 
356+      /// #     structures::{ 
357+      /// #         RsaExponent, RsaScheme, 
358+      /// #     }, 
359+      /// #     utils::{create_unrestricted_signing_rsa_public, create_restricted_decryption_rsa_public}, 
360+      /// # }; 
361+      /// use std::convert::TryInto; 
362+      /// use tss_esapi::{ 
363+      ///     structures::{Data, SignatureScheme}, 
364+      ///     interface_types::session_handles::AuthSession, 
365+      /// }; 
366+      /// # let mut context = 
367+      /// #     Context::new( 
368+      /// #         TctiNameConf::from_environment_variable().expect("Failed to get TCTI"), 
369+      /// #     ).expect("Failed to create Context"); 
370+      /// let qualifying_data = vec![0xff; 16]; 
371+      /// # let signing_key_pub = create_unrestricted_signing_rsa_public( 
372+      /// #         RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256)) 
373+      /// #         .expect("Failed to create RSA scheme"), 
374+      /// #     RsaKeyBits::Rsa2048, 
375+      /// #     RsaExponent::default(), 
376+      /// # ) 
377+      /// # .expect("Failed to create an unrestricted signing rsa public structure"); 
378+      /// # let sign_key_handle = context 
379+      /// #     .execute_with_nullauth_session(|ctx| { 
380+      /// #         ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None) 
381+      /// #     }) 
382+      /// #     .unwrap() 
383+      /// #     .key_handle; 
384+      /// let (attest, signature) = context 
385+      ///     .execute_with_sessions( 
386+      ///         ( 
387+      ///             Some(AuthSession::Password), 
388+      ///             Some(AuthSession::Password), 
389+      ///             None, 
390+      ///         ), 
391+      ///         |ctx| { 
392+      ///             ctx.get_time( 
393+      ///                 sign_key_handle, 
394+      ///                 Data::try_from(qualifying_data).unwrap(), 
395+      ///                 SignatureScheme::Null, 
396+      ///             ) 
397+      ///         }, 
398+      ///     ) 
399+      ///     .expect("Failed to get tpm time"); 
400+      /// ``` 
401+      pub  fn  get_time ( 
402+         & mut  self , 
403+         signing_key_handle :  KeyHandle , 
404+         qualifying_data :  Data , 
405+         signing_scheme :  SignatureScheme , 
406+     )  -> Result < ( Attest ,  Signature ) >  { 
407+         let  mut  timeinfo_ptr = null_mut ( ) ; 
408+         let  mut  signature_ptr = null_mut ( ) ; 
409+         ReturnCode :: ensure_success ( 
410+             unsafe  { 
411+                 Esys_GetTime ( 
412+                     self . mut_context ( ) , 
413+                     ObjectHandle :: Endorsement . into ( ) , 
414+                     signing_key_handle. into ( ) , 
415+                     self . optional_session_1 ( ) , 
416+                     self . optional_session_2 ( ) , 
417+                     self . optional_session_3 ( ) , 
418+                     & qualifying_data. into ( ) , 
419+                     & signing_scheme. into ( ) , 
420+                     & mut  timeinfo_ptr, 
421+                     & mut  signature_ptr, 
422+                 ) 
423+             } , 
424+             |ret| { 
425+                 error ! ( "Error in GetTime: {:#010X}" ,  ret) ; 
426+             } , 
427+         ) ?; 
428+ 
429+         let  timeinfo = Context :: ffi_data_to_owned ( timeinfo_ptr) ; 
430+         let  signature = Context :: ffi_data_to_owned ( signature_ptr) ; 
431+         Ok ( ( 
432+             Attest :: try_from ( AttestBuffer :: try_from ( timeinfo) ?) ?, 
433+             Signature :: try_from ( signature) ?, 
434+         ) ) 
435+     } 
436+ 
325437    // Missing function: GetSessionAuditDigest 
326438    // Missing function: GestCommandAuditDigest 
327-     // Missing function: GetTime 
328439    // Missing function: CertifyX509 
329440} 
0 commit comments