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