record_rdata.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright (c) 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef NET_DNS_RECORD_RDATA_H_
  5. #define NET_DNS_RECORD_RDATA_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <string>
  10. #include <vector>
  11. #include "base/check_op.h"
  12. #include "base/compiler_specific.h"
  13. #include "base/strings/string_piece.h"
  14. #include "net/base/io_buffer.h"
  15. #include "net/base/ip_address.h"
  16. #include "net/base/net_export.h"
  17. #include "net/dns/public/dns_protocol.h"
  18. #include "third_party/abseil-cpp/absl/types/optional.h"
  19. #include "third_party/boringssl/src/include/openssl/sha.h"
  20. namespace net {
  21. class DnsRecordParser;
  22. // Parsed represenation of the extra data in a record. Does not include standard
  23. // DNS record data such as TTL, Name, Type and Class.
  24. class NET_EXPORT RecordRdata {
  25. public:
  26. virtual ~RecordRdata() = default;
  27. // Return true if `data` represents RDATA in the wire format with a valid size
  28. // for the give `type`. Always returns true for unrecognized `type`s as the
  29. // size is never known to be invalid.
  30. static bool HasValidSize(const base::StringPiece& data, uint16_t type);
  31. virtual bool IsEqual(const RecordRdata* other) const = 0;
  32. virtual uint16_t Type() const = 0;
  33. };
  34. // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
  35. // 2 bytes network-order unsigned priority
  36. // 2 bytes network-order unsigned weight
  37. // 2 bytes network-order unsigned port
  38. // target: domain name (on-the-wire representation)
  39. class NET_EXPORT_PRIVATE SrvRecordRdata : public RecordRdata {
  40. public:
  41. static const uint16_t kType = dns_protocol::kTypeSRV;
  42. SrvRecordRdata(const SrvRecordRdata&) = delete;
  43. SrvRecordRdata& operator=(const SrvRecordRdata&) = delete;
  44. ~SrvRecordRdata() override;
  45. static std::unique_ptr<SrvRecordRdata> Create(const base::StringPiece& data,
  46. const DnsRecordParser& parser);
  47. bool IsEqual(const RecordRdata* other) const override;
  48. uint16_t Type() const override;
  49. uint16_t priority() const { return priority_; }
  50. uint16_t weight() const { return weight_; }
  51. uint16_t port() const { return port_; }
  52. const std::string& target() const { return target_; }
  53. private:
  54. SrvRecordRdata();
  55. uint16_t priority_ = 0;
  56. uint16_t weight_ = 0;
  57. uint16_t port_ = 0;
  58. std::string target_;
  59. };
  60. // A Record format (http://www.ietf.org/rfc/rfc1035.txt):
  61. // 4 bytes for IP address.
  62. class NET_EXPORT ARecordRdata : public RecordRdata {
  63. public:
  64. static const uint16_t kType = dns_protocol::kTypeA;
  65. ARecordRdata(const ARecordRdata&) = delete;
  66. ARecordRdata& operator=(const ARecordRdata&) = delete;
  67. ~ARecordRdata() override;
  68. static std::unique_ptr<ARecordRdata> Create(const base::StringPiece& data,
  69. const DnsRecordParser& parser);
  70. bool IsEqual(const RecordRdata* other) const override;
  71. uint16_t Type() const override;
  72. const IPAddress& address() const { return address_; }
  73. private:
  74. ARecordRdata();
  75. IPAddress address_;
  76. };
  77. // AAAA Record format (http://www.ietf.org/rfc/rfc1035.txt):
  78. // 16 bytes for IP address.
  79. class NET_EXPORT AAAARecordRdata : public RecordRdata {
  80. public:
  81. static const uint16_t kType = dns_protocol::kTypeAAAA;
  82. AAAARecordRdata(const AAAARecordRdata&) = delete;
  83. AAAARecordRdata& operator=(const AAAARecordRdata&) = delete;
  84. ~AAAARecordRdata() override;
  85. static std::unique_ptr<AAAARecordRdata> Create(const base::StringPiece& data,
  86. const DnsRecordParser& parser);
  87. bool IsEqual(const RecordRdata* other) const override;
  88. uint16_t Type() const override;
  89. const IPAddress& address() const { return address_; }
  90. private:
  91. AAAARecordRdata();
  92. IPAddress address_;
  93. };
  94. // CNAME record format (http://www.ietf.org/rfc/rfc1035.txt):
  95. // cname: On the wire representation of domain name.
  96. class NET_EXPORT_PRIVATE CnameRecordRdata : public RecordRdata {
  97. public:
  98. static const uint16_t kType = dns_protocol::kTypeCNAME;
  99. CnameRecordRdata(const CnameRecordRdata&) = delete;
  100. CnameRecordRdata& operator=(const CnameRecordRdata&) = delete;
  101. ~CnameRecordRdata() override;
  102. static std::unique_ptr<CnameRecordRdata> Create(
  103. const base::StringPiece& data,
  104. const DnsRecordParser& parser);
  105. bool IsEqual(const RecordRdata* other) const override;
  106. uint16_t Type() const override;
  107. const std::string& cname() const { return cname_; }
  108. private:
  109. CnameRecordRdata();
  110. std::string cname_;
  111. };
  112. // PTR record format (http://www.ietf.org/rfc/rfc1035.txt):
  113. // domain: On the wire representation of domain name.
  114. class NET_EXPORT_PRIVATE PtrRecordRdata : public RecordRdata {
  115. public:
  116. static const uint16_t kType = dns_protocol::kTypePTR;
  117. PtrRecordRdata(const PtrRecordRdata&) = delete;
  118. PtrRecordRdata& operator=(const PtrRecordRdata&) = delete;
  119. ~PtrRecordRdata() override;
  120. static std::unique_ptr<PtrRecordRdata> Create(const base::StringPiece& data,
  121. const DnsRecordParser& parser);
  122. bool IsEqual(const RecordRdata* other) const override;
  123. uint16_t Type() const override;
  124. std::string ptrdomain() const { return ptrdomain_; }
  125. private:
  126. PtrRecordRdata();
  127. std::string ptrdomain_;
  128. };
  129. // TXT record format (http://www.ietf.org/rfc/rfc1035.txt):
  130. // texts: One or more <character-string>s.
  131. // a <character-string> is a length octet followed by as many characters.
  132. class NET_EXPORT_PRIVATE TxtRecordRdata : public RecordRdata {
  133. public:
  134. static const uint16_t kType = dns_protocol::kTypeTXT;
  135. TxtRecordRdata(const TxtRecordRdata&) = delete;
  136. TxtRecordRdata& operator=(const TxtRecordRdata&) = delete;
  137. ~TxtRecordRdata() override;
  138. static std::unique_ptr<TxtRecordRdata> Create(const base::StringPiece& data,
  139. const DnsRecordParser& parser);
  140. bool IsEqual(const RecordRdata* other) const override;
  141. uint16_t Type() const override;
  142. const std::vector<std::string>& texts() const { return texts_; }
  143. private:
  144. TxtRecordRdata();
  145. std::vector<std::string> texts_;
  146. };
  147. // Only the subset of the NSEC record format required by mDNS is supported.
  148. // Nsec record format is described in http://www.ietf.org/rfc/rfc3845.txt and
  149. // the limited version required for mDNS described in
  150. // http://www.rfc-editor.org/rfc/rfc6762.txt Section 6.1.
  151. class NET_EXPORT_PRIVATE NsecRecordRdata : public RecordRdata {
  152. public:
  153. static const uint16_t kType = dns_protocol::kTypeNSEC;
  154. NsecRecordRdata(const NsecRecordRdata&) = delete;
  155. NsecRecordRdata& operator=(const NsecRecordRdata&) = delete;
  156. ~NsecRecordRdata() override;
  157. static std::unique_ptr<NsecRecordRdata> Create(const base::StringPiece& data,
  158. const DnsRecordParser& parser);
  159. bool IsEqual(const RecordRdata* other) const override;
  160. uint16_t Type() const override;
  161. // Length of the bitmap in bits.
  162. // This will be between 8 and 256, per RFC 3845, Section 2.1.2.
  163. uint16_t bitmap_length() const {
  164. DCHECK_LE(bitmap_.size(), 32u);
  165. return static_cast<uint16_t>(bitmap_.size() * 8);
  166. }
  167. // Returns bit i-th bit in the bitmap, where bits withing a byte are organized
  168. // most to least significant. If it is set, a record with rrtype i exists for
  169. // the domain name of this nsec record.
  170. bool GetBit(unsigned i) const;
  171. private:
  172. NsecRecordRdata();
  173. std::vector<uint8_t> bitmap_;
  174. };
  175. // This class parses and serializes the INTEGRITY DNS record.
  176. //
  177. // This RR was invented for a preliminary HTTPSSVC experiment. See the public
  178. // design doc:
  179. // https://docs.google.com/document/d/14eCqVyT_3MSj7ydqNFl1Yl0yg1fs6g24qmYUUdi5V-k/edit?usp=sharing
  180. //
  181. // The wire format of INTEGRITY records consists of a U16-prefixed nonce
  182. // followed by |kDigestLen| bytes, which should be equal to the SHA256 hash of
  183. // the nonce contents.
  184. class NET_EXPORT IntegrityRecordRdata : public RecordRdata {
  185. public:
  186. static constexpr uint16_t kType = dns_protocol::kExperimentalTypeIntegrity;
  187. static constexpr size_t kDigestLen = SHA256_DIGEST_LENGTH;
  188. using Nonce = std::vector<uint8_t>;
  189. using Digest = std::array<uint8_t, kDigestLen>;
  190. IntegrityRecordRdata() = delete;
  191. // Constructs a new record, computing the digest value from |nonce|.
  192. explicit IntegrityRecordRdata(Nonce nonce);
  193. IntegrityRecordRdata(IntegrityRecordRdata&&);
  194. IntegrityRecordRdata(const IntegrityRecordRdata&);
  195. ~IntegrityRecordRdata() override;
  196. IntegrityRecordRdata& operator=(const IntegrityRecordRdata&) = default;
  197. IntegrityRecordRdata& operator=(IntegrityRecordRdata&&) = default;
  198. // RecordRdata:
  199. bool IsEqual(const RecordRdata* other) const override;
  200. uint16_t Type() const override;
  201. // Attempts to parse an INTEGRITY record from |data|. Never returns nullptr.
  202. // The caller can check the intactness of the record with |IsIntact()|.
  203. static std::unique_ptr<IntegrityRecordRdata> Create(
  204. const base::StringPiece& data);
  205. // Generate an integrity record with a random nonce and corresponding digest.
  206. // Postcondition: |IsIntact()| is true.
  207. static IntegrityRecordRdata Random();
  208. // Serialize |this| using the INTEGRITY wire format. Returns |absl::nullopt|
  209. // when |!IsIntact()|.
  210. absl::optional<std::vector<uint8_t>> Serialize() const;
  211. // Precondition: |IsIntact()|.
  212. const Nonce& nonce() const {
  213. CHECK(is_intact_);
  214. return nonce_;
  215. }
  216. // Precondition: |IsIntact()|.
  217. const Digest& digest() const {
  218. CHECK(is_intact_);
  219. return digest_;
  220. }
  221. // To be considered intact, this record must have parsed successfully (if
  222. // parsed by |Create()|) and the digest must match the hash of the nonce.
  223. bool IsIntact() const { return is_intact_; }
  224. private:
  225. IntegrityRecordRdata(Nonce nonce_, Digest digest_, size_t rdata_len);
  226. static Digest Hash(const Nonce& nonce);
  227. // Returns the exact number of bytes a record constructed from |nonce| would
  228. // occupy when serialized.
  229. static size_t LengthForSerialization(const Nonce& nonce);
  230. Nonce nonce_;
  231. Digest digest_;
  232. bool is_intact_;
  233. };
  234. } // namespace net
  235. #endif // NET_DNS_RECORD_RDATA_H_