// Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 mod test_quote { use crate::common::{create_ctx_with_session, decryption_key_pub, signing_key_pub}; use std::convert::TryFrom; use tss_esapi::{ constants::StructureTag, handles::KeyHandle, interface_types::{ algorithm::{HashingAlgorithm, SignatureSchemeAlgorithm}, resource_handles::Hierarchy, session_handles::AuthSession, structure_tags::AttestationType, }, structures::{ AttestInfo, Data, HashScheme, MaxBuffer, PcrSelectionListBuilder, PcrSlot, SignatureScheme, Ticket, }, traits::Marshall, }; #[test] fn pcr_quote() { let mut context = create_ctx_with_session(); // Quote PCR 0 let pcr_selection_list = PcrSelectionListBuilder::new() .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0]) .build() .expect("Failed to create PcrSelectionList"); // No qualifying data let qualifying_data = vec![0xff; 16]; let key_handle = context .create_primary(Hierarchy::Owner, signing_key_pub(), None, None, None, None) .unwrap() .key_handle; let (attest, _signature) = context .quote( key_handle, Data::try_from(qualifying_data).unwrap(), SignatureScheme::Null, pcr_selection_list.clone(), ) .expect("Failed to get a quote"); assert_eq!( AttestationType::Quote, attest.attestation_type(), "Attestation type of the returned value is not indicating Quote" ); match attest.attested() { AttestInfo::Quote { info } => { assert!(info.pcr_digest().len() != 0, "Digest in QuoteInfo is empty"); assert_eq!( &pcr_selection_list, info.pcr_selection(), "QuoteInfo selection list did not match the input selection list" ); } _ => { panic!("Attested did not contain the expected variant.") } } } #[test] fn certify() { let mut context = create_ctx_with_session(); let qualifying_data = vec![0xff; 16]; let sign_key_handle = context .create_primary(Hierarchy::Owner, signing_key_pub(), None, None, None, None) .unwrap() .key_handle; let obj_key_handle = context .create_primary( Hierarchy::Owner, decryption_key_pub(), None, None, None, None, ) .unwrap() .key_handle; let (attest, signature) = context .execute_with_sessions( ( Some(AuthSession::Password), Some(AuthSession::Password), None, ), |ctx| { ctx.certify( obj_key_handle.into(), sign_key_handle, Data::try_from(qualifying_data.clone()).unwrap(), SignatureScheme::Null, ) }, ) .expect("Failed to certify object handle"); // Verify the signature is valid for the attestation data let data = MaxBuffer::try_from(attest.marshall().unwrap()) .expect("Failed to get data buffer from attestation data"); let (digest, _) = context .hash(data, HashingAlgorithm::Sha256, Hierarchy::Null) .expect("Failed to hash data"); let ticket = context .execute_with_nullauth_session(|ctx| { ctx.verify_signature(sign_key_handle, digest, signature) }) .expect("Failed to verify signature"); assert_eq!(ticket.tag(), StructureTag::Verified); // Verify the attestation data is as expected assert_eq!(attest.attestation_type(), AttestationType::Certify); assert!(matches!(attest.attested(), AttestInfo::Certify { .. })); assert_eq!(attest.extra_data().value(), qualifying_data); } #[test] fn certify_null() { let mut context = create_ctx_with_session(); let qualifying_data = vec![0xff; 16]; let sign_scheme = SignatureScheme::RsaPss { hash_scheme: HashScheme::new(HashingAlgorithm::Sha256), }; let obj_key_handle = context .create_primary( Hierarchy::Owner, decryption_key_pub(), None, None, None, None, ) .unwrap() .key_handle; let (_attest, signature) = context .execute_with_sessions( ( Some(AuthSession::Password), Some(AuthSession::Password), None, ), |ctx| { ctx.certify( obj_key_handle.into(), KeyHandle::Null, Data::try_from(qualifying_data).unwrap(), sign_scheme, ) }, ) .expect("Failed to certify object handle"); assert_eq!(signature.algorithm(), SignatureSchemeAlgorithm::Null); } }