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