hickory_proto/rr/rdata/
openpgpkey.rs

1// Copyright 2015-2023 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! OPENPGPKEY records for OpenPGP public keys
9use alloc::vec::Vec;
10use core::fmt;
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15use crate::{
16    error::ProtoResult,
17    rr::{RData, RecordData, RecordDataDecodable, RecordType},
18    serialize::binary::{BinDecoder, BinEncodable, BinEncoder, Restrict},
19};
20
21/// [RFC 7929](https://tools.ietf.org/html/rfc7929#section-2.1)
22///
23/// ```text
24/// The RDATA portion of an OPENPGPKEY resource record contains a single
25/// value consisting of a Transferable Public Key formatted as specified
26/// in [RFC4880].
27/// ```
28#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
29#[derive(Debug, PartialEq, Eq, Hash, Clone)]
30pub struct OPENPGPKEY {
31    public_key: Vec<u8>,
32}
33
34impl OPENPGPKEY {
35    /// Creates a new OPENPGPKEY record data.
36    ///
37    /// # Arguments
38    ///
39    /// * `public_key` - an OpenPGP Transferable Public Key. This will NOT
40    ///    be checked.
41    pub fn new(public_key: Vec<u8>) -> Self {
42        Self { public_key }
43    }
44
45    /// The public key. This should be an OpenPGP Transferable Public Key,
46    /// but this is not guaranteed.
47    pub fn public_key(&self) -> &[u8] {
48        &self.public_key
49    }
50}
51
52impl BinEncodable for OPENPGPKEY {
53    fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
54        encoder.emit_vec(self.public_key())
55    }
56}
57
58impl<'r> RecordDataDecodable<'r> for OPENPGPKEY {
59    fn read_data(decoder: &mut BinDecoder<'r>, length: Restrict<u16>) -> ProtoResult<Self> {
60        let rdata_length = length.map(usize::from).unverified();
61        let public_key =
62            decoder.read_vec(rdata_length)?.unverified(/*we do not enforce a specific format*/);
63        Ok(Self::new(public_key))
64    }
65}
66
67impl RecordData for OPENPGPKEY {
68    fn try_from_rdata(data: RData) -> Result<Self, RData> {
69        match data {
70            RData::OPENPGPKEY(csync) => Ok(csync),
71            _ => Err(data),
72        }
73    }
74
75    fn try_borrow(data: &RData) -> Option<&Self> {
76        match data {
77            RData::OPENPGPKEY(csync) => Some(csync),
78            _ => None,
79        }
80    }
81
82    fn record_type(&self) -> RecordType {
83        RecordType::OPENPGPKEY
84    }
85
86    fn into_rdata(self) -> RData {
87        RData::OPENPGPKEY(self)
88    }
89}
90
91/// Parse the RData from a set of tokens.
92///
93/// [RFC 7929](https://tools.ietf.org/html/rfc7929#section-2.3)
94///
95/// ```text
96/// 2.3.  The OPENPGPKEY RDATA Presentation Format
97///
98///    The RDATA Presentation Format, as visible in Zone Files [RFC1035],
99///    consists of a single OpenPGP Transferable Public Key as defined in
100///    Section 11.1 of [RFC4880] encoded in base64 as defined in Section 4
101///    of [RFC4648].
102/// ```
103impl fmt::Display for OPENPGPKEY {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
105        f.write_str(&data_encoding::BASE64.encode(&self.public_key))
106    }
107}
108
109// TODO test