| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ |
| #define NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "base/string_piece.h" |
| |
| namespace net { |
| |
| // DNSSECChainVerifier verifies a chain of DNSSEC records. These records |
| // eventually prove the validity of a set of resource records for the target |
| // name. For example, if the fingerprint of a certificate was stored in a CERT |
| // record for a given domain, then a chain could prove the validity of that |
| // fingerprint. |
| class DNSSECChainVerifier { |
| public: |
| enum Error { |
| OK = 0, |
| BAD_DATA, // The chain was corrupt in some fashion. |
| UNKNOWN_ROOT_KEY, // The chain is assuming an unknown DNS root. |
| UNKNOWN_DIGEST, // An omitted DS record used an unknown hash function. |
| UNKNOWN_TERMINAL_RRTYPE, // The chain proved an unknown RRTYPE. |
| BAD_SIGNATURE, // One of the signature was incorrect. |
| NO_DS_LINK, // a DS set didn't include the next entry key. |
| OFF_COURSE, // the chain is diverging from the target name. |
| BAD_TARGET, // the chain didn't end up at the target. |
| }; |
| |
| // |target|: the target hostname. This must be in canonical (all |
| // lower-case), length-prefixed DNS form. For example: |
| // "\003www\007example\003com\000" |
| // |chain|: the contents of the chain. |
| DNSSECChainVerifier(const std::string& target, |
| const base::StringPiece& chain); |
| ~DNSSECChainVerifier(); |
| |
| // If called, timestamps in the signatures will be ignored. This is for |
| // testing only. |
| void IgnoreTimestamps(); |
| |
| // Verify verifies the chain. Returns |OK| on success. |
| Error Verify(); |
| |
| // rrtype returns the RRTYPE of the proven resource records. Only call this |
| // after Verify has returned OK. |
| uint16 rrtype() const; |
| // rrdatas returns the contents of the proven resource records. Only call |
| // this after Verify has returned OK. |
| const std::vector<base::StringPiece>& rrdatas() const; |
| |
| // ParseTLSTXTRecord parses a TXT record which should contain TLS fingerprint |
| // information. |
| // rrdata: the raw TXT RRDATA from DNS |
| // returns: an empty map on failure, or the result of the parse. |
| static std::map<std::string, std::string> |
| ParseTLSTXTRecord(base::StringPiece rrdata); |
| |
| // Exposed for testing only. |
| static unsigned MatchingLabels(base::StringPiece a, |
| base::StringPiece b); |
| |
| private: |
| struct Zone; |
| |
| bool U8(uint8*); |
| bool U16(uint16*); |
| bool VariableLength16(base::StringPiece*); |
| bool ReadName(base::StringPiece*); |
| |
| bool ReadAheadEntryKey(base::StringPiece*); |
| bool ReadAheadKey(base::StringPiece*, uint8 entry_key); |
| bool ReadDNSKEYs(std::vector<base::StringPiece>*, bool is_root); |
| bool DigestKey(base::StringPiece* digest, |
| const base::StringPiece& name, |
| const base::StringPiece& dnskey, |
| uint8 digest_type, |
| uint16 keyid, |
| uint8 algorithm); |
| |
| Error EnterRoot(); |
| Error EnterZone(const base::StringPiece& zone); |
| Error LeaveZone(base::StringPiece* next_name); |
| Error ReadDSSet(std::vector<base::StringPiece>*, |
| const base::StringPiece& next_name); |
| Error ReadGenericRRs(std::vector<base::StringPiece>*); |
| Error ReadCNAME(std::vector<base::StringPiece>*); |
| |
| Zone* current_zone_; |
| std::string target_; |
| base::StringPiece chain_; |
| bool ignore_timestamps_; |
| bool valid_; |
| // already_entered_zone_ is set to true when we unwind a Zone chain and start |
| // off from a point where we have already entered a zone. |
| bool already_entered_zone_; |
| uint16 rrtype_; |
| std::vector<base::StringPiece> rrdatas_; |
| // A list of pointers which need to be free()ed on destruction. |
| std::vector<void*> scratch_pool_; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ |