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

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

Issue 1285593003: Add parsing code for TBSCertificate's "validity" field. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_parsing
Patch Set: rebase Created 5 years, 4 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
« no previous file with comments | « net/cert/internal/parse_certificate.h ('k') | net/cert/internal/parse_certificate_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/internal/parse_certificate.cc
diff --git a/net/cert/internal/parse_certificate.cc b/net/cert/internal/parse_certificate.cc
index e04adb89d48640716b0d7c1002b71bbb0a8fdf9f..9535459bb8ad27ccb39b0807e24d210d4c5212ff 100644
--- a/net/cert/internal/parse_certificate.cc
+++ b/net/cert/internal/parse_certificate.cc
@@ -103,6 +103,75 @@ WARN_UNUSED_RESULT bool VerifySerialNumber(const der::Input& value) {
return true;
}
+// Consumes a "Time" value (as defined by RFC 5280) from |parser|. On success
+// writes the result to |*out| and returns true. On failure no guarantees are
+// made about the state of |parser|.
+//
+// From RFC 5280:
+//
+// Time ::= CHOICE {
+// utcTime UTCTime,
+// generalTime GeneralizedTime }
+WARN_UNUSED_RESULT bool ReadTime(der::Parser* parser,
+ der::GeneralizedTime* out) {
+ der::Input value;
+ der::Tag tag;
+
+ if (!parser->ReadTagAndValue(&tag, &value))
+ return false;
+
+ if (tag == der::kUtcTime)
+ return der::ParseUTCTime(value, out);
+
+ if (tag == der::kGeneralizedTime)
+ return der::ParseGeneralizedTime(value, out);
+
+ // Unrecognized tag.
+ return false;
+}
+
+// Parses a DER-encoded "Validity" as specified by RFC 5280. Returns true on
+// success and sets the results in |not_before| and |not_after|:
+//
+// Validity ::= SEQUENCE {
+// notBefore Time,
+// notAfter Time }
+//
+// Note that upon success it is NOT guaranteed that |*not_before <= *not_after|.
+bool ParseValidity(const der::Input& validity_tlv,
+ der::GeneralizedTime* not_before,
+ der::GeneralizedTime* not_after) {
+ der::Parser parser(validity_tlv);
+
+ // Validity ::= SEQUENCE {
+ der::Parser validity_parser;
+ if (!parser.ReadSequence(&validity_parser))
+ return false;
+
+ // notBefore Time,
+ if (!ReadTime(&validity_parser, not_before))
+ return false;
+
+ // notAfter Time }
+ if (!ReadTime(&validity_parser, not_after))
+ return false;
+
+ // By definition the input was a single Validity sequence, so there shouldn't
+ // be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ // The Validity type does not have an extension point.
+ if (validity_parser.HasMore())
+ return false;
+
+ // Note that RFC 5280 doesn't require notBefore to be <=
+ // notAfter, so that will not be considered a "parsing" error here. Instead it
+ // will be considered an expired certificate later when testing against the
+ // current timestamp.
+ return true;
+}
+
} // namespace
ParsedTbsCertificate::ParsedTbsCertificate() {}
@@ -201,8 +270,13 @@ bool ParseTbsCertificate(const der::Input& tbs_tlv, ParsedTbsCertificate* out) {
return false;
// validity Validity,
- if (!ReadSequenceTLV(&tbs_parser, &out->validity_tlv))
+ der::Input validity_tlv;
+ if (!tbs_parser.ReadRawTLV(&validity_tlv))
+ return false;
+ if (!ParseValidity(validity_tlv, &out->validity_not_before,
+ &out->validity_not_after)) {
return false;
+ }
// subject Name,
if (!ReadSequenceTLV(&tbs_parser, &out->subject_tlv))
« no previous file with comments | « net/cert/internal/parse_certificate.h ('k') | net/cert/internal/parse_certificate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698