(&self)
| 79 | } |
| 80 | |
| 81 | pub async fn get_sealing_key(&self) -> Result<KeyProvision> { |
| 82 | let (pk, sk) = generate_keypair(); |
| 83 | let mut report_data = [0u8; 64]; |
| 84 | report_data[..PUBLICKEYBYTES].copy_from_slice(pk.as_bytes()); |
| 85 | let quote = tdx_attest::get_quote(&report_data).context("Failed to get quote")?; |
| 86 | let Some(client) = &self.client else { |
| 87 | return Err(anyhow!("Host API client not initialized")); |
| 88 | }; |
| 89 | let provision = client |
| 90 | .get_sealing_key(host_api::GetSealingKeyRequest { |
| 91 | quote: quote.to_vec(), |
| 92 | }) |
| 93 | .await |
| 94 | .map_err(|err| anyhow!("Failed to get sealing key: {err:?}"))?; |
| 95 | |
| 96 | // verify the key provider quote |
| 97 | let verified_report = dcap_qvl::collateral::get_collateral_and_verify( |
| 98 | &provision.provider_quote, |
| 99 | self.pccs_url.as_deref(), |
| 100 | ) |
| 101 | .await |
| 102 | .context("Failed to get quote collateral")?; |
| 103 | validate_tcb(&verified_report)?; |
| 104 | let sgx_report = verified_report |
| 105 | .report |
| 106 | .as_sgx() |
| 107 | .context("Invalid sgx report")?; |
| 108 | let key_hash = sha256(&provision.encrypted_key); |
| 109 | if sgx_report.report_data[..32] != key_hash { |
| 110 | bail!("Invalid key hash"); |
| 111 | } |
| 112 | let mr = sgx_report.mr_enclave; |
| 113 | |
| 114 | // write to fs |
| 115 | let sealing_key = open_sealed_box(&provision.encrypted_key, &pk, &sk) |
| 116 | .ok() |
| 117 | .context("Failed to open sealing key")?; |
| 118 | let sk = sealing_key |
| 119 | .try_into() |
| 120 | .ok() |
| 121 | .context("Invalid sealing key length")?; |
| 122 | Ok(KeyProvision { sk, mr }) |
| 123 | } |
| 124 | } |
no test coverage detected