diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 00:04:25 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 00:04:25 +0000 |
commit | 5351bd70aefdf610d871b8ed00d6e345a06075dc (patch) | |
tree | 74b419e73d7648c572ba44474845f2d0a85709da /net | |
parent | ae27dc38b417e979b1728fbe43c3668d693930da (diff) | |
download | chromium_src-5351bd70aefdf610d871b8ed00d6e345a06075dc.zip chromium_src-5351bd70aefdf610d871b8ed00d6e345a06075dc.tar.gz chromium_src-5351bd70aefdf610d871b8ed00d6e345a06075dc.tar.bz2 |
Remove support for DNSSEC stapled certificates.
BUG=none
Review URL: https://chromiumcodereview.appspot.com/11293234
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168085 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/cert_status_flags.h | 2 | ||||
-rw-r--r-- | net/base/dns_util.h | 2 | ||||
-rw-r--r-- | net/base/dnssec_chain_verifier.cc | 995 | ||||
-rw-r--r-- | net/base/dnssec_chain_verifier.h | 177 | ||||
-rw-r--r-- | net/base/dnssec_keyset.cc | 478 | ||||
-rw-r--r-- | net/base/dnssec_keyset.h | 63 | ||||
-rw-r--r-- | net/base/dnssec_unittest.cc | 887 | ||||
-rw-r--r-- | net/net.gyp | 20 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 220 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.h | 2 | ||||
-rw-r--r-- | net/tools/dnssec_chain_verify/dnssec_chain_verify.cc | 109 |
11 files changed, 2 insertions, 2953 deletions
diff --git a/net/base/cert_status_flags.h b/net/base/cert_status_flags.h index 5c4c7f1..ff23375 100644 --- a/net/base/cert_status_flags.h +++ b/net/base/cert_status_flags.h @@ -36,7 +36,7 @@ static const CertStatus CERT_STATUS_WEAK_KEY = 1 << 11; // Bits 16 to 31 are for non-error statuses. static const CertStatus CERT_STATUS_IS_EV = 1 << 16; static const CertStatus CERT_STATUS_REV_CHECKING_ENABLED = 1 << 17; -static const CertStatus CERT_STATUS_IS_DNSSEC = 1 << 18; +// bit 18 was CERT_STATUS_IS_DNSSEC. // Returns true if the specified cert status has an error set. static inline bool IsCertStatusError(CertStatus status) { diff --git a/net/base/dns_util.h b/net/base/dns_util.h index 3a76e7a..3836657 100644 --- a/net/base/dns_util.h +++ b/net/base/dns_util.h @@ -51,9 +51,7 @@ static const uint16 kDNS_CERT = 37; static const uint16 kDNS_DS = 43; static const uint16 kDNS_RRSIG = 46; static const uint16 kDNS_DNSKEY = 48; -static const uint16 kDNS_TLSA = 52; static const uint16 kDNS_ANY = 0xff; -static const uint16 kDNS_CAA = 257; static const uint16 kDNS_TESTING = 0xfffe; // in private use area. // http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml diff --git a/net/base/dnssec_chain_verifier.cc b/net/base/dnssec_chain_verifier.cc deleted file mode 100644 index 4ea79b3..0000000 --- a/net/base/dnssec_chain_verifier.cc +++ /dev/null @@ -1,995 +0,0 @@ -// Copyright (c) 2011 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. - -#include "net/base/dnssec_chain_verifier.h" - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/sha1.h" -#include "base/string_util.h" -#include "crypto/sha2.h" -#include "net/base/asn1_util.h" -#include "net/base/dns_util.h" -#include "net/base/dnssec_keyset.h" - -// We don't have a location for the spec yet, so we'll include it here until it -// finds a better home. - -/* -When connecting to a host www.example.com, www.example.com may present a certificate which includes a DNSSEC chain embedded in it. The aim of the embedded chain is to prove that the fingerprint of the public key is valid DNSSEC data. This is achieved by proving a CERT record for the target domain. - -Initially, the target domain is constructed by prepending _ssl. For example, the initial target domain for www.example.com is _ssl.www.example.com. - -A DNSSEC chain verifier can be in one of two states: entering a zone, or within a zone. Initially, the verifier is entering the root zone. - -When entering a zone, the verifier reads the following structure: - -uint8 entryKey -uint16 signature length: - // See RRSIG RDATA in RFC 4043 for details - uint8 algorithm - uint8 labels - uint32 ttl - uint32 expires - uint32 begins - uint16 keyid - []byte signature -uint8 numKeys -// for each key: -uint16 key length: - []byte DNSKEY RDATA - -|entryKey| indexes the array of DNSKEYs and MUST be less than |numKeys|. The indexed DNSKEY MUST be a key that the verifier trusts, either because it's the long-term root key, or because of a previously presented DS signature. - -If only a trusted key is needed within this zone, then the signature length MAY be zero. In which case, |entryKey| MUST be 0 and |numKeys| MUST be 1. - -After processing this data, the verifier trusts one or more keys for this zone. - -When within a zone, the verifier reads the following structure: - -dnsName name -uint16 RRtype - -|name| is in DNS format (a series of 8-bit, length prefixed strings). No DNS name compression is permitted. - -|name| must be closer to the current target domain than the current zone. Here, 'closer' is defined as a greater number of matching labels when comparing right to left. - -|RRtype| may be either DS, CERT or CNAME: - -DS: this indicates a zone transition to a new zone named |name|. The verifier reads the following structure: - uint16 signature length: - ... (see above for the signature structure) - uint8 num_ds - // for each DS: - uint8 digest_type - uint16 length - []byte DS DATA - -The verifier is now entering the named zone. It reads ahead and extracts the entry key from the zone entry data and synthisises a DS record for the given digest type and verifies the signature. It then enters the next zone. - - -CERT: |name| MUST match the target domain. The verifier reads the following structure: - uint16 signature length: - ... (see above for the signature structure) - []byte CERT RDATA - -(The format of the CERT RDATA isn't specified here, but the verifier must be able to extract a public key fingerprint in order to validate the original certificate.) - -This terminates the verification. There MUST NOT be any more data in the chain. - - -CNAME: |name| MUST match the target domain. The verifier reads the following structure: - uint16 signature length: - ... (see above for the signature structure) - []byte CNAME RDATA - -This replaces the target domain with a new domain. The new domain is the target of the CNAME with _ssl prepended. The verifier is now in the zone that is the greatest common ancestor of the old and new target domains. (For example, when switching from _ssl.www.example.com to _ssl.www.example2.com, the verifier is now in com.) - - -Example for www.google.com: - -The target domain is www.google.com. - -The verifier enters ., it already trusts the long-term root key and both root keys are presented in order to extend the trust to the smaller root key. - -A DS signature is presented for .com. The verifier is now entering .com. - -All four .com keys are presented. The verifier is now in .com. - -A DS signature is presented for google.com. The verifier is now entering google.com - -As google.com contains only a single DNSKEY, it is included without a signature. The verifier is now in google.com. - -A CNAME is presented for www.google.com pointing to www.l.google.com. The target domain is now www.l.google.com. The verifier is now in google.com. - -A DS signature is presented for l.google.com. The verifier is now entering l.google.com. - -As l.google.com contains only a single DNSKEY, it is included without a signature. The verifier is now in l.google.com. - -A CERT record is presented for www.l.google.com. The verification is complete. -*/ - -namespace { - -// This is the 2048-bit DNS root key: http://www.iana.org/dnssec -// 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 -const unsigned char kRootKey[] = { - 0x01, 0x01, 0x03, 0x08, 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9, 0x55, - 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80, 0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, - 0x6d, 0xbd, 0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec, 0x90, 0x6d, 0x21, - 0x16, 0xd0, 0xef, 0x20, 0x70, 0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf, - 0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82, 0x34, 0x13, 0x3a, 0xc0, 0x71, - 0x0a, 0x81, 0x18, 0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc, 0x83, 0x43, - 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32, 0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, - 0x51, 0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb, 0x35, 0x95, 0x80, 0x25, - 0x0f, 0x55, 0x9c, 0xc5, 0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8, 0xcf, - 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4, 0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, - 0x5f, 0xa4, 0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e, 0xcb, 0xcf, 0x56, - 0x34, 0x74, 0x65, 0x2c, 0x33, 0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9, - 0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04, 0x1b, 0x6e, 0x03, 0xa1, 0xb7, - 0x2d, 0x0a, 0x73, 0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33, 0x23, 0x24, - 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9, 0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, - 0x2e, 0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e, 0xce, 0xc9, 0x07, 0x57, - 0x7d, 0x9e, 0x7b, 0xad, 0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9, 0x01, - 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14, 0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, - 0x9c, 0x2e, 0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5, 0x75, 0xfc, 0x21, - 0x60, 0x1e, 0x0d, 0xee, 0x49, 0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52, - 0x4d, 0x62, 0x87, 0x3d, -}; - -// kRootKeyID is the key id for kRootKey -const uint16 kRootKeyID = 19036; - -// CountLabels returns the number of DNS labels in |a|, which must be in DNS, -// length-prefixed form. -unsigned CountLabels(base::StringPiece a) { - for (unsigned c = 0;; c++) { - if (!a.size()) - return c; - uint8 label_len = a.data()[0]; - a.remove_prefix(1); - DCHECK_GE(a.size(), label_len); - a.remove_prefix(label_len); - } -} - -// RemoveLeadingLabel removes the first label from |a|, which must be in DNS, -// length-prefixed form. -void RemoveLeadingLabel(base::StringPiece* a) { - if (!a->size()) - return; - uint8 label_len = a->data()[0]; - a->remove_prefix(1); - a->remove_prefix(label_len); -} - -} // namespace - -namespace net { - -struct DNSSECChainVerifier::Zone { - base::StringPiece name; - // The number of consecutive labels which |name| shares with |target_|, - // counting right-to-left from the root. - unsigned matching_labels; - DNSSECKeySet trusted_keys; - Zone* prev; -}; - -DNSSECChainVerifier::DNSSECChainVerifier(const std::string& target, - const base::StringPiece& chain) - : current_zone_(NULL), - target_(target), - chain_(chain), - ignore_timestamps_(false), - valid_(false), - already_entered_zone_(false), - rrtype_(0) { -} - -DNSSECChainVerifier::~DNSSECChainVerifier() { - for (std::vector<void*>::iterator - i = scratch_pool_.begin(); i != scratch_pool_.end(); i++) { - free(*i); - } - - Zone* next; - for (Zone* cur = current_zone_; cur; cur = next) { - next = cur->prev; - delete cur; - } -} - -void DNSSECChainVerifier::IgnoreTimestamps() { - ignore_timestamps_ = true; -} - -DNSSECChainVerifier::Error DNSSECChainVerifier::Verify() { - Error err; - - err = EnterRoot(); - if (err != OK) - return err; - - for (;;) { - base::StringPiece next_name; - err = LeaveZone(&next_name); - if (err != OK) - return err; - if (valid_) { - if (!chain_.empty()) - return BAD_DATA; // no trailing data allowed. - break; - } - - if (already_entered_zone_) { - already_entered_zone_ = false; - } else { - err = EnterZone(next_name); - if (err != OK) - return err; - } - } - - return OK; -} - -uint16 DNSSECChainVerifier::rrtype() const { - DCHECK(valid_); - return rrtype_; -} - -const std::vector<base::StringPiece>& DNSSECChainVerifier::rrdatas() const { - DCHECK(valid_); - return rrdatas_; -} - -// MatchingLabels returns the number of labels which |a| and |b| share, -// counting right-to-left from the root. |a| and |b| must be DNS, -// length-prefixed names. All names match at the root label, so this always -// returns a value >= 1. - -// static -unsigned DNSSECChainVerifier::MatchingLabels(base::StringPiece a, - base::StringPiece b) { - unsigned c = 0; - unsigned a_labels = CountLabels(a); - unsigned b_labels = CountLabels(b); - - while (a_labels > b_labels) { - RemoveLeadingLabel(&a); - a_labels--; - } - while (b_labels > a_labels) { - RemoveLeadingLabel(&b); - b_labels--; - } - - for (;;) { - if (!a.size()) { - if (!b.size()) - return c; - return 0; - } - if (!b.size()) - return 0; - uint8 a_length = a.data()[0]; - a.remove_prefix(1); - uint8 b_length = b.data()[0]; - b.remove_prefix(1); - DCHECK_GE(a.size(), a_length); - DCHECK_GE(b.size(), b_length); - - if (a_length == b_length && memcmp(a.data(), b.data(), a_length) == 0) { - c++; - } else { - c = 0; - } - - a.remove_prefix(a_length); - b.remove_prefix(b_length); - } -} - -// U8 reads, and removes, a single byte from |chain_| -bool DNSSECChainVerifier::U8(uint8* v) { - if (chain_.size() < 1) - return false; - *v = chain_[0]; - chain_.remove_prefix(1); - return true; -} - -// U16 reads, and removes, a big-endian uint16 from |chain_| -bool DNSSECChainVerifier::U16(uint16* v) { - if (chain_.size() < 2) - return false; - const uint8* data = reinterpret_cast<const uint8*>(chain_.data()); - *v = static_cast<uint16>(data[0]) << 8 | - static_cast<uint16>(data[1]); - chain_.remove_prefix(2); - return true; -} - -// VariableLength16 reads, and removes, a big-endian, uint16, length-prefixed -// chunk from |chain_| -bool DNSSECChainVerifier::VariableLength16(base::StringPiece* v) { - uint16 length; - if (!U16(&length)) - return false; - if (chain_.size() < length) - return false; - *v = chain_.substr(0, length); - chain_.remove_prefix(length); - return true; -} - -// ReadName reads, and removes, an 8-bit length prefixed DNS name from |chain_| -bool DNSSECChainVerifier::ReadName(base::StringPiece* v) { - base::StringPiece saved = chain_; - unsigned length = 0; - static const uint8 kMaxDNSLabelLen = 63; - - for (;;) { - if (chain_.size() < 1) - return false; - uint8 label_len = chain_.data()[0]; - chain_.remove_prefix(1); - if (label_len > kMaxDNSLabelLen) - return false; - length += 1 + label_len; - - if (label_len == 0) - break; - - if (chain_.size() < label_len) - return false; - chain_.remove_prefix(label_len); - } - - *v = base::StringPiece(saved.data(), length); - return true; -} - -// ReadAheadEntryKey returns the entry key when |chain_| is positioned at the -// start of a zone. -bool DNSSECChainVerifier::ReadAheadEntryKey(base::StringPiece* v) { - base::StringPiece saved = chain_; - - uint8 entry_key; - base::StringPiece sig; - if (!U8(&entry_key) || - !VariableLength16(&sig)) { - return false; - } - - if (!ReadAheadKey(v, entry_key)) - return false; - chain_ = saved; - return true; -} - -// ReadAheadKey returns the entry key when |chain_| is positioned at the start -// of a list of keys. -bool DNSSECChainVerifier::ReadAheadKey(base::StringPiece* v, uint8 entry_key) { - base::StringPiece saved = chain_; - - uint8 num_keys; - if (!U8(&num_keys)) - return false; - - for (unsigned i = 0; i < num_keys; i++) { - if (!VariableLength16(v)) - return false; - if (i == entry_key) { - chain_ = saved; - return true; - } - } - - return false; -} - -bool DNSSECChainVerifier::ReadDNSKEYs(std::vector<base::StringPiece>* out, - bool is_root) { - uint8 num_keys; - if (!U8(&num_keys)) - return false; - - for (unsigned i = 0; i < num_keys; i++) { - base::StringPiece key; - if (!VariableLength16(&key)) - return false; - if (key.empty()) { - if (!is_root) - return false; - key = base::StringPiece(reinterpret_cast<const char*>(kRootKey), - sizeof(kRootKey)); - } - - out->push_back(key); - } - - return true; -} - -// DigestKey calculates a DS digest as specified in -// http://tools.ietf.org/html/rfc4034#section-5.1.4 -// name: the DNS form name of the key -// dnskey: the DNSKEY's RRDATA -// digest_type: see http://tools.ietf.org/html/rfc4034#appendix-A.2 -// keyid: the key's id -// algorithm: see http://tools.ietf.org/html/rfc4034#appendix-A.1 -bool DNSSECChainVerifier::DigestKey(base::StringPiece* out, - const base::StringPiece& name, - const base::StringPiece& dnskey, - uint8 digest_type, - uint16 keyid, - uint8 algorithm) { - std::string temp; - uint8 temp2[crypto::kSHA256Length]; - const uint8* digest; - unsigned digest_len; - - std::string input = name.as_string() + dnskey.as_string(); - - if (digest_type == kDNSSEC_SHA1) { - temp = base::SHA1HashString(input); - digest = reinterpret_cast<const uint8*>(temp.data()); - digest_len = base::kSHA1Length; - } else if (digest_type == kDNSSEC_SHA256) { - crypto::SHA256HashString(input, temp2, sizeof(temp2)); - digest = temp2; - digest_len = sizeof(temp2); - } else { - return false; - } - - uint8* output = static_cast<uint8*>(malloc(4 + digest_len)); - scratch_pool_.push_back(output); - output[0] = static_cast<uint8>(keyid >> 8); - output[1] = static_cast<uint8>(keyid); - output[2] = algorithm; - output[3] = digest_type; - memcpy(output + 4, digest, digest_len); - *out = base::StringPiece(reinterpret_cast<char*>(output), 4 + digest_len); - return true; -} - -// EnterRoot enters the root zone at the beginning of the chain. This is -// special because no DS record lead us here: we have to validate that the -// entry key is the DNS root key that we already know and trust. Additionally, -// for the root zone only, the keyid of the entry key is prepended to the data. -DNSSECChainVerifier::Error DNSSECChainVerifier::EnterRoot() { - uint16 root_keyid; - - if (!U16(&root_keyid)) - return BAD_DATA; - - if (root_keyid != kRootKeyID) - return UNKNOWN_ROOT_KEY; - - base::StringPiece root_key; - if (!ReadAheadEntryKey(&root_key)) - return BAD_DATA; - - // If the root key is given then it must match the expected root key exactly. - if (root_key.size()) { - if (root_key.size() != sizeof(kRootKey) || - memcmp(root_key.data(), kRootKey, sizeof(kRootKey))) { - return UNKNOWN_ROOT_KEY; - } - } - - base::StringPiece root("", 1); - return EnterZone(root); -} - -// EnterZone enters a new DNS zone. On entry it's assumed that the entry key -// has been validated. -DNSSECChainVerifier::Error DNSSECChainVerifier::EnterZone( - const base::StringPiece& zone) { - Zone* prev = current_zone_; - current_zone_ = new Zone; - current_zone_->prev = prev; - current_zone_->name = zone; - current_zone_->matching_labels = MatchingLabels(target_, zone); - if (ignore_timestamps_) - current_zone_->trusted_keys.IgnoreTimestamps(); - - uint8 entry_key; - base::StringPiece sig; - if (!U8(&entry_key) || - !VariableLength16(&sig)) { - return BAD_DATA; - } - - base::StringPiece key; - if (!ReadAheadKey(&key, entry_key)) - return BAD_DATA; - - if (zone.size() == 1 && key.empty()) { - // If a key is omitted in the root zone then it's the root key. - key = base::StringPiece(reinterpret_cast<const char*>(kRootKey), - sizeof(kRootKey)); - } - if (!current_zone_->trusted_keys.AddKey(key)) - return BAD_DATA; - - std::vector<base::StringPiece> dnskeys; - if (!ReadDNSKEYs(&dnskeys, zone.size() == 1)) - return BAD_DATA; - - if (sig.empty()) { - // An omitted signature on the keys means that only the entry key is used. - if (dnskeys.size() > 1 || entry_key != 0) - return BAD_DATA; - return OK; - } - - if (!current_zone_->trusted_keys.CheckSignature( - zone, zone, sig, kDNS_DNSKEY, dnskeys)) { - return BAD_SIGNATURE; - } - - // Add all the keys as trusted. - for (unsigned i = 0; i < dnskeys.size(); i++) { - if (i == entry_key) - continue; - current_zone_->trusted_keys.AddKey(dnskeys[i]); - } - - return OK; -} - -// IsValidTerminalRRType returns true if the given RR type is one that we -// accept as the terminal record in a DNSSEC chain. -bool DNSSECChainVerifier::IsValidTerminalRRType(uint16 rrtype) { - switch (rrtype) { - case kDNS_CAA: - case kDNS_CERT: - case kDNS_TLSA: - case kDNS_TXT: - return true; - } - - return false; -} - -// LeaveZone transitions out of the current zone, either by following DS -// records to validate the entry key of the next zone, or because the final -// resource records are given. -DNSSECChainVerifier::Error DNSSECChainVerifier::LeaveZone( - base::StringPiece* next_name) { - base::StringPiece sig; - uint16 rrtype; - Error err; - - if (!ReadName(next_name) || - !U16(&rrtype) || - !VariableLength16(&sig)) { - return BAD_DATA; - } - - std::vector<base::StringPiece> rrdatas; - - if (rrtype == kDNS_DS) { - err = ReadDSSet(&rrdatas, *next_name); - } else if (IsValidTerminalRRType(rrtype)) { - err = ReadGenericRRs(&rrdatas); - } else if (rrtype == kDNS_CNAME) { - err = ReadCNAME(&rrdatas); - } else { - return UNKNOWN_TERMINAL_RRTYPE; - } - if (err != OK) - return err; - - if (!current_zone_->trusted_keys.CheckSignature( - *next_name, current_zone_->name, sig, rrtype, rrdatas)) { - return BAD_SIGNATURE; - } - - if (rrtype == kDNS_DS) { - // If we are transitioning to another zone then the next zone must be - // 'closer' to the target than the current zone. - if (MatchingLabels(target_, *next_name) <= current_zone_->matching_labels) - return OFF_COURSE; - } else if (IsValidTerminalRRType(rrtype)) { - // If this is the final entry in the chain then the name must match target_ - if (next_name->size() != target_.size() || - memcmp(next_name->data(), target_.data(), target_.size())) { - return BAD_TARGET; - } - rrdatas_ = rrdatas; - valid_ = true; - rrtype_ = rrtype; - } else if (rrtype == kDNS_CNAME) { - // A CNAME must match the current target. Then we update the current target - // and unwind the chain to the closest common ancestor. - if (next_name->size() != target_.size() || - memcmp(next_name->data(), target_.data(), target_.size())) { - return BAD_TARGET; - } - DCHECK_EQ(1u, rrdatas.size()); - target_ = rrdatas[0].as_string(); - // We unwind the zones until the current zone is a (non-strict) subset of - // the new target. - while (MatchingLabels(target_, current_zone_->name) < - CountLabels(current_zone_->name)) { - Zone* prev = current_zone_->prev; - delete current_zone_; - current_zone_ = prev; - if (!current_zone_) { - NOTREACHED(); - return BAD_DATA; - } - } - already_entered_zone_ = true; - } else { - NOTREACHED(); - return UNKNOWN_TERMINAL_RRTYPE; - } - - return OK; -} - -// ReadDSSet reads a set of DS records from the chain. DS records which are -// omitted are calculated from the entry key of the next zone. -DNSSECChainVerifier::Error DNSSECChainVerifier::ReadDSSet( - std::vector<base::StringPiece>* rrdatas, - const base::StringPiece& next_name) { - uint8 num_ds; - if (!U8(&num_ds)) - return BAD_DATA; - scoped_array<uint8> digest_types(new uint8[num_ds]); - // lookahead[i] is true iff the i'th DS record was empty and needs to be - // computed by hashing the next entry key. - scoped_array<bool> lookahead(new bool[num_ds]); - rrdatas->resize(num_ds); - - for (unsigned i = 0; i < num_ds; i++) { - uint8 digest_type; - base::StringPiece digest; - if (!U8(&digest_type) || - !VariableLength16(&digest)) { - return BAD_DATA; - } - - digest_types[i] = digest_type; - lookahead[i] = digest.empty(); - if (!digest.empty()) - (*rrdatas)[i] = digest; - } - - base::StringPiece next_entry_key; - if (!ReadAheadEntryKey(&next_entry_key)) - return BAD_DATA; - if (next_entry_key.size() < 4) - return BAD_DATA; - uint16 keyid = DNSSECKeySet::DNSKEYToKeyID(next_entry_key); - uint8 algorithm = next_entry_key[3]; - - bool good = false; - for (unsigned i = 0; i < num_ds; i++) { - base::StringPiece digest; - bool have_digest = false; - if (DigestKey(&digest, next_name, next_entry_key, digest_types[i], - keyid, algorithm)) { - have_digest = true; - } - - if (lookahead[i]) { - // If we needed to fill in one of the DS entries, but we can't calculate - // that type of digest, then we can't continue. - if (!have_digest) - return UNKNOWN_DIGEST; - (*rrdatas)[i] = digest; - good = true; - } else { - const base::StringPiece& given_digest = (*rrdatas)[i]; - if (have_digest && - given_digest.size() == digest.size() && - memcmp(given_digest.data(), digest.data(), digest.size()) == 0) { - good = true; - } - } - } - - if (!good) { - // We didn't calculate or match any of the digests. - return NO_DS_LINK; - } - - return OK; -} - -DNSSECChainVerifier::Error DNSSECChainVerifier::ReadGenericRRs( - std::vector<base::StringPiece>* rrdatas) { - uint8 num_rrs; - if (!U8(&num_rrs)) - return BAD_DATA; - rrdatas->resize(num_rrs); - - for (unsigned i = 0; i < num_rrs; i++) { - base::StringPiece rrdata; - if (!VariableLength16(&rrdata)) - return BAD_DATA; - (*rrdatas)[i] = rrdata; - } - - return OK; -} - -DNSSECChainVerifier::Error DNSSECChainVerifier::ReadCNAME( - std::vector<base::StringPiece>* rrdatas) { - base::StringPiece name; - if (!ReadName(&name)) - return BAD_DATA; - - rrdatas->resize(1); - (*rrdatas)[0] = name; - return OK; -} - -struct CAAHashTargetOID { - uint8 length; - uint8 bytes[13]; - DnsCAARecord::Policy::HashTarget value; -}; - -// kCAAHashTargets maps from the DER encoding of a hash target OID to our -// internal enumeration values. -static CAAHashTargetOID kCAAHashTargets[] = { - { 5, "\x06\x03\x55\x04\x24", DnsCAARecord::Policy::USER_CERTIFICATE }, - { 5, "\x06\x03\x55\x04\x25", DnsCAARecord::Policy::CA_CERTIFICATE }, - { 12 , "\x06\x0a\x2b\x06\x01\x04\x01\xd6\x79\x02\x03\x01", - DnsCAARecord::Policy::SUBJECT_PUBLIC_KEY_INFO}, - { 0 }, -}; - -struct CAAHashFunctionOID { - uint8 length; - uint8 bytes[12]; - int value; -}; - -// The values here are taken from NSS's freebl/hasht.h. Sadly, we cannot -// include it because it pulls in #defines that conflict with Chromium headers. -// However, these values are part of NSS's public API and so are stable. -static const int kHashNone = 0; -static const int kHashSHA256 = 4; -static const int kHashSHA384 = 5; -static const int kHashSHA512 = 6; - -// kCAAHashFunctions maps from the DER encoding of hash function OIDs to NSS's -// hash function enumeration. -static CAAHashFunctionOID kCAAHashFunctions[] = { - { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", kHashSHA256 }, - { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02", kHashSHA384 }, - { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03", kHashSHA512 }, - // WARNING: if you update this, be sure to update DigestLength too. - { 0 }, -}; - -// DigestLength returns the expected length of the digest for a given hash -// function. -static unsigned DigestLength(int algorithm) { - switch (algorithm) { - case kHashSHA256: - return 32; - case kHashSHA384: - return 48; - case kHashSHA512: - return 64; - default: - CHECK_NE(algorithm, algorithm); - return 0; - } -} - -DnsCAARecord::Policy::Policy() { -} - -DnsCAARecord::Policy::~Policy() { -} - -// ParseEnumeratedOID parses an OID from |i| and sets |*result| to one of the -// values from |values|, depending on the OID found. |i| is then advanced over -// the OID. -// -// If no OID is found then DISCARD is returned, unless |critical| is true, in -// which case |UNKNOWN_CRITICAL| is returned. -template<typename A, typename Enum> -static DnsCAARecord::ParseResult ParseEnumeratedOID(base::StringPiece* i, - bool critical, - const A* values, - Enum* result) { - base::StringPiece element; - if (!asn1::ParseElement(i, asn1::kOID, &element, NULL)) - return DnsCAARecord::SYNTAX_ERROR; - unsigned j; - for (j = 0; values[j].length; j++) { - if (element.size() == values[j].length && - memcmp(element.data(), values[j].bytes, element.size()) == 0) { - *result = values[j].value; - return DnsCAARecord::SUCCESS; - } - } - - if (critical) - return DnsCAARecord::UNKNOWN_CRITICAL; - return DnsCAARecord::DISCARD; -} - -// static -DnsCAARecord::ParseResult DnsCAARecord::Parse( - const std::vector<base::StringPiece>& rrdatas, - DnsCAARecord::Policy* output) { - // see http://tools.ietf.org/html/draft-hallambaker-donotissue-04 - output->authorized_hashes.clear(); - - for (std::vector<base::StringPiece>::const_iterator - ii = rrdatas.begin(); ii != rrdatas.end(); ++ii) { - base::StringPiece i = *ii; - - if (i.size() < 2) - return SYNTAX_ERROR; - const bool critical = (i[0] & 128) != 0; - const bool must_be_zero = (i[0] & 4) != 0; - const bool relying_use = (i[0] & 2) != 0; - const unsigned tag_length = i[1]; - i.remove_prefix(2); - - if (must_be_zero) - return UNKNOWN_CRITICAL; - - if (!relying_use) - continue; - - if (tag_length == 0 || tag_length > i.size()) - return SYNTAX_ERROR; - - const std::string tag(i.data(), tag_length); - i.remove_prefix(tag_length); - - if (tag_length == 4 && LowerCaseEqualsASCII(tag, "auth")) { - Policy::Hash hash; - - // AuthData ::= SEQUENCE { - // odi ObjectDigestIdentifier - // port INTEGER - // } - // ObjectDigestIdentifier ::= SEQUENCE { - // type OBJECT IDENTIFIER, - // digestAlgorithm OBJECT IDENTIFIER, - // digest OCTET STRING - // } - base::StringPiece seq; - if (!asn1::GetElement(&i, asn1::kSEQUENCE, &seq)) - return SYNTAX_ERROR; - - base::StringPiece odi; - if (!asn1::GetElement(&seq, asn1::kSEQUENCE, &odi)) - return SYNTAX_ERROR; - - // type - ParseResult r = ParseEnumeratedOID(&odi, critical, kCAAHashTargets, - &hash.target); - if (r == DISCARD) - continue; - if (r != SUCCESS) - return r; - - // hash function - r = ParseEnumeratedOID(&odi, critical, kCAAHashFunctions, - &hash.algorithm); - if (r == DISCARD) - continue; - if (r != SUCCESS) - return r; - - base::StringPiece hash_bytes; - if (!asn1::GetElement(&odi, asn1::kOCTETSTRING, &hash_bytes)) - return SYNTAX_ERROR; - - if (hash_bytes.size() != DigestLength(hash.algorithm)) - return SYNTAX_ERROR; - hash.data = hash_bytes.as_string(); - - base::StringPiece port_bytes; - if (!asn1::GetElement(&seq, asn1::kINTEGER, &port_bytes)) - return SYNTAX_ERROR; - - // The port is 1, 2 or 3 bytes. The three byte form is needed because - // values >= 0x8000 would be treated as signed unless padded with a - // leading zero byte. - if (port_bytes.size() == 0 || port_bytes.size() > 3) - return SYNTAX_ERROR; - hash.port = reinterpret_cast<const uint8*>(port_bytes.data())[0]; - if (port_bytes.size() > 1) { - hash.port <<= 8; - hash.port |= reinterpret_cast<const uint8*>(port_bytes.data())[1]; - } - if (port_bytes.size() > 2) { - hash.port <<= 8; - hash.port |= reinterpret_cast<const uint8*>(port_bytes.data())[2]; - } - if (hash.port > 65535) - return SYNTAX_ERROR; - - output->authorized_hashes.push_back(hash); - } else if (critical) { - return UNKNOWN_CRITICAL; - } - } - - if (output->authorized_hashes.empty()) - return DISCARD; - - return SUCCESS; -} - -void DnsTLSARecord::Parse( - const std::vector<base::StringPiece>& rrdatas, - std::vector<DnsTLSARecord::Match>* output) { - // see https://tools.ietf.org/html/rfc6698#section-2.1 - output->clear(); - - for (std::vector<base::StringPiece>::const_iterator - ii = rrdatas.begin(); ii != rrdatas.end(); ++ii) { - base::StringPiece i = *ii; - - if (i.size() < 3) - continue; - - const uint8 cert_usage = i[0]; - const uint8 selector = i[1]; - const uint8 match_type = i[2]; - i.remove_prefix(3); - - if (cert_usage != 3) { - // Type 3 is a "domain issued certificate" - i.e. a certificate (or - // public key) which is granted authority by the TLSA record. - continue; - } - - Match match; - - switch (selector) { - case 0: - match.target = Match::CERTIFICATE; - break; - case 1: - match.target = Match::SUBJECT_PUBLIC_KEY_INFO; - break; - default: - continue; - } - - switch (match_type) { - case 0: - match.algorithm = kHashNone; - break; - case 1: - match.algorithm = kHashSHA256; - break; - case 2: - match.algorithm = kHashSHA512; - break; - default: - continue; - } - - if (match.algorithm != kHashNone && - i.size() != DigestLength(match.algorithm)) { - continue; - } - - match.data = i.as_string(); - output->push_back(match); - } -} - -} // namespace net diff --git a/net/base/dnssec_chain_verifier.h b/net/base/dnssec_chain_verifier.h deleted file mode 100644 index f5a066b..0000000 --- a/net/base/dnssec_chain_verifier.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2011 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" -#include "net/base/net_export.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 NET_EXPORT_PRIVATE 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; - - // 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(); - static bool IsValidTerminalRRType(uint16 rrtype); - 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_; -}; - -// DnsCAARecord encapsulates code and types for dealing with Certificate -// Authority Authorization records. These are DNS records which can express -// limitations regarding acceptable certificates for a domain. See -// http://tools.ietf.org/html/draft-hallambaker-donotissue-04 -// TODO(agl): remove once DANE support has been released. -class NET_EXPORT_PRIVATE DnsCAARecord { - public: - enum ParseResult { - SUCCESS, // parse successful. - DISCARD, // no policies applying to this client were found. - SYNTAX_ERROR, // the record was syntactically invalid. - UNKNOWN_CRITICAL, // a critical record was not understood. - }; - - // A CAAPolicy is the result of parsing a set of CAA records. It describes a - // number of properies of certificates in a chain, any of which is sufficient - // to validate the chain. - struct NET_EXPORT_PRIVATE Policy { - public: - Policy(); - ~Policy(); - - // A HashTarget identifies the object that we are hashing. - enum HashTarget { - USER_CERTIFICATE, - CA_CERTIFICATE, - SUBJECT_PUBLIC_KEY_INFO, - }; - - // A Hash is a digest of some property of a certificate. - struct Hash { - HashTarget target; // what do we hash? - int algorithm; // NSS value, i.e. HASH_AlgSHA1. - std::string data; // digest, i.e. 20 bytes for SHA1. - unsigned port; // port number or 0 for any. - }; - - std::vector<Hash> authorized_hashes; - }; - - // Parse parses a series of DNS resource records and sets |output| to the - // result. - static ParseResult Parse(const std::vector<base::StringPiece>& rrdatas, - Policy* output); -}; - -class NET_EXPORT_PRIVATE DnsTLSARecord { - public: - // A Match is an authorized certificate or public key from the TLSA records. - struct NET_EXPORT_PRIVATE Match { - // A HashTarget identifies the object that we are hashing. - enum HashTarget { - CERTIFICATE, - SUBJECT_PUBLIC_KEY_INFO, - }; - - HashTarget target; // what do we hash? - // algorithm is an NSS HASH_HashType (i.e. HASH_AlgSHA1). But note that - // it can also be HASH_AlgNULL to indicate that |data| isn't hashed at - // all. - int algorithm; - std::string data; // digest, or raw data if |algorithm == HASH_AlgNULL|. - }; - - // Parse parses a series of TLSA resource records and sets |output| to the - // result. Unknown or invalid records are ignored, as are records with a - // usage other than "domain-issued certificate" (type 3). See - // https://tools.ietf.org/html/rfc6698#section-2.1.1. - static void Parse(const std::vector<base::StringPiece>& rrdatas, - std::vector<Match>* output); -}; - -} // namespace net - -#endif // NET_BASE_DNSSEC_CHAIN_VERIFIER_H_ diff --git a/net/base/dnssec_keyset.cc b/net/base/dnssec_keyset.cc deleted file mode 100644 index 133d158..0000000 --- a/net/base/dnssec_keyset.cc +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) 2012 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. - -#include "net/base/dnssec_keyset.h" - -#include <cryptohi.h> -#include <cryptoht.h> -#include <keyhi.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/time.h" -#include "crypto/nss_util.h" -#include "net/base/dns_util.h" - -namespace { - -// These are encoded AlgorithmIdentifiers for the given signature algorithm -// from RFC 4055. - -// 1.2.840.113549.1.1.5 -const unsigned char kRSAWithSHA1[] = { - 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0xd, 0x1, 0x1, 0x5, 0x5, 0x0, -}; - -// 1.2.840.113549.1.1.11 -const unsigned char kRSAWithSHA256[] = { - 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0, -}; - -// 1.2.840.113549.1.1.13 -const unsigned char kRSAWithSHA512[] = { - 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0xd, 0x1, 0x1, 0xd, 0x5, 0x0, -}; - -} // namespace - -namespace net { - -DNSSECKeySet::DNSSECKeySet() - : ignore_timestamps_(false) { -} - -DNSSECKeySet::~DNSSECKeySet() { -} - -bool DNSSECKeySet::AddKey(const base::StringPiece& dnskey) { - uint16 keyid = DNSKEYToKeyID(dnskey); - std::string der_encoded = ASN1WrapDNSKEY(dnskey); - if (der_encoded.empty()) - return false; - - keyids_.push_back(keyid); - public_keys_.push_back(der_encoded); - return true; -} - -bool DNSSECKeySet::CheckSignature( - const base::StringPiece& name, - const base::StringPiece& zone, - const base::StringPiece& signature, - uint16 rrtype, - const std::vector<base::StringPiece>& rrdatas) { - // signature has this format: - // algorithm uint8 - // labels uint8 - // ttl uint32 - // expires uint32 - // begins uint32 - // keyid uint16 - // - // followed by the actual signature. - if (signature.size() < 16) - return false; - const unsigned char* sigdata = - reinterpret_cast<const unsigned char*>(signature.data()); - - uint8 algorithm = sigdata[0]; - uint32 expires = static_cast<uint32>(sigdata[6]) << 24 | - static_cast<uint32>(sigdata[7]) << 16 | - static_cast<uint32>(sigdata[8]) << 8 | - static_cast<uint32>(sigdata[9]); - uint32 begins = static_cast<uint32>(sigdata[10]) << 24 | - static_cast<uint32>(sigdata[11]) << 16 | - static_cast<uint32>(sigdata[12]) << 8 | - static_cast<uint32>(sigdata[13]); - uint16 keyid = static_cast<uint16>(sigdata[14]) << 8 | - static_cast<uint16>(sigdata[15]); - - if (!ignore_timestamps_) { - uint32 now = static_cast<uint32>(base::Time::Now().ToTimeT()); - if (now < begins || now >= expires) - return false; - } - - base::StringPiece sig(signature.data() + 16, signature.size() - 16); - - // You should have RFC 4034, 3.1.8.1 open when reading this code. - unsigned signed_data_len = 0; - signed_data_len += 2; // rrtype - signed_data_len += 16; // (see signature format, above) - signed_data_len += zone.size(); - - for (std::vector<base::StringPiece>::const_iterator - i = rrdatas.begin(); i != rrdatas.end(); i++) { - signed_data_len += name.size(); - signed_data_len += 2; // rrtype - signed_data_len += 2; // class - signed_data_len += 4; // ttl - signed_data_len += 2; // RRDATA length - signed_data_len += i->size(); - } - - scoped_array<unsigned char> signed_data(new unsigned char[signed_data_len]); - unsigned j = 0; - - signed_data[j++] = static_cast<uint8>(rrtype >> 8); - signed_data[j++] = static_cast<uint8>(rrtype); - memcpy(&signed_data[j], sigdata, 16); - j += 16; - memcpy(&signed_data[j], zone.data(), zone.size()); - j += zone.size(); - - for (std::vector<base::StringPiece>::const_iterator - i = rrdatas.begin(); i != rrdatas.end(); i++) { - memcpy(&signed_data[j], name.data(), name.size()); - j += name.size(); - signed_data[j++] = static_cast<uint8>(rrtype >> 8); - signed_data[j++] = static_cast<uint8>(rrtype); - signed_data[j++] = 0; // CLASS (always IN = 1) - signed_data[j++] = 1; - // Copy the TTL from |signature|. - memcpy(&signed_data[j], signature.data() + 2, sizeof(uint32)); - j += sizeof(uint32); - unsigned rrdata_len = i->size(); - signed_data[j++] = rrdata_len >> 8; - signed_data[j++] = rrdata_len; - memcpy(&signed_data[j], i->data(), i->size()); - j += i->size(); - } - - DCHECK_EQ(j, signed_data_len); - - base::StringPiece signature_algorithm; - if (algorithm == kDNSSEC_RSA_SHA1 || - algorithm == kDNSSEC_RSA_SHA1_NSEC3) { - signature_algorithm = base::StringPiece( - reinterpret_cast<const char*>(kRSAWithSHA1), - sizeof(kRSAWithSHA1)); - } else if (algorithm == kDNSSEC_RSA_SHA256) { - signature_algorithm = base::StringPiece( - reinterpret_cast<const char*>(kRSAWithSHA256), - sizeof(kRSAWithSHA256)); - } else if (algorithm == kDNSSEC_RSA_SHA512) { - signature_algorithm = base::StringPiece( - reinterpret_cast<const char*>(kRSAWithSHA512), - sizeof(kRSAWithSHA512)); - } else { - // Unknown algorithm. - return false; - } - - // Check the signature with each trusted key which has a matching keyid. - DCHECK_EQ(public_keys_.size(), keyids_.size()); - for (unsigned i = 0; i < public_keys_.size(); i++) { - if (keyids_[i] != keyid) - continue; - - if (VerifySignature( - signature_algorithm, sig, public_keys_[i], - base::StringPiece(reinterpret_cast<const char*>(signed_data.get()), - signed_data_len))) { - return true; - } - } - - return false; -} - -// static -uint16 DNSSECKeySet::DNSKEYToKeyID(const base::StringPiece& dnskey) { - const unsigned char* data = - reinterpret_cast<const unsigned char*>(dnskey.data()); - - // RFC 4034: App B - uint32 ac = 0; - for (unsigned i = 0; i < dnskey.size(); i++) { - if (i & 1) { - ac += data[i]; - } else { - ac += static_cast<uint32>(data[i]) << 8; - } - } - ac += (ac >> 16) & 0xffff; - return ac; -} - -void DNSSECKeySet::IgnoreTimestamps() { - ignore_timestamps_ = true; -} - -bool DNSSECKeySet::VerifySignature( - base::StringPiece signature_algorithm, - base::StringPiece signature, - base::StringPiece public_key, - base::StringPiece signed_data) { - // This code is largely a copy-and-paste from - // crypto/signature_verifier_nss.cc. We can't change - // crypto::SignatureVerifier to always use NSS because we want the ability to - // be FIPS 140-2 compliant. However, we can't use crypto::SignatureVerifier - // here because some platforms don't support SHA256 signatures. Therefore, we - // use NSS directly. - - crypto::EnsureNSSInit(); - - CERTSubjectPublicKeyInfo* spki = NULL; - SECItem spki_der; - spki_der.type = siBuffer; - spki_der.data = (uint8*) public_key.data(); - spki_der.len = public_key.size(); - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der); - if (!spki) - return false; - SECKEYPublicKey* pub_key = SECKEY_ExtractPublicKey(spki); - SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki. - if (!pub_key) - return false; - - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - SECKEY_DestroyPublicKey(pub_key); - return false; - } - - SECItem sig_alg_der; - sig_alg_der.type = siBuffer; - sig_alg_der.data = (uint8*) signature_algorithm.data(); - sig_alg_der.len = signature_algorithm.size(); - SECAlgorithmID sig_alg_id; - SECStatus rv; - rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, - SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), - &sig_alg_der); - if (rv != SECSuccess) { - SECKEY_DestroyPublicKey(pub_key); - PORT_FreeArena(arena, PR_TRUE); - return false; - } - - SECItem sig; - sig.type = siBuffer; - sig.data = (uint8*) signature.data(); - sig.len = signature.size(); - SECOidTag hash_alg_tag; - VFYContext* vfy_context = - VFY_CreateContextWithAlgorithmID(pub_key, &sig, - &sig_alg_id, &hash_alg_tag, - NULL); - SECKEY_DestroyPublicKey(pub_key); - PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id. - if (!vfy_context) { - // A corrupted RSA signature could be detected without the data, so - // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE - // (-8182). - return false; - } - - rv = VFY_Begin(vfy_context); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - rv = VFY_Update(vfy_context, (uint8*) signed_data.data(), signed_data.size()); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - rv = VFY_End(vfy_context); - VFY_DestroyContext(vfy_context, PR_TRUE); - - return rv == SECSuccess; -} - -// This is an ASN.1 encoded AlgorithmIdentifier for RSA -static const unsigned char kASN1AlgorithmIdentifierRSA[] = { - 0x30, // SEQUENCE - 0x0d, // length (11 bytes) - 0x06, // OBJECT IDENTIFER - 0x09, // length (9 bytes) - // OID 1.2.840.113549.1.1.1 (RSA) - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - // NULL of length 0 - 0x05, 0x00, -}; - -// EncodeASN1Length assumes that |*length| contains the number of DER-encoded, -// length-prefixed ASN.1 bytes to follow and serialises the length to |out[*j]| -// and updates |j| and |length| accordingly. -static void EncodeASN1Length(unsigned char* out, unsigned* j, - unsigned* length) { - if ((*length - 1) < 128) { - (*length) -= 1; - out[(*j)++] = *length; - } else if ((*length - 2) < 256) { - (*length) -= 2; - out[(*j)++] = 0x80 | 1; - out[(*j)++] = *length; - } else { - (*length) -= 3; - out[(*j)++] = 0x80 | 2; - out[(*j)++] = *length >> 8; - out[(*j)++] = *length; - } -} - -// AdvanceForASN1Length returns the number of bytes required to encode a ASN1 -// DER length value of |remaining|. -static unsigned AdvanceForASN1Length(unsigned remaining) { - if (remaining < 128) { - return 1; - } else if (remaining < 256) { - return 2; - } else if (remaining < 65536) { - return 3; - } else { - NOTREACHED(); - return 3; - } -} - -// ASN1WrapDNSKEY converts the DNSKEY RDATA in |dnskey| into the ASN.1 wrapped -// format expected by NSS. To wit: -// SubjectPublicKeyInfo ::= SEQUENCE { -// algorithm AlgorithmIdentifier, -// subjectPublicKey BIT STRING } -std::string DNSSECKeySet::ASN1WrapDNSKEY(const base::StringPiece& dnskey) { - const unsigned char* data = - reinterpret_cast<const unsigned char*>(dnskey.data()); - - if (dnskey.size() < 5 || dnskey.size() > 32767) - return ""; - const uint8 algorithm = data[3]; - if (algorithm != kDNSSEC_RSA_SHA1 && - algorithm != kDNSSEC_RSA_SHA1_NSEC3 && - algorithm != kDNSSEC_RSA_SHA256 && - algorithm != kDNSSEC_RSA_SHA512) { - return ""; - } - - unsigned exp_length; - unsigned exp_offset; - // First we extract the public exponent. - if (data[4] == 0) { - if (dnskey.size() < 7) - return ""; - exp_length = static_cast<unsigned>(data[5]) << 8 | - static_cast<unsigned>(data[6]); - exp_offset = 7; - } else { - exp_length = static_cast<unsigned>(data[4]); - exp_offset = 5; - } - - // We refuse to deal with large public exponents. - if (exp_length > 3) - return ""; - if (dnskey.size() < exp_offset + exp_length) - return ""; - - unsigned exp = 0; - for (unsigned i = 0; i < exp_length; i++) { - exp <<= 8; - exp |= static_cast<unsigned>(data[exp_offset + i]); - } - - unsigned n_offset = exp_offset + exp_length; - unsigned n_length = dnskey.size() - n_offset; - - // Anything smaller than 512 bits is too weak to be trusted. - if (n_length < 64) - return ""; - - // If the MSB of exp is true then we need to prefix a zero byte to stop the - // ASN.1 encoding from being negative. - if (exp & (1 << ((8 * exp_length) - 1))) - exp_length++; - - // Likewise with the modulus - unsigned n_padding = data[n_offset] & 0x80 ? 1 : 0; - - // We now calculate the length of the full ASN.1 encoded public key. We're - // working backwards from the end of the structure. Keep in mind that it's: - // SEQUENCE - // AlgorithmIdentifier - // BITSTRING - // SEQUENCE - // INTEGER - // INTEGER - unsigned length = 0; - length += exp_length; // exponent data - length++; // we know that |exp_length| < 128 - length++; // INTEGER tag for exponent - length += n_length + n_padding; - length += AdvanceForASN1Length(n_length + n_padding); - length++; // INTEGER tag for modulus - length += AdvanceForASN1Length(length); // SEQUENCE length - length++; // SEQUENCE tag - length++; // BITSTRING unused bits - length += AdvanceForASN1Length(length); // BITSTRING length - length++; // BITSTRING tag - length += sizeof(kASN1AlgorithmIdentifierRSA); - length += AdvanceForASN1Length(length); // SEQUENCE length - length++; // SEQUENCE tag - - scoped_array<unsigned char> out(new unsigned char[length]); - - // Now we walk forwards and serialise the ASN.1, undoing the steps above. - unsigned j = 0; - out[j++] = 0x30; // SEQUENCE - length--; - EncodeASN1Length(out.get(), &j, &length); - memcpy(&out[j], kASN1AlgorithmIdentifierRSA, - sizeof(kASN1AlgorithmIdentifierRSA)); - j += sizeof(kASN1AlgorithmIdentifierRSA); - length -= sizeof(kASN1AlgorithmIdentifierRSA); - out[j++] = 3; // BITSTRING tag - length--; - EncodeASN1Length(out.get(), &j, &length); - out[j++] = 0; // BITSTRING unused bits - length--; - out[j++] = 0x30; // SEQUENCE - length--; - EncodeASN1Length(out.get(), &j, &length); - out[j++] = 2; // INTEGER - length--; - unsigned l = n_length + n_padding; - if (l < 128) { - out[j++] = l; - length--; - } else if (l < 256) { - out[j++] = 0x80 | 1; - out[j++] = l; - length -= 2; - } else if (l < 65536) { - out[j++] = 0x80 | 2; - out[j++] = l >> 8; - out[j++] = l; - length -= 3; - } else { - NOTREACHED(); - } - - if (n_padding) { - out[j++] = 0; - length--; - } - memcpy(&out[j], &data[n_offset], n_length); - j += n_length; - length -= n_length; - out[j++] = 2; // INTEGER - length--; - out[j++] = exp_length; - length--; - for (unsigned i = exp_length - 1; i < exp_length; i--) { - out[j++] = exp >> (8 * i); - length--; - } - - DCHECK_EQ(0u, length); - - return std::string(reinterpret_cast<char*>(out.get()), j); -} - -} // namespace net diff --git a/net/base/dnssec_keyset.h b/net/base/dnssec_keyset.h deleted file mode 100644 index 0db4d96..0000000 --- a/net/base/dnssec_keyset.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2011 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_KEYSET_H_ -#define NET_BASE_DNSSEC_KEYSET_H_ - -#include <string> -#include <vector> - -#include "base/string_piece.h" -#include "net/base/net_export.h" - -namespace net { - -// DNSSECKeySet function wraps crypto/signature_verifier.h to accept -// DNSSEC encodings. (See RFC 4043) -class NET_EXPORT_PRIVATE DNSSECKeySet { - public: - DNSSECKeySet(); - ~DNSSECKeySet(); - - // AddKey adds a key to the trusted set. - // dnskey: the RRDATA of a DNSKEY. - bool AddKey(const base::StringPiece& dnskey); - - // CheckSignature checks the DNSSEC signature on set of resource records. - // name: the domain that the records are from - // zone: the signing zone - // signature: the RRSIG signature, not include the signing zone. - // rrtype: the type of the resource records - // rrdatas: the RRDATA of the signed resource records, in canonical order. - bool CheckSignature(const base::StringPiece& name, - const base::StringPiece& zone, - const base::StringPiece& signature, - uint16 rrtype, - const std::vector<base::StringPiece>& rrdatas); - - // DNSKEYToKeyID converts the RRDATA of a DNSKEY to its key id. See RFC 4043, - // app B. - static uint16 DNSKEYToKeyID(const base::StringPiece& dnskey); - - // Used for testing: the timestamps on signatures will be ignored to allow - // golden data to remain valid. - void IgnoreTimestamps(); - - private: - bool VerifySignature( - base::StringPiece signature_algorithm, - base::StringPiece signature, - base::StringPiece public_key, - base::StringPiece signed_data); - - std::string ASN1WrapDNSKEY(const base::StringPiece& dnskey); - - bool ignore_timestamps_; - std::vector<uint16> keyids_; - std::vector<std::string> public_keys_; -}; - -} // namespace net - -#endif // NET_BASE_DNSSEC_KEYSET_H_ diff --git a/net/base/dnssec_unittest.cc b/net/base/dnssec_unittest.cc deleted file mode 100644 index ae004bf..0000000 --- a/net/base/dnssec_unittest.cc +++ /dev/null @@ -1,887 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/asn1_util.h" -#include "net/base/dns_util.h" -#include "net/base/dnssec_chain_verifier.h" -#include "net/base/dnssec_keyset.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -// This is a DNSKEY record. You can get one with `dig dnskey .` (where '.' can -// be any signed zone). -static const unsigned char kExampleKey[] = { - 0x01, 0x01, 0x03, 0x08, 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9, 0x55, - 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80, 0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, - 0x6d, 0xbd, 0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec, 0x90, 0x6d, 0x21, - 0x16, 0xd0, 0xef, 0x20, 0x70, 0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf, - 0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82, 0x34, 0x13, 0x3a, 0xc0, 0x71, - 0x0a, 0x81, 0x18, 0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc, 0x83, 0x43, - 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32, 0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, - 0x51, 0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb, 0x35, 0x95, 0x80, 0x25, - 0x0f, 0x55, 0x9c, 0xc5, 0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8, 0xcf, - 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4, 0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, - 0x5f, 0xa4, 0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e, 0xcb, 0xcf, 0x56, - 0x34, 0x74, 0x65, 0x2c, 0x33, 0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9, - 0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04, 0x1b, 0x6e, 0x03, 0xa1, 0xb7, - 0x2d, 0x0a, 0x73, 0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33, 0x23, 0x24, - 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9, 0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, - 0x2e, 0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e, 0xce, 0xc9, 0x07, 0x57, - 0x7d, 0x9e, 0x7b, 0xad, 0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9, 0x01, - 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14, 0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, - 0x9c, 0x2e, 0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5, 0x75, 0xfc, 0x21, - 0x60, 0x1e, 0x0d, 0xee, 0x49, 0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52, - 0x4d, 0x62, 0x87, 0x3d, -}; - -TEST(SignatureVerifierDNSSECTest, KeyID) { - uint16 keyid = DNSSECKeySet::DNSKEYToKeyID( - base::StringPiece(reinterpret_cast<const char*>(kExampleKey), - sizeof(kExampleKey))); - ASSERT_EQ(19036u, keyid); -} - -TEST(SignatureVerifierDNSSECTest, ImportKey) { - DNSSECKeySet keyset; - - ASSERT_TRUE(keyset.AddKey( - base::StringPiece(reinterpret_cast<const char*>(kExampleKey), - sizeof(kExampleKey)))); -} - -// This is root's DNSSKEY signature -const unsigned char kSignatureData[] = { - 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x4c, 0x59, 0xfe, 0xff, 0x4c, 0x46, 0x38, - 0x80, 0x4a, 0x5c, 0x2e, 0x63, 0xb7, 0x71, 0xf6, 0xb0, 0x32, 0xb7, 0x71, 0xb5, - 0xaa, 0xca, 0xd4, 0x4c, 0xeb, 0xf1, 0x7f, 0xa3, 0x28, 0x00, 0x43, 0x85, 0x76, - 0x9f, 0x46, 0x3d, 0x85, 0x39, 0x8d, 0x66, 0x7a, 0xeb, 0x4c, 0x6e, 0x60, 0x0a, - 0xe6, 0x49, 0x20, 0x47, 0xf9, 0x13, 0x81, 0x3e, 0xc8, 0xf5, 0x09, 0x92, 0x75, - 0xab, 0x87, 0xc6, 0x70, 0x35, 0xdd, 0xd9, 0x9e, 0xb6, 0xd4, 0x09, 0x66, 0xcc, - 0x0d, 0x71, 0x71, 0x3d, 0x4c, 0x96, 0xbc, 0x7d, 0x2c, 0x05, 0x0a, 0x9c, 0xc3, - 0xcd, 0x5d, 0xfa, 0xab, 0xb5, 0x17, 0x55, 0xca, 0x86, 0x31, 0x4b, 0x7b, 0x93, - 0x4a, 0x4b, 0x91, 0xd9, 0xea, 0x71, 0xf8, 0x3f, 0xb3, 0x4f, 0xb4, 0x94, 0xcd, - 0x6f, 0xe4, 0x83, 0xf6, 0xd4, 0xcb, 0xb8, 0x3c, 0x7d, 0xf6, 0x73, 0xf7, 0xf2, - 0x6f, 0xa5, 0x92, 0x25, 0xdc, 0xe5, 0xdd, 0x83, 0x55, 0xef, 0xde, 0x20, 0x00, - 0x64, 0x9e, 0x25, 0x76, 0x70, 0x08, 0x14, 0x29, 0xec, 0x66, 0xa3, 0xfd, 0x48, - 0x3b, 0x67, 0x21, 0x6e, 0x3d, 0x1e, 0x26, 0xb4, 0x74, 0x07, 0x1f, 0x1f, 0x4d, - 0xdf, 0x74, 0xae, 0x04, 0x70, 0xf0, 0x08, 0x3f, 0xe2, 0x6a, 0x39, 0x51, 0x79, - 0x25, 0xd9, 0xc2, 0xf9, 0xa4, 0xb6, 0x38, 0x4a, 0x5f, 0x80, 0x12, 0x4d, 0x98, - 0x7a, 0x3b, 0x8d, 0xb8, 0x3d, 0x51, 0x6b, 0x7c, 0x27, 0xc9, 0xc0, 0xcc, 0x26, - 0x73, 0xef, 0x43, 0x8a, 0x6c, 0x42, 0xa5, 0x2d, 0x11, 0x77, 0x9f, 0xe4, 0xa4, - 0x50, 0xb3, 0x29, 0xe4, 0x5c, 0x04, 0xc7, 0x38, 0xbb, 0xfa, 0x27, 0xfa, 0x02, - 0x76, 0x07, 0x5b, 0x88, 0x39, 0xd8, 0x60, 0x81, 0x9f, 0x36, 0xfc, 0x9c, 0x17, - 0x83, 0x0a, 0x54, 0x59, 0x86, 0x6b, 0xd6, 0x54, 0x5c, 0x9a, 0xba, 0x10, 0xe6, - 0x2e, 0x12, 0x78, 0x85, 0x1c, 0xed, 0x26, 0x79, 0xd4, 0xfc, 0x83, 0x51, -}; - -// The is root's 1024-bit key. -static const unsigned char kRRDATA1[] = { - 1, 0, 3, 8, 3, 1, 0, 1, 189, 96, 112, 56, 65, 148, 127, 253, 50, 88, 20, 197, - 45, 34, 147, 103, 112, 99, 242, 98, 4, 138, 85, 248, 72, 74, 101, 94, 203, - 113, 204, 77, 115, 164, 37, 143, 142, 187, 66, 49, 208, 220, 88, 38, 218, 45, - 139, 19, 220, 58, 46, 163, 197, 13, 41, 224, 230, 165, 106, 212, 230, 5, 201, - 48, 109, 220, 52, 41, 166, 160, 231, 0, 250, 226, 79, 5, 185, 168, 132, 13, - 12, 209, 111, 223, 140, 168, 235, 123, 0, 116, 23, 148, 224, 111, 109, 191, - 183, 115, 79, 155, 15, 200, 8, 38, 86, 30, 71, 12, 39, 190, 233, 115, 54, - 248, 135, 165, 215, 233, 20, 40, 39, 165, 240, 135, 50, 215, 216, 81, -}; - -// The is root's 2048-bit key. -static const unsigned char kRRDATA2[] = { - 1, 1, 3, 8, 3, 1, 0, 1, 168, 0, 32, 169, 85, 102, 186, 66, 232, 134, 187, - 128, 76, 218, 132, 228, 126, 245, 109, 189, 122, 236, 97, 38, 21, 85, 44, - 236, 144, 109, 33, 22, 208, 239, 32, 112, 40, 197, 21, 84, 20, 77, 254, 175, - 231, 199, 203, 143, 0, 93, 209, 130, 52, 19, 58, 192, 113, 10, 129, 24, 44, - 225, 253, 20, 173, 34, 131, 188, 131, 67, 95, 157, 242, 246, 49, 50, 81, 147, - 26, 23, 109, 240, 218, 81, 229, 79, 66, 230, 4, 134, 13, 251, 53, 149, 128, - 37, 15, 85, 156, 197, 67, 196, 255, 213, 28, 190, 61, 232, 207, 208, 103, 25, - 35, 127, 159, 196, 126, 231, 41, 218, 6, 131, 95, 164, 82, 232, 37, 233, 161, - 142, 188, 46, 203, 207, 86, 52, 116, 101, 44, 51, 207, 86, 169, 3, 59, 205, - 245, 217, 115, 18, 23, 151, 236, 128, 137, 4, 27, 110, 3, 161, 183, 45, 10, - 115, 91, 152, 78, 3, 104, 115, 9, 51, 35, 36, 242, 124, 45, 186, 133, 233, - 219, 21, 232, 58, 1, 67, 56, 46, 151, 75, 6, 33, 193, 142, 98, 94, 206, 201, - 7, 87, 125, 158, 123, 173, 233, 82, 65, 168, 30, 187, 232, 169, 1, 212, 211, - 39, 110, 64, 177, 20, 192, 162, 230, 252, 56, 209, 156, 46, 106, 171, 2, 100, - 75, 40, 19, 245, 117, 252, 33, 96, 30, 13, 238, 73, 205, 158, 233, 106, 67, - 16, 62, 82, 77, 98, 135, 61, -}; - -TEST(SignatureVerifierDNSSECTest, VerifySignature) { - DNSSECKeySet keyset; - - ASSERT_TRUE(keyset.AddKey( - base::StringPiece(reinterpret_cast<const char*>(kExampleKey), - sizeof(kExampleKey)))); - keyset.IgnoreTimestamps(); - - static const uint16 kDNSKEY = 48; // RRTYPE for DNSKEY - static const char kRootLabel[] = ""; - base::StringPiece root(kRootLabel, 1); - base::StringPiece signature(reinterpret_cast<const char*>(kSignatureData), - sizeof(kSignatureData)); - std::vector<base::StringPiece> rrdatas; - rrdatas.push_back(base::StringPiece(reinterpret_cast<const char*>(kRRDATA1), - sizeof(kRRDATA1))); - rrdatas.push_back(base::StringPiece(reinterpret_cast<const char*>(kRRDATA2), - sizeof(kRRDATA2))); - ASSERT_TRUE(keyset.CheckSignature(root, root, signature, kDNSKEY, rrdatas)); -} - -static std::string FromDNSName(const char* name) { - std::string result; - bool ok = DNSDomainFromDot(name, &result); - EXPECT_TRUE(ok); - if (!ok) - result = ""; - return result; -} - -TEST(DNSSECChainVerifierTest, MatchingLabels) { - ASSERT_EQ(1u, DNSSECChainVerifier::MatchingLabels( - FromDNSName(""), FromDNSName(""))); - ASSERT_EQ(2u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("org"), FromDNSName("org"))); - ASSERT_EQ(3u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("foo.org"), FromDNSName("foo.org"))); - ASSERT_EQ(3u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("bar.foo.org"), FromDNSName("foo.org"))); - ASSERT_EQ(3u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("foo.org"), FromDNSName("bar.foo.org"))); - ASSERT_EQ(1u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("foo.org"), FromDNSName("foo.com"))); - ASSERT_EQ(2u, DNSSECChainVerifier::MatchingLabels( - FromDNSName("foo.org"), FromDNSName("bar.org"))); -} - -static const unsigned char kChain[] = { - 0x4a, 0x5c, 0x01, 0x01, 0x10, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x4c, 0x59, - 0xfe, 0xff, 0x4c, 0x46, 0x38, 0x80, 0x4a, 0x5c, 0x2e, 0x63, 0xb7, 0x71, 0xf6, - 0xb0, 0x32, 0xb7, 0x71, 0xb5, 0xaa, 0xca, 0xd4, 0x4c, 0xeb, 0xf1, 0x7f, 0xa3, - 0x28, 0x00, 0x43, 0x85, 0x76, 0x9f, 0x46, 0x3d, 0x85, 0x39, 0x8d, 0x66, 0x7a, - 0xeb, 0x4c, 0x6e, 0x60, 0x0a, 0xe6, 0x49, 0x20, 0x47, 0xf9, 0x13, 0x81, 0x3e, - 0xc8, 0xf5, 0x09, 0x92, 0x75, 0xab, 0x87, 0xc6, 0x70, 0x35, 0xdd, 0xd9, 0x9e, - 0xb6, 0xd4, 0x09, 0x66, 0xcc, 0x0d, 0x71, 0x71, 0x3d, 0x4c, 0x96, 0xbc, 0x7d, - 0x2c, 0x05, 0x0a, 0x9c, 0xc3, 0xcd, 0x5d, 0xfa, 0xab, 0xb5, 0x17, 0x55, 0xca, - 0x86, 0x31, 0x4b, 0x7b, 0x93, 0x4a, 0x4b, 0x91, 0xd9, 0xea, 0x71, 0xf8, 0x3f, - 0xb3, 0x4f, 0xb4, 0x94, 0xcd, 0x6f, 0xe4, 0x83, 0xf6, 0xd4, 0xcb, 0xb8, 0x3c, - 0x7d, 0xf6, 0x73, 0xf7, 0xf2, 0x6f, 0xa5, 0x92, 0x25, 0xdc, 0xe5, 0xdd, 0x83, - 0x55, 0xef, 0xde, 0x20, 0x00, 0x64, 0x9e, 0x25, 0x76, 0x70, 0x08, 0x14, 0x29, - 0xec, 0x66, 0xa3, 0xfd, 0x48, 0x3b, 0x67, 0x21, 0x6e, 0x3d, 0x1e, 0x26, 0xb4, - 0x74, 0x07, 0x1f, 0x1f, 0x4d, 0xdf, 0x74, 0xae, 0x04, 0x70, 0xf0, 0x08, 0x3f, - 0xe2, 0x6a, 0x39, 0x51, 0x79, 0x25, 0xd9, 0xc2, 0xf9, 0xa4, 0xb6, 0x38, 0x4a, - 0x5f, 0x80, 0x12, 0x4d, 0x98, 0x7a, 0x3b, 0x8d, 0xb8, 0x3d, 0x51, 0x6b, 0x7c, - 0x27, 0xc9, 0xc0, 0xcc, 0x26, 0x73, 0xef, 0x43, 0x8a, 0x6c, 0x42, 0xa5, 0x2d, - 0x11, 0x77, 0x9f, 0xe4, 0xa4, 0x50, 0xb3, 0x29, 0xe4, 0x5c, 0x04, 0xc7, 0x38, - 0xbb, 0xfa, 0x27, 0xfa, 0x02, 0x76, 0x07, 0x5b, 0x88, 0x39, 0xd8, 0x60, 0x81, - 0x9f, 0x36, 0xfc, 0x9c, 0x17, 0x83, 0x0a, 0x54, 0x59, 0x86, 0x6b, 0xd6, 0x54, - 0x5c, 0x9a, 0xba, 0x10, 0xe6, 0x2e, 0x12, 0x78, 0x85, 0x1c, 0xed, 0x26, 0x79, - 0xd4, 0xfc, 0x83, 0x51, 0x02, 0x00, 0x88, 0x01, 0x00, 0x03, 0x08, 0x03, 0x01, - 0x00, 0x01, 0xbd, 0x60, 0x70, 0x38, 0x41, 0x94, 0x7f, 0xfd, 0x32, 0x58, 0x14, - 0xc5, 0x2d, 0x22, 0x93, 0x67, 0x70, 0x63, 0xf2, 0x62, 0x04, 0x8a, 0x55, 0xf8, - 0x48, 0x4a, 0x65, 0x5e, 0xcb, 0x71, 0xcc, 0x4d, 0x73, 0xa4, 0x25, 0x8f, 0x8e, - 0xbb, 0x42, 0x31, 0xd0, 0xdc, 0x58, 0x26, 0xda, 0x2d, 0x8b, 0x13, 0xdc, 0x3a, - 0x2e, 0xa3, 0xc5, 0x0d, 0x29, 0xe0, 0xe6, 0xa5, 0x6a, 0xd4, 0xe6, 0x05, 0xc9, - 0x30, 0x6d, 0xdc, 0x34, 0x29, 0xa6, 0xa0, 0xe7, 0x00, 0xfa, 0xe2, 0x4f, 0x05, - 0xb9, 0xa8, 0x84, 0x0d, 0x0c, 0xd1, 0x6f, 0xdf, 0x8c, 0xa8, 0xeb, 0x7b, 0x00, - 0x74, 0x17, 0x94, 0xe0, 0x6f, 0x6d, 0xbf, 0xb7, 0x73, 0x4f, 0x9b, 0x0f, 0xc8, - 0x08, 0x26, 0x56, 0x1e, 0x47, 0x0c, 0x27, 0xbe, 0xe9, 0x73, 0x36, 0xf8, 0x87, - 0xa5, 0xd7, 0xe9, 0x14, 0x28, 0x27, 0xa5, 0xf0, 0x87, 0x32, 0xd7, 0xd8, 0x51, - 0x01, 0x08, 0x01, 0x01, 0x03, 0x08, 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, - 0xa9, 0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80, 0x4c, 0xda, 0x84, 0xe4, - 0x7e, 0xf5, 0x6d, 0xbd, 0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec, 0x90, - 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70, 0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, - 0xfe, 0xaf, 0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82, 0x34, 0x13, 0x3a, - 0xc0, 0x71, 0x0a, 0x81, 0x18, 0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc, - 0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32, 0x51, 0x93, 0x1a, 0x17, 0x6d, - 0xf0, 0xda, 0x51, 0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb, 0x35, 0x95, - 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5, 0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, - 0xe8, 0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4, 0x7e, 0xe7, 0x29, 0xda, - 0x06, 0x83, 0x5f, 0xa4, 0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e, 0xcb, - 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33, 0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, - 0xf5, 0xd9, 0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04, 0x1b, 0x6e, 0x03, - 0xa1, 0xb7, 0x2d, 0x0a, 0x73, 0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33, - 0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9, 0xdb, 0x15, 0xe8, 0x3a, 0x01, - 0x43, 0x38, 0x2e, 0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e, 0xce, 0xc9, - 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad, 0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, - 0xa9, 0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14, 0xc0, 0xa2, 0xe6, 0xfc, - 0x38, 0xd1, 0x9c, 0x2e, 0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5, 0x75, - 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49, 0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, - 0x3e, 0x52, 0x4d, 0x62, 0x87, 0x3d, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x2b, - 0x00, 0x90, 0x08, 0x01, 0x00, 0x02, 0xa3, 0x00, 0x4c, 0x54, 0xb9, 0x00, 0x4c, - 0x4b, 0x70, 0x70, 0xa1, 0x20, 0x5c, 0x2f, 0xd0, 0x29, 0x2c, 0x13, 0xf8, 0xbc, - 0xbb, 0xfe, 0xd2, 0xb2, 0xf2, 0x6a, 0xfa, 0xe0, 0x4a, 0x2e, 0x80, 0xb5, 0x3c, - 0xb9, 0xa1, 0x6f, 0x14, 0x57, 0x9e, 0x80, 0x3f, 0xb8, 0x5d, 0xbc, 0xac, 0x81, - 0x1f, 0x7a, 0xf9, 0x18, 0xda, 0x31, 0x3f, 0x97, 0x68, 0x2b, 0x37, 0x79, 0xb2, - 0xb8, 0xd7, 0x1a, 0x40, 0x35, 0xb1, 0x3b, 0x64, 0x22, 0x0d, 0xb6, 0xb9, 0x17, - 0x64, 0xfe, 0xed, 0x23, 0xaf, 0x17, 0xb2, 0x7f, 0x49, 0xa9, 0x2b, 0xa0, 0x06, - 0xfb, 0xe9, 0x4a, 0x17, 0x88, 0x91, 0x55, 0xe5, 0xb3, 0x5f, 0xee, 0x73, 0xd7, - 0x00, 0x58, 0x21, 0x29, 0x39, 0x7a, 0xe2, 0xc5, 0x03, 0x8f, 0xf2, 0x11, 0xed, - 0xd6, 0xb0, 0xdb, 0x5e, 0x7f, 0x37, 0x46, 0x80, 0xf9, 0x67, 0xfc, 0xdd, 0xbf, - 0xb5, 0x46, 0x4d, 0xe5, 0xcf, 0x3f, 0xf9, 0xb2, 0x08, 0x52, 0x36, 0xf5, 0x7f, - 0x8c, 0x19, 0x88, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x10, - 0x07, 0x01, 0x00, 0x00, 0x03, 0x84, 0x4c, 0x54, 0x44, 0xe0, 0x4c, 0x41, 0xc1, - 0xd0, 0x53, 0x76, 0x53, 0x1b, 0xac, 0x55, 0xb7, 0x5b, 0xc8, 0xca, 0xe7, 0x05, - 0xe2, 0x19, 0x50, 0x5b, 0xf4, 0x05, 0xc6, 0x11, 0x41, 0xb7, 0xde, 0x29, 0xd8, - 0x71, 0x9b, 0x1d, 0x44, 0x8b, 0x1f, 0xf9, 0x9d, 0x4e, 0x94, 0xc9, 0xe9, 0xfe, - 0xc2, 0x7c, 0x73, 0xd1, 0xc7, 0x9b, 0xbe, 0x15, 0x8f, 0xc4, 0xb6, 0xe7, 0x91, - 0xe4, 0x67, 0xc3, 0xab, 0x2f, 0x89, 0x60, 0xf0, 0x29, 0xfb, 0xb1, 0x0a, 0x05, - 0xc6, 0xf2, 0xf6, 0xb3, 0xf2, 0x4d, 0x68, 0xb5, 0xde, 0x66, 0x45, 0x39, 0xe8, - 0x9b, 0xfa, 0x0f, 0x7d, 0x9d, 0xbc, 0xd4, 0xc5, 0xb7, 0x14, 0x9d, 0xa0, 0x21, - 0x33, 0x04, 0x2a, 0x97, 0x40, 0x98, 0x40, 0x16, 0xfe, 0xe0, 0xcf, 0xdd, 0x22, - 0x94, 0xbe, 0xbc, 0x4c, 0x09, 0x5c, 0xef, 0x0e, 0x99, 0xac, 0xa0, 0xb6, 0xa5, - 0xde, 0xe8, 0xf1, 0x1f, 0xff, 0x84, 0x3a, 0x19, 0x7e, 0x46, 0x26, 0x6f, 0xdc, - 0xfd, 0x15, 0x9d, 0xfd, 0x6e, 0x58, 0xf2, 0x94, 0x02, 0x25, 0x9a, 0x37, 0x99, - 0x9f, 0x27, 0xdb, 0xbe, 0xcd, 0x3a, 0x2b, 0xa8, 0xa3, 0xd6, 0x96, 0x4e, 0xdb, - 0xe5, 0x87, 0x55, 0xd8, 0xd2, 0x6e, 0xa7, 0x09, 0x7d, 0xe4, 0xfc, 0x20, 0x6c, - 0x4d, 0x99, 0xb3, 0x48, 0xf9, 0x63, 0xee, 0x4e, 0xa5, 0x24, 0xcc, 0xb1, 0x99, - 0xf8, 0x0e, 0x1d, 0x6e, 0x1a, 0x88, 0x0b, 0x98, 0xa5, 0x21, 0xdc, 0x43, 0x75, - 0xb5, 0x20, 0x5a, 0xcd, 0xac, 0xb8, 0x08, 0x60, 0x2c, 0xb0, 0x2f, 0x6f, 0xac, - 0x7b, 0xda, 0x16, 0x24, 0xc7, 0xc6, 0x22, 0xf6, 0xc8, 0x47, 0x8a, 0x93, 0x93, - 0x1e, 0x1d, 0xb5, 0xe2, 0x1e, 0xe5, 0xc6, 0x8e, 0xa9, 0xe4, 0xd3, 0x35, 0x97, - 0x31, 0x64, 0xce, 0xd8, 0xa1, 0x16, 0x1d, 0x67, 0x0e, 0x2c, 0x07, 0x2e, 0x67, - 0xef, 0xcc, 0x80, 0x59, 0x35, 0xdd, 0xa0, 0xa8, 0x60, 0x99, 0x4e, 0x8e, 0x04, - 0x00, 0x88, 0x01, 0x00, 0x03, 0x07, 0x03, 0x01, 0x00, 0x01, 0x9c, 0xf3, 0x56, - 0x70, 0x44, 0x1d, 0x37, 0x51, 0xf9, 0x88, 0xa4, 0xf7, 0xf9, 0x1f, 0x60, 0x1b, - 0x14, 0x03, 0xa8, 0xcd, 0xc1, 0xaf, 0x44, 0x6e, 0x5c, 0xdb, 0x83, 0x64, 0x48, - 0x9a, 0x7f, 0xdc, 0x6b, 0x64, 0x46, 0x72, 0xb5, 0xd5, 0x7f, 0xd2, 0xe9, 0x95, - 0x2f, 0x14, 0xf9, 0xff, 0x68, 0xbf, 0x35, 0xb7, 0xcc, 0x13, 0x95, 0xab, 0x07, - 0x4d, 0x5d, 0x47, 0xdb, 0xaa, 0xc0, 0xfc, 0xf9, 0xdc, 0xd4, 0x97, 0x51, 0x64, - 0xbb, 0x8a, 0x66, 0x71, 0xa8, 0x1c, 0xb8, 0x7b, 0xa4, 0xf6, 0xb9, 0x54, 0x98, - 0xf6, 0xa7, 0x41, 0xa8, 0xae, 0x8e, 0x17, 0x2b, 0x7e, 0xdd, 0x60, 0x8b, 0x84, - 0x21, 0xe4, 0x68, 0xdd, 0xfc, 0x34, 0x5b, 0x8f, 0x53, 0x14, 0x93, 0xa3, 0xb1, - 0xd6, 0xcb, 0x9f, 0x26, 0xac, 0xfd, 0x9e, 0xf3, 0x44, 0x8a, 0x35, 0xf6, 0x8b, - 0x20, 0xf8, 0x7a, 0xf7, 0xa2, 0x2c, 0xf3, 0xfd, 0x00, 0x88, 0x01, 0x00, 0x03, - 0x07, 0x03, 0x01, 0x00, 0x01, 0xc9, 0x06, 0x00, 0x53, 0x45, 0x4a, 0x0b, 0xb8, - 0xe2, 0xb0, 0x4e, 0x29, 0xc8, 0x19, 0xb4, 0xa3, 0x63, 0x27, 0xe2, 0xcd, 0xc7, - 0xc7, 0x6d, 0x60, 0x31, 0xeb, 0xc0, 0x82, 0x5f, 0x44, 0x14, 0x96, 0x60, 0x4e, - 0xc8, 0x62, 0xf4, 0xcc, 0xb9, 0x99, 0x7a, 0x19, 0xf0, 0xaf, 0x34, 0xd9, 0x63, - 0xca, 0x40, 0xe3, 0x7b, 0xb6, 0xbc, 0xfa, 0x40, 0x08, 0x1d, 0xe7, 0xc3, 0xa4, - 0xd2, 0x73, 0x3a, 0x32, 0xf2, 0xa4, 0x4c, 0x3c, 0x4f, 0xd6, 0x52, 0x52, 0xc8, - 0x6d, 0xa5, 0xf6, 0xd9, 0x4d, 0x0c, 0xfd, 0xb4, 0x93, 0x8b, 0x61, 0x72, 0xdb, - 0x6e, 0x5f, 0x2d, 0xd9, 0x2d, 0xab, 0x18, 0x2f, 0x87, 0x2d, 0xbf, 0x8d, 0x42, - 0x37, 0x93, 0x41, 0x18, 0xf6, 0x93, 0x97, 0xda, 0x27, 0x31, 0xdc, 0xda, 0xec, - 0x21, 0x16, 0x61, 0xe1, 0xe0, 0x7a, 0x53, 0x26, 0x82, 0xc7, 0x62, 0x99, 0x18, - 0x81, 0x6a, 0x65, 0x01, 0x08, 0x01, 0x01, 0x03, 0x07, 0x03, 0x01, 0x00, 0x01, - 0x8a, 0x58, 0x7e, 0x3d, 0xda, 0x69, 0x1c, 0xf3, 0x93, 0x15, 0x90, 0xa8, 0xc7, - 0x65, 0xed, 0x81, 0x31, 0x63, 0xcd, 0x4d, 0x75, 0x84, 0xaf, 0xfa, 0xa6, 0xb2, - 0xb9, 0x90, 0xe8, 0x76, 0x76, 0x7d, 0x20, 0xc8, 0x74, 0x6f, 0x03, 0x1c, 0x61, - 0xa5, 0x54, 0x77, 0x33, 0x40, 0x6d, 0x57, 0x89, 0xf2, 0x07, 0x7a, 0x8e, 0xad, - 0x6c, 0x47, 0x75, 0x6f, 0x3f, 0xf4, 0x91, 0xdf, 0xa9, 0xa6, 0x1a, 0xcb, 0x1b, - 0x57, 0x85, 0x1d, 0x97, 0x93, 0x91, 0x0e, 0xda, 0xa2, 0x64, 0xfd, 0x93, 0x0c, - 0xd0, 0xc7, 0xc4, 0x49, 0xca, 0x29, 0x35, 0xfe, 0x8d, 0x67, 0xf2, 0xb5, 0x97, - 0x93, 0xed, 0xdd, 0xc0, 0x6d, 0x2c, 0xc1, 0x28, 0x2d, 0x2f, 0xee, 0xe6, 0x6b, - 0x33, 0xa3, 0x36, 0x7a, 0x82, 0x67, 0x97, 0xa8, 0x9d, 0xeb, 0xaa, 0xc4, 0x52, - 0x64, 0x02, 0xda, 0x9f, 0x43, 0xae, 0xb0, 0xe0, 0xf4, 0x5e, 0xad, 0x5c, 0x2f, - 0x42, 0x0f, 0xfc, 0xc2, 0xef, 0xfc, 0xbe, 0x04, 0xd3, 0x69, 0x88, 0xe7, 0x67, - 0x33, 0x90, 0xd7, 0x93, 0xb1, 0xe1, 0x66, 0x6e, 0xeb, 0x6b, 0xd1, 0x3b, 0x96, - 0xd2, 0xf5, 0xde, 0x1d, 0xa6, 0xc7, 0xb9, 0x04, 0x81, 0x4f, 0x1e, 0xea, 0x7a, - 0x49, 0x94, 0x2a, 0x17, 0x8e, 0xb6, 0x88, 0x06, 0x05, 0x03, 0xb6, 0x16, 0x2c, - 0xe3, 0xc5, 0xbf, 0xb1, 0xd4, 0xc3, 0x2e, 0xee, 0xcd, 0xe7, 0xda, 0xe3, 0x08, - 0x6f, 0x9b, 0xa6, 0x29, 0x7e, 0x73, 0xca, 0x19, 0xf5, 0xfe, 0xcd, 0x47, 0x7a, - 0xa6, 0x49, 0x3a, 0x53, 0x3f, 0x59, 0xbc, 0xe9, 0x1a, 0x94, 0x42, 0x75, 0x44, - 0xae, 0x27, 0xeb, 0x1f, 0xc2, 0xa3, 0x0e, 0xa2, 0xfe, 0xdf, 0x0c, 0xd4, 0x74, - 0x5e, 0x40, 0x0a, 0x46, 0x30, 0xb7, 0x55, 0xe1, 0x3d, 0x53, 0xd4, 0xfb, 0x04, - 0x88, 0x97, 0x36, 0xda, 0x01, 0x03, 0x78, 0xf4, 0xf5, 0x01, 0x08, 0x01, 0x01, - 0x03, 0x07, 0x03, 0x01, 0x00, 0x01, 0x94, 0xe3, 0x6c, 0x83, 0xb9, 0x90, 0x8a, - 0x71, 0x59, 0x4b, 0x72, 0x5d, 0xcf, 0x1a, 0xbe, 0xc2, 0xb2, 0x1c, 0x82, 0x19, - 0xf8, 0xb8, 0xc2, 0xd8, 0x3b, 0xfc, 0x9d, 0xa3, 0xbe, 0x4f, 0x3e, 0x97, 0xd9, - 0xfa, 0xb3, 0x0c, 0x2d, 0x5b, 0x76, 0xae, 0xc7, 0x95, 0x9c, 0x2d, 0x91, 0xaa, - 0x93, 0x90, 0xc5, 0x55, 0x27, 0xef, 0x20, 0x13, 0xd1, 0x48, 0xad, 0xe1, 0x89, - 0xe1, 0xcf, 0x06, 0xd4, 0x67, 0x5b, 0x8d, 0x08, 0x1b, 0x3f, 0x53, 0xb2, 0x60, - 0x81, 0xbb, 0x38, 0x74, 0xdc, 0xe2, 0x1b, 0xf9, 0x4f, 0x63, 0x65, 0xc9, 0x6a, - 0xfa, 0x93, 0xa4, 0x05, 0xcf, 0xdf, 0x10, 0xe3, 0x3c, 0x05, 0x20, 0x64, 0xc5, - 0x56, 0xfc, 0x01, 0x86, 0x6a, 0xcc, 0x0d, 0x8b, 0x0e, 0x4e, 0xd5, 0xda, 0x90, - 0xae, 0x90, 0xc0, 0x7a, 0x2f, 0x03, 0x5f, 0xbc, 0xdc, 0x1b, 0x14, 0x00, 0x2c, - 0x65, 0x89, 0xda, 0x70, 0x07, 0x48, 0x50, 0x69, 0xc6, 0xc3, 0xeb, 0x1f, 0x88, - 0xd9, 0x10, 0x83, 0xcd, 0x8b, 0x93, 0xce, 0x3e, 0xb8, 0x26, 0xfd, 0x3f, 0xf5, - 0x7b, 0x17, 0xe8, 0x06, 0x15, 0xdd, 0xe6, 0xdc, 0x82, 0x7e, 0x21, 0x2f, 0x58, - 0xc8, 0x47, 0x67, 0x89, 0x63, 0x25, 0xe5, 0xac, 0x0a, 0x16, 0xc5, 0xdc, 0xf1, - 0x71, 0x6f, 0xff, 0xe7, 0x27, 0x8b, 0xe5, 0x15, 0x56, 0xba, 0x14, 0x71, 0x7a, - 0x39, 0xa7, 0x49, 0x59, 0xc2, 0xbb, 0x19, 0x1f, 0x4b, 0x80, 0x10, 0xe3, 0xce, - 0x4a, 0x1f, 0x6b, 0x69, 0x75, 0xb5, 0x9c, 0x0a, 0x8a, 0x4b, 0x25, 0x9b, 0x3a, - 0xb7, 0x0f, 0x2a, 0xde, 0x35, 0x9c, 0xa5, 0x31, 0xb3, 0x76, 0x1f, 0xef, 0xdf, - 0x17, 0x58, 0x7c, 0xda, 0x50, 0x35, 0xc3, 0xc8, 0x98, 0x59, 0x71, 0x02, 0xe9, - 0xf7, 0x06, 0xd3, 0x91, 0x3c, 0x0d, 0xab, 0xf2, 0xd8, 0xba, 0x30, 0xda, 0x09, - 0x10, 0x75, 0x0a, 0x64, 0x6e, 0x73, 0x73, 0x65, 0x63, 0x2d, 0x65, 0x78, 0x70, - 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x2b, 0x00, 0x90, 0x07, 0x02, 0x00, 0x01, - 0x51, 0x80, 0x4c, 0x54, 0x44, 0xe0, 0x4c, 0x41, 0xc1, 0xd0, 0xf2, 0x12, 0x0d, - 0x95, 0xb4, 0x6f, 0x7c, 0xfc, 0xde, 0x67, 0xa0, 0x1d, 0x84, 0x49, 0x3e, 0xa8, - 0xe1, 0x07, 0xea, 0xde, 0x75, 0x14, 0x98, 0xa9, 0xcc, 0x09, 0x20, 0x66, 0x59, - 0xd2, 0x40, 0xfd, 0xc6, 0xcf, 0x54, 0x22, 0x4a, 0x13, 0xf9, 0xc2, 0x1e, 0xe3, - 0x48, 0xf1, 0xd0, 0x6d, 0x18, 0x27, 0xe5, 0x8e, 0x92, 0xc2, 0x5f, 0xcc, 0xb8, - 0xd6, 0x1a, 0xbb, 0xfa, 0xe7, 0xac, 0xa8, 0x23, 0x4b, 0x89, 0xef, 0xb0, 0xc7, - 0x9a, 0xaa, 0x00, 0x99, 0x82, 0x3d, 0xa8, 0x25, 0x6b, 0xb3, 0x59, 0xd5, 0x7a, - 0x90, 0xba, 0xc4, 0xa4, 0x79, 0x8c, 0xa4, 0x39, 0xc2, 0xe9, 0x54, 0xc0, 0x4c, - 0x0a, 0x0e, 0x06, 0xcc, 0x25, 0xac, 0xb6, 0x75, 0x45, 0x8c, 0xd9, 0x99, 0x4f, - 0x31, 0xff, 0x3d, 0x40, 0x3b, 0x1c, 0x40, 0x94, 0xed, 0x9d, 0x7f, 0x60, 0x08, - 0x23, 0x63, 0x18, 0x5c, 0x50, 0x6f, 0x26, 0x7b, 0x39, 0x8b, 0x01, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x03, 0x05, 0x03, 0x01, - 0x00, 0x01, 0xd0, 0x0a, 0x64, 0x8e, 0xb5, 0x90, 0x0b, 0x75, 0xc2, 0xeb, 0x52, - 0x5f, 0xa4, 0xcb, 0xeb, 0x1d, 0x77, 0x8d, 0x84, 0x2c, 0xef, 0xb6, 0x88, 0xd4, - 0x7c, 0x50, 0x4c, 0x52, 0x7b, 0x9d, 0x37, 0x31, 0x36, 0xb2, 0x5b, 0x6c, 0x47, - 0xb4, 0x21, 0x80, 0x61, 0x46, 0xfa, 0x5b, 0x44, 0x50, 0x91, 0x9d, 0xf8, 0xc1, - 0x78, 0x00, 0x78, 0x29, 0xfe, 0xe2, 0x08, 0x65, 0xf8, 0xc9, 0xdf, 0x69, 0x0b, - 0x59, 0x6b, 0xf4, 0x93, 0x9f, 0x8b, 0x25, 0x0b, 0x6b, 0x93, 0x12, 0x06, 0x57, - 0xc8, 0x04, 0x9d, 0x3f, 0x33, 0xbd, 0x2b, 0x35, 0x54, 0xb9, 0x98, 0x75, 0xe4, - 0xb0, 0x49, 0x3c, 0x29, 0xc1, 0xfb, 0x74, 0xbc, 0x91, 0x82, 0x9e, 0xc5, 0x61, - 0xa6, 0x16, 0xe1, 0xf0, 0x8f, 0xe9, 0xe1, 0x23, 0x55, 0x5e, 0xfb, 0xf1, 0xcc, - 0x8a, 0x75, 0x5d, 0xf2, 0x86, 0x89, 0x0a, 0x29, 0xcb, 0xca, 0x33, 0xde, 0x9d, - 0x74, 0x43, 0x0d, 0xde, 0x67, 0xde, 0x71, 0x0f, 0x7f, 0xa3, 0xbb, 0x22, 0x82, - 0x81, 0x66, 0xd1, 0xbd, 0x49, 0x0d, 0x89, 0x45, 0xd7, 0x18, 0xcf, 0x98, 0x2c, - 0x19, 0xaf, 0x63, 0x16, 0x20, 0x91, 0x0a, 0x64, 0x6e, 0x73, 0x73, 0x65, 0x63, - 0x2d, 0x65, 0x78, 0x70, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x25, 0x00, 0xb0, - 0x05, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x4c, 0x71, 0x48, 0x0a, 0x4c, 0x49, 0xb6, - 0xcb, 0x83, 0x7f, 0x3d, 0xfa, 0xd9, 0x59, 0x7a, 0xc5, 0xa2, 0xd3, 0x0e, 0x3e, - 0x48, 0xa8, 0x9b, 0xc5, 0xef, 0x43, 0xe3, 0x3e, 0x3a, 0x1a, 0xb2, 0x39, 0x00, - 0x01, 0x73, 0x78, 0x80, 0x26, 0xac, 0xb0, 0x01, 0xe9, 0xc9, 0x7a, 0x0f, 0x5e, - 0xa7, 0xa2, 0x7f, 0xec, 0xa8, 0xf4, 0x42, 0x58, 0xdc, 0xba, 0xc1, 0x9e, 0xc8, - 0xa8, 0xc7, 0x93, 0x9f, 0x13, 0xc5, 0xbe, 0x99, 0xa9, 0xcc, 0x75, 0xd6, 0x7b, - 0xb4, 0xd4, 0x9b, 0x0e, 0x61, 0x96, 0x6d, 0x3f, 0xbf, 0x47, 0x42, 0xae, 0x8c, - 0xd7, 0xc1, 0x09, 0xb3, 0x84, 0x50, 0xac, 0xae, 0xbd, 0xc4, 0x54, 0x77, 0xe0, - 0xfe, 0xa8, 0xc3, 0xd4, 0x68, 0x76, 0x07, 0xdb, 0x14, 0x51, 0x2e, 0x43, 0x15, - 0x2b, 0x67, 0x4b, 0x76, 0x18, 0xbd, 0x04, 0xb3, 0xb7, 0xe5, 0xb7, 0xaf, 0xaa, - 0xb1, 0x4c, 0xa6, 0xd2, 0xbe, 0x2d, 0xdb, 0xa5, 0x2c, 0x1d, 0xe7, 0x67, 0x79, - 0x0b, 0xc4, 0x2e, 0x26, 0x0f, 0x9d, 0x98, 0x1f, 0x21, 0x1f, 0x9e, 0xfe, 0x3f, - 0x67, 0xf3, 0x67, 0x73, 0xe5, 0x88, 0xdf, 0xa8, 0x9f, 0x8c, 0x74, 0x97, 0xc2, - 0x44, 0x29, 0x28, 0x15, 0x0f, 0x1f, 0x83, 0x01, 0x00, 0x19, 0x00, 0x09, 0x00, - 0x00, 0x00, 0x90, 0x38, 0x61, 0x31, 0x19, 0x52, 0x21, 0x14, 0x83, 0x08, 0x44, - 0xeb, 0xdd, 0xe5, 0xc7, 0x1d, 0x16, 0xa2, 0x45, 0x1c, -}; - -// kCNAMEChain is a chain which proves that www.dnssec-exp.org is a CNAME to -// dnssec-exp.org and then proves a TXT record on dnssec-exp.org. -static const unsigned char kCNAMEChain[] = { - 0x4a, 0x5c, 0x01, 0x01, 0x10, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x4c, 0x8e, - 0xba, 0xff, 0x4c, 0x7a, 0xf4, 0x80, 0x4a, 0x5c, 0x6d, 0xe6, 0xa7, 0xaa, 0x97, - 0xca, 0x48, 0x4a, 0x49, 0xbb, 0xff, 0x91, 0x1a, 0xd8, 0xc2, 0x55, 0x0d, 0x80, - 0x1c, 0x83, 0x41, 0x2b, 0x89, 0x70, 0x87, 0xd9, 0x3a, 0x23, 0x9f, 0xdc, 0xa4, - 0xb6, 0x0c, 0xe3, 0x3a, 0x5a, 0xbe, 0xfc, 0x2b, 0xcb, 0xb7, 0x14, 0xbd, 0xbf, - 0x43, 0xaa, 0x03, 0x34, 0xe8, 0x84, 0x18, 0x2e, 0x95, 0x0e, 0x77, 0xb1, 0xe2, - 0x74, 0x86, 0xd8, 0xc3, 0x9c, 0xdc, 0x00, 0x80, 0x8c, 0x92, 0xfc, 0x92, 0xfe, - 0x25, 0xe3, 0x6d, 0x94, 0xe5, 0xc4, 0x08, 0x18, 0xf7, 0xc2, 0x96, 0xde, 0x8c, - 0x85, 0x73, 0x22, 0x0d, 0x03, 0x7a, 0xe0, 0xa9, 0x51, 0x27, 0x24, 0xbc, 0xf8, - 0xbf, 0x63, 0x52, 0xef, 0xbd, 0xb8, 0x07, 0xe8, 0xf6, 0xaa, 0x3d, 0x02, 0x28, - 0xfe, 0x44, 0xd4, 0xe4, 0x04, 0x10, 0x61, 0x95, 0x6c, 0x87, 0x06, 0x2a, 0x5c, - 0xdb, 0x67, 0x0d, 0xac, 0x1a, 0x02, 0x2e, 0x66, 0x35, 0x08, 0x28, 0x29, 0x24, - 0x8e, 0xad, 0x4c, 0x3b, 0x6a, 0x99, 0x88, 0xd6, 0x32, 0xa6, 0x7d, 0xc3, 0x0c, - 0x3d, 0xbc, 0x0b, 0xff, 0x86, 0x8d, 0xc6, 0x50, 0x8b, 0xad, 0x1f, 0x1f, 0xf7, - 0x06, 0xc5, 0x9e, 0x0c, 0x6f, 0xbb, 0x3c, 0x02, 0x5c, 0x67, 0xa7, 0xaf, 0x53, - 0x63, 0x5a, 0xae, 0x99, 0x47, 0x93, 0x61, 0xc8, 0x4f, 0xfb, 0x03, 0xec, 0xfe, - 0xa3, 0xc1, 0xee, 0x45, 0xf8, 0x56, 0x73, 0x88, 0xf4, 0x14, 0x6d, 0x96, 0x7c, - 0xdc, 0x88, 0x01, 0x99, 0x04, 0x18, 0x3d, 0x42, 0x56, 0x57, 0x54, 0xd7, 0xed, - 0xf8, 0x6b, 0x46, 0xff, 0x01, 0xe6, 0x1a, 0x75, 0x37, 0xd4, 0xf6, 0xb2, 0x57, - 0x61, 0x6b, 0xbf, 0x24, 0x99, 0x6d, 0xcd, 0x63, 0xc6, 0x45, 0xd0, 0x0a, 0x93, - 0x5c, 0xbb, 0xd3, 0x36, 0xac, 0xfa, 0x57, 0x51, 0xa0, 0xcf, 0x32, 0x0e, 0xb3, - 0x57, 0xf3, 0x02, 0x77, 0x02, 0x00, 0x88, 0x01, 0x00, 0x03, 0x08, 0x03, 0x01, - 0x00, 0x01, 0xbd, 0x60, 0x70, 0x38, 0x41, 0x94, 0x7f, 0xfd, 0x32, 0x58, 0x14, - 0xc5, 0x2d, 0x22, 0x93, 0x67, 0x70, 0x63, 0xf2, 0x62, 0x04, 0x8a, 0x55, 0xf8, - 0x48, 0x4a, 0x65, 0x5e, 0xcb, 0x71, 0xcc, 0x4d, 0x73, 0xa4, 0x25, 0x8f, 0x8e, - 0xbb, 0x42, 0x31, 0xd0, 0xdc, 0x58, 0x26, 0xda, 0x2d, 0x8b, 0x13, 0xdc, 0x3a, - 0x2e, 0xa3, 0xc5, 0x0d, 0x29, 0xe0, 0xe6, 0xa5, 0x6a, 0xd4, 0xe6, 0x05, 0xc9, - 0x30, 0x6d, 0xdc, 0x34, 0x29, 0xa6, 0xa0, 0xe7, 0x00, 0xfa, 0xe2, 0x4f, 0x05, - 0xb9, 0xa8, 0x84, 0x0d, 0x0c, 0xd1, 0x6f, 0xdf, 0x8c, 0xa8, 0xeb, 0x7b, 0x00, - 0x74, 0x17, 0x94, 0xe0, 0x6f, 0x6d, 0xbf, 0xb7, 0x73, 0x4f, 0x9b, 0x0f, 0xc8, - 0x08, 0x26, 0x56, 0x1e, 0x47, 0x0c, 0x27, 0xbe, 0xe9, 0x73, 0x36, 0xf8, 0x87, - 0xa5, 0xd7, 0xe9, 0x14, 0x28, 0x27, 0xa5, 0xf0, 0x87, 0x32, 0xd7, 0xd8, 0x51, - 0x00, 0x00, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x2b, 0x00, 0x90, 0x08, 0x01, - 0x00, 0x02, 0xa3, 0x00, 0x4c, 0x90, 0x0c, 0x80, 0x4c, 0x86, 0xc3, 0xf0, 0xa1, - 0x20, 0x10, 0x1a, 0xab, 0x3c, 0x50, 0xae, 0x3f, 0x7f, 0x49, 0x4a, 0x3f, 0xfc, - 0xf1, 0xfb, 0x5c, 0x63, 0x76, 0x7f, 0x60, 0xf8, 0x0e, 0x08, 0x30, 0x23, 0xb1, - 0xe7, 0xa9, 0xbc, 0x23, 0xa4, 0x1a, 0xaf, 0xc5, 0x99, 0x3e, 0x85, 0x1f, 0x0b, - 0xf3, 0x7f, 0x04, 0x12, 0x5b, 0x7e, 0x26, 0xb1, 0x87, 0xa0, 0x4c, 0xd9, 0xaf, - 0xf0, 0x30, 0xeb, 0x88, 0xb0, 0xf6, 0x88, 0xb5, 0x10, 0xb7, 0xc9, 0xa8, 0xc8, - 0xc0, 0xc0, 0x26, 0x69, 0x16, 0x90, 0xec, 0xec, 0x53, 0xf2, 0xc4, 0x24, 0x7c, - 0x24, 0xc0, 0x67, 0x09, 0x29, 0x4b, 0xcc, 0x80, 0x92, 0xe5, 0xd9, 0xc4, 0xa3, - 0x18, 0x0b, 0x16, 0x65, 0xc2, 0x11, 0x7a, 0x3b, 0xb1, 0xc0, 0xaf, 0x0b, 0x93, - 0xe6, 0x7b, 0x76, 0x25, 0x18, 0x7a, 0x1e, 0x8e, 0x4f, 0x50, 0xf2, 0xb4, 0xda, - 0x72, 0x72, 0x44, 0x3a, 0x18, 0xf9, 0xed, 0x72, 0x05, 0x19, 0x77, 0x34, 0x02, - 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x10, 0x07, 0x01, 0x00, 0x00, - 0x03, 0x84, 0x4c, 0x90, 0xea, 0x0d, 0x4c, 0x7e, 0x66, 0xfd, 0x53, 0x76, 0x37, - 0x11, 0x28, 0x49, 0x49, 0xa9, 0xaa, 0x7e, 0xe7, 0xc6, 0x2b, 0x0f, 0x0e, 0x76, - 0xb7, 0xa6, 0x15, 0x4d, 0xcf, 0x95, 0x9e, 0x5b, 0x25, 0x5a, 0x52, 0xcc, 0x62, - 0xd7, 0x31, 0x2b, 0x6a, 0x35, 0xf7, 0x9f, 0x5b, 0xc1, 0x5e, 0xba, 0xc1, 0x53, - 0x98, 0x3e, 0xc8, 0x6c, 0x21, 0x6f, 0xf1, 0x93, 0xb6, 0xb7, 0x6e, 0x65, 0x04, - 0x30, 0xe2, 0x0c, 0x6d, 0xa5, 0xdd, 0x15, 0xd4, 0x01, 0xb8, 0xd3, 0x9b, 0xd2, - 0x86, 0x38, 0x24, 0x6f, 0xed, 0x03, 0x47, 0xb4, 0x9e, 0x0b, 0x1a, 0xe3, 0x16, - 0x7d, 0x20, 0x68, 0x50, 0xe5, 0xb1, 0x2c, 0xae, 0x14, 0xc0, 0xdc, 0x09, 0x31, - 0x6d, 0xa0, 0x4e, 0x55, 0xdc, 0x65, 0xbe, 0xe5, 0x89, 0xe4, 0x35, 0x57, 0x3e, - 0x2b, 0xda, 0x06, 0x8d, 0xef, 0xc8, 0xdf, 0xf9, 0xf6, 0xc3, 0x09, 0x39, 0xc7, - 0x83, 0xe9, 0xe0, 0xf0, 0x2e, 0xad, 0x21, 0x56, 0x8b, 0x60, 0xf9, 0x84, 0x53, - 0xac, 0x1e, 0x84, 0x42, 0x7a, 0xfa, 0xa1, 0xbd, 0x86, 0x61, 0x12, 0xd0, 0x70, - 0xdc, 0x54, 0x50, 0x0e, 0xbe, 0x1a, 0x47, 0xe4, 0x38, 0x96, 0xb4, 0xe7, 0x3c, - 0x26, 0xae, 0x1d, 0x7e, 0x37, 0x28, 0xf5, 0x54, 0xe6, 0x94, 0x63, 0x30, 0x42, - 0x7e, 0x52, 0xb2, 0x8b, 0xda, 0x96, 0x44, 0x0c, 0xa4, 0xda, 0x33, 0x28, 0x77, - 0x02, 0xdf, 0xcf, 0xa0, 0xc7, 0x14, 0x2b, 0x68, 0xbb, 0x5d, 0x1b, 0x7e, 0x32, - 0x5c, 0xf2, 0x0e, 0xcb, 0x1b, 0xe1, 0x6d, 0x1c, 0xb8, 0x96, 0xbf, 0x0d, 0x1a, - 0xcc, 0x0f, 0x2f, 0xfd, 0x25, 0xff, 0x33, 0x3d, 0x89, 0x6d, 0x27, 0x9e, 0xe0, - 0xb9, 0x5a, 0x72, 0xbb, 0x2f, 0xe5, 0x95, 0xbb, 0x40, 0xb6, 0x4c, 0x11, 0x6c, - 0x80, 0xb6, 0x9e, 0xa9, 0xd9, 0x31, 0x61, 0xb9, 0x69, 0x9c, 0xf2, 0xe8, 0xc5, - 0xa0, 0xfd, 0x07, 0x59, 0x87, 0x38, 0xff, 0x25, 0x04, 0x00, 0x88, 0x01, 0x00, - 0x03, 0x07, 0x03, 0x01, 0x00, 0x01, 0x80, 0x97, 0x87, 0xf6, 0x40, 0x06, 0x2f, - 0x24, 0x88, 0x92, 0x03, 0x5d, 0x89, 0xb2, 0x52, 0x51, 0xf3, 0x0b, 0x40, 0x87, - 0x78, 0x1c, 0xea, 0x72, 0x9c, 0x99, 0x00, 0x88, 0xc2, 0xed, 0xd2, 0xb5, 0xc2, - 0x44, 0x58, 0x55, 0xc5, 0x2f, 0x22, 0x5a, 0x53, 0x3a, 0x99, 0xce, 0x55, 0x57, - 0xdc, 0x0b, 0x73, 0xf2, 0xf5, 0x48, 0xbf, 0xc7, 0x8e, 0x6a, 0x29, 0xbd, 0x0b, - 0xca, 0xdb, 0xca, 0xed, 0x66, 0x00, 0x7b, 0x75, 0xb2, 0x38, 0xec, 0x24, 0xe6, - 0x49, 0x70, 0x22, 0xa4, 0x42, 0xff, 0x4a, 0x78, 0x96, 0xe6, 0x9f, 0x6d, 0xdd, - 0xb2, 0x85, 0x13, 0x05, 0xee, 0xab, 0x8e, 0x05, 0x5a, 0x98, 0xac, 0xba, 0x07, - 0xc2, 0xff, 0x22, 0xf4, 0xba, 0xd5, 0xfa, 0xbf, 0x1d, 0x84, 0x1e, 0xeb, 0x5e, - 0xff, 0xe5, 0x91, 0x34, 0x88, 0xea, 0x61, 0x19, 0xb2, 0x0e, 0x6b, 0x0d, 0xf7, - 0x9e, 0xf1, 0x8c, 0xb5, 0x00, 0x88, 0x01, 0x00, 0x03, 0x07, 0x03, 0x01, 0x00, - 0x01, 0xc9, 0x06, 0x00, 0x53, 0x45, 0x4a, 0x0b, 0xb8, 0xe2, 0xb0, 0x4e, 0x29, - 0xc8, 0x19, 0xb4, 0xa3, 0x63, 0x27, 0xe2, 0xcd, 0xc7, 0xc7, 0x6d, 0x60, 0x31, - 0xeb, 0xc0, 0x82, 0x5f, 0x44, 0x14, 0x96, 0x60, 0x4e, 0xc8, 0x62, 0xf4, 0xcc, - 0xb9, 0x99, 0x7a, 0x19, 0xf0, 0xaf, 0x34, 0xd9, 0x63, 0xca, 0x40, 0xe3, 0x7b, - 0xb6, 0xbc, 0xfa, 0x40, 0x08, 0x1d, 0xe7, 0xc3, 0xa4, 0xd2, 0x73, 0x3a, 0x32, - 0xf2, 0xa4, 0x4c, 0x3c, 0x4f, 0xd6, 0x52, 0x52, 0xc8, 0x6d, 0xa5, 0xf6, 0xd9, - 0x4d, 0x0c, 0xfd, 0xb4, 0x93, 0x8b, 0x61, 0x72, 0xdb, 0x6e, 0x5f, 0x2d, 0xd9, - 0x2d, 0xab, 0x18, 0x2f, 0x87, 0x2d, 0xbf, 0x8d, 0x42, 0x37, 0x93, 0x41, 0x18, - 0xf6, 0x93, 0x97, 0xda, 0x27, 0x31, 0xdc, 0xda, 0xec, 0x21, 0x16, 0x61, 0xe1, - 0xe0, 0x7a, 0x53, 0x26, 0x82, 0xc7, 0x62, 0x99, 0x18, 0x81, 0x6a, 0x65, 0x01, - 0x08, 0x01, 0x01, 0x03, 0x07, 0x03, 0x01, 0x00, 0x01, 0x8a, 0x58, 0x7e, 0x3d, - 0xda, 0x69, 0x1c, 0xf3, 0x93, 0x15, 0x90, 0xa8, 0xc7, 0x65, 0xed, 0x81, 0x31, - 0x63, 0xcd, 0x4d, 0x75, 0x84, 0xaf, 0xfa, 0xa6, 0xb2, 0xb9, 0x90, 0xe8, 0x76, - 0x76, 0x7d, 0x20, 0xc8, 0x74, 0x6f, 0x03, 0x1c, 0x61, 0xa5, 0x54, 0x77, 0x33, - 0x40, 0x6d, 0x57, 0x89, 0xf2, 0x07, 0x7a, 0x8e, 0xad, 0x6c, 0x47, 0x75, 0x6f, - 0x3f, 0xf4, 0x91, 0xdf, 0xa9, 0xa6, 0x1a, 0xcb, 0x1b, 0x57, 0x85, 0x1d, 0x97, - 0x93, 0x91, 0x0e, 0xda, 0xa2, 0x64, 0xfd, 0x93, 0x0c, 0xd0, 0xc7, 0xc4, 0x49, - 0xca, 0x29, 0x35, 0xfe, 0x8d, 0x67, 0xf2, 0xb5, 0x97, 0x93, 0xed, 0xdd, 0xc0, - 0x6d, 0x2c, 0xc1, 0x28, 0x2d, 0x2f, 0xee, 0xe6, 0x6b, 0x33, 0xa3, 0x36, 0x7a, - 0x82, 0x67, 0x97, 0xa8, 0x9d, 0xeb, 0xaa, 0xc4, 0x52, 0x64, 0x02, 0xda, 0x9f, - 0x43, 0xae, 0xb0, 0xe0, 0xf4, 0x5e, 0xad, 0x5c, 0x2f, 0x42, 0x0f, 0xfc, 0xc2, - 0xef, 0xfc, 0xbe, 0x04, 0xd3, 0x69, 0x88, 0xe7, 0x67, 0x33, 0x90, 0xd7, 0x93, - 0xb1, 0xe1, 0x66, 0x6e, 0xeb, 0x6b, 0xd1, 0x3b, 0x96, 0xd2, 0xf5, 0xde, 0x1d, - 0xa6, 0xc7, 0xb9, 0x04, 0x81, 0x4f, 0x1e, 0xea, 0x7a, 0x49, 0x94, 0x2a, 0x17, - 0x8e, 0xb6, 0x88, 0x06, 0x05, 0x03, 0xb6, 0x16, 0x2c, 0xe3, 0xc5, 0xbf, 0xb1, - 0xd4, 0xc3, 0x2e, 0xee, 0xcd, 0xe7, 0xda, 0xe3, 0x08, 0x6f, 0x9b, 0xa6, 0x29, - 0x7e, 0x73, 0xca, 0x19, 0xf5, 0xfe, 0xcd, 0x47, 0x7a, 0xa6, 0x49, 0x3a, 0x53, - 0x3f, 0x59, 0xbc, 0xe9, 0x1a, 0x94, 0x42, 0x75, 0x44, 0xae, 0x27, 0xeb, 0x1f, - 0xc2, 0xa3, 0x0e, 0xa2, 0xfe, 0xdf, 0x0c, 0xd4, 0x74, 0x5e, 0x40, 0x0a, 0x46, - 0x30, 0xb7, 0x55, 0xe1, 0x3d, 0x53, 0xd4, 0xfb, 0x04, 0x88, 0x97, 0x36, 0xda, - 0x01, 0x03, 0x78, 0xf4, 0xf5, 0x01, 0x08, 0x01, 0x01, 0x03, 0x07, 0x03, 0x01, - 0x00, 0x01, 0x94, 0xe3, 0x6c, 0x83, 0xb9, 0x90, 0x8a, 0x71, 0x59, 0x4b, 0x72, - 0x5d, 0xcf, 0x1a, 0xbe, 0xc2, 0xb2, 0x1c, 0x82, 0x19, 0xf8, 0xb8, 0xc2, 0xd8, - 0x3b, 0xfc, 0x9d, 0xa3, 0xbe, 0x4f, 0x3e, 0x97, 0xd9, 0xfa, 0xb3, 0x0c, 0x2d, - 0x5b, 0x76, 0xae, 0xc7, 0x95, 0x9c, 0x2d, 0x91, 0xaa, 0x93, 0x90, 0xc5, 0x55, - 0x27, 0xef, 0x20, 0x13, 0xd1, 0x48, 0xad, 0xe1, 0x89, 0xe1, 0xcf, 0x06, 0xd4, - 0x67, 0x5b, 0x8d, 0x08, 0x1b, 0x3f, 0x53, 0xb2, 0x60, 0x81, 0xbb, 0x38, 0x74, - 0xdc, 0xe2, 0x1b, 0xf9, 0x4f, 0x63, 0x65, 0xc9, 0x6a, 0xfa, 0x93, 0xa4, 0x05, - 0xcf, 0xdf, 0x10, 0xe3, 0x3c, 0x05, 0x20, 0x64, 0xc5, 0x56, 0xfc, 0x01, 0x86, - 0x6a, 0xcc, 0x0d, 0x8b, 0x0e, 0x4e, 0xd5, 0xda, 0x90, 0xae, 0x90, 0xc0, 0x7a, - 0x2f, 0x03, 0x5f, 0xbc, 0xdc, 0x1b, 0x14, 0x00, 0x2c, 0x65, 0x89, 0xda, 0x70, - 0x07, 0x48, 0x50, 0x69, 0xc6, 0xc3, 0xeb, 0x1f, 0x88, 0xd9, 0x10, 0x83, 0xcd, - 0x8b, 0x93, 0xce, 0x3e, 0xb8, 0x26, 0xfd, 0x3f, 0xf5, 0x7b, 0x17, 0xe8, 0x06, - 0x15, 0xdd, 0xe6, 0xdc, 0x82, 0x7e, 0x21, 0x2f, 0x58, 0xc8, 0x47, 0x67, 0x89, - 0x63, 0x25, 0xe5, 0xac, 0x0a, 0x16, 0xc5, 0xdc, 0xf1, 0x71, 0x6f, 0xff, 0xe7, - 0x27, 0x8b, 0xe5, 0x15, 0x56, 0xba, 0x14, 0x71, 0x7a, 0x39, 0xa7, 0x49, 0x59, - 0xc2, 0xbb, 0x19, 0x1f, 0x4b, 0x80, 0x10, 0xe3, 0xce, 0x4a, 0x1f, 0x6b, 0x69, - 0x75, 0xb5, 0x9c, 0x0a, 0x8a, 0x4b, 0x25, 0x9b, 0x3a, 0xb7, 0x0f, 0x2a, 0xde, - 0x35, 0x9c, 0xa5, 0x31, 0xb3, 0x76, 0x1f, 0xef, 0xdf, 0x17, 0x58, 0x7c, 0xda, - 0x50, 0x35, 0xc3, 0xc8, 0x98, 0x59, 0x71, 0x02, 0xe9, 0xf7, 0x06, 0xd3, 0x91, - 0x3c, 0x0d, 0xab, 0xf2, 0xd8, 0xba, 0x30, 0xda, 0x09, 0x10, 0x75, 0x0a, 0x64, - 0x6e, 0x73, 0x73, 0x65, 0x63, 0x2d, 0x65, 0x78, 0x70, 0x03, 0x6f, 0x72, 0x67, - 0x00, 0x00, 0x2b, 0x00, 0x90, 0x07, 0x02, 0x00, 0x01, 0x51, 0x80, 0x4c, 0x90, - 0xea, 0x0d, 0x4c, 0x7e, 0x66, 0xfd, 0x93, 0xb4, 0x39, 0xee, 0x27, 0x29, 0x54, - 0x9e, 0x57, 0x41, 0x12, 0x60, 0x19, 0xf6, 0x3f, 0xa6, 0xba, 0xd6, 0x41, 0x98, - 0x57, 0xec, 0x30, 0x9e, 0x96, 0x08, 0x8c, 0x13, 0xa9, 0x76, 0x95, 0x74, 0xcd, - 0xcd, 0x2e, 0xa6, 0x22, 0x21, 0x44, 0x3f, 0x13, 0xdf, 0x7a, 0x33, 0xf1, 0x8c, - 0x4c, 0xf9, 0xa3, 0x6d, 0x50, 0x38, 0xfa, 0x71, 0x7b, 0x7a, 0xfe, 0x54, 0xa9, - 0x44, 0x81, 0x8c, 0xd5, 0x04, 0x9e, 0x46, 0x89, 0xda, 0x26, 0x43, 0x40, 0xf6, - 0xd7, 0x23, 0x48, 0x07, 0x0e, 0x48, 0x2e, 0x19, 0x0d, 0x41, 0x27, 0x85, 0x75, - 0x1e, 0xa0, 0xa9, 0xad, 0x39, 0xaf, 0x8d, 0xc1, 0xed, 0xc5, 0x93, 0x73, 0x05, - 0x09, 0x7a, 0x8f, 0xf0, 0x97, 0xc3, 0x98, 0xab, 0xcc, 0x7c, 0xbf, 0x48, 0xef, - 0xea, 0x34, 0xf3, 0xe6, 0x5d, 0x8d, 0x1b, 0xbe, 0x43, 0x97, 0x56, 0x4e, 0x60, - 0x9f, 0xdd, 0x1b, 0xf5, 0x15, 0x6c, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0xa8, 0x01, 0x00, 0x03, 0x05, 0x03, 0x01, 0x00, 0x01, 0xd0, 0x0a, - 0x64, 0x8e, 0xb5, 0x90, 0x0b, 0x75, 0xc2, 0xeb, 0x52, 0x5f, 0xa4, 0xcb, 0xeb, - 0x1d, 0x77, 0x8d, 0x84, 0x2c, 0xef, 0xb6, 0x88, 0xd4, 0x7c, 0x50, 0x4c, 0x52, - 0x7b, 0x9d, 0x37, 0x31, 0x36, 0xb2, 0x5b, 0x6c, 0x47, 0xb4, 0x21, 0x80, 0x61, - 0x46, 0xfa, 0x5b, 0x44, 0x50, 0x91, 0x9d, 0xf8, 0xc1, 0x78, 0x00, 0x78, 0x29, - 0xfe, 0xe2, 0x08, 0x65, 0xf8, 0xc9, 0xdf, 0x69, 0x0b, 0x59, 0x6b, 0xf4, 0x93, - 0x9f, 0x8b, 0x25, 0x0b, 0x6b, 0x93, 0x12, 0x06, 0x57, 0xc8, 0x04, 0x9d, 0x3f, - 0x33, 0xbd, 0x2b, 0x35, 0x54, 0xb9, 0x98, 0x75, 0xe4, 0xb0, 0x49, 0x3c, 0x29, - 0xc1, 0xfb, 0x74, 0xbc, 0x91, 0x82, 0x9e, 0xc5, 0x61, 0xa6, 0x16, 0xe1, 0xf0, - 0x8f, 0xe9, 0xe1, 0x23, 0x55, 0x5e, 0xfb, 0xf1, 0xcc, 0x8a, 0x75, 0x5d, 0xf2, - 0x86, 0x89, 0x0a, 0x29, 0xcb, 0xca, 0x33, 0xde, 0x9d, 0x74, 0x43, 0x0d, 0xde, - 0x67, 0xde, 0x71, 0x0f, 0x7f, 0xa3, 0xbb, 0x22, 0x82, 0x81, 0x66, 0xd1, 0xbd, - 0x49, 0x0d, 0x89, 0x45, 0xd7, 0x18, 0xcf, 0x98, 0x2c, 0x19, 0xaf, 0x63, 0x16, - 0x20, 0x91, 0x03, 0x77, 0x77, 0x77, 0x0a, 0x64, 0x6e, 0x73, 0x73, 0x65, 0x63, - 0x2d, 0x65, 0x78, 0x70, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x05, 0x00, 0xb0, - 0x05, 0x03, 0x00, 0x00, 0x00, 0x3c, 0x4c, 0xae, 0xeb, 0xfc, 0x4c, 0x87, 0x59, - 0xf6, 0x83, 0x7f, 0x01, 0x90, 0xde, 0x40, 0xa3, 0x42, 0x73, 0x59, 0xb7, 0xc7, - 0x3a, 0xe1, 0x01, 0xae, 0x5c, 0x0f, 0xd4, 0x22, 0x9d, 0xb5, 0x88, 0xb8, 0xbb, - 0x14, 0x95, 0x7f, 0xfa, 0xa7, 0xff, 0x48, 0x30, 0x90, 0x4c, 0x1b, 0x71, 0x33, - 0x1c, 0x36, 0xbc, 0xaf, 0xae, 0x1d, 0x97, 0xec, 0xee, 0x71, 0xb8, 0xb1, 0x2a, - 0x19, 0xd7, 0xf3, 0x25, 0x78, 0x94, 0x59, 0x54, 0xbb, 0x2b, 0xac, 0xe6, 0x3c, - 0x3e, 0x7e, 0x43, 0x7c, 0x2d, 0xc0, 0x72, 0x58, 0xe8, 0x4a, 0xa2, 0xed, 0x1f, - 0x39, 0x5f, 0x6a, 0x98, 0x62, 0xd0, 0xfc, 0x6e, 0xbe, 0x01, 0x1f, 0xa0, 0x39, - 0xf2, 0xb4, 0x4d, 0x33, 0x9b, 0x4d, 0xe3, 0x81, 0x65, 0x77, 0x80, 0x3d, 0x2c, - 0x44, 0xee, 0x1a, 0x65, 0xf7, 0x25, 0x68, 0x95, 0x3f, 0xa1, 0x22, 0xd5, 0x9d, - 0x59, 0x7e, 0xa7, 0xa6, 0xf2, 0x7e, 0x4d, 0x47, 0x8b, 0x98, 0x4a, 0x0d, 0x16, - 0xa1, 0x78, 0x12, 0xc7, 0x90, 0xe2, 0xe9, 0x6d, 0xe6, 0x89, 0xf3, 0xa1, 0xc4, - 0x30, 0xbd, 0xe8, 0xf9, 0x75, 0xc6, 0x49, 0x9e, 0x5f, 0x9c, 0x1e, 0x23, 0xb5, - 0x0e, 0x82, 0x70, 0x8e, 0xb3, 0x0d, 0x1c, 0x0a, 0x64, 0x6e, 0x73, 0x73, 0x65, - 0x63, 0x2d, 0x65, 0x78, 0x70, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x0a, 0x64, 0x6e, - 0x73, 0x73, 0x65, 0x63, 0x2d, 0x65, 0x78, 0x70, 0x03, 0x6f, 0x72, 0x67, 0x00, - 0x00, 0x10, 0x00, 0xb0, 0x05, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x4c, 0xae, 0xf6, - 0xe5, 0x4c, 0x87, 0x5e, 0xd9, 0x83, 0x7f, 0x2a, 0x88, 0x85, 0xb8, 0xf1, 0x73, - 0x93, 0xe3, 0x85, 0xee, 0xc8, 0x93, 0x34, 0x2d, 0xd2, 0x47, 0x2d, 0x86, 0xe5, - 0xc6, 0x18, 0x69, 0x94, 0x94, 0x7a, 0x2d, 0x7e, 0xa2, 0x57, 0xf1, 0x75, 0x3e, - 0x51, 0xbf, 0xaa, 0xed, 0xdd, 0xf8, 0x1a, 0xb9, 0x1e, 0x86, 0x6f, 0x7f, 0xe9, - 0xdc, 0xad, 0x83, 0xda, 0x7d, 0xcd, 0x2d, 0x4d, 0x9b, 0xe3, 0x66, 0x92, 0xb9, - 0x21, 0x96, 0xbf, 0xea, 0x70, 0x55, 0xbf, 0xb3, 0xb0, 0x85, 0x90, 0x72, 0x5f, - 0x09, 0xd1, 0x7c, 0x49, 0x25, 0x07, 0x79, 0x34, 0x48, 0xe7, 0x1c, 0xaa, 0x53, - 0x33, 0xcb, 0x62, 0xb9, 0x9f, 0x42, 0x6e, 0x36, 0x00, 0x31, 0xab, 0x9f, 0xcc, - 0xf5, 0xa9, 0x02, 0x2f, 0x75, 0x4c, 0xf1, 0xd6, 0x86, 0x3a, 0x7f, 0x08, 0xe4, - 0x72, 0x7d, 0x34, 0xe0, 0x40, 0x76, 0xd1, 0xf0, 0xe3, 0x98, 0x37, 0xe7, 0x93, - 0x94, 0x57, 0x95, 0x6c, 0xde, 0x9e, 0x17, 0x57, 0x3a, 0x78, 0xe9, 0x8b, 0x57, - 0x7f, 0x74, 0xe2, 0xaf, 0xf8, 0xaf, 0x11, 0x64, 0xa9, 0xe9, 0xdb, 0xb2, 0x58, - 0xda, 0x7c, 0xfe, 0x3f, 0x52, 0x06, 0x39, 0xfc, 0xdd, 0x1c, 0x1c, 0x01, 0x00, - 0x3a, 0x39, 0x76, 0x3d, 0x74, 0x6c, 0x73, 0x31, 0x20, 0x68, 0x61, 0x3d, 0x73, - 0x68, 0x61, 0x31, 0x20, 0x68, 0x3d, 0x31, 0x30, 0x39, 0x63, 0x38, 0x31, 0x34, - 0x36, 0x33, 0x30, 0x34, 0x64, 0x65, 0x37, 0x63, 0x34, 0x63, 0x38, 0x37, 0x30, - 0x35, 0x62, 0x63, 0x63, 0x31, 0x64, 0x38, 0x61, 0x32, 0x63, 0x32, 0x33, 0x37, - 0x66, 0x30, 0x35, 0x35, 0x38, 0x64, 0x37, -}; - -TEST(DNSSECChainVerifierTest, TestChain) { - base::StringPiece chain(reinterpret_cast<const char*>(kChain), - sizeof(kChain)); - DNSSECChainVerifier verifier(FromDNSName("dnssec-exp.org"), chain); - verifier.IgnoreTimestamps(); - ASSERT_EQ(DNSSECChainVerifier::OK, verifier.Verify()); - ASSERT_EQ(kDNS_CERT, verifier.rrtype()); -} - -TEST(DNSSECChainVerifierTest, OffCourse) { - base::StringPiece chain(reinterpret_cast<const char*>(kChain), - sizeof(kChain)); - DNSSECChainVerifier verifier(FromDNSName("foo.org"), chain); - verifier.IgnoreTimestamps(); - ASSERT_EQ(DNSSECChainVerifier::OFF_COURSE, verifier.Verify()); -} - -TEST(DNSSECChainVerifierTest, BadTarget) { - base::StringPiece chain(reinterpret_cast<const char*>(kChain), - sizeof(kChain)); - DNSSECChainVerifier verifier(FromDNSName("www.dnssec-exp.org"), chain); - verifier.IgnoreTimestamps(); - ASSERT_EQ(DNSSECChainVerifier::BAD_TARGET, verifier.Verify()); -} - -TEST(DNSSECChainVerifierTest, TestCNAMEChain) { - base::StringPiece chain(reinterpret_cast<const char*>(kCNAMEChain), - sizeof(kCNAMEChain)); - DNSSECChainVerifier verifier(FromDNSName("www.dnssec-exp.org"), chain); - verifier.IgnoreTimestamps(); - ASSERT_EQ(DNSSECChainVerifier::OK, verifier.Verify()); - ASSERT_EQ(kDNS_TXT, verifier.rrtype()); -} - -// This is too slow to run all the time. -TEST(DNSSECChainVerifierTest, DISABLED_Fuzz) { - uint8 copy[sizeof(kChain)]; - base::StringPiece chain(reinterpret_cast<const char*>(copy), sizeof(copy)); - static const unsigned bit_length = sizeof(kChain) * 8; - - for (unsigned bit_to_flip = 0; bit_to_flip < bit_length; bit_to_flip++) { - memcpy(copy, kChain, sizeof(copy)); - - unsigned byte = bit_to_flip >> 3; - unsigned bit = bit_to_flip & 7; - copy[byte] ^= (1 << bit); - - DNSSECChainVerifier verifier(FromDNSName("dnssec-exp.org"), chain); - verifier.IgnoreTimestamps(); - ASSERT_NE(DNSSECChainVerifier::OK, verifier.Verify()); - } -} - -static std::string MakeCAA(bool critical, - bool relying_use, - const char* key, - const std::string& value) { - std::string r; - - char a = 0; - if (critical) - a |= 128; - if (relying_use) { - a |= 2; - } else { - // For issuer use only. - a |= 1; - } - r.push_back(a); - r.push_back(static_cast<char>(strlen(key))); - r += key; - r += value; - - return r; -} - -static std::string MakeAuth(const char* target_oid, - const char* hash_func_oid, - unsigned num_hash_bytes, - unsigned port) { - // AuthData ::= SEQUENCE { - // odi ObjectDigestIdentifier - // port INTEGER - // } - // ObjectDigestIdentifier ::= SEQUENCE { - // type OBJECT IDENTIFIER, - // digestAlgorithm OBJECT IDENTIFIER, - // digest OCTET STRING - // } - unsigned odi_len = strlen(target_oid) + - strlen(hash_func_oid) + - 2 /* OCTET STRING and length bytes */ + - num_hash_bytes; - unsigned len = odi_len + - 2 /* SEQUENCE and length bytes */ + - 2 /* INTEGER and length bytes */ + - 1 /* at least one byte of port number */; - if (port >= 256) - len++; // port number needs at least two bytes. - if (port >= 0x8000) - len++; // port number needs three bytes. - CHECK_LT(len, 128u); - - std::string r; - r.push_back(static_cast<char>(asn1::kSEQUENCE)); - r.push_back(static_cast<char>(len)); - r.push_back(static_cast<char>(asn1::kSEQUENCE)); - r.push_back(static_cast<char>(odi_len)); - r += target_oid; - r += hash_func_oid; - r.push_back(static_cast<char>(asn1::kOCTETSTRING)); - r.push_back(static_cast<char>(num_hash_bytes)); - r += std::string(num_hash_bytes, 'a'); - r.push_back(static_cast<char>(asn1::kINTEGER)); - if (port < 256) { - r.push_back(static_cast<char>(1)); - r.push_back(static_cast<char>(port)); - } else if (port < 0x8000) { - r.push_back(static_cast<char>(2)); - r.push_back(static_cast<char>(port >> 8)); - r.push_back(static_cast<char>(port)); - } else { - r.push_back(static_cast<char>(3)); - // A leading zero is needed to stop the MSB from indicating that the number - // is signed. - r.push_back(static_cast<char>(0)); - r.push_back(static_cast<char>(port >> 8)); - r.push_back(static_cast<char>(port)); - } - return r; -} - -TEST(CAAParserTest, Empty) { - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - - ASSERT_EQ(net::DnsCAARecord::DISCARD, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, UnknownCriticalCAEntry) { - // Check that unknown critical keys that aren't for relying parties are - // ignored. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA(true /* critical */, false /* CAs only */, - "foo", "")); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::DISCARD, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, UnknownCriticalEntry) { - // Check that unknown critical keys for relying parties cause an error. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA(true /* critical */, true /* for us */, - "foo", "")); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::UNKNOWN_CRITICAL, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, UnknownEntry) { - // Check that unknown, non-critical keys are ignored - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA(false /* not critical */, true /* for us */, - "foo", "")); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::DISCARD, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -static void CAAFuzz(const std::string& in) { - net::DnsCAARecord::Policy policy; - - for (unsigned i = 0; i < in.size() * 8; i++) { - const unsigned byte = i >> 3; - const unsigned bit = i & 7; - - std::string copy(in); - copy[byte] ^= static_cast<char>(1) << bit; - - std::vector<base::StringPiece> rrdatas; - rrdatas.push_back(copy); - - net::DnsCAARecord::Parse(rrdatas, &policy); - } -} - -TEST(CAAParserTest, PolicyFuzz) { - // Fuzz the policy input for valgrind's. - const std::string policy_value("\x06\x03\x55\x04\x24"); - const std::string in = - MakeCAA(false /* not critical */, true /* for us */, "policy", - policy_value); - - CAAFuzz(in); -} - -TEST(CAAParserTest, Auth) { - // Check that a hash element is parsed correctly. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::SUCCESS, - net::DnsCAARecord::Parse(rrdatas, &policy)); - ASSERT_EQ(1u, policy.authorized_hashes.size()); - ASSERT_EQ(4 /* SHA256 */, policy.authorized_hashes[0].algorithm); - ASSERT_EQ(net::DnsCAARecord::Policy::USER_CERTIFICATE, - policy.authorized_hashes[0].target); - ASSERT_EQ(32u, policy.authorized_hashes[0].data.size()); - ASSERT_EQ(443u, policy.authorized_hashes[0].port); -} - -TEST(CAAParserTest, AuthFuzz) { - // Fuzz the auth value for valgrind. - const std::string in = MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 443)); - - CAAFuzz(in); -} - -TEST(CAAParserTest, UnknownHashFunction) { - // Check that an unknown hash is ignored. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x70", 32, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::DISCARD, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, CriticalUnknownHashFunction) { - // Check that a critical unknown hash is an error. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - true /* critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x70", 32, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::UNKNOWN_CRITICAL, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, UnknownHashTarget) { - // Check that an unknown hash is ignored. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x55\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::DISCARD, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, CriticalUnknownHashTarget) { - // Check that a critical unknown hash target is an error. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - true /* critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x55\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::UNKNOWN_CRITICAL, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, IncorrectDigestLength) { - // Check that a digest with the wrong length is an error. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 31, 443))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::SYNTAX_ERROR, - net::DnsCAARecord::Parse(rrdatas, &policy)); -} - -TEST(CAAParserTest, ZeroPort) { - // Check that a hash element with a zero port is parsed correctly. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 0))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::SUCCESS, - net::DnsCAARecord::Parse(rrdatas, &policy)); - ASSERT_EQ(1u, policy.authorized_hashes.size()); - ASSERT_EQ(0u, policy.authorized_hashes[0].port); -} - -TEST(CAAParserTest, LargePort) { - // Check that a hash element with a large port is parsed correctly. - std::vector<base::StringPiece> rrdatas; - net::DnsCAARecord::Policy policy; - const std::string caa(MakeCAA( - false /* not critical */, true /* for us */, "auth", - MakeAuth("\x06\x03\x55\x04\x24", - "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", 32, 40000))); - rrdatas.push_back(caa); - - ASSERT_EQ(net::DnsCAARecord::SUCCESS, - net::DnsCAARecord::Parse(rrdatas, &policy)); - ASSERT_EQ(1u, policy.authorized_hashes.size()); - ASSERT_EQ(40000u, policy.authorized_hashes[0].port); -} - -} // namespace net diff --git a/net/net.gyp b/net/net.gyp index 150d9ac..1f67e52 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -123,10 +123,6 @@ 'base/dns_util.h', 'base/dnsrr_resolver.cc', 'base/dnsrr_resolver.h', - 'base/dnssec_chain_verifier.cc', - 'base/dnssec_chain_verifier.h', - 'base/dnssec_keyset.cc', - 'base/dnssec_keyset.h', 'base/escape.cc', 'base/escape.h', 'base/ev_root_ca_metadata.cc', @@ -999,8 +995,6 @@ 'base/cert_verify_proc_nss.cc', 'base/cert_verify_proc_nss.h', 'base/crypto_module_nss.cc', - 'base/dnssec_keyset.cc', - 'base/dnssec_keyset.h', 'base/keygen_handler_nss.cc', 'base/nss_cert_database.cc', 'base/nss_cert_database.h', @@ -1193,7 +1187,6 @@ 'net_jni_headers', ], 'sources!': [ - 'base/dnssec_chain_verifier.cc', 'base/openssl_memory_private_key_store.cc', ], }, { # else OS! = "android" @@ -1269,7 +1262,6 @@ 'base/data_url_unittest.cc', 'base/default_server_bound_cert_store_unittest.cc', 'base/directory_lister_unittest.cc', - 'base/dnssec_unittest.cc', 'base/dns_util_unittest.cc', 'base/dnsrr_resolver_unittest.cc', 'base/escape_unittest.cc', @@ -1588,7 +1580,6 @@ # functionality is ported to OpenSSL. 'sources!': [ 'base/x509_util_nss_unittest.cc', - 'base/dnssec_unittest.cc', 'base/nss_cert_database_unittest.cc', ], }, { # else !use_openssl: remove the unneeded files @@ -2008,17 +1999,6 @@ ], }, { - 'target_name': 'dnssec_chain_verify', - 'type': 'executable', - 'dependencies': [ - '../base/base.gyp:base', - 'net', - ], - 'sources': [ - 'tools/dnssec_chain_verify/dnssec_chain_verify.cc', - ], - }, - { 'target_name': 'fetch_client', 'type': 'executable', 'variables': { 'enable_wexit_time_destructors': 1, }, diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 0170708..5fba60a 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -91,7 +91,6 @@ #include "net/base/cert_verifier.h" #include "net/base/connection_type_histograms.h" #include "net/base/dns_util.h" -#include "net/base/dnssec_chain_verifier.h" #include "net/base/transport_security_state.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -266,201 +265,6 @@ BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context, #endif -// DNSValidationResult enumerates the possible outcomes from processing a -// set of DNS records. -enum DNSValidationResult { - DNSVR_SUCCESS, // the cert is immediately acceptable. - DNSVR_FAILURE, // the cert is unconditionally rejected. - DNSVR_CONTINUE, // perform CA validation as usual. -}; - -// VerifyCAARecords processes DNSSEC validated RRDATA for a number of DNS CAA -// records and checks them against the given chain. -// server_cert_nss: the server's leaf certificate. -// rrdatas: the CAA records for the current domain. -// port: the TCP port number that we connected to. -// TODO(agl): remove once DANE support has been released. -DNSValidationResult VerifyCAARecords( - CERTCertificate* server_cert_nss, - const std::vector<base::StringPiece>& rrdatas, - uint16 port) { - DnsCAARecord::Policy policy; - const DnsCAARecord::ParseResult r = DnsCAARecord::Parse(rrdatas, &policy); - if (r == DnsCAARecord::SYNTAX_ERROR || r == DnsCAARecord::UNKNOWN_CRITICAL) - return DNSVR_FAILURE; - if (r == DnsCAARecord::DISCARD) - return DNSVR_CONTINUE; - DCHECK(r == DnsCAARecord::SUCCESS); - - for (std::vector<DnsCAARecord::Policy::Hash>::const_iterator - hash = policy.authorized_hashes.begin(); - hash != policy.authorized_hashes.end(); - ++hash) { - if (hash->target == DnsCAARecord::Policy::SUBJECT_PUBLIC_KEY_INFO && - (hash->port == 0 || hash->port == port)) { - CHECK_LE(hash->data.size(), static_cast<unsigned>(SHA512_LENGTH)); - uint8 calculated_hash[SHA512_LENGTH]; // SHA512 is the largest. - SECStatus rv = HASH_HashBuf( - static_cast<HASH_HashType>(hash->algorithm), - calculated_hash, - server_cert_nss->derPublicKey.data, - server_cert_nss->derPublicKey.len); - DCHECK(rv == SECSuccess); - const std::string actual_digest(reinterpret_cast<char*>(calculated_hash), - hash->data.size()); - - // Note that the parser ensures that hash->data.size() is correct for the - // given algorithm. An attacker cannot give a zero length hash that - // always matches. - if (actual_digest == hash->data) { - // A DNSSEC secure hash over the public key of the leaf-certificate - // is sufficient. - return DNSVR_SUCCESS; - } - } - } - - // If a CAA record was found, but nothing matched, then we reject the - // certificate. - return DNSVR_FAILURE; -} - -// VerifyTLSARecords processes DNSSEC validated RRDATA for a number of DNS TLSA -// records and checks them against the given chain. -// server_cert_nss: the server's leaf certificate. -// rrdatas: the TLSA records for the current domain. -DNSValidationResult VerifyTLSARecords( - CERTCertificate* server_cert_nss, - const std::vector<base::StringPiece>& rrdatas) { - std::vector<DnsTLSARecord::Match> matches; - DnsTLSARecord::Parse(rrdatas, &matches); - - for (std::vector<DnsTLSARecord::Match>::const_iterator - i = matches.begin(); i != matches.end(); ++i) { - SECItem matched_data; - switch (i->target) { - case DnsTLSARecord::Match::CERTIFICATE: - matched_data = server_cert_nss->derCert; - break; - case DnsTLSARecord::Match::SUBJECT_PUBLIC_KEY_INFO: - matched_data = server_cert_nss->derPublicKey; - break; - default: - continue; - } - - uint8 calculated_hash[HASH_LENGTH_MAX]; - SECItem processed_data; - if (i->algorithm == HASH_AlgNULL) { - processed_data = matched_data; - } else { - SECStatus rv = HASH_HashBuf( - static_cast<HASH_HashType>(i->algorithm), - calculated_hash, - matched_data.data, - matched_data.len); - if (rv != SECSuccess) - continue; - processed_data.data = calculated_hash; - processed_data.len = i->data.size(); - } - - if (processed_data.len == i->data.size() && - memcmp(processed_data.data, i->data.data(), i->data.size()) == 0) { - return DNSVR_SUCCESS; - } - } - - // No TLSA records matched so we reject the certificate. - return DNSVR_FAILURE; -} - -// CheckDNSSECChain tries to validate a DNSSEC chain embedded in -// |server_cert_nss|. It returns true iff a chain is found that proves the -// value of a CAA record that contains a valid public key fingerprint. -// |port| contains the TCP port number that we connected to as CAA records can -// be specific to a given port. -DNSValidationResult CheckDNSSECChain( - const std::string& hostname, - CERTCertificate* server_cert_nss, - uint16 port) { - if (!server_cert_nss) - return DNSVR_CONTINUE; - - // CERT_FindCertExtensionByOID isn't exported so we have to install an OID, - // get a tag for it and find the extension by using that tag. - static SECOidTag dnssec_chain_tag; - static bool dnssec_chain_tag_valid; - if (!dnssec_chain_tag_valid) { - // It's harmless if multiple threads enter this block concurrently. - static const uint8 kDNSSECChainOID[] = - // 1.3.6.1.4.1.11129.2.1.4 - // (iso.org.dod.internet.private.enterprises.google.googleSecurity. - // certificateExtensions.dnssecEmbeddedChain) - {0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x04}; - SECOidData oid_data; - memset(&oid_data, 0, sizeof(oid_data)); - oid_data.oid.data = const_cast<uint8*>(kDNSSECChainOID); - oid_data.oid.len = sizeof(kDNSSECChainOID); - oid_data.desc = "DNSSEC chain"; - oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION; - dnssec_chain_tag = SECOID_AddEntry(&oid_data); - DCHECK_NE(SEC_OID_UNKNOWN, dnssec_chain_tag); - dnssec_chain_tag_valid = true; - } - - SECItem dnssec_embedded_chain; - SECStatus rv = CERT_FindCertExtension(server_cert_nss, - dnssec_chain_tag, &dnssec_embedded_chain); - if (rv != SECSuccess) - return DNSVR_CONTINUE; - - std::string chain( - reinterpret_cast<char*>(dnssec_embedded_chain.data), - dnssec_embedded_chain.len); - SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE); - std::string dns_hostname; - if (!DNSDomainFromDot(hostname, &dns_hostname)) - return DNSVR_CONTINUE; - - DNSSECChainVerifier verifier(dns_hostname, chain); - DNSSECChainVerifier::Error err = verifier.Verify(); - bool is_tlsa = false; - if (err == DNSSECChainVerifier::BAD_TARGET) { - // We might have failed because this is a DANE chain, not a CAA chain. - // DANE stores records in a subdomain of the name that includes the port - // and protocol, i.e. _443._tcp.www.example.com. We have to construct - // such a name for |hostname|. - const std::string port_str = base::UintToString(port); - char port_label_len = 1 + static_cast<char>(port_str.size()); - const std::string tlsa_domain = - std::string(&port_label_len, 1) + "_" + port_str + - "\x04_tcp" + - dns_hostname; - - verifier = DNSSECChainVerifier(tlsa_domain, chain); - err = verifier.Verify(); - is_tlsa = true; - } - - if (err != DNSSECChainVerifier::OK) { - LOG(ERROR) << "DNSSEC chain verification failed: " << err; - return DNSVR_CONTINUE; - } - - if (is_tlsa) { - if (verifier.rrtype() != kDNS_TLSA) - return DNSVR_CONTINUE; - - return VerifyTLSARecords(server_cert_nss, verifier.rrdatas()); - } - - if (verifier.rrtype() != kDNS_CAA) - return DNSVR_CONTINUE; - - return VerifyCAARecords(server_cert_nss, verifier.rrdatas(), port); -} - void DestroyCertificates(CERTCertificate** certs, size_t len) { for (size_t i = 0; i < len; i++) CERT_DestroyCertificate(certs[i]); @@ -3399,9 +3203,6 @@ int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) { case STATE_HANDSHAKE_COMPLETE: rv = DoHandshakeComplete(rv); break; - case STATE_VERIFY_DNSSEC: - rv = DoVerifyDNSSEC(rv); - break; case STATE_VERIFY_CERT: DCHECK(rv == OK); rv = DoVerifyCert(rv); @@ -3436,7 +3237,7 @@ int SSLClientSocketNSS::DoHandshakeComplete(int result) { if (result == OK) { // SSL handshake is completed. Let's verify the certificate. - GotoState(STATE_VERIFY_DNSSEC); + GotoState(STATE_VERIFY_CERT); // Done! } set_channel_id_sent(core_->state().channel_id_sent); @@ -3446,25 +3247,6 @@ int SSLClientSocketNSS::DoHandshakeComplete(int result) { } -int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { - DCHECK(!core_->state().server_cert_chain.empty()); - DCHECK(core_->state().server_cert_chain[0]); - - DNSValidationResult r = CheckDNSSECChain( - host_and_port_.host(), core_->state().server_cert_chain[0], - host_and_port_.port()); - if (r == DNSVR_SUCCESS) { - server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC; - server_cert_verify_result_.verified_cert = core_->state().server_cert; - GotoState(STATE_VERIFY_CERT_COMPLETE); - return OK; - } - - GotoState(STATE_VERIFY_CERT); - - return OK; -} - int SSLClientSocketNSS::DoVerifyCert(int result) { DCHECK(!core_->state().server_cert_chain.empty()); DCHECK(core_->state().server_cert_chain[0]); diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 95e0566..6f3f7bb 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -115,7 +115,6 @@ class SSLClientSocketNSS : public SSLClientSocket { STATE_NONE, STATE_HANDSHAKE, STATE_HANDSHAKE_COMPLETE, - STATE_VERIFY_DNSSEC, STATE_VERIFY_CERT, STATE_VERIFY_CERT_COMPLETE, }; @@ -135,7 +134,6 @@ class SSLClientSocketNSS : public SSLClientSocket { int DoHandshakeLoop(int last_io_result); int DoHandshake(); int DoHandshakeComplete(int result); - int DoVerifyDNSSEC(int result); int DoVerifyCert(int result); int DoVerifyCertComplete(int result); diff --git a/net/tools/dnssec_chain_verify/dnssec_chain_verify.cc b/net/tools/dnssec_chain_verify/dnssec_chain_verify.cc deleted file mode 100644 index b27c375..0000000 --- a/net/tools/dnssec_chain_verify/dnssec_chain_verify.cc +++ /dev/null @@ -1,109 +0,0 @@ -// 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. - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> - -#include "base/at_exit.h" -#include "net/base/dns_util.h" -#include "net/base/dnssec_chain_verifier.h" - -static int usage(const char* argv0) { - fprintf(stderr, "Usage: %s [--ignore-timestamps] <target domain> " - "<input file>\n", argv0); - return 1; -} - -int main(int argc, char** argv) { - base::AtExitManager at_exit_manager; - - if (argc < 3) - return usage(argv[0]); - - const char* target = NULL; - const char* infilename = NULL; - bool ignore_timestamps = false; - - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--ignore-timestamps") == 0) { - ignore_timestamps = true; - } else if (!target) { - target = argv[i]; - } else if (!infilename) { - infilename = argv[i]; - } else { - return usage(argv[0]); - } - } - - if (!target || !infilename) - return usage(argv[0]); - - FILE* infile = fopen(infilename, "r"); - if (!infile) { - perror("open"); - return usage(argv[0]); - } - - fseek(infile, 0, SEEK_END); - unsigned long inlen = ftell(infile); - fseek(infile, 0, SEEK_SET); - - char* const input = (char *) malloc(inlen); - if (fread(input, inlen, 1, infile) != 1) { - perror("read"); - return 1; - } - - std::string target_dns; - if (!net::DNSDomainFromDot(target, &target_dns)) { - fprintf(stderr, "Not a valid DNS name: %s\n", target); - return usage(argv[0]); - } - - net::DNSSECChainVerifier verifier(target_dns, - base::StringPiece(input, inlen)); - if (ignore_timestamps) - verifier.IgnoreTimestamps(); - net::DNSSECChainVerifier::Error err = verifier.Verify(); - const char* err_str; - switch (err) { - case net::DNSSECChainVerifier::BAD_DATA: - err_str = "Bad data"; - break; - case net::DNSSECChainVerifier::UNKNOWN_ROOT_KEY: - err_str = "Unknown root key"; - break; - case net::DNSSECChainVerifier::UNKNOWN_DIGEST: - err_str = "Unknown digest"; - break; - case net::DNSSECChainVerifier::UNKNOWN_TERMINAL_RRTYPE: - err_str = "Unknown terminal RR type"; - break; - case net::DNSSECChainVerifier::BAD_SIGNATURE: - err_str = "Bad signature"; - break; - case net::DNSSECChainVerifier::NO_DS_LINK: - err_str = "No DS link"; - break; - case net::DNSSECChainVerifier::OFF_COURSE: - err_str = "Off course"; - break; - case net::DNSSECChainVerifier::BAD_TARGET: - err_str = "Bad target"; - break; - default: - err_str = "Unknown"; - break; - } - - if (err != net::DNSSECChainVerifier::OK) { - fprintf(stderr, "Chain error: %s (%d)\n", err_str, (int) err); - return 1; - } - - fprintf(stderr, "Chain good: rrtype:%d\n", verifier.rrtype()); - return 0; -} |