Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: net/base/dnssec_chain_verifier.cc

Issue 11184027: net: add DANE support for DNSSEC stapled certificates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/dnssec_chain_verifier.h" 5 #include "net/base/dnssec_chain_verifier.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/sha1.h" 9 #include "base/sha1.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // Add all the keys as trusted. 536 // Add all the keys as trusted.
537 for (unsigned i = 0; i < dnskeys.size(); i++) { 537 for (unsigned i = 0; i < dnskeys.size(); i++) {
538 if (i == entry_key) 538 if (i == entry_key)
539 continue; 539 continue;
540 current_zone_->trusted_keys.AddKey(dnskeys[i]); 540 current_zone_->trusted_keys.AddKey(dnskeys[i]);
541 } 541 }
542 542
543 return OK; 543 return OK;
544 } 544 }
545 545
546 // IsValidTerminalRRType returns true if the given RR type is one that we
547 // accept as the terminal record in a DNSSEC chain.
548 bool DNSSECChainVerifier::IsValidTerminalRRType(uint16 rrtype) {
549 switch (rrtype) {
550 case kDNS_CAA:
551 case kDNS_CERT:
552 case kDNS_TLSA:
553 case kDNS_TXT:
554 return true;
555 }
556
557 return false;
558 }
559
546 // LeaveZone transitions out of the current zone, either by following DS 560 // LeaveZone transitions out of the current zone, either by following DS
547 // records to validate the entry key of the next zone, or because the final 561 // records to validate the entry key of the next zone, or because the final
548 // resource records are given. 562 // resource records are given.
549 DNSSECChainVerifier::Error DNSSECChainVerifier::LeaveZone( 563 DNSSECChainVerifier::Error DNSSECChainVerifier::LeaveZone(
550 base::StringPiece* next_name) { 564 base::StringPiece* next_name) {
551 base::StringPiece sig; 565 base::StringPiece sig;
552 uint16 rrtype; 566 uint16 rrtype;
553 Error err; 567 Error err;
554 568
555 if (!ReadName(next_name) || 569 if (!ReadName(next_name) ||
556 !U16(&rrtype) || 570 !U16(&rrtype) ||
557 !VariableLength16(&sig)) { 571 !VariableLength16(&sig)) {
558 return BAD_DATA; 572 return BAD_DATA;
559 } 573 }
560 574
561 std::vector<base::StringPiece> rrdatas; 575 std::vector<base::StringPiece> rrdatas;
562 576
563 if (rrtype == kDNS_DS) { 577 if (rrtype == kDNS_DS) {
564 err = ReadDSSet(&rrdatas, *next_name); 578 err = ReadDSSet(&rrdatas, *next_name);
565 } else if (rrtype == kDNS_CERT || rrtype == kDNS_TXT || rrtype == kDNS_CAA) { 579 } else if (IsValidTerminalRRType(rrtype)) {
566 err = ReadGenericRRs(&rrdatas); 580 err = ReadGenericRRs(&rrdatas);
567 } else if (rrtype == kDNS_CNAME) { 581 } else if (rrtype == kDNS_CNAME) {
568 err = ReadCNAME(&rrdatas); 582 err = ReadCNAME(&rrdatas);
569 } else { 583 } else {
570 return UNKNOWN_TERMINAL_RRTYPE; 584 return UNKNOWN_TERMINAL_RRTYPE;
571 } 585 }
572 if (err != OK) 586 if (err != OK)
573 return err; 587 return err;
574 588
575 if (!current_zone_->trusted_keys.CheckSignature( 589 if (!current_zone_->trusted_keys.CheckSignature(
576 *next_name, current_zone_->name, sig, rrtype, rrdatas)) { 590 *next_name, current_zone_->name, sig, rrtype, rrdatas)) {
577 return BAD_SIGNATURE; 591 return BAD_SIGNATURE;
578 } 592 }
579 593
580 if (rrtype == kDNS_DS) { 594 if (rrtype == kDNS_DS) {
581 // If we are transitioning to another zone then the next zone must be 595 // If we are transitioning to another zone then the next zone must be
582 // 'closer' to the target than the current zone. 596 // 'closer' to the target than the current zone.
583 if (MatchingLabels(target_, *next_name) <= current_zone_->matching_labels) 597 if (MatchingLabels(target_, *next_name) <= current_zone_->matching_labels)
584 return OFF_COURSE; 598 return OFF_COURSE;
585 } else if (rrtype == kDNS_CERT || rrtype == kDNS_TXT || rrtype == kDNS_CAA) { 599 } else if (IsValidTerminalRRType(rrtype)) {
586 // If this is the final entry in the chain then the name must match target_ 600 // If this is the final entry in the chain then the name must match target_
587 if (next_name->size() != target_.size() || 601 if (next_name->size() != target_.size() ||
588 memcmp(next_name->data(), target_.data(), target_.size())) { 602 memcmp(next_name->data(), target_.data(), target_.size())) {
589 return BAD_TARGET; 603 return BAD_TARGET;
590 } 604 }
591 rrdatas_ = rrdatas; 605 rrdatas_ = rrdatas;
592 valid_ = true; 606 valid_ = true;
593 rrtype_ = rrtype; 607 rrtype_ = rrtype;
594 } else if (rrtype == kDNS_CNAME) { 608 } else if (rrtype == kDNS_CNAME) {
595 // A CNAME must match the current target. Then we update the current target 609 // A CNAME must match the current target. Then we update the current target
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 751
738 struct CAAHashFunctionOID { 752 struct CAAHashFunctionOID {
739 uint8 length; 753 uint8 length;
740 uint8 bytes[12]; 754 uint8 bytes[12];
741 int value; 755 int value;
742 }; 756 };
743 757
744 // The values here are taken from NSS's freebl/hasht.h. Sadly, we cannot 758 // The values here are taken from NSS's freebl/hasht.h. Sadly, we cannot
745 // include it because it pulls in #defines that conflict with Chromium headers. 759 // include it because it pulls in #defines that conflict with Chromium headers.
746 // However, these values are part of NSS's public API and so are stable. 760 // However, these values are part of NSS's public API and so are stable.
761 static const int kHashNone = 0;
747 static const int kHashSHA256 = 4; 762 static const int kHashSHA256 = 4;
748 static const int kHashSHA384 = 5; 763 static const int kHashSHA384 = 5;
749 static const int kHashSHA512 = 6; 764 static const int kHashSHA512 = 6;
750 765
751 // kCAAHashFunctions maps from the DER encoding of hash function OIDs to NSS's 766 // kCAAHashFunctions maps from the DER encoding of hash function OIDs to NSS's
752 // hash function enumeration. 767 // hash function enumeration.
753 static CAAHashFunctionOID kCAAHashFunctions[] = { 768 static CAAHashFunctionOID kCAAHashFunctions[] = {
754 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", kHashSHA256 }, 769 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01", kHashSHA256 },
755 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02", kHashSHA384 }, 770 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02", kHashSHA384 },
756 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03", kHashSHA512 }, 771 { 11, "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03", kHashSHA512 },
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 return UNKNOWN_CRITICAL; 924 return UNKNOWN_CRITICAL;
910 } 925 }
911 } 926 }
912 927
913 if (output->authorized_hashes.empty()) 928 if (output->authorized_hashes.empty())
914 return DISCARD; 929 return DISCARD;
915 930
916 return SUCCESS; 931 return SUCCESS;
917 } 932 }
918 933
934 void DnsTLSARecord::Parse(
935 const std::vector<base::StringPiece>& rrdatas,
936 std::vector<DnsTLSARecord::Match>* output) {
937 // see https://tools.ietf.org/html/rfc6698#section-2.1
938 output->clear();
939
940 for (std::vector<base::StringPiece>::const_iterator
941 ii = rrdatas.begin(); ii != rrdatas.end(); ++ii) {
942 base::StringPiece i = *ii;
943
944 if (i.size() < 3)
945 continue;
946
947 const uint8 cert_usage = i[0];
948 const uint8 selector = i[1];
949 const uint8 match_type = i[2];
950 i.remove_prefix(3);
951
952 if (cert_usage != 3) {
953 // Type 3 is a "domain issued certificate" - i.e. a certificate (or
954 // public key) which is granted authority by the TLSA record.
955 continue;
956 }
957
958 Match match;
959
960 switch (selector) {
961 case 0:
962 match.target = Match::CERTIFICATE;
963 break;
964 case 1:
965 match.target = Match::SUBJECT_PUBLIC_KEY_INFO;
966 break;
967 default:
968 continue;
969 }
Ryan Sleevi 2012/10/18 23:21:13 style nit: indent 'case' to two spaces, inner bloc
agl 2012/10/29 15:41:56 Done.
970
971 switch (match_type) {
972 case 0:
973 match.algorithm = kHashNone;
974 break;
975 case 1:
976 match.algorithm = kHashSHA256;
977 break;
978 case 2:
979 match.algorithm = kHashSHA512;
980 break;
981 default:
982 continue;
983 }
984
985 if (match.algorithm != kHashNone &&
986 i.size() != DigestLength(match.algorithm)) {
987 continue;
988 }
989
990 match.data = i.as_string();
991 output->push_back(match);
992 }
993 }
994
919 } // namespace net 995 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698