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