Skip to main content

oasis_core_runtime/host/
attestation.rs

1use std::collections::BTreeMap;
2
3use async_trait::async_trait;
4
5use crate::{
6    common::crypto::signature::{PublicKey, Signature},
7    protocol::Protocol,
8};
9
10use super::{host_rpc_call, Error};
11
12/// Name of the local RPC endpoint for the attestation methods.
13pub const LOCAL_RPC_ENDPOINT_ATTESTATION: &str = "attestation";
14
15/// Name of the AttestLabels method.
16pub const METHOD_ATTEST_LABELS: &str = "AttestLabels";
17
18/// Signature context used for label attestation.
19pub const ATTEST_LABELS_SIGNATURE_CONTEXT: &[u8] = b"oasis-core/node: attest component labels";
20
21/// Attestaion interface.
22#[allow(clippy::double_must_use)]
23#[async_trait]
24pub trait Attestation: Send + Sync {
25    /// Request to host to attest component labels.
26    async fn attest_labels(&self, args: AttestLabelsRequest)
27        -> Result<AttestLabelsResponse, Error>;
28}
29
30#[allow(clippy::double_must_use)]
31#[async_trait]
32impl Attestation for Protocol {
33    async fn attest_labels(
34        &self,
35        args: AttestLabelsRequest,
36    ) -> Result<AttestLabelsResponse, Error> {
37        host_rpc_call(
38            self,
39            LOCAL_RPC_ENDPOINT_ATTESTATION,
40            METHOD_ATTEST_LABELS,
41            args,
42        )
43        .await
44    }
45}
46
47/// Request to attest labels.
48#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
49pub struct AttestLabelsRequest {
50    /// Labels to attest to.
51    pub labels: Vec<String>,
52}
53
54/// Response from the AttestLabels method.
55#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
56pub struct AttestLabelsResponse {
57    /// CBOR-serialized label attestation.
58    pub attestation: Vec<u8>,
59    /// Public key of the node attesting to the labels.
60    pub node_id: PublicKey,
61    /// Signature of the attested labels.
62    pub signature: Signature,
63}
64
65/// Attestation of component labels.
66#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
67pub struct LabelAttestation {
68    /// Attested label values.
69    pub labels: BTreeMap<String, String>,
70    /// Component RAK.
71    pub rak: PublicKey,
72}
73
74#[cfg(test)]
75mod test {
76    use super::*;
77
78    #[test]
79    fn test_label_attestation() {
80        // NOTE: Test vectors from Go implementation.
81        let la = LabelAttestation {
82            labels: BTreeMap::from([("foo".to_string(), "bar".to_string())]),
83            rak: "4242424242424242424242424242424242424242424242424242424242424242"
84                .parse()
85                .unwrap(),
86        };
87        let pk = "4b386050bd904dbe4de4f6f0040ab64a18f8a305c9609231bcf90aa1dbd14a3c";
88        let sig = "6e7103250a95ed0b560dfabddec022bcd5416b96db1a999c725373e7d033dbfa14b8af29572fbe4b5cb2d30ac839ff4a465bb967169e5dcf888d06af90a3c809";
89
90        let la_enc = cbor::to_vec(la);
91        let pk = pk.parse().unwrap();
92        let sig: Signature = sig.parse().unwrap();
93        sig.verify(&pk, ATTEST_LABELS_SIGNATURE_CONTEXT, &la_enc)
94            .expect("label attestation signature should be correct");
95    }
96}