13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
23345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Use of this source code is governed by a BSD-style license that can be
33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// found in the LICENSE file.
43345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifndef NET_BASE_DNSSEC_CHAIN_VERIFIER_H_
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#define NET_BASE_DNSSEC_CHAIN_VERIFIER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <map>
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string>
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <vector>
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_piece.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace net {
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// DNSSECChainVerifier verifies a chain of DNSSEC records. These records
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// eventually prove the validity of a set of resource records for the target
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// name. For example, if the fingerprint of a certificate was stored in a CERT
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// record for a given domain, then a chain could prove the validity of that
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// fingerprint.
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass DNSSECChainVerifier {
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  enum Error {
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    OK = 0,
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    BAD_DATA,  // The chain was corrupt in some fashion.
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    UNKNOWN_ROOT_KEY,  // The chain is assuming an unknown DNS root.
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    UNKNOWN_DIGEST,  // An omitted DS record used an unknown hash function.
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    UNKNOWN_TERMINAL_RRTYPE,  // The chain proved an unknown RRTYPE.
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    BAD_SIGNATURE,  // One of the signature was incorrect.
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NO_DS_LINK,  // a DS set didn't include the next entry key.
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    OFF_COURSE,  // the chain is diverging from the target name.
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    BAD_TARGET,  // the chain didn't end up at the target.
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |target|: the target hostname. This must be in canonical (all
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //     lower-case), length-prefixed DNS form. For example:
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //     "\003www\007example\003com\000"
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |chain|: the contents of the chain.
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DNSSECChainVerifier(const std::string& target,
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      const base::StringPiece& chain);
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ~DNSSECChainVerifier();
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If called, timestamps in the signatures will be ignored. This is for
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // testing only.
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void IgnoreTimestamps();
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Verify verifies the chain. Returns |OK| on success.
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error Verify();
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // rrtype returns the RRTYPE of the proven resource records. Only call this
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // after Verify has returned OK.
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  uint16 rrtype() const;
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // rrdatas returns the contents of the proven resource records. Only call
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // this after Verify has returned OK.
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::vector<base::StringPiece>& rrdatas() const;
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // ParseTLSTXTRecord parses a TXT record which should contain TLS fingerprint
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // information.
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   rrdata: the raw TXT RRDATA from DNS
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   returns: an empty map on failure, or the result of the parse.
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static std::map<std::string, std::string>
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ParseTLSTXTRecord(base::StringPiece rrdata);
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Exposed for testing only.
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static unsigned MatchingLabels(base::StringPiece a,
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 base::StringPiece b);
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  struct Zone;
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool U8(uint8*);
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool U16(uint16*);
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool VariableLength16(base::StringPiece*);
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ReadName(base::StringPiece*);
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ReadAheadEntryKey(base::StringPiece*);
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ReadAheadKey(base::StringPiece*, uint8 entry_key);
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ReadDNSKEYs(std::vector<base::StringPiece>*, bool is_root);
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool DigestKey(base::StringPiece* digest,
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 const base::StringPiece& name,
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 const base::StringPiece& dnskey,
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 uint8 digest_type,
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 uint16 keyid,
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 uint8 algorithm);
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error EnterRoot();
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error EnterZone(const base::StringPiece& zone);
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error LeaveZone(base::StringPiece* next_name);
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error ReadDSSet(std::vector<base::StringPiece>*,
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  const base::StringPiece& next_name);
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error ReadGenericRRs(std::vector<base::StringPiece>*);
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Error ReadCNAME(std::vector<base::StringPiece>*);
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Zone* current_zone_;
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string target_;
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::StringPiece chain_;
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ignore_timestamps_;
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool valid_;
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // already_entered_zone_ is set to true when we unwind a Zone chain and start
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // off from a point where we have already entered a zone.
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool already_entered_zone_;
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  uint16 rrtype_;
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::vector<base::StringPiece> rrdatas_;
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // A list of pointers which need to be free()ed on destruction.
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::vector<void*> scratch_pool_;
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace net
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif  // NET_BASE_DNSSEC_CHAIN_VERIFIER_H_
111