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
14namespace 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.
21class 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