@@ -11,8 +11,11 @@ use tokio_rustls::rustls::pki_types::CertificateDer;
1111use crate :: attestation:: {
1212 self , compute_report_input,
1313 measurements:: { CvmImageMeasurements , Measurements , PlatformMeasurements } ,
14+ nv_index,
1415} ;
1516
17+ const TPM_AK_CERT_IDX : u32 = 0x1C101D0 ;
18+
1619pub async fn create_azure_attestation (
1720 cert_chain : & [ CertificateDer < ' _ > ] ,
1821 exporter : [ u8 ; 32 ] ,
@@ -27,11 +30,14 @@ pub async fn create_azure_attestation(
2730
2831 let hcl_report_bytes = vtpm:: get_report_with_report_data ( & input_data) ?;
2932
30- // let quote_b64 = ;
31- // let runtime_b64 = BASE64_URL_SAFE.encode(hcl_var_data);
33+ let ak_certificate_der = read_ak_certificate_from_tpm ( ) ?;
3234
3335 let tpm_attestation = TpmAttest {
34- ak_pub : vtpm:: get_ak_pub ( ) ?,
36+ ak_certificate_pem : pem_rfc7468:: encode_string (
37+ "CERTIFICATE" ,
38+ pem_rfc7468:: LineEnding :: default ( ) ,
39+ & ak_certificate_der,
40+ ) ?,
3541 quote : vtpm:: get_quote ( & input_data) ?,
3642 event_log : Vec :: new ( ) ,
3743 instance_info : None ,
@@ -94,7 +100,6 @@ pub async fn verify_azure_attestation(
94100 . unwrap ( ) ;
95101
96102 let hcl_report = hcl:: HclReport :: new ( hcl_report_bytes) ?;
97- //
98103 let var_data_hash = hcl_report. var_data_sha256 ( ) ;
99104 let hcl_ak_pub = hcl_report. ak_pub ( ) ?;
100105 let td_report: az_tdx_vtpm:: tdx:: TdReport = hcl_report. try_into ( ) ?;
@@ -106,6 +111,10 @@ pub async fn verify_azure_attestation(
106111 vtpm_quote. verify ( & pub_key, & input_data) ?;
107112 let _pcrs = vtpm_quote. pcrs_sha256 ( ) ;
108113
114+ // TODO parse AK certificate
115+ // Check that AK public key matches that from TPM quote
116+ // Verify AK certificate against microsoft root cert
117+
109118 Ok ( Measurements {
110119 platform : PlatformMeasurements :: from_dcap_qvl_quote ( & quote) . unwrap ( ) ,
111120 cvm_image : CvmImageMeasurements :: from_dcap_qvl_quote ( & quote) . unwrap ( ) ,
@@ -124,19 +133,23 @@ struct AttestationDocument {
124133}
125134
126135#[ derive( Debug , Serialize , Deserialize ) ]
127- pub struct TpmAttest {
128- /// vTPM Attestation Key (AK) public key
129- // TODO do we need this? it is already given in HCL report
130- pub ak_pub : vtpm:: PublicKey ,
136+ struct TpmAttest {
137+ /// Attestation Key certificate from vTPM
138+ ak_certificate_pem : String ,
131139 /// vTPM quotes over the selected PCR bank(s).
132- pub quote : vtpm:: Quote ,
140+ quote : vtpm:: Quote ,
133141 /// Raw TCG event log bytes (UEFI + IMA)
134142 ///
135143 /// `/sys/kernel/security/ima/ascii_runtime_measurements`,
136144 /// `/sys/kernel/security/tpm0/binary_bios_measurements`,
137- pub event_log : Vec < u8 > ,
145+ event_log : Vec < u8 > ,
138146 /// Optional platform / instance metadata used to bind or verify the AK
139- pub instance_info : Option < Vec < u8 > > ,
147+ instance_info : Option < Vec < u8 > > ,
148+ }
149+
150+ fn read_ak_certificate_from_tpm ( ) -> Result < Vec < u8 > , tss_esapi:: Error > {
151+ let mut context = nv_index:: get_session_context ( ) ?;
152+ Ok ( nv_index:: read_nv_index ( & mut context, TPM_AK_CERT_IDX ) ?)
140153}
141154
142155#[ derive( Error , Debug ) ]
@@ -165,6 +178,10 @@ pub enum MaaError {
165178 AkPub ( #[ from] vtpm:: AKPubError ) ,
166179 #[ error( "vTPM quote could not be verified: {0}" ) ]
167180 TpmQuoteVerify ( #[ from] vtpm:: VerifyError ) ,
181+ #[ error( "vTPM read: {0}" ) ]
182+ TssEsapi ( #[ from] tss_esapi:: Error ) ,
183+ #[ error( "PEM encode: {0}" ) ]
184+ Pem ( #[ from] pem_rfc7468:: Error ) ,
168185}
169186
170187#[ cfg( test) ]
0 commit comments