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

Unified Diff: net/cert/internal/verify_name_match.cc

Issue 1214933009: Class for parsing and evaluating RFC 5280 NameConstraints. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compare_DN2
Patch Set: win compile fix Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: net/cert/internal/verify_name_match.cc
diff --git a/net/cert/internal/verify_name_match.cc b/net/cert/internal/verify_name_match.cc
index c34bb2c5fdb3505434d510a6f1281fb878cedb02..8256170eb92867437cd8c37f15b82603aa1a1fee 100644
--- a/net/cert/internal/verify_name_match.cc
+++ b/net/cert/internal/verify_name_match.cc
@@ -22,6 +22,26 @@ namespace net {
namespace {
+// RFC 5280 section A.1:
+//
+// pkcs-9 OBJECT IDENTIFIER ::=
+// { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+//
+// id-emailAddress AttributeType ::= { pkcs-9 1 }
+//
+// In dotted form: 1.2.840.113549.1.9.1
+const uint8_t kOidEmailAddress[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
+ 0x0D, 0x01, 0x09, 0x01};
+
+// RFC 5280 section A.1:
+//
+// id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
+//
+// id-at-commonName AttributeType ::= { id-at 3 }
+//
+// In dotted form: 2.5.4.3
+const uint8_t kOidCommonName[] = {0x55, 0x04, 0x03};
+
// Types of character set checking that NormalizeDirectoryString can perform.
enum CharsetEnforcement {
NO_ENFORCEMENT,
@@ -384,8 +404,16 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
return true;
}
-} // namespace
+enum NameMatchType {
+ EXACT_MATCH,
+ SUBTREE_MATCH,
+};
+// Verify that |a| matches |b|. If |match_type| is EXACT_MATCH, returns true if
+// they are an exact match as defined by RFC 5280 7.1. If |match_type| is
+// SUBTREE_MATCH, returns true if |a| is within the subtree defined by |b| as
+// defined by RFC 5280 7.1.
+//
// |a| and |b| are ASN.1 RDNSequence values (not including the Sequence tag),
// defined in RFC 5280 section 4.1.2.4:
//
@@ -396,7 +424,9 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
//
// RelativeDistinguishedName ::=
// SET SIZE (1..MAX) OF AttributeTypeAndValue
-bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
+bool VerifyNameMatchInternal(const der::Input& a,
+ const der::Input& b,
+ NameMatchType match_type) {
// Empty Names are allowed. RFC 5280 section 4.1.2.4 requires "The issuer
// field MUST contain a non-empty distinguished name (DN)", while section
// 4.1.2.6 allows for the Subject to be empty in certain cases. The caller is
@@ -416,7 +446,12 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return false;
}
}
- if (a_rdn_sequence_counter.HasMore() || b_rdn_sequence_counter.HasMore())
+ // If doing exact match and either of the sequences has more elements than the
+ // other, not a match. If doing a subtree match, the first Name may have more
+ // RDNs than the second.
+ if (b_rdn_sequence_counter.HasMore())
+ return false;
+ if (match_type == EXACT_MATCH && a_rdn_sequence_counter.HasMore())
return false;
// Same number of RDNs, now check if they match.
@@ -435,4 +470,68 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return true;
}
+} // namespace
+
+bool VerifyNameMatch(const der::Input& a_rdn_sequence,
+ const der::Input& b_rdn_sequence) {
+ return VerifyNameMatchInternal(a_rdn_sequence, b_rdn_sequence, EXACT_MATCH);
+}
+
+bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
+ const der::Input& parent_rdn_sequence) {
+ return VerifyNameMatchInternal(name_rdn_sequence, parent_rdn_sequence,
+ SUBTREE_MATCH);
+}
+
+bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
+ bool* contained_email_address) {
+ der::Parser rdn_sequence_parser(name_rdn_sequence);
+
+ while (rdn_sequence_parser.HasMore()) {
+ der::Parser rdn_parser;
+ if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
+ return false;
+
+ std::vector<AttributeTypeAndValue> type_and_values;
+ if (!ReadRdn(&rdn_parser, &type_and_values))
+ return false;
+
+ for (const auto& type_and_value : type_and_values) {
+ if (type_and_value.type.Equals(der::Input(kOidEmailAddress))) {
+ *contained_email_address = true;
+ return true;
+ }
+ }
+ }
+
+ *contained_email_address = false;
+ return true;
+}
+
+bool GetNormalizedCommonNameFromName(const der::Input& name_rdn_sequence,
+ std::string* normalized_common_name) {
+ der::Parser rdn_sequence_parser(name_rdn_sequence);
+
+ while (rdn_sequence_parser.HasMore()) {
+ der::Parser rdn_parser;
+ if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
+ return false;
+
+ std::vector<AttributeTypeAndValue> type_and_values;
+ if (!ReadRdn(&rdn_parser, &type_and_values))
+ return false;
+
+ for (const auto& type_and_value : type_and_values) {
+ if (type_and_value.type.Equals(der::Input(kOidCommonName))) {
+ if (!IsNormalizableDirectoryString(type_and_value.value_tag))
+ return false;
+ return NormalizeValue(type_and_value.value_tag, type_and_value.value,
+ normalized_common_name);
+ }
+ }
+ }
+
+ return false;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698