|
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