| Index: net/cert/internal/parse_certificate.cc
|
| diff --git a/net/cert/internal/parse_certificate.cc b/net/cert/internal/parse_certificate.cc
|
| index 291e91c28bfde0c58d65fb920eae072c6966b631..6cfc4b5afeb51a12ea96db689d9c4af7f6b121b5 100644
|
| --- a/net/cert/internal/parse_certificate.cc
|
| +++ b/net/cert/internal/parse_certificate.cc
|
| @@ -638,6 +638,7 @@ bool ParseBasicConstraints(const der::Input& basic_constraints_tlv,
|
| return false;
|
| }
|
| if (out->has_path_len) {
|
| + // TODO(eroman): Surface reason for failure if length was longer than uint8.
|
| if (!der::ParseUint8(encoded_path_len, &out->path_len))
|
| return false;
|
| } else {
|
| @@ -729,4 +730,68 @@ bool ParseAuthorityInfoAccess(
|
| return true;
|
| }
|
|
|
| +// From RFC 5280:
|
| +//
|
| +// PolicyConstraints ::= SEQUENCE {
|
| +// requireExplicitPolicy [0] SkipCerts OPTIONAL,
|
| +// inhibitPolicyMapping [1] SkipCerts OPTIONAL }
|
| +//
|
| +// SkipCerts ::= INTEGER (0..MAX)
|
| +bool ParsePolicyConstraints(const der::Input& policy_constraints_tlv,
|
| + ParsedPolicyConstraints* out) {
|
| + der::Parser parser(policy_constraints_tlv);
|
| +
|
| + // PolicyConstraints ::= SEQUENCE {
|
| + der::Parser sequence_parser;
|
| + if (!parser.ReadSequence(&sequence_parser))
|
| + return false;
|
| +
|
| + // RFC 5280 prohibits CAs from issuing PolicyConstraints as an empty sequence:
|
| + //
|
| + // Conforming CAs MUST NOT issue certificates where policy constraints
|
| + // is an empty sequence. That is, either the inhibitPolicyMapping field
|
| + // or the requireExplicitPolicy field MUST be present. The behavior of
|
| + // clients that encounter an empty policy constraints field is not
|
| + // addressed in this profile.
|
| + if (!sequence_parser.HasMore())
|
| + return false;
|
| +
|
| + der::Input value;
|
| + if (!sequence_parser.ReadOptionalTag(der::ContextSpecificPrimitive(0), &value,
|
| + &out->has_require_explicit_policy)) {
|
| + return false;
|
| + }
|
| +
|
| + if (out->has_require_explicit_policy) {
|
| + if (!ParseUint8(value, &out->require_explicit_policy)) {
|
| + // TODO(eroman): Surface reason for failure if length was longer than
|
| + // uint8.
|
| + return false;
|
| + }
|
| + } else {
|
| + out->require_explicit_policy = 0;
|
| + }
|
| +
|
| + if (!sequence_parser.ReadOptionalTag(der::ContextSpecificPrimitive(1), &value,
|
| + &out->has_inhibit_policy_mapping)) {
|
| + return false;
|
| + }
|
| +
|
| + if (out->has_inhibit_policy_mapping) {
|
| + if (!ParseUint8(value, &out->inhibit_policy_mapping)) {
|
| + // TODO(eroman): Surface reason for failure if length was longer than
|
| + // uint8.
|
| + return false;
|
| + }
|
| + } else {
|
| + out->inhibit_policy_mapping = 0;
|
| + }
|
| +
|
| + // There should be no remaining data.
|
| + if (sequence_parser.HasMore() || parser.HasMore())
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace net
|
|
|