1#[cfg(feature = "alloc")]
5use alloc::prelude::v1::*;
6
7use crate::base::Header;
8use crate::error::Error;
9use crate::options::{Options, OptionsError};
10use crate::types::*;
11use crate::wire::Container;
12
13#[derive(Clone, Debug)]
14pub struct Base {
15 pub(crate) id: Id,
17
18 pub(crate) header: Header,
20
21 pub(crate) body: Body,
23
24 pub(crate) private_options: PrivateOptions,
27
28 pub(crate) public_options: Vec<Options>,
30
31 pub(crate) parent: Option<Signature>,
35
36 pub(crate) public_key: Option<PublicKey>,
40
41 pub(crate) peer_id: Option<Id>,
45
46 pub(crate) signature: Option<Signature>,
48
49 pub(crate) verified: bool,
51
52 pub(crate) raw: Option<Vec<u8>>,
54}
55
56pub struct BaseOptions {
58 pub private_options: PrivateOptions,
60 pub public_options: Vec<Options>,
62 pub parent: Option<Signature>,
64 pub public_key: Option<PublicKey>,
66 pub peer_id: Option<Id>,
68 pub signature: Option<Signature>,
70 pub raw: Option<Vec<u8>>,
72}
73
74impl Default for BaseOptions {
75 fn default() -> Self {
76 Self {
77 private_options: PrivateOptions::None,
78 public_options: vec![],
79 parent: None,
80 public_key: None,
81 peer_id: None,
82 signature: None,
83 raw: None,
84 }
85 }
86}
87
88impl BaseOptions {
89 pub fn append_public_option(&mut self, o: Options) -> &mut Self {
90 self.public_options.push(o);
91 self
92 }
93
94 pub fn append_private_option(&mut self, o: Options) -> &mut Self {
95 match &mut self.private_options {
96 PrivateOptions::Cleartext(opts) => opts.push(o),
97 _ => self.private_options = PrivateOptions::Cleartext(vec![o]),
98 }
99 self
100 }
101}
102
103impl PartialEq for Base {
104 fn eq(&self, other: &Self) -> bool {
105 self.id == other.id
106 && self.header == other.header
107 && self.body == other.body
108 && self.private_options == other.private_options
109 && self.public_options == other.public_options
110 && self.parent == other.parent
111 && self.public_key == other.public_key
112 && self.peer_id == other.peer_id
113 && self.signature == other.signature
114 }
115}
116
117#[derive(PartialEq, Debug, Clone)]
118#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
119pub enum NewBody<T: ImmutableData> {
120 Cleartext(T),
121 Encrypted(T),
122 None,
123}
124
125impl Body {
126 pub fn decrypt(&mut self, secret_key: Option<&SecretKey>) -> Result<(), Error> {
128 let body = match (&self, &secret_key) {
129 (NewBody::Cleartext(b), _) => b.to_vec(),
130 (NewBody::Encrypted(e), Some(sk)) => {
131 let mut d = e.to_vec();
132
133 let n = match crate::crypto::sk_decrypt2(sk, &mut d) {
134 Ok(n) => n,
135 Err(_) => return Err(Error::SecretKeyMismatch),
136 };
137
138 d.truncate(n);
139
140 d
141 }
142 _ => return Err(Error::NoSecretKey),
143 };
144
145 *self = Self::Cleartext(body);
146
147 Ok(())
148 }
149}
150
151pub type Body = NewBody<Vec<u8>>;
154
155impl From<Vec<u8>> for Body {
156 fn from(o: Vec<u8>) -> Self {
157 if o.len() > 0 {
158 Body::Cleartext(o)
159 } else {
160 Body::None
161 }
162 }
163}
164
165impl From<Option<Body>> for Body {
166 fn from(o: Option<Body>) -> Self {
167 match o {
168 Some(b) => b,
169 None => Body::None,
170 }
171 }
172}
173
174pub type PrivateOptions = crate::options::OptionsList<Vec<Options>, Vec<u8>>;
176
177impl From<Vec<Options>> for PrivateOptions {
178 fn from(o: Vec<Options>) -> Self {
179 if o.len() > 0 {
180 PrivateOptions::Cleartext(o)
181 } else {
182 PrivateOptions::None
183 }
184 }
185}
186
187impl PrivateOptions {
188 pub fn append(&mut self, o: Options) {
189 match self {
190 PrivateOptions::Cleartext(opts) => opts.push(o),
191 PrivateOptions::None => *self = PrivateOptions::Cleartext(vec![o]),
192 _ => panic!("attmepting to append private options to encrypted object"),
193 }
194 }
195}
196
197#[derive(PartialEq, Debug, Clone)]
198#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
199pub enum BaseError {
200 Io,
201 Options(OptionsError),
202 InvalidSignature,
203 NoPublicKey,
204 NoPrivateKey,
205 NoPeerId,
206 ValidateError,
207 DecryptError,
208 NoDecryptionKey,
209 PublicKeyIdMismatch,
210}
211
212use crate::net;
213use crate::page;
214
215pub enum Parent<'a, 'b, 'c> {
216 None,
217 Page(&'a page::Page),
218 Request(&'b net::Request),
219 Response(&'c net::Response),
220}
221
222impl From<OptionsError> for BaseError {
223 fn from(o: OptionsError) -> BaseError {
224 BaseError::Options(o)
225 }
226}
227
228#[cfg(feature = "std")]
229impl From<std::io::Error> for BaseError {
230 fn from(e: std::io::Error) -> BaseError {
231 error!("io error: {}", e);
232 BaseError::Io
233 }
234}
235
236impl Base {
237 pub fn new(id: Id, header: Header, body: Body, options: BaseOptions) -> Self {
239 Self {
240 id,
241 header,
242 body,
243 private_options: options.private_options,
244 public_options: options.public_options,
245 parent: options.parent,
246 public_key: options.public_key,
247 peer_id: options.peer_id,
248 signature: options.signature,
249 verified: false,
250 raw: options.raw,
251 }
252 }
253
254 pub fn id(&self) -> &Id {
255 &self.id
256 }
257
258 pub fn header(&self) -> &Header {
259 &self.header
260 }
261
262 pub fn flags(&self) -> Flags {
263 self.header.flags()
264 }
265
266 pub fn body(&self) -> &Body {
267 &self.body
268 }
269
270 pub fn public_options(&self) -> &[Options] {
271 &self.public_options
272 }
273
274 pub fn private_options(&self) -> &PrivateOptions {
275 &self.private_options
276 }
277
278 pub fn signature(&self) -> &Option<Signature> {
279 &self.signature
280 }
281
282 pub fn set_signature(&mut self, sig: Signature) {
283 self.signature = Some(sig);
284 }
285
286 pub fn append_public_option(&mut self, o: Options) {
287 self.public_options.push(o);
288 }
289
290 pub fn append_private_option(&mut self, o: Options) {
291 match &mut self.private_options {
292 PrivateOptions::Cleartext(opts) => opts.push(o),
293 PrivateOptions::None => self.private_options = PrivateOptions::Cleartext(vec![o]),
294 _ => panic!("attmepting to append private options to encrypted object"),
295 }
296 }
297
298 pub fn clean(&mut self) {}
299}
300
301impl Base {
303 pub fn pub_key_option(options: &[Options]) -> Option<PublicKey> {
304 options.iter().find_map(|o| match o {
305 Options::PubKey(pk) => Some(pk.public_key.clone()),
306 _ => None,
307 })
308 }
309
310 pub fn peer_id_option(options: &[Options]) -> Option<Id> {
311 options.iter().find_map(|o| match o {
312 Options::PeerId(peer_id) => Some(peer_id.peer_id.clone()),
313 _ => None,
314 })
315 }
316
317 pub fn issued_option(options: &[Options]) -> Option<DateTime> {
318 options.iter().find_map(|o| match o {
319 Options::Issued(t) => Some(t.when),
320 _ => None,
321 })
322 }
323
324 pub fn expiry_option(options: &[Options]) -> Option<DateTime> {
325 options.iter().find_map(|o| match o {
326 Options::Expiry(t) => Some(t.when),
327 _ => None,
328 })
329 }
330
331 pub fn prev_sig_option(options: &[Options]) -> Option<Signature> {
332 options.iter().find_map(|o| match o {
333 Options::PrevSig(s) => Some(s.sig.clone()),
334 _ => None,
335 })
336 }
337
338 pub fn address_option(options: &[Options]) -> Option<Address> {
339 options.iter().find_map(|o| match o {
340 Options::IPv4(addr) => Some(addr.clone().into()),
341 Options::IPv6(addr) => Some(addr.clone().into()),
342 _ => None,
343 })
344 }
345
346 pub fn raw(&self) -> &Option<Vec<u8>> {
347 &self.raw
348 }
349
350 pub fn set_raw(&mut self, raw: Vec<u8>) {
351 self.raw = Some(raw);
352 }
353}
354
355impl Base {
356 pub fn parse<'a, P, S, T: AsRef<[u8]>>(
359 data: T,
360 pub_key_s: P,
361 sec_key_s: S,
362 ) -> Result<(Base, usize), BaseError>
363 where
364 P: FnMut(&Id) -> Option<PublicKey>,
365 S: FnMut(&Id) -> Option<SecretKey>,
366 {
367 Container::parse(data, pub_key_s, sec_key_s)
368 }
369}
370
371impl Base {
372 pub fn encode<'a, T: AsRef<[u8]> + AsMut<[u8]>>(
373 &mut self,
374 signing_key: Option<&PrivateKey>,
375 encryption_key: Option<&SecretKey>,
376 mut buff: T,
377 ) -> Result<usize, BaseError> {
378 if let Some(raw) = &self.raw {
380 let d = buff.as_mut();
381
382 &mut d[0..raw.len()].copy_from_slice(&raw);
383
384 return Ok(raw.len());
385 }
386
387 let signing_key = match signing_key {
388 Some(k) => k,
389 None => return Err(BaseError::NoPrivateKey),
390 };
391
392 let (container, n) = Container::encode(buff, &self, signing_key, encryption_key);
394
395 self.set_signature(container.signature().into());
397
398 Ok(n)
399 }
400}
401
402#[cfg(test)]
403mod tests {
404
405 use super::*;
406 use crate::base::*;
407 use crate::types::PageKind;
408
409 use crate::crypto;
410
411 fn setup() -> (Id, PublicKey, PrivateKey, SecretKey) {
412 let (pub_key, pri_key) =
413 crypto::new_pk().expect("Error generating new public/private key pair");
414 let id = crypto::hash(&pub_key)
415 .expect("Error generating new ID")
416 .into();
417 let sec_key = crypto::new_sk().expect("Error generating new secret key");
418 (id, pub_key, pri_key, sec_key)
419 }
420
421 #[test]
422 fn encode_decode_primary_page() {
423 let (id, pub_key, pri_key, _sec_key) = setup();
424
425 let header = Header {
426 kind: PageKind::Generic.into(),
427 ..Default::default()
428 };
429 let data = vec![1, 2, 3, 4, 5, 6, 7];
430
431 let mut page = Base::new(id, header, Body::Cleartext(data), BaseOptions::default());
432
433 let mut buff = vec![0u8; 1024];
434 let n = page
435 .encode(Some(&pri_key), None, &mut buff)
436 .expect("Error encoding page");
437
438 let (mut decoded, m) = Base::parse(&buff[..n], |_id| Some(pub_key.clone()), |_id| None)
439 .expect("Error decoding page");
440
441 decoded.clean();
442
443 assert_eq!(page, decoded);
444 assert_eq!(n, m);
445 }
446
447 #[test]
448 fn encode_decode_secondary_page() {
449 let (id, pub_key, pri_key, _sec_key) = setup();
450
451 let header = Header {
452 kind: PageKind::Replica.into(),
453 flags: Flags::SECONDARY,
454 ..Default::default()
455 };
456 let data = vec![1, 2, 3, 4, 5, 6, 7];
457
458 let mut page = Base::new(
459 id.clone(),
460 header,
461 Body::Cleartext(data),
462 BaseOptions {
463 peer_id: Some(id.clone()),
464 public_key: Some(pub_key.clone()),
465 ..Default::default()
466 },
467 );
468
469 let mut buff = vec![0u8; 1024];
470 let n = page
471 .encode(Some(&pri_key), None, &mut buff)
472 .expect("Error encoding page");
473 page.raw = Some(buff[..n].to_vec());
474
475 let (mut decoded, m) = Base::parse(&buff[..n], |_id| Some(pub_key.clone()), |_id| None)
476 .expect("Error decoding page with known public key");
477
478 decoded.clean();
479 assert_eq!(page, decoded);
480 assert_eq!(n, m);
481
482 let (mut decoded, m) = Base::parse(&buff[..n], |_id| None, |_id| None)
483 .expect("Error decoding page with unknown public key");
484
485 decoded.clean();
486 assert_eq!(page, decoded);
487 assert_eq!(n, m);
488 }
489
490 #[test]
491 fn encode_decode_encrypted_page() {
492 let (id, pub_key, pri_key, sec_key) = setup();
493
494 let header = Header {
495 kind: PageKind::Generic.into(),
496 flags: Flags::ENCRYPTED,
497 ..Default::default()
498 };
499 let data = vec![1, 2, 3, 4, 5, 6, 7];
500
501 let mut page = Base::new(id, header, Body::Cleartext(data), BaseOptions::default());
502
503 let mut buff = vec![0u8; 1024];
504 let n = page
505 .encode(Some(&pri_key), Some(&sec_key), &mut buff)
506 .expect("Error encoding page");
507
508 let (mut decoded, m) = Base::parse(
509 &buff[..n],
510 |_id| Some(pub_key.clone()),
511 |_id| Some(sec_key.clone()),
512 )
513 .expect("Error decoding page");
514
515 decoded.clean();
516
517 assert_eq!(page, decoded);
518 assert_eq!(n, m);
519 }
520}