1 // Copyright (c) 2010 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 5 #ifndef NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ 6 #define NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/string_piece.h" 13 14 namespace net { 15 16 // DNSSECChainVerifier verifies a chain of DNSSEC records. These records 17 // eventually prove the validity of a set of resource records for the target 18 // name. For example, if the fingerprint of a certificate was stored in a CERT 19 // record for a given domain, then a chain could prove the validity of that 20 // fingerprint. 21 class DNSSECChainVerifier { 22 public: 23 enum Error { 24 OK = 0, 25 BAD_DATA, // The chain was corrupt in some fashion. 26 UNKNOWN_ROOT_KEY, // The chain is assuming an unknown DNS root. 27 UNKNOWN_DIGEST, // An omitted DS record used an unknown hash function. 28 UNKNOWN_TERMINAL_RRTYPE, // The chain proved an unknown RRTYPE. 29 BAD_SIGNATURE, // One of the signature was incorrect. 30 NO_DS_LINK, // a DS set didn't include the next entry key. 31 OFF_COURSE, // the chain is diverging from the target name. 32 BAD_TARGET, // the chain didn't end up at the target. 33 }; 34 35 // |target|: the target hostname. This must be in canonical (all 36 // lower-case), length-prefixed DNS form. For example: 37 // "\003www\007example\003com\000" 38 // |chain|: the contents of the chain. 39 DNSSECChainVerifier(const std::string& target, 40 const base::StringPiece& chain); 41 ~DNSSECChainVerifier(); 42 43 // If called, timestamps in the signatures will be ignored. This is for 44 // testing only. 45 void IgnoreTimestamps(); 46 47 // Verify verifies the chain. Returns |OK| on success. 48 Error Verify(); 49 50 // rrtype returns the RRTYPE of the proven resource records. Only call this 51 // after Verify has returned OK. 52 uint16 rrtype() const; 53 // rrdatas returns the contents of the proven resource records. Only call 54 // this after Verify has returned OK. 55 const std::vector<base::StringPiece>& rrdatas() const; 56 57 // ParseTLSTXTRecord parses a TXT record which should contain TLS fingerprint 58 // information. 59 // rrdata: the raw TXT RRDATA from DNS 60 // returns: an empty map on failure, or the result of the parse. 61 static std::map<std::string, std::string> 62 ParseTLSTXTRecord(base::StringPiece rrdata); 63 64 // Exposed for testing only. 65 static unsigned MatchingLabels(base::StringPiece a, 66 base::StringPiece b); 67 68 private: 69 struct Zone; 70 71 bool U8(uint8*); 72 bool U16(uint16*); 73 bool VariableLength16(base::StringPiece*); 74 bool ReadName(base::StringPiece*); 75 76 bool ReadAheadEntryKey(base::StringPiece*); 77 bool ReadAheadKey(base::StringPiece*, uint8 entry_key); 78 bool ReadDNSKEYs(std::vector<base::StringPiece>*, bool is_root); 79 bool DigestKey(base::StringPiece* digest, 80 const base::StringPiece& name, 81 const base::StringPiece& dnskey, 82 uint8 digest_type, 83 uint16 keyid, 84 uint8 algorithm); 85 86 Error EnterRoot(); 87 Error EnterZone(const base::StringPiece& zone); 88 Error LeaveZone(base::StringPiece* next_name); 89 Error ReadDSSet(std::vector<base::StringPiece>*, 90 const base::StringPiece& next_name); 91 Error ReadGenericRRs(std::vector<base::StringPiece>*); 92 Error ReadCNAME(std::vector<base::StringPiece>*); 93 94 Zone* current_zone_; 95 std::string target_; 96 base::StringPiece chain_; 97 bool ignore_timestamps_; 98 bool valid_; 99 // already_entered_zone_ is set to true when we unwind a Zone chain and start 100 // off from a point where we have already entered a zone. 101 bool already_entered_zone_; 102 uint16 rrtype_; 103 std::vector<base::StringPiece> rrdatas_; 104 // A list of pointers which need to be free()ed on destruction. 105 std::vector<void*> scratch_pool_; 106 }; 107 108 } // namespace net 109 110 #endif // NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ 111