@@ -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 . required_session_1 ( ) ?,
416+ self . required_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