summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-16 00:04:25 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-16 00:04:25 +0000
commit5351bd70aefdf610d871b8ed00d6e345a06075dc (patch)
tree74b419e73d7648c572ba44474845f2d0a85709da /net
parentae27dc38b417e979b1728fbe43c3668d693930da (diff)
downloadchromium_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.h2
-rw-r--r--net/base/dns_util.h2
-rw-r--r--net/base/dnssec_chain_verifier.cc995
-rw-r--r--net/base/dnssec_chain_verifier.h177
-rw-r--r--net/base/dnssec_keyset.cc478
-rw-r--r--net/base/dnssec_keyset.h63
-rw-r--r--net/base/dnssec_unittest.cc887
-rw-r--r--net/net.gyp20
-rw-r--r--net/socket/ssl_client_socket_nss.cc220
-rw-r--r--net/socket/ssl_client_socket_nss.h2
-rw-r--r--net/tools/dnssec_chain_verify/dnssec_chain_verify.cc109
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;
-}