@@ -9,6 +9,7 @@ use crate::{
99use log:: error;
1010use std:: convert:: TryFrom ;
1111use std:: ptr:: null_mut;
12+ use tss_esapi_sys:: Esys_GetTime ;
1213
1314impl Context {
1415 /// Prove that an object is loaded in the TPM
@@ -197,8 +198,122 @@ impl Context {
197198 }
198199 }
199200
201+ /// Get the current time and clock from the TPM
202+ ///
203+ /// # Arguments
204+ /// * `signing_key_handle` - Handle of the key used to sign the attestation buffer
205+ /// * `qualifying_data` - Qualifying data
206+ /// * `signing_scheme` - Signing scheme to use if the scheme for `signing_key_handle` is `Null`.
207+ ///
208+ /// The `signing_key_handle` must be usable for signing.
209+ ///
210+ /// If `signing_key_handle` has the Restricted attribute set to `true` then `signing_scheme` must be
211+ /// [SignatureScheme::Null].
212+ ///
213+ /// # Returns
214+ /// The command returns a tuple consisting of:
215+ /// * `attest_data` - TPM-generated attestation data.
216+ /// * `signature` - Signature for the attestation data.
217+ ///
218+ /// # Errors
219+ /// * if the qualifying data provided is too long, a `WrongParamSize` wrapper error will be returned
220+ ///
221+ /// # Examples
222+ ///
223+ /// ```rust
224+ /// # use tss_esapi::{Context, TctiNameConf};
225+ /// # use std::convert::TryFrom;
226+ /// # use tss_esapi::{
227+ /// # abstraction::cipher::Cipher,
228+ /// # interface_types::{
229+ /// # algorithm::{HashingAlgorithm, RsaSchemeAlgorithm},
230+ /// # key_bits::RsaKeyBits,
231+ /// # resource_handles::Hierarchy,
232+ /// # },
233+ /// # structures::{
234+ /// # RsaExponent, RsaScheme,
235+ /// # },
236+ /// # utils::{create_unrestricted_signing_rsa_public, create_restricted_decryption_rsa_public},
237+ /// # };
238+ /// use std::convert::TryInto;
239+ /// use tss_esapi::{
240+ /// structures::{Data, SignatureScheme},
241+ /// interface_types::session_handles::AuthSession,
242+ /// };
243+ /// # let mut context =
244+ /// # Context::new(
245+ /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
246+ /// # ).expect("Failed to create Context");
247+ /// let qualifying_data = vec![0xff; 16];
248+ /// # let signing_key_pub = create_unrestricted_signing_rsa_public(
249+ /// # RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
250+ /// # .expect("Failed to create RSA scheme"),
251+ /// # RsaKeyBits::Rsa2048,
252+ /// # RsaExponent::default(),
253+ /// # )
254+ /// # .expect("Failed to create an unrestricted signing rsa public structure");
255+ /// # let sign_key_handle = context
256+ /// # .execute_with_nullauth_session(|ctx| {
257+ /// # ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None)
258+ /// # })
259+ /// # .unwrap()
260+ /// # .key_handle;
261+ /// let (attest, signature) = context
262+ /// .execute_with_sessions(
263+ /// (
264+ /// Some(AuthSession::Password),
265+ /// Some(AuthSession::Password),
266+ /// None,
267+ /// ),
268+ /// |ctx| {
269+ /// ctx.get_time(
270+ /// sign_key_handle,
271+ /// Data::try_from(qualifying_data).unwrap(),
272+ /// SignatureScheme::Null,
273+ /// )
274+ /// },
275+ /// )
276+ /// .expect("Failed to get tpm time");
277+ /// ```
278+ pub fn get_time (
279+ & mut self ,
280+ signing_key_handle : KeyHandle ,
281+ qualifying_data : Data ,
282+ signing_scheme : SignatureScheme ,
283+ ) -> Result < ( Attest , Signature ) > {
284+ let mut timeinfo_ptr = null_mut ( ) ;
285+ let mut signature_ptr = null_mut ( ) ;
286+ let ret = unsafe {
287+ Esys_GetTime (
288+ self . mut_context ( ) ,
289+ ObjectHandle :: Endorsement . into ( ) ,
290+ signing_key_handle. into ( ) ,
291+ self . required_session_1 ( ) ?,
292+ self . required_session_2 ( ) ?,
293+ self . optional_session_3 ( ) ,
294+ & qualifying_data. into ( ) ,
295+ & signing_scheme. into ( ) ,
296+ & mut timeinfo_ptr,
297+ & mut signature_ptr,
298+ )
299+ } ;
300+
301+ let ret = Error :: from_tss_rc ( ret) ;
302+
303+ if ret. is_success ( ) {
304+ let timeinfo = Context :: ffi_data_to_owned ( timeinfo_ptr) ;
305+ let signature = Context :: ffi_data_to_owned ( signature_ptr) ;
306+ Ok ( (
307+ Attest :: try_from ( AttestBuffer :: try_from ( timeinfo) ?) ?,
308+ Signature :: try_from ( signature) ?,
309+ ) )
310+ } else {
311+ error ! ( "Error in Get Time: {}" , ret) ;
312+ Err ( ret)
313+ }
314+ }
315+
200316 // Missing function: GetSessionAuditDigest
201317 // Missing function: GestCommandAuditDigest
202- // Missing function: GetTime
203318 // Missing function: CertifyX509
204319}
0 commit comments