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