|
2 | 2 | // SPDX-License-Identifier: Apache-2.0
|
3 | 3 | use crate::{
|
4 | 4 | handles::{KeyHandle, ObjectHandle},
|
5 |
| - structures::{Attest, AttestBuffer, Data, PcrSelectionList, Signature, SignatureScheme}, |
| 5 | + structures::{ |
| 6 | + Attest, AttestBuffer, CreationTicket, Data, Digest, PcrSelectionList, Signature, |
| 7 | + SignatureScheme, |
| 8 | + }, |
6 | 9 | tss2_esys::{Esys_Certify, Esys_Quote},
|
7 | 10 | Context, Result, ReturnCode,
|
8 | 11 | };
|
9 | 12 | use log::error;
|
10 | 13 | use std::convert::TryFrom;
|
11 | 14 | use std::ptr::null_mut;
|
| 15 | +use tss_esapi_sys::Esys_CertifyCreation; |
12 | 16 |
|
13 | 17 | impl Context {
|
14 | 18 | /// Prove that an object is loaded in the TPM
|
@@ -152,7 +156,132 @@ impl Context {
|
152 | 156 | ))
|
153 | 157 | }
|
154 | 158 |
|
155 |
| - // Missing function: CertifyCreation |
| 159 | + /// Prove the association between an object and its creation data |
| 160 | + /// |
| 161 | + /// # Arguments |
| 162 | + /// * `signing_key_handle` - Handle of the key used to sign the attestation buffer |
| 163 | + /// * `object_handle` - Handle of the object to be certified |
| 164 | + /// * `qualifying_data` - Qualifying data |
| 165 | + /// * `creation_hash` - Digest of the creation data |
| 166 | + /// * `signing_scheme` - Signing scheme to use if the scheme for `signing_key_handle` is `Null`. |
| 167 | + /// * `creation_ticket` - CreationTicket returned at object creation time. |
| 168 | + /// |
| 169 | + /// The object may be any object that is loaded with [Self::load()] or [Self::create_primary()]. An object that |
| 170 | + /// only has its public area loaded may not be certified. |
| 171 | + /// |
| 172 | + /// The `signing_key_handle` must be usable for signing. |
| 173 | + /// |
| 174 | + /// If `signing_key_handle` has the Restricted attribute set to `true` then `signing_scheme` must be |
| 175 | + /// [SignatureScheme::Null]. |
| 176 | + /// |
| 177 | + /// # Returns |
| 178 | + /// The command returns a tuple consisting of: |
| 179 | + /// * `attest_data` - TPM-generated attestation data. |
| 180 | + /// * `signature` - Signature for the attestation data. |
| 181 | + /// |
| 182 | + /// # Errors |
| 183 | + /// * if the qualifying data provided is too long, a `WrongParamSize` wrapper error will be returned |
| 184 | + /// |
| 185 | + /// # Examples |
| 186 | + /// |
| 187 | + /// ```rust |
| 188 | + /// # use tss_esapi::{Context, TctiNameConf}; |
| 189 | + /// # use std::convert::TryFrom; |
| 190 | + /// # use tss_esapi::{ |
| 191 | + /// # abstraction::cipher::Cipher, |
| 192 | + /// # handles::KeyHandle, |
| 193 | + /// # interface_types::{ |
| 194 | + /// # algorithm::{HashingAlgorithm, EccSchemeAlgorithm, SignatureSchemeAlgorithm}, |
| 195 | + /// # ecc::EccCurve, |
| 196 | + /// # resource_handles::Hierarchy, |
| 197 | + /// # }, |
| 198 | + /// # structures::{ |
| 199 | + /// # EccScheme |
| 200 | + /// # }, |
| 201 | + /// # utils::create_unrestricted_signing_ecc_public, |
| 202 | + /// # }; |
| 203 | + /// use std::convert::TryInto; |
| 204 | + /// use tss_esapi::{ |
| 205 | + /// structures::{Data, SignatureScheme}, |
| 206 | + /// interface_types::session_handles::AuthSession, |
| 207 | + /// }; |
| 208 | + /// # let mut context = |
| 209 | + /// # Context::new( |
| 210 | + /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"), |
| 211 | + /// # ).expect("Failed to create Context"); |
| 212 | + /// let qualifying_data = vec![0xff; 16]; |
| 213 | + /// # let signing_key_pub = create_unrestricted_signing_ecc_public( |
| 214 | + /// # EccScheme::create(EccSchemeAlgorithm::EcDsa, Some(HashingAlgorithm::Sha256), None) |
| 215 | + /// # .expect("Failed to create ECC scheme"), |
| 216 | + /// # EccCurve::NistP256, |
| 217 | + /// # ) |
| 218 | + /// # .expect("Failed to create an unrestricted signing ecc public structure"); |
| 219 | + /// # let create_result = context |
| 220 | + /// # .execute_with_nullauth_session(|ctx| { |
| 221 | + /// # ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None) |
| 222 | + /// # }).unwrap(); |
| 223 | + /// let (attest, signature) = context |
| 224 | + /// .execute_with_sessions( |
| 225 | + /// ( |
| 226 | + /// Some(AuthSession::Password), |
| 227 | + /// None, |
| 228 | + /// None, |
| 229 | + /// ), |
| 230 | + /// |ctx| { |
| 231 | + /// ctx.certify_creation( |
| 232 | + /// create_result.key_handle, |
| 233 | + /// create_result.key_handle.into(), |
| 234 | + /// qualifying_data.try_into()?, |
| 235 | + /// create_result.creation_hash, |
| 236 | + /// SignatureScheme::Null, |
| 237 | + /// create_result.creation_ticket, |
| 238 | + /// ) |
| 239 | + /// }, |
| 240 | + /// ) |
| 241 | + /// .expect("Failed to certify creation"); |
| 242 | + /// ``` |
| 243 | + pub fn certify_creation( |
| 244 | + &mut self, |
| 245 | + signing_key_handle: KeyHandle, |
| 246 | + created_object: ObjectHandle, |
| 247 | + qualifying_data: Data, |
| 248 | + creation_hash: Digest, |
| 249 | + signing_scheme: SignatureScheme, |
| 250 | + creation_ticket: CreationTicket, |
| 251 | + ) -> Result<(Attest, Signature)> { |
| 252 | + use std::convert::TryInto; |
| 253 | + |
| 254 | + let mut certify_info_ptr = null_mut(); |
| 255 | + let mut signature_ptr = null_mut(); |
| 256 | + ReturnCode::ensure_success( |
| 257 | + unsafe { |
| 258 | + Esys_CertifyCreation( |
| 259 | + self.mut_context(), |
| 260 | + signing_key_handle.into(), |
| 261 | + created_object.into(), |
| 262 | + self.required_session_1()?, |
| 263 | + self.optional_session_2(), |
| 264 | + self.optional_session_3(), |
| 265 | + &qualifying_data.into(), |
| 266 | + &creation_hash.into(), |
| 267 | + &signing_scheme.into(), |
| 268 | + &creation_ticket.try_into()?, |
| 269 | + &mut certify_info_ptr, |
| 270 | + &mut signature_ptr, |
| 271 | + ) |
| 272 | + }, |
| 273 | + |ret| { |
| 274 | + error!("Error in certifying creation: {:#010X}", ret); |
| 275 | + }, |
| 276 | + )?; |
| 277 | + |
| 278 | + let certify_info = Context::ffi_data_to_owned(certify_info_ptr); |
| 279 | + let signature = Context::ffi_data_to_owned(signature_ptr); |
| 280 | + Ok(( |
| 281 | + Attest::try_from(AttestBuffer::try_from(certify_info)?)?, |
| 282 | + Signature::try_from(signature)?, |
| 283 | + )) |
| 284 | + } |
156 | 285 |
|
157 | 286 | /// Generate a quote on the selected PCRs
|
158 | 287 | ///
|
|
0 commit comments