xref: /aosp_15_r20/tools/security/remote_provisioning/hwtrust/src/rkp/csr.rs (revision d9ecfb0f4d734c9ce41cde8ac4d585b094fd4222)
1 use std::{collections::HashMap, fmt};
2 
3 use openssl::x509::X509;
4 
5 use crate::{dice::ChainForm, rkp::DeviceInfo};
6 
7 use super::ProtectedData;
8 
9 /// Represents the payload of a Certificate Signing Request
10 #[derive(Clone, Eq, PartialEq)]
11 pub struct CsrPayload {
12     /// RKP VM or other?
13     pub certificate_type: String,
14     /// Describes the device that is requesting certificates.
15     pub device_info: DeviceInfo,
16     /// The keys to attest to when doing key attestation in one buffer
17     pub keys_to_sign: Vec<u8>,
18 }
19 
20 /// Represents a Certificate Signing Request that is sent to an RKP backend to request
21 /// certificates to be signed for a set of public keys. The CSR is partially generated by an
22 /// IRemotelyProvisionedComponent HAL. The set of public keys to be signed is authenticated
23 /// (signed) with a device-unique key.
24 #[derive(Clone, Eq, PartialEq)]
25 pub enum Csr {
26     /// CSR V2 was introduced in Android T. In this version, the payload is encrypted using
27     /// an Endpoint Encryption Key (EEK).
28     V2 {
29         /// Describes the device that is requesting certificates.
30         device_info: DeviceInfo,
31         /// This is the challenge that is authenticated inside the protected data.
32         challenge: Vec<u8>,
33         /// Contains the plaintext of the payload that was encrypted to an EEK.
34         protected_data: ProtectedData,
35     },
36     /// CSR V3 was introduced in Android T. This version drops encryption of the payload.
37     V3 {
38         /// The DICE chain for the device
39         dice_chain: ChainForm,
40         /// X.509 certificate chain that certifies the dice_chain root key (UDS_pub)
41         uds_certs: HashMap<String, Vec<X509>>,
42         /// This is the challenge that is authenticated inside the signed data.
43         /// The signed data is version (3), certificate type, device info, and keys to sign
44         challenge: Vec<u8>,
45         /// csr payload
46         csr_payload: CsrPayload,
47     },
48 }
49 
50 impl Csr {
51     /// copy the DICE chain and return it
52     #[allow(dead_code)]
dice_chain(&self) -> ChainForm53     pub fn dice_chain(&self) -> ChainForm {
54         match self {
55             Csr::V2 { protected_data, .. } => protected_data.dice_chain(),
56             Csr::V3 { dice_chain, .. } => dice_chain.clone(),
57         }
58     }
59 }
60 
61 impl fmt::Debug for Csr {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result62     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
63         match self {
64             Csr::V2 { device_info, challenge, protected_data } => fmt
65                 .debug_struct("CSR V2")
66                 .field("DeviceInfo", &device_info)
67                 .field("Challenge", &hex::encode(challenge))
68                 .field("ProtectedData", &protected_data)
69                 .finish(),
70             Csr::V3 { dice_chain, uds_certs, csr_payload, .. } => fmt
71                 .debug_struct("CSR V3")
72                 .field("DeviceInfo", &csr_payload.device_info)
73                 .field("DiceChain", &dice_chain)
74                 .field("UdsCerts", &uds_certs)
75                 .finish(),
76         }
77     }
78 }
79