ndn_protocol/
certificate.rs1use std::path::Path;
11
12use base64::Engine;
13use bytes::Bytes;
14use ndn_tlv::{Tlv, TlvDecode, TlvEncode};
15use rsa::{
16 pkcs8::{DecodePrivateKey, DecodePublicKey},
17 RsaPrivateKey, RsaPublicKey,
18};
19
20use crate::{error::NdnError, Data, KeyLocator, Name, SignatureInfo};
21
22#[derive(Tlv, Clone, Hash, Debug)]
25#[tlv(128)]
26pub struct SafeBag {
27 pub certificate: Data<Bytes>,
29 pub encrypted_key: EncryptedKey,
31}
32
33#[derive(Tlv, Clone, Hash, Debug)]
35#[tlv(129)]
36pub struct EncryptedKey {
37 pub data: Bytes,
39}
40
41#[derive(Clone, Debug, Hash)]
44pub struct Certificate(pub Data<Bytes>);
45
46pub trait ToCertificate {
49 fn to_certificate(&self) -> Certificate;
51}
52
53#[derive(Clone, Debug, Hash)]
57pub struct RsaCertificate {
58 cert: Certificate,
59 public_key: RsaPublicKey,
60 private_key: Option<RsaPrivateKey>,
61}
62
63impl RsaCertificate {
64 pub fn new(cert: Certificate) -> Option<Self> {
70 let key = RsaPublicKey::from_public_key_der(&cert.0.content()?).ok()?;
71 Some(Self {
72 cert,
73 public_key: key,
74 private_key: None,
75 })
76 }
77
78 pub fn with_private(cert: Certificate, private_key: RsaPrivateKey) -> Option<Self> {
84 let key = RsaPublicKey::from_public_key_der(&cert.0.content()?).ok()?;
85 Some(Self {
86 cert,
87 public_key: key,
88 private_key: Some(private_key),
89 })
90 }
91
92 pub fn from_safebag<P>(bag: SafeBag, password: P) -> Option<Self>
98 where
99 P: AsRef<[u8]>,
100 {
101 let key =
102 RsaPrivateKey::from_pkcs8_encrypted_der(&bag.encrypted_key.data, password).ok()?;
103 Self::with_private(Certificate(bag.certificate), key)
104 }
105
106 pub fn name(&self) -> &Name {
108 self.cert.name()
109 }
110
111 pub fn public_key(&self) -> &RsaPublicKey {
113 &self.public_key
114 }
115
116 pub fn private_key(&self) -> Option<&RsaPrivateKey> {
118 self.private_key.as_ref()
119 }
120}
121
122impl ToCertificate for RsaCertificate {
123 fn to_certificate(&self) -> Certificate {
124 self.cert.clone()
125 }
126}
127
128impl SafeBag {
129 pub fn load_file(path: impl AsRef<Path>) -> Result<Self, NdnError> {
132 let mut file_content = std::fs::read(path)?;
133 file_content.retain(|x| *x != b'\n' && *x != b'\r');
134 let safebag_data = base64::engine::general_purpose::STANDARD
135 .decode(&file_content)
136 .map_err(|_| {
137 NdnError::GenericError("Could not base64-decode certificate".to_string())
138 })?;
139 Ok(SafeBag::decode(&mut Bytes::from(safebag_data))?)
140 }
141}
142
143impl Certificate {
144 pub fn load_file<P>(path: P) -> Result<Self, NdnError>
147 where
148 P: AsRef<Path>,
149 {
150 let mut file_content = std::fs::read(path)?;
151 file_content.retain(|x| *x != b'\n' && *x != b'\r');
152 let safebag_data = base64::engine::general_purpose::STANDARD
153 .decode(&file_content)
154 .map_err(|_| {
155 NdnError::GenericError("Could not base64-decode certificate".to_string())
156 })?;
157 Ok(Self(Data::<Bytes>::decode(&mut Bytes::from(safebag_data))?))
158 }
159
160 pub fn name(&self) -> &Name {
162 self.0.name()
163 }
164
165 pub fn identity(&self) -> Name {
168 let mut name = self.name().clone();
169 name.components.pop();
170 name.components.pop();
171 name.components.pop();
172 name.components.pop();
173 name
174 }
175
176 pub fn name_locator(&self) -> KeyLocator {
179 KeyLocator::new(crate::signature::KeyLocatorData::Name(self.name().clone()))
180 }
181
182 pub fn as_data(&self) -> &Data<Bytes> {
184 &self.0
185 }
186
187 pub fn signature_info(&self) -> Option<&SignatureInfo> {
190 self.0.signature_info()
191 }
192}
193
194impl TlvEncode for Certificate {
195 fn encode(&self) -> Bytes {
196 self.0.encode()
197 }
198
199 fn size(&self) -> usize {
200 self.0.size()
201 }
202}
203
204impl TlvDecode for Certificate {
205 fn decode(bytes: &mut Bytes) -> ndn_tlv::Result<Self> {
206 Data::<Bytes>::decode(bytes).map(Self)
207 }
208}