Index: net/cert/internal/parse_certificate.cc |
diff --git a/net/cert/internal/parse_certificate.cc b/net/cert/internal/parse_certificate.cc |
index af2f1c21dae8d8fc6d8dcb3733839cc3158e1cfb..c888d73e3e7cbc64e9a830859fa363ef2510ee1e 100644 |
--- a/net/cert/internal/parse_certificate.cc |
+++ b/net/cert/internal/parse_certificate.cc |
@@ -7,6 +7,7 @@ |
#include <utility> |
#include "base/strings/string_util.h" |
+#include "net/cert/internal/cert_errors.h" |
#include "net/der/input.h" |
#include "net/der/parse_values.h" |
#include "net/der/parser.h" |
@@ -15,6 +16,20 @@ namespace net { |
namespace { |
+DEFINE_CERT_ERROR_ID(kCertificateNotSequence, |
+ "Failed parsing Certificate SEQUENCE"); |
+DEFINE_CERT_ERROR_ID(kUnconsumedDataInsideCertificateSequence, |
+ "Unconsumed data inside Certificate SEQUENCE"); |
+DEFINE_CERT_ERROR_ID(kUnconsumedDataAfterCertificateSequence, |
+ "Unconsumed data after Certificate SEQUENCE"); |
+DEFINE_CERT_ERROR_ID(kTbsCertificateNotSequence, |
+ "Couldn't read tbsCertificate as SEQUENCE"); |
+DEFINE_CERT_ERROR_ID( |
+ kSignatureAlgorithmNotSequence, |
+ "Couldn't read Certificate.signatureAlgorithm as SEQUENCE"); |
+DEFINE_CERT_ERROR_ID(kSignatureValueNotBitString, |
+ "Couldn't read Certificate.signatureValue as BIT STRING"); |
+ |
// Returns true if |input| is a SEQUENCE and nothing else. |
WARN_UNUSED_RESULT bool IsSequenceTLV(const der::Input& input) { |
der::Parser parser(input); |
@@ -172,35 +187,54 @@ bool ParseCertificate(const der::Input& certificate_tlv, |
der::Input* out_signature_algorithm_tlv, |
der::BitString* out_signature_value, |
CertErrors* out_errors) { |
- // TODO(crbug.com/634443): Fill |out_errors| (which may be null) with error |
- // information. |
+ // |out_errors| is optional. But ensure it is non-null for the remainder of |
+ // this function. |
+ if (!out_errors) { |
+ CertErrors unused_errors; |
+ return ParseCertificate(certificate_tlv, out_tbs_certificate_tlv, |
+ out_signature_algorithm_tlv, out_signature_value, |
+ &unused_errors); |
+ } |
+ |
der::Parser parser(certificate_tlv); |
// Certificate ::= SEQUENCE { |
der::Parser certificate_parser; |
- if (!parser.ReadSequence(&certificate_parser)) |
+ if (!parser.ReadSequence(&certificate_parser)) { |
+ out_errors->AddError(kCertificateNotSequence); |
return false; |
+ } |
// tbsCertificate TBSCertificate, |
- if (!ReadSequenceTLV(&certificate_parser, out_tbs_certificate_tlv)) |
+ if (!ReadSequenceTLV(&certificate_parser, out_tbs_certificate_tlv)) { |
+ out_errors->AddError(kTbsCertificateNotSequence); |
return false; |
+ } |
// signatureAlgorithm AlgorithmIdentifier, |
- if (!ReadSequenceTLV(&certificate_parser, out_signature_algorithm_tlv)) |
+ if (!ReadSequenceTLV(&certificate_parser, out_signature_algorithm_tlv)) { |
+ out_errors->AddError(kSignatureAlgorithmNotSequence); |
return false; |
+ } |
// signatureValue BIT STRING } |
- if (!certificate_parser.ReadBitString(out_signature_value)) |
+ if (!certificate_parser.ReadBitString(out_signature_value)) { |
+ out_errors->AddError(kSignatureValueNotBitString); |
return false; |
+ } |
// There isn't an extension point at the end of Certificate. |
- if (certificate_parser.HasMore()) |
+ if (certificate_parser.HasMore()) { |
+ out_errors->AddError(kUnconsumedDataInsideCertificateSequence); |
return false; |
+ } |
// By definition the input was a single Certificate, so there shouldn't be |
// unconsumed data. |
- if (parser.HasMore()) |
+ if (parser.HasMore()) { |
+ out_errors->AddError(kUnconsumedDataAfterCertificateSequence); |
return false; |
+ } |
return true; |
} |