caa.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. use log::*;
  2. use crate::wire::*;
  3. /// A **CAA** record. These allow domain names to specify which Certificate
  4. /// Authorities are allowed to issue certificates for the domain.
  5. ///
  6. /// # References
  7. ///
  8. /// - [RFC 6844](https://tools.ietf.org/html/rfc6844) — DNS Certification Authority Authorization Resource Record (January 2013s
  9. #[derive(PartialEq, Debug, Clone)]
  10. pub struct CAA {
  11. /// Whether this record is marked as “critical” or not.
  12. pub critical: bool,
  13. /// The “tag” part of the CAA record.
  14. pub tag: String,
  15. /// The “value” part of the CAA record.
  16. pub value: String,
  17. }
  18. impl Wire for CAA {
  19. const NAME: &'static str = "CAA";
  20. const RR_TYPE: u16 = 257;
  21. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  22. fn read(len: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  23. let flags = c.read_u8()?;
  24. trace!("Parsed flags -> {:#08b}", flags);
  25. let critical = flags & 0b_1000_0000 == 0b_1000_0000;
  26. trace!("Parsed critical flag -> {:?}", critical);
  27. let tag_length = c.read_u8()?;
  28. trace!("Parsed tag length -> {:?}", tag_length);
  29. let mut tag_buf = Vec::new();
  30. for _ in 0 .. tag_length {
  31. tag_buf.push(c.read_u8()?);
  32. }
  33. let tag = String::from_utf8_lossy(&tag_buf).to_string();
  34. trace!("Parsed tag -> {:?}", tag);
  35. let remaining_length = len.saturating_sub(u16::from(tag_length)).saturating_sub(2);
  36. trace!("Remaining length -> {:?}", remaining_length);
  37. let mut value_buf = Vec::new();
  38. for _ in 0 .. remaining_length {
  39. value_buf.push(c.read_u8()?);
  40. }
  41. let value = String::from_utf8_lossy(&value_buf).to_string();
  42. trace!("Parsed value -> {:?}", value);
  43. Ok(CAA { critical, tag, value })
  44. }
  45. }
  46. #[cfg(test)]
  47. mod test {
  48. use super::*;
  49. #[test]
  50. fn parses() {
  51. let buf = &[
  52. 0x00, // flags
  53. 0x09, // tag length
  54. 0x69, 0x73, 0x73, 0x75, 0x65, 0x77, 0x69, 0x6c, 0x64, // tag
  55. 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, // value
  56. ];
  57. assert_eq!(CAA::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
  58. CAA {
  59. critical: false,
  60. tag: String::from("issuewild"),
  61. value: String::from("entrust.net"),
  62. });
  63. }
  64. #[test]
  65. fn empty() {
  66. assert_eq!(CAA::read(0, &mut Cursor::new(&[])),
  67. Err(WireError::IO));
  68. }
  69. }