[client-vm] Build client VM CSR and sign the CSR with two keys
This cl builds the CSR that a client VM sends to the RKP VM for
remote attestation and adjusted the API accordingly as discussed
in the doc go/pvm-remote-attestation
The CSR payload is signed with both the CDI_Leaf_Priv of the
client VM's DICE chain and the attestation key. RKP VM should
verify the signature later with the CDI_Leaf_Pub extracted
from the same DICE chain in the CSR and the attestation public
key.
The new unit tests are added to config at cl/577763874.
Bug: 303807447
Test: run ServiceVmClientTestApp
Test: atest libservice_vm_comm.test
Test: atest microdroid_manager_test
Change-Id: Ic2c09e7339d9981edda028e2694fa551c911a274
diff --git a/virtualizationservice/aidl/android/system/virtualizationcommon/Certificate.aidl b/virtualizationservice/aidl/android/system/virtualizationcommon/Certificate.aidl
new file mode 100644
index 0000000..d587541
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualizationcommon/Certificate.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualizationcommon;
+
+/**
+ * This encodes a X.509 certificate returned in the pVM remote attestation.
+ */
+parcelable Certificate {
+ /**
+ * Contains the bytes of a DER-encoded X.509 certificate.
+ */
+ byte[] encodedCertificate;
+}
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl b/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
index 099a2c0..2592135 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
@@ -15,6 +15,7 @@
*/
package android.system.virtualizationservice_internal;
+import android.system.virtualizationcommon.Certificate;
import android.system.virtualizationservice.AssignableDevice;
import android.system.virtualizationservice.VirtualMachineDebugInfo;
import android.system.virtualizationservice_internal.AtomVmBooted;
@@ -62,7 +63,7 @@
* @return A sequence of DER-encoded X.509 certificates that make up the attestation
* key's certificate chain. The attestation key is provided in the CSR.
*/
- byte[] requestAttestation(in byte[] csr);
+ Certificate[] requestAttestation(in byte[] csr);
/**
* Get a list of assignable devices.
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
index 87d3056..3c60478 100644
--- a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
@@ -15,6 +15,7 @@
*/
package android.system.virtualmachineservice;
+import android.system.virtualizationcommon.Certificate;
import android.system.virtualizationcommon.ErrorCode;
/** {@hide} */
@@ -52,5 +53,5 @@
* @return A sequence of DER-encoded X.509 certificates that make up the attestation
* key's certificate chain. The attestation key is provided in the CSR.
*/
- byte[] requestAttestation(in byte[] csr);
+ Certificate[] requestAttestation(in byte[] csr);
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 4daa0cf..2be2b19 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -18,6 +18,7 @@
use crate::atom::{forward_vm_booted_atom, forward_vm_creation_atom, forward_vm_exited_atom};
use crate::rkpvm::request_attestation;
use android_os_permissions_aidl::aidl::android::os::IPermissionController;
+use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::Certificate::Certificate;
use android_system_virtualizationservice::{
aidl::android::system::virtualizationservice::AssignableDevice::AssignableDevice,
aidl::android::system::virtualizationservice::VirtualMachineDebugInfo::VirtualMachineDebugInfo,
@@ -158,7 +159,7 @@
Ok(cids)
}
- fn requestAttestation(&self, csr: &[u8]) -> binder::Result<Vec<u8>> {
+ fn requestAttestation(&self, csr: &[u8]) -> binder::Result<Vec<Certificate>> {
check_manage_access()?;
info!("Received csr. Requestting attestation...");
if cfg!(remote_attestation) {
diff --git a/virtualizationservice/src/rkpvm.rs b/virtualizationservice/src/rkpvm.rs
index 443b280..8f1de6b 100644
--- a/virtualizationservice/src/rkpvm.rs
+++ b/virtualizationservice/src/rkpvm.rs
@@ -17,18 +17,23 @@
//! serves as a trusted platform to attest a client VM.
use android_hardware_security_rkp::aidl::android::hardware::security::keymint::MacedPublicKey::MacedPublicKey;
+use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::Certificate::Certificate;
use anyhow::{bail, Context, Result};
use service_vm_comm::{GenerateCertificateRequestParams, Request, Response};
use service_vm_manager::ServiceVm;
-pub(crate) fn request_attestation(csr: &[u8]) -> Result<Vec<u8>> {
+pub(crate) fn request_attestation(csr: &[u8]) -> Result<Vec<Certificate>> {
let mut vm = ServiceVm::start()?;
// TODO(b/271275206): Send the correct request type with client VM's
// information to be attested.
let request = Request::Reverse(csr.to_vec());
match vm.process_request(request).context("Failed to process request")? {
- Response::Reverse(cert) => Ok(cert),
+ // TODO(b/271275206): Adjust the response type.
+ Response::Reverse(cert) => {
+ let cert = Certificate { encodedCertificate: cert };
+ Ok(vec![cert])
+ }
_ => bail!("Incorrect response type"),
}
}