ndn_protocol/
certificate.rs

1use std::path::Path;
2
3use base64::Engine;
4use bytes::Bytes;
5use ndn_tlv::{Tlv, TlvDecode, TlvEncode};
6use rsa::{
7    pkcs8::{DecodePrivateKey, DecodePublicKey},
8    RsaPrivateKey, RsaPublicKey,
9};
10
11use crate::{error::NdnError, Data, KeyLocator, Name, SignatureInfo};
12
13#[derive(Tlv, Clone, Hash, Debug)]
14#[tlv(128)]
15pub struct SafeBag {
16    pub certificate: Data<Bytes>,
17    pub encrypted_key: EncryptedKey,
18}
19
20#[derive(Tlv, Clone, Hash, Debug)]
21#[tlv(129)]
22pub struct EncryptedKey {
23    pub data: Bytes,
24}
25
26#[derive(Clone, Debug, Hash)]
27pub struct Certificate(pub Data<Bytes>);
28
29pub trait ToCertificate {
30    fn to_certificate(&self) -> Certificate;
31}
32
33#[derive(Clone, Debug, Hash)]
34pub struct RsaCertificate {
35    cert: Certificate,
36    public_key: RsaPublicKey,
37    private_key: Option<RsaPrivateKey>,
38}
39
40impl RsaCertificate {
41    pub fn new(cert: Certificate) -> Option<Self> {
42        let key = RsaPublicKey::from_public_key_der(&cert.0.content()?).ok()?;
43        Some(Self {
44            cert,
45            public_key: key,
46            private_key: None,
47        })
48    }
49
50    pub fn with_private(cert: Certificate, private_key: RsaPrivateKey) -> Option<Self> {
51        let key = RsaPublicKey::from_public_key_der(&cert.0.content()?).ok()?;
52        Some(Self {
53            cert,
54            public_key: key,
55            private_key: Some(private_key),
56        })
57    }
58
59    pub fn from_safebag<P>(bag: SafeBag, password: P) -> Option<Self>
60    where
61        P: AsRef<[u8]>,
62    {
63        let key =
64            RsaPrivateKey::from_pkcs8_encrypted_der(&bag.encrypted_key.data, password).ok()?;
65        Self::with_private(Certificate(bag.certificate), key)
66    }
67
68    pub fn name(&self) -> &Name {
69        self.cert.name()
70    }
71
72    pub fn public_key(&self) -> &RsaPublicKey {
73        &self.public_key
74    }
75
76    pub fn private_key(&self) -> Option<&RsaPrivateKey> {
77        self.private_key.as_ref()
78    }
79}
80
81impl ToCertificate for RsaCertificate {
82    fn to_certificate(&self) -> Certificate {
83        self.cert.clone()
84    }
85}
86
87impl SafeBag {
88    pub fn load_file(path: impl AsRef<Path>) -> Result<Self, NdnError> {
89        let mut file_content = std::fs::read(path)?;
90        file_content.retain(|x| *x != b'\n' && *x != b'\r');
91        let safebag_data = base64::engine::general_purpose::STANDARD
92            .decode(&file_content)
93            .map_err(|_| {
94                NdnError::GenericError("Could not base64-decode certificate".to_string())
95            })?;
96        Ok(SafeBag::decode(&mut Bytes::from(safebag_data))?)
97    }
98}
99
100impl Certificate {
101    pub fn load_file<P>(path: P) -> Result<Self, NdnError>
102    where
103        P: AsRef<Path>,
104    {
105        let mut file_content = std::fs::read(path)?;
106        file_content.retain(|x| *x != b'\n' && *x != b'\r');
107        let safebag_data = base64::engine::general_purpose::STANDARD
108            .decode(&file_content)
109            .map_err(|_| {
110                NdnError::GenericError("Could not base64-decode certificate".to_string())
111            })?;
112        Ok(Self(Data::<Bytes>::decode(&mut Bytes::from(safebag_data))?))
113    }
114
115    pub fn name(&self) -> &Name {
116        self.0.name()
117    }
118
119    pub fn identity(&self) -> Name {
120        let mut name = self.name().clone();
121        name.components.pop();
122        name.components.pop();
123        name.components.pop();
124        name.components.pop();
125        name
126    }
127
128    pub fn name_locator(&self) -> KeyLocator {
129        KeyLocator::new(crate::signature::KeyLocatorData::Name(self.name().clone()))
130    }
131
132    pub fn as_data(&self) -> &Data<Bytes> {
133        &self.0
134    }
135
136    pub fn signature_info(&self) -> Option<&SignatureInfo> {
137        self.0.signature_info()
138    }
139}
140
141impl TlvEncode for Certificate {
142    fn encode(&self) -> Bytes {
143        self.0.encode()
144    }
145
146    fn size(&self) -> usize {
147        self.0.size()
148    }
149}
150
151impl TlvDecode for Certificate {
152    fn decode(bytes: &mut Bytes) -> ndn_tlv::Result<Self> {
153        Data::<Bytes>::decode(bytes).map(Self)
154    }
155}