hickory_proto/dnssec/rdata/key.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//! public key record data for signing zone records
9#![allow(clippy::use_self)]
10
11use alloc::{sync::Arc, vec::Vec};
12use core::fmt;
13
14#[cfg(feature = "serde")]
15use serde::{Deserialize, Serialize};
16
17use super::DNSSECRData;
18use crate::{
19 dnssec::{Algorithm, PublicKey, Verifier, crypto::decode_public_key},
20 error::ProtoResult,
21 rr::{RecordData, RecordDataDecodable, RecordType, record_data::RData},
22 serialize::binary::{
23 BinDecodable, BinDecoder, BinEncodable, BinEncoder, DecodeError, Restrict, RestrictedMath,
24 },
25};
26
27/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-3), Domain Name System Security Extensions, March 1999
28///
29/// ```text
30/// 3. The KEY Resource Record
31///
32/// The KEY resource record (RR) is used to store a public key that is
33/// associated with a Domain Name System (DNS) name. This can be the
34/// public key of a zone, a user, or a host or other end entity. Security
35/// aware DNS implementations MUST be designed to handle at least two
36/// simultaneously valid keys of the same type associated with the same
37/// name.
38///
39/// The type number for the KEY RR is 25.
40///
41/// A KEY RR is, like any other RR, authenticated by a SIG RR. KEY RRs
42/// must be signed by a zone level key.
43///
44/// 3.1 KEY RDATA format
45///
46/// The RDATA for a KEY RR consists of flags, a protocol octet, the
47/// algorithm number octet, and the public key itself. The format is as
48/// follows:
49///
50/// 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
51/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
52/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53/// | flags | protocol | algorithm |
54/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55/// | /
56/// / public key /
57/// / /
58/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
59///
60/// The KEY RR is not intended for storage of certificates and a separate
61/// certificate RR has been developed for that purpose, defined in [RFC
62/// 2538].
63///
64/// The meaning of the KEY RR owner name, flags, and protocol octet are
65/// described in Sections 3.1.1 through 3.1.5 below. The flags and
66/// algorithm must be examined before any data following the algorithm
67/// octet as they control the existence and format of any following data.
68/// The algorithm and public key fields are described in Section 3.2.
69/// The format of the public key is algorithm dependent.
70///
71/// KEY RRs do not specify their validity period but their authenticating
72/// SIG RR(s) do as described in Section 4 below.
73///
74/// 3.1.1 Object Types, DNS Names, and Keys
75///
76/// The public key in a KEY RR is for the object named in the owner name.
77///
78/// A DNS name may refer to three different categories of things. For
79/// example, foo.host.example could be (1) a zone, (2) a host or other
80/// end entity , or (3) the mapping into a DNS name of the user or
81/// account foo@host.example. Thus, there are flag bits, as described
82/// below, in the KEY RR to indicate with which of these roles the owner
83/// name and public key are associated. Note that an appropriate zone
84/// KEY RR MUST occur at the apex node of a secure zone and zone KEY RRs
85/// occur only at delegation points.
86///
87/// 3.1.2 The KEY RR Flag Field
88///
89/// In the "flags" field:
90///
91/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
92/// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
93/// | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG |
94/// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
95///
96/// Bit 0 and 1 are the key "type" bits whose values have the following
97/// meanings:
98///
99/// 10: Use of the key is prohibited for authentication.
100/// 01: Use of the key is prohibited for confidentiality.
101/// 00: Use of the key for authentication and/or confidentiality
102/// is permitted. Note that DNS security makes use of keys
103/// for authentication only. Confidentiality use flagging is
104/// provided for use of keys in other protocols.
105/// Implementations not intended to support key distribution
106/// for confidentiality MAY require that the confidentiality
107/// use prohibited bit be on for keys they serve.
108/// 11: If both bits are one, the "no key" value, there is no key
109/// information and the RR stops after the algorithm octet.
110/// By the use of this "no key" value, a signed KEY RR can
111/// authentically assert that, for example, a zone is not
112/// secured. See section 3.4 below.
113///
114/// Bits 2 is reserved and must be zero.
115///
116/// Bits 3 is reserved as a flag extension bit. If it is a one, a second
117/// 16 bit flag field is added after the algorithm octet and
118/// before the key data. This bit MUST NOT be set unless one or
119/// more such additional bits have been defined and are non-zero.
120///
121/// Bits 4-5 are reserved and must be zero.
122///
123/// Bits 6 and 7 form a field that encodes the name type. Field values
124/// have the following meanings:
125///
126/// 00: indicates that this is a key associated with a "user" or
127/// "account" at an end entity, usually a host. The coding
128/// of the owner name is that used for the responsible
129/// individual mailbox in the SOA and RP RRs: The owner name
130/// is the user name as the name of a node under the entity
131/// name. For example, "j_random_user" on
132/// host.subdomain.example could have a public key associated
133/// through a KEY RR with name
134/// j_random_user.host.subdomain.example. It could be used
135/// in a security protocol where authentication of a user was
136/// desired. This key might be useful in IP or other
137/// security for a user level service such a telnet, ftp,
138/// rlogin, etc.
139/// 01: indicates that this is a zone key for the zone whose name
140/// is the KEY RR owner name. This is the public key used
141/// for the primary DNS security feature of data origin
142/// authentication. Zone KEY RRs occur only at delegation
143/// points.
144/// 10: indicates that this is a key associated with the non-zone
145/// "entity" whose name is the RR owner name. This will
146/// commonly be a host but could, in some parts of the DNS
147/// tree, be some other type of entity such as a telephone
148/// number [RFC 1530] or numeric IP address. This is the
149/// public key used in connection with DNS request and
150/// transaction authentication services. It could also be
151/// used in an IP-security protocol where authentication at
152/// the host, rather than user, level was desired, such as
153/// routing, NTP, etc.
154/// 11: reserved.
155///
156/// Bits 8-11 are reserved and must be zero.
157///
158/// Bits 12-15 are the "signatory" field. If non-zero, they indicate
159/// that the key can validly sign things as specified in DNS
160/// dynamic update [RFC 2137]. Note that zone keys (see bits
161/// 6 and 7 above) always have authority to sign any RRs in
162/// the zone regardless of the value of the signatory field.
163/// ```
164#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
165#[derive(Debug, PartialEq, Eq, Hash, Clone)]
166pub struct KEY {
167 key_trust: KeyTrust,
168 key_usage: KeyUsage,
169 signatory: UpdateScope,
170 protocol: Protocol,
171 algorithm: Algorithm,
172 public_key: Vec<u8>,
173}
174
175impl KEY {
176 /// Construct a new KEY RData
177 ///
178 /// # Arguments
179 ///
180 /// * `key_trust` - declare the security level of this key
181 /// * `key_usage` - what type of thing is this key associated to
182 /// * `revoke` - this key has been revoked
183 /// * `algorithm` - specifies the algorithm which this Key uses to sign records
184 /// * `public_key` - the public key material, in native endian, the emitter will perform any necessary conversion
185 ///
186 /// # Return
187 ///
188 /// A new KEY RData for use in a Resource Record
189 pub fn new(
190 key_trust: KeyTrust,
191 key_usage: KeyUsage,
192 signatory: UpdateScope,
193 protocol: Protocol,
194 algorithm: Algorithm,
195 public_key: Vec<u8>,
196 ) -> Self {
197 Self {
198 key_trust,
199 key_usage,
200 signatory,
201 protocol,
202 algorithm,
203 public_key,
204 }
205 }
206
207 /// Returns the trust level of the key
208 pub fn key_trust(&self) -> KeyTrust {
209 self.key_trust
210 }
211
212 /// Returns the entity type using this key
213 pub fn key_usage(&self) -> KeyUsage {
214 self.key_usage
215 }
216
217 /// Returns the signatory information of the KEY
218 pub fn signatory(&self) -> UpdateScope {
219 self.signatory
220 }
221
222 /// Returns true if the key_trust is DoNotTrust
223 pub fn revoke(&self) -> bool {
224 self.key_trust == KeyTrust::DoNotTrust
225 }
226
227 /// Returns the protocol which this key can be used with
228 pub fn protocol(&self) -> Protocol {
229 self.protocol
230 }
231
232 /// [RFC 4034, DNSSEC Resource Records, March 2005](https://tools.ietf.org/html/rfc4034#section-2.1.3)
233 ///
234 /// ```text
235 /// 2.1.3. The Algorithm Field
236 ///
237 /// The Algorithm field identifies the public key's cryptographic
238 /// algorithm and determines the format of the Public Key field. A list
239 /// of DNSSEC algorithm types can be found in Appendix A.1
240 /// ```
241 pub fn algorithm(&self) -> Algorithm {
242 self.algorithm
243 }
244
245 /// [RFC 4034, DNSSEC Resource Records, March 2005](https://tools.ietf.org/html/rfc4034#section-2.1.4)
246 ///
247 /// ```text
248 /// 2.1.4. The Public Key Field
249 ///
250 /// The Public Key Field holds the public key material. The format
251 /// depends on the algorithm of the key being stored and is described in
252 /// separate documents.
253 /// ```
254 pub fn public_key(&self) -> &[u8] {
255 &self.public_key
256 }
257
258 /// Output the encoded form of the flags
259 pub fn flags(&self) -> u16 {
260 let mut flags: u16 = 0;
261 flags |= u16::from(self.key_trust);
262 flags |= u16::from(self.key_usage);
263 flags |= u16::from(self.signatory);
264
265 flags
266 }
267
268 // /// Creates a message digest for this KEY record.
269 // ///
270 // /// ```text
271 // /// 5.1.4. The Digest Field
272 // ///
273 // /// The DS record refers to a KEY RR by including a digest of that
274 // /// KEY RR.
275 // ///
276 // /// The digest is calculated by concatenating the canonical form of the
277 // /// fully qualified owner name of the KEY RR with the KEY RDATA,
278 // /// and then applying the digest algorithm.
279 // ///
280 // /// digest = digest_algorithm( KEY owner name | KEY RDATA);
281 // ///
282 // /// "|" denotes concatenation
283 // ///
284 // /// KEY RDATA = Flags | Protocol | Algorithm | Public Key.
285 // ///
286 // /// The size of the digest may vary depending on the digest algorithm and
287 // /// KEY RR size. As of the time of this writing, the only defined
288 // /// digest algorithm is SHA-1, which produces a 20 octet digest.
289 // /// ```
290 // ///
291 // /// # Arguments
292 // ///
293 // /// * `name` - the label of of the KEY record.
294 // /// * `digest_type` - the `DigestType` with which to create the message digest.
295 // pub fn to_digest(&self, name: &Name, digest_type: DigestType) -> ProtoResult<Vec<u8>> {
296 // let mut buf: Vec<u8> = Vec::new();
297 // {
298 // let mut encoder: BinEncoder = BinEncoder::new(&mut buf);
299 // encoder.set_canonical_names(true);
300 // if let Err(e) = name.emit(&mut encoder)
301 // .and_then(|_| emit(&mut encoder, self)) {
302 // warn!("error serializing KEY: {}", e);
303 // return Err(format!("error serializing KEY: {}", e).into());
304 // }
305 // }
306
307 // digest_type.hash(&buf).map_err(|e| e.into())
308 // }
309}
310
311impl Verifier for KEY {
312 fn algorithm(&self) -> Algorithm {
313 self.algorithm()
314 }
315
316 fn key(&self) -> ProtoResult<Arc<dyn PublicKey + '_>> {
317 decode_public_key(&self.public_key, self.algorithm)
318 }
319}
320
321impl BinEncodable for KEY {
322 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
323 encoder.emit_u16(self.flags())?;
324 encoder.emit(u8::from(self.protocol))?;
325 self.algorithm().emit(encoder)?;
326 encoder.emit_vec(self.public_key())?;
327
328 Ok(())
329 }
330}
331
332impl<'r> RecordDataDecodable<'r> for KEY {
333 fn read_data(decoder: &mut BinDecoder<'r>, length: Restrict<u16>) -> Result<Self, DecodeError> {
334 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
335 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
336 // | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG |
337 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
338 let flags: u16 = decoder
339 .read_u16()?
340 .verify_unwrap(|flags| {
341 // Bits 2 is reserved and must be zero.
342 // Bits 4-5 are reserved and must be zero.
343 // Bits 8-11 are reserved and must be zero.
344 flags & 0b0010_1100_1111_0000 == 0
345 })
346 .map_err(DecodeError::KeyFlagsReserved)?;
347
348 let key_trust = KeyTrust::from(flags);
349 let extended_flags: bool = flags & 0b0001_0000_0000_0000 != 0;
350 let key_usage = KeyUsage::from(flags);
351 let signatory = UpdateScope::from(flags);
352
353 if extended_flags {
354 return Err(DecodeError::ExtendedKeyFlagsUnsupported(flags));
355 }
356
357 // TODO: protocol my be infallible
358 let protocol =
359 Protocol::from(decoder.read_u8()?.unverified(/*Protocol is verified as safe*/));
360
361 let algorithm: Algorithm = Algorithm::read(decoder)?;
362
363 // the public key is the left-over bytes minus 4 for the first fields
364 // TODO: decode the key here?
365 let key_len = length
366 .map(|u| u as usize)
367 .checked_sub(4)
368 .map_err(|len| DecodeError::IncorrectRDataLengthRead { read: 4, len })?
369 .unverified(/*used only as length safely*/);
370 let public_key: Vec<u8> =
371 decoder.read_vec(key_len)?.unverified(/*the byte array will fail in usage if invalid*/);
372
373 Ok(Self::new(
374 key_trust, key_usage, signatory, protocol, algorithm, public_key,
375 ))
376 }
377}
378
379impl RecordData for KEY {
380 fn try_borrow(data: &RData) -> Option<&Self> {
381 match data {
382 RData::DNSSEC(DNSSECRData::KEY(csync)) => Some(csync),
383 _ => None,
384 }
385 }
386
387 fn record_type(&self) -> RecordType {
388 RecordType::KEY
389 }
390
391 fn into_rdata(self) -> RData {
392 RData::DNSSEC(DNSSECRData::KEY(self))
393 }
394}
395
396/// Note that KEY is a deprecated type in DNS
397///
398/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-7.1), Domain Name System Security Extensions, March 1999
399///
400/// ```text
401/// 7.1 Presentation of KEY RRs
402///
403/// KEY RRs may appear as single logical lines in a zone data master file
404/// [RFC 1033].
405///
406/// The flag field is represented as an unsigned integer or a sequence of
407/// mnemonics as follows separated by instances of the vertical bar ("|")
408/// character:
409///
410/// BIT Mnemonic Explanation
411/// 0-1 key type
412/// NOCONF =1 confidentiality use prohibited
413/// NOAUTH =2 authentication use prohibited
414/// NOKEY =3 no key present
415/// 2 FLAG2 - reserved
416/// 3 EXTEND flags extension
417/// 4 FLAG4 - reserved
418/// 5 FLAG5 - reserved
419/// 6-7 name type
420/// USER =0 (default, may be omitted)
421/// ZONE =1
422/// HOST =2 (host or other end entity)
423/// NTYP3 - reserved
424/// 8 FLAG8 - reserved
425/// 9 FLAG9 - reserved
426/// 10 FLAG10 - reserved
427/// 11 FLAG11 - reserved
428/// 12-15 signatory field, values 0 to 15
429/// can be represented by SIG0, SIG1, ... SIG15
430///
431/// No flag mnemonic need be present if the bit or field it represents is
432/// zero.
433///
434/// The protocol octet can be represented as either an unsigned integer
435/// or symbolically. The following initial symbols are defined:
436///
437/// 000 NONE
438/// 001 TLS
439/// 002 EMAIL
440/// 003 DNSSEC
441/// 004 IPSEC
442/// 255 ALL
443///
444/// Note that if the type flags field has the NOKEY value, nothing
445/// appears after the algorithm octet.
446///
447/// The remaining public key portion is represented in base 64 (see
448/// Appendix A) and may be divided up into any number of white space
449/// separated substrings, down to single base 64 digits, which are
450/// concatenated to obtain the full signature. These substrings can span
451/// lines using the standard parenthesis.
452///
453/// Note that the public key may have internal sub-fields but these do
454/// not appear in the master file representation. For example, with
455/// algorithm 1 there is a public exponent size, then a public exponent,
456/// and then a modulus. With algorithm 254, there will be an OID size,
457/// an OID, and algorithm dependent information. But in both cases only a
458/// single logical base 64 string will appear in the master file.
459/// ```
460impl fmt::Display for KEY {
461 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
462 write!(
463 f,
464 "{flags} {proto} {alg} {key}",
465 flags = self.flags(),
466 proto = u8::from(self.protocol),
467 alg = self.algorithm,
468 key = data_encoding::BASE64.encode(&self.public_key)
469 )
470 }
471}
472
473impl From<KEY> for RData {
474 fn from(key: KEY) -> Self {
475 Self::DNSSEC(DNSSECRData::KEY(key))
476 }
477}
478
479/// Specifies in what contexts this key may be trusted for use
480#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
481#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
482pub enum KeyTrust {
483 /// Use of the key is prohibited for authentication
484 NotAuth,
485 /// Use of the key is prohibited for confidentiality
486 NotPrivate,
487 /// Use of the key for authentication and/or confidentiality is permitted
488 #[default]
489 AuthOrPrivate,
490 /// If both bits are one, the "no key" value, (revocation?)
491 DoNotTrust,
492}
493
494impl From<u16> for KeyTrust {
495 fn from(flags: u16) -> Self {
496 // we only care about the first two bits, zero out the rest
497 match flags & 0b1100_0000_0000_0000 {
498 // 10: Use of the key is prohibited for authentication.
499 0b1000_0000_0000_0000 => Self::NotAuth,
500 // 01: Use of the key is prohibited for confidentiality.
501 0b0100_0000_0000_0000 => Self::NotPrivate,
502 // 00: Use of the key for authentication and/or confidentiality
503 0b0000_0000_0000_0000 => Self::AuthOrPrivate,
504 // 11: If both bits are one, the "no key" value, there is no key
505 0b1100_0000_0000_0000 => Self::DoNotTrust,
506 _ => panic!("All other bit fields should have been cleared"),
507 }
508 }
509}
510
511impl From<KeyTrust> for u16 {
512 fn from(key_trust: KeyTrust) -> Self {
513 match key_trust {
514 // 10: Use of the key is prohibited for authentication.
515 KeyTrust::NotAuth => 0b1000_0000_0000_0000,
516 // 01: Use of the key is prohibited for confidentiality.
517 KeyTrust::NotPrivate => 0b0100_0000_0000_0000,
518 // 00: Use of the key for authentication and/or confidentiality
519 KeyTrust::AuthOrPrivate => 0b0000_0000_0000_0000,
520 // 11: If both bits are one, the "no key" value, there is no key
521 KeyTrust::DoNotTrust => 0b1100_0000_0000_0000,
522 }
523 }
524}
525
526/// Declares what this key is for
527#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
528#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
529pub enum KeyUsage {
530 /// key associated with a "user" or "account" at an end entity, usually a host
531 Host,
532 /// zone key for the zone whose name is the KEY RR owner name
533 #[deprecated = "For Zone signing DNSKEY should be used"]
534 Zone,
535 /// associated with the non-zone "entity" whose name is the RR owner name
536 #[default]
537 Entity,
538 /// Reserved
539 Reserved,
540}
541
542impl From<u16> for KeyUsage {
543 fn from(flags: u16) -> Self {
544 // we only care about the 6&7 two bits, zero out the rest
545 match flags & 0b0000_0011_0000_0000 {
546 // 00: indicates that this is a key associated with a "user" or
547 0b0000_0000_0000_0000 => Self::Host,
548 // 01: indicates that this is a zone key for the zone whose name
549 0b0000_0001_0000_0000 => Self::Zone,
550 // 10: indicates that this is a key associated with the non-zone
551 0b0000_0010_0000_0000 => Self::Entity,
552 // 11: reserved.
553 0b0000_0011_0000_0000 => Self::Reserved,
554 _ => panic!("All other bit fields should have been cleared"),
555 }
556 }
557}
558
559impl From<KeyUsage> for u16 {
560 fn from(key_usage: KeyUsage) -> Self {
561 match key_usage {
562 // 00: indicates that this is a key associated with a "user" or
563 KeyUsage::Host => 0b0000_0000_0000_0000,
564 // 01: indicates that this is a zone key for the zone whose name
565 KeyUsage::Zone => 0b0000_0001_0000_0000,
566 // 10: indicates that this is a key associated with the non-zone
567 KeyUsage::Entity => 0b0000_0010_0000_0000,
568 // 11: reserved.
569 KeyUsage::Reserved => 0b0000_0011_0000_0000,
570 }
571 }
572}
573
574/// [RFC 2137](https://tools.ietf.org/html/rfc2137#section-3.1), Secure Domain Name System Dynamic Update, April 1997
575///
576/// ```text
577/// 3.1.1 Update Key Name Scope
578///
579/// The owner name of any update authorizing KEY RR must (1) be the same
580/// as the owner name of any RRs being added or deleted or (2) a wildcard
581/// name including within its extended scope (see section 3.3) the name
582/// of any RRs being added or deleted and those RRs must be in the same
583/// zone.
584///
585/// 3.1.2 Update Key Class Scope
586///
587/// The class of any update authorizing KEY RR must be the same as the
588/// class of any RR's being added or deleted.
589///
590/// 3.1.3 Update Key Signatory Field
591///
592/// The four bit "signatory field" (see RFC 2065) of any update
593/// authorizing KEY RR must be non-zero. The bits have the meanings
594/// described below for non-zone keys (see section 3.2 for zone type
595/// keys).
596///
597/// UPDATE KEY RR SIGNATORY FIELD BITS
598///
599/// 0 1 2 3
600/// +-----------+-----------+-----------+-----------+
601/// | zone | strong | unique | general |
602/// +-----------+-----------+-----------+-----------+
603///
604/// Bit 0, zone control - If nonzero, this key is authorized to attach,
605/// detach, and move zones by creating and deleting NS, glue A, and
606/// zone KEY RR(s). If zero, the key can not authorize any update
607/// that would effect such RRs. This bit is meaningful for both
608/// type A and type B dynamic secure zones.
609///
610/// NOTE: do not confuse the "zone" signatory field bit with the
611/// "zone" key type bit.
612///
613/// Bit 1, strong update - If nonzero, this key is authorized to add and
614/// delete RRs even if there are other RRs with the same owner name
615/// and class that are authenticated by a SIG signed with a
616/// different dynamic update KEY. If zero, the key can only
617/// authorize updates where any existing RRs of the same owner and
618/// class are authenticated by a SIG using the same key. This bit
619/// is meaningful only for type A dynamic zones and is ignored in
620/// type B dynamic zones.
621///
622/// Keeping this bit zero on multiple KEY RRs with the same or
623/// nested wild card owner names permits multiple entities to exist
624/// that can create and delete names but can not effect RRs with
625/// different owner names from any they created. In effect, this
626/// creates two levels of dynamic update key, strong and weak, where
627/// weak keys are limited in interfering with each other but a
628/// strong key can interfere with any weak keys or other strong
629/// keys.
630///
631/// Bit 2, unique name update - If nonzero, this key is authorized to add
632/// and update RRs for only a single owner name. If there already
633/// exist RRs with one or more names signed by this key, they may be
634/// updated but no new name created until the number of existing
635/// names is reduced to zero. This bit is meaningful only for mode
636/// A dynamic zones and is ignored in mode B dynamic zones. This bit
637/// is meaningful only if the owner name is a wildcard. (Any
638/// dynamic update KEY with a non-wildcard name is, in effect, a
639/// unique name update key.)
640///
641/// This bit can be used to restrict a KEY from flooding a zone with
642/// new names. In conjunction with a local administratively imposed
643/// limit on the number of dynamic RRs with a particular name, it
644/// can completely restrict a KEY from flooding a zone with RRs.
645///
646/// Bit 3, general update - The general update signatory field bit has no
647/// special meaning. If the other three bits are all zero, it must
648/// be one so that the field is non-zero to designate that the key
649/// is an update key. The meaning of all values of the signatory
650/// field with the general bit and one or more other signatory field
651/// bits on is reserved.
652///
653/// All the signatory bit update authorizations described above only
654/// apply if the update is within the name and class scope as per
655/// sections 3.1.1 and 3.1.2.
656/// ```
657///
658/// [RFC 3007](https://tools.ietf.org/html/rfc3007#section-1.5), Secure Dynamic Update, November 2000
659///
660/// ```text
661/// [RFC2535, section 3.1.2] defines the signatory field of a key as the
662/// final 4 bits of the flags field, but does not define its value. This
663/// proposal leaves this field undefined. Updating [RFC2535], this field
664/// SHOULD be set to 0 in KEY records, and MUST be ignored.
665///
666/// ```
667#[deprecated = "Deprecated by RFC3007"]
668#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
669#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
670pub struct UpdateScope {
671 /// this key is authorized to attach,
672 /// detach, and move zones by creating and deleting NS, glue A, and
673 /// zone KEY RR(s)
674 pub zone: bool,
675 /// this key is authorized to add and
676 /// delete RRs even if there are other RRs with the same owner name
677 /// and class that are authenticated by a SIG signed with a
678 /// different dynamic update KEY
679 pub strong: bool,
680 /// this key is authorized to add and update RRs for only a single owner name
681 pub unique: bool,
682 /// The general update signatory field bit has no special meaning, (true if the others are false)
683 pub general: bool,
684}
685
686impl From<u16> for UpdateScope {
687 fn from(flags: u16) -> Self {
688 // we only care about the final four bits, zero out the rest
689 Self {
690 // Bit 0, zone control - If nonzero, this key is authorized to attach,
691 zone: flags & 0b0000_0000_0000_1000 != 0,
692 // Bit 1, strong update - If nonzero, this key is authorized to add and
693 strong: flags & 0b0000_0000_0000_0100 != 0,
694 // Bit 2, unique name update - If nonzero, this key is authorized to add
695 unique: flags & 0b0000_0000_0000_0010 != 0,
696 // Bit 3, general update - The general update signatory field bit has no
697 general: flags & 0b0000_0000_0000_0001 != 0,
698 }
699 }
700}
701
702impl From<UpdateScope> for u16 {
703 fn from(update_scope: UpdateScope) -> Self {
704 let mut flags = 0_u16;
705
706 if update_scope.zone {
707 flags |= 0b0000_0000_0000_1000;
708 }
709
710 if update_scope.strong {
711 flags |= 0b0000_0000_0000_0100;
712 }
713
714 if update_scope.unique {
715 flags |= 0b0000_0000_0000_0010;
716 }
717
718 if update_scope.general {
719 flags |= 0b0000_0000_0000_0001;
720 }
721
722 flags
723 }
724}
725
726/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-3.1.3), Domain Name System Security Extensions, March 1999
727///
728/// ```text
729/// 3.1.3 The Protocol Octet
730///
731/// It is anticipated that keys stored in DNS will be used in conjunction
732/// with a variety of Internet protocols. It is intended that the
733/// protocol octet and possibly some of the currently unused (must be
734/// zero) bits in the KEY RR flags as specified in the future will be
735/// used to indicate a key's validity for different protocols.
736///
737/// The following values of the Protocol Octet are reserved as indicated:
738///
739/// VALUE Protocol
740///
741/// 0 -reserved
742/// 1 TLS
743/// 2 email
744/// 3 dnssec
745/// 4 IPSEC
746/// 5-254 - available for assignment by IANA
747/// 255 All
748///
749/// In more detail:
750/// 1 is reserved for use in connection with TLS.
751/// 2 is reserved for use in connection with email.
752/// 3 is used for DNS security. The protocol field SHOULD be set to
753/// this value for zone keys and other keys used in DNS security.
754/// Implementations that can determine that a key is a DNS
755/// security key by the fact that flags label it a zone key or the
756/// signatory flag field is non-zero are NOT REQUIRED to check the
757/// protocol field.
758/// 4 is reserved to refer to the Oakley/IPSEC [RFC 2401] protocol
759/// and indicates that this key is valid for use in conjunction
760/// with that security standard. This key could be used in
761/// connection with secured communication on behalf of an end
762/// entity or user whose name is the owner name of the KEY RR if
763/// the entity or user flag bits are set. The presence of a KEY
764/// resource with this protocol value is an assertion that the
765/// host speaks Oakley/IPSEC.
766/// 255 indicates that the key can be used in connection with any
767/// protocol for which KEY RR protocol octet values have been
768/// defined. The use of this value is discouraged and the use of
769/// different keys for different protocols is encouraged.
770/// ```
771///
772/// [RFC3445](https://tools.ietf.org/html/rfc3445#section-4), Limiting the KEY Resource Record (RR), December 2002
773///
774/// ```text
775/// All Protocol Octet values except DNSSEC (3) are eliminated
776/// ```
777#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
778#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
779pub enum Protocol {
780 /// Not in use
781 #[deprecated = "Deprecated by RFC3445"]
782 Reserved,
783 /// Reserved for use with TLS
784 #[deprecated = "Deprecated by RFC3445"]
785 TLS,
786 /// Reserved for use with email
787 #[deprecated = "Deprecated by RFC3445"]
788 Email,
789 /// Reserved for use with DNSSEC (Hickory DNS only supports DNSKEY with DNSSEC)
790 #[default]
791 DNSSEC,
792 /// Reserved to refer to the Oakley/IPSEC
793 #[deprecated = "Deprecated by RFC3445"]
794 IPSec,
795 /// Undefined
796 #[deprecated = "Deprecated by RFC3445"]
797 Other(u8),
798 /// the key can be used in connection with any protocol
799 #[deprecated = "Deprecated by RFC3445"]
800 All,
801}
802
803impl From<u8> for Protocol {
804 fn from(field: u8) -> Self {
805 match field {
806 0 => Self::Reserved,
807 1 => Self::TLS,
808 2 => Self::Email,
809 3 => Self::DNSSEC,
810 4 => Self::IPSec,
811 255 => Self::All,
812 _ => Self::Other(field),
813 }
814 }
815}
816
817impl From<Protocol> for u8 {
818 fn from(protocol: Protocol) -> Self {
819 match protocol {
820 Protocol::Reserved => 0,
821 Protocol::TLS => 1,
822 Protocol::Email => 2,
823 Protocol::DNSSEC => 3,
824 Protocol::IPSec => 4,
825 Protocol::All => 255,
826 Protocol::Other(field) => field,
827 }
828 }
829}
830
831#[cfg(test)]
832mod tests {
833 #![allow(clippy::dbg_macro, clippy::print_stdout)]
834
835 use std::println;
836
837 use super::*;
838 use crate::dnssec::{SigningKey, crypto::EcdsaSigningKey};
839
840 #[test]
841 fn test() {
842 let algorithm = Algorithm::ECDSAP256SHA256;
843 let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
844 let signing_key = EcdsaSigningKey::from_pkcs8(&pkcs8, algorithm).unwrap();
845
846 let rdata = KEY::new(
847 KeyTrust::default(),
848 KeyUsage::default(),
849 UpdateScope::default(),
850 Protocol::default(),
851 algorithm,
852 signing_key.to_public_key().unwrap().public_bytes().to_vec(),
853 );
854
855 let mut bytes = Vec::new();
856 let mut encoder: BinEncoder<'_> = BinEncoder::new(&mut bytes);
857 assert!(rdata.emit(&mut encoder).is_ok());
858 let bytes = encoder.into_bytes();
859
860 println!("bytes: {bytes:?}");
861
862 let mut decoder: BinDecoder<'_> = BinDecoder::new(bytes);
863 let restrict = Restrict::new(bytes.len() as u16);
864 let read_rdata = KEY::read_data(&mut decoder, restrict).expect("Decoding error");
865 assert_eq!(rdata, read_rdata);
866 // assert!(rdata
867 // .to_digest(&Name::parse("www.example.com.", None).unwrap(),
868 // DigestType::SHA256)
869 // .is_ok());
870 }
871
872 #[test]
873 fn test_key_usage() {
874 assert_eq!(KeyUsage::Host, KeyUsage::from(u16::from(KeyUsage::Host)));
875 assert_eq!(KeyUsage::Zone, KeyUsage::from(u16::from(KeyUsage::Zone)));
876 assert_eq!(
877 KeyUsage::Entity,
878 KeyUsage::from(u16::from(KeyUsage::Entity))
879 );
880 assert_eq!(
881 KeyUsage::Reserved,
882 KeyUsage::from(u16::from(KeyUsage::Reserved))
883 );
884 }
885
886 #[test]
887 fn test_update_scope() {
888 assert_eq!(
889 UpdateScope::default(),
890 UpdateScope::from(u16::from(UpdateScope::default()))
891 );
892
893 let update_scope = UpdateScope {
894 zone: true,
895 strong: true,
896 unique: true,
897 general: true,
898 };
899 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
900
901 let update_scope = UpdateScope {
902 zone: true,
903 strong: false,
904 unique: true,
905 general: false,
906 };
907 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
908
909 let update_scope = UpdateScope {
910 zone: false,
911 strong: true,
912 unique: false,
913 general: true,
914 };
915 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
916
917 let update_scope = UpdateScope {
918 zone: false,
919 strong: true,
920 unique: true,
921 general: false,
922 };
923 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
924
925 let update_scope = UpdateScope {
926 zone: true,
927 strong: false,
928 unique: false,
929 general: true,
930 };
931 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
932 }
933
934 #[test]
935 fn test_key_trust() {
936 assert_eq!(
937 KeyTrust::NotAuth,
938 KeyTrust::from(u16::from(KeyTrust::NotAuth))
939 );
940 assert_eq!(
941 KeyTrust::NotPrivate,
942 KeyTrust::from(u16::from(KeyTrust::NotPrivate))
943 );
944 assert_eq!(
945 KeyTrust::AuthOrPrivate,
946 KeyTrust::from(u16::from(KeyTrust::AuthOrPrivate))
947 );
948 assert_eq!(
949 KeyTrust::DoNotTrust,
950 KeyTrust::from(u16::from(KeyTrust::DoNotTrust))
951 );
952 }
953}