openpgp.rs

  1// Copyright (c) 2019 Maxime “pep” Buquet <pep@bouah.net>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use xso::{text::Base64, AsXml, FromXml};
  8
  9use crate::date::DateTime;
 10use crate::ns;
 11use crate::pubsub::PubSubPayload;
 12
 13/// Data contained in the PubKey element
 14// TODO: Merge this container with the PubKey struct
 15#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 16#[xml(namespace = ns::OX, name = "data")]
 17pub struct PubKeyData {
 18    /// Base64 data
 19    #[xml(text = Base64)]
 20    pub data: Vec<u8>,
 21}
 22
 23/// Pubkey element to be used in PubSub publish payloads.
 24#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 25#[xml(namespace = ns::OX, name = "pubkey")]
 26pub struct PubKey {
 27    /// Last updated date
 28    #[xml(attribute(default))]
 29    pub date: Option<DateTime>,
 30
 31    /// Public key as base64 data
 32    #[xml(child)]
 33    pub data: PubKeyData,
 34}
 35
 36impl PubSubPayload for PubKey {}
 37
 38/// Public key metadata
 39#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 40#[xml(namespace = ns::OX, name = "pubkey-metadata")]
 41pub struct PubKeyMeta {
 42    /// OpenPGP v4 fingerprint
 43    #[xml(attribute = "v4-fingerprint")]
 44    pub v4fingerprint: String,
 45
 46    /// Time the key was published or updated
 47    #[xml(attribute = "date")]
 48    pub date: DateTime,
 49}
 50
 51/// List of public key metadata
 52#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 53#[xml(namespace = ns::OX, name = "public-key-list")]
 54pub struct PubKeysMeta {
 55    /// Public keys
 56    #[xml(child(n = ..))]
 57    pub pubkeys: Vec<PubKeyMeta>,
 58}
 59
 60impl PubSubPayload for PubKeysMeta {}
 61
 62#[cfg(test)]
 63mod tests {
 64    use super::*;
 65    use crate::ns;
 66    use crate::pubsub::{
 67        pubsub::{Item, Publish},
 68        NodeName,
 69    };
 70    use core::str::FromStr;
 71    use minidom::Element;
 72
 73    #[test]
 74    fn pubsub_publish_pubkey_data() {
 75        let pubkey = PubKey {
 76            date: None,
 77            data: PubKeyData {
 78                data: (&"Foo").as_bytes().to_vec(),
 79            },
 80        };
 81        println!("Foo1: {:?}", pubkey);
 82
 83        let pubsub = Publish {
 84            node: NodeName(format!("{}:{}", ns::OX_PUBKEYS, "some-fingerprint")),
 85            items: vec![Item::new(None, None, Some(pubkey))],
 86        };
 87        println!("Foo2: {:?}", pubsub);
 88    }
 89
 90    #[test]
 91    fn pubsub_publish_pubkey_meta() {
 92        let pubkeymeta = PubKeysMeta {
 93            pubkeys: vec![PubKeyMeta {
 94                v4fingerprint: "some-fingerprint".to_owned(),
 95                date: DateTime::from_str("2019-03-30T18:30:25Z").unwrap(),
 96            }],
 97        };
 98        println!("Foo1: {:?}", pubkeymeta);
 99
100        let pubsub = Publish {
101            node: NodeName("foo".to_owned()),
102            items: vec![Item::new(None, None, Some(pubkeymeta))],
103        };
104        println!("Foo2: {:?}", pubsub);
105    }
106
107    #[test]
108    fn test_serialize_pubkey() {
109        let reference: Element = "<pubkey xmlns='urn:xmpp:openpgp:0'><data>AAAA</data></pubkey>"
110            .parse()
111            .unwrap();
112
113        let pubkey = PubKey {
114            date: None,
115            data: PubKeyData {
116                data: b"\0\0\0".to_vec(),
117            },
118        };
119
120        let serialized: Element = pubkey.into();
121        assert_eq!(serialized, reference);
122    }
123}