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

Unified Diff: net/cert/ocsp_parser.cc

Issue 1541213002: Adding OCSP Parser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding initial unittest. Created 5 years 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/ocsp_parser.cc
diff --git a/net/cert/ocsp_parser.cc b/net/cert/ocsp_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8672dbff9157436b8ddf902e28596366d57a1499
--- /dev/null
+++ b/net/cert/ocsp_parser.cc
@@ -0,0 +1,255 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ocsp_parser.h"
+
+namespace net {
+
+namespace ct {
+
+namespace {
+
+bool ParseOCSPSingleResponse(der::Parser* parser, OCSPSingleResponse* data) {
+ der::Input cert_id;
+ if (!parser->ReadTag(der::kSequence, &cert_id))
+ return false;
+ data->cert_id = cert_id.AsString();
+ der::Tag status_tag;
+ der::Input status;
+ if (!parser->ReadTagAndValue(&status_tag, &status))
+ return false;
+ if (status_tag == der::ContextSpecificPrimitive(0)) {
+ data->cert_status = OCSP_CERT_GOOD;
+ } else if (status_tag == der::ContextSpecificPrimitive(1)) {
+ data->cert_status = OCSP_CERT_REVOKED;
+ der::Parser revoked_info_parser(status);
+ der::Input revocation_time;
+ der::Input revocation_reason;
+ if (!revoked_info_parser.ReadTag(der::kGeneralizedTime, &revocation_time))
+ return false;
+ if (!der::ParseGeneralizedTime(revocation_time, &(data->revocation_time)))
+ return false;
+ if (!revoked_info_parser.ReadTag(der::kEnumerated, &revocation_reason))
+ return false;
+ uint8_t revocation_reason_value;
+ if (!der::ParseUint8(revocation_reason, &revocation_reason_value))
+ return false;
+ data->revocation_reason =
+ static_cast<OCSPRevocationReason>(revocation_reason_value);
+ } else if (status_tag == der::ContextSpecificPrimitive(2)) {
+ data->cert_status = OCSP_CERT_UNKNOWN;
+ }
Ryan Sleevi 2015/12/30 18:55:18 BUG: Fail to handle other status tags.
svaldez 2015/12/30 19:31:37 Done.
+
+ der::Input this_update;
+ if (!parser->ReadTag(der::kGeneralizedTime, &this_update))
+ return false;
+ if (!der::ParseGeneralizedTime(this_update, &(data->this_update)))
+ return false;
+ der::Input next_update_input;
+ bool next_update_present;
+ if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(0),
+ &next_update_input, &next_update_present)) {
+ return false;
+ }
+
+ if (next_update_present) {
+ der::Parser next_update_parser(next_update_input);
+ der::Input next_update;
+ if (!next_update_parser.ReadTag(der::kGeneralizedTime, &next_update))
+ return false;
+ if (!der::ParseGeneralizedTime(next_update, &(data->next_update)))
+ return false;
+ }
+ der::Input extensions_input;
+ bool extensions_present;
+ if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(1),
+ &extensions_input, &extensions_present)) {
+ return false;
+ }
+
+ if (!extensions_present)
+ return true;
+ der::Parser extensions_input_parser(extensions_input);
+ der::Parser extensions_parser;
+ if (!extensions_input_parser.ReadSequence(&extensions_parser))
+ return false;
+ while (extensions_parser.HasMore()) {
+ ParsedExtension extension;
+ der::Input extension_tlv;
+ if (!extensions_parser.ReadRawTLV(&extension_tlv))
+ return false;
+ if (!ParseExtension(extension_tlv, &extension))
+ return false;
+ data->extensions.push_back(extension);
+ }
+ return true;
+}
+
+bool ParseOCSPResponseData(der::Parser* parser, OCSPResponseData* data) {
+ der::Input version_input;
+ bool version_present;
+ if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(0),
+ &version_input, &version_present)) {
+ return false;
+ }
+ if (version_present) {
Ryan Sleevi 2015/12/30 18:55:18 newline
svaldez 2015/12/30 19:31:37 Done.
+ der::Parser version_parser(version_input);
+ der::Input version;
+ if (!version_parser.ReadTag(der::kInteger, &version))
+ return false;
+ if (!der::ParseUint8(version, &(data->version)))
+ return false;
+ } else {
+ data->version = 0;
+ }
+
+ der::Tag id_tag;
+ der::Input responder_id;
+ if (!parser->ReadTagAndValue(&id_tag, &responder_id))
+ return false;
+ if (id_tag == der::ContextSpecificConstructed(1)) {
+ data->responder_id_name = responder_id.AsString();
+ } else if (id_tag == der::ContextSpecificConstructed(2)) {
+ der::Parser key_parser(responder_id);
+ der::Input responder_key;
+ if (!key_parser.ReadTag(der::kOctetString, &responder_key))
+ return false;
+ data->responder_id_key = responder_key.AsString();
+ } else {
+ return false;
+ }
+
+ der::Input produced_at;
+ if (!parser->ReadTag(der::kGeneralizedTime, &produced_at))
+ return false;
+ if (!der::ParseGeneralizedTime(produced_at, &(data->produced_at)))
+ return false;
+
+ der::Parser responses_parser;
+ if (!parser->ReadSequence(&responses_parser))
+ return false;
+ while (responses_parser.HasMore()) {
+ OCSPSingleResponse single_response;
+ der::Parser response_parser;
+ if (!responses_parser.ReadSequence(&response_parser))
+ return false;
+ if (!ParseOCSPSingleResponse(&response_parser, &single_response))
+ return false;
+ data->responses.push_back(single_response);
+ }
+
+ der::Input extensions_input;
+ bool extensions_present;
+ if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(1),
+ &extensions_input, &extensions_present)) {
+ return false;
+ }
+
+ if (!extensions_present)
+ return true;
+ der::Parser extensions_input_parser(extensions_input);
+ der::Parser extensions_parser;
+ if (!extensions_input_parser.ReadSequence(&extensions_parser))
+ return false;
+ while (extensions_parser.HasMore()) {
+ ParsedExtension extension;
+ der::Input extension_tlv;
+ if (!extensions_parser.ReadRawTLV(&extension_tlv))
+ return false;
+ if (!ParseExtension(extension_tlv, &extension))
+ return false;
+ data->extensions.push_back(extension);
+ }
+ return true;
+}
+
+} // namespace
+
+OCSPSingleResponse::OCSPSingleResponse() {}
+OCSPSingleResponse::~OCSPSingleResponse() {}
+
+OCSPResponseData::OCSPResponseData() {}
+OCSPResponseData::~OCSPResponseData() {}
+
+OCSPResponse::OCSPResponse() {}
+OCSPResponse::~OCSPResponse() {}
+
+bool ParseOCSPResponse(const std::string& ocsp_response,
+ OCSPResponse* response) {
+ der::Parser parser(
+ der::Input(reinterpret_cast<const uint8_t*>(ocsp_response.data()),
+ ocsp_response.size()));
+ der::Input response_status;
+ der::Parser ocsp_response_parser;
+ if (!parser.ReadSequence(&ocsp_response_parser))
+ return false;
+ if (!ocsp_response_parser.ReadTag(der::kEnumerated, &response_status))
+ return false;
+ uint8_t response_status_value;
+ if (!der::ParseUint8(response_status, &response_status_value))
+ return false;
+ response->status = static_cast<OCSPResponseStatus>(response_status_value);
+ if (response->status != OCSP_SUCCESSFUL)
+ return true;
+
+ der::Input response_type_oid;
+ der::Input response_string;
+ der::Parser response_bytes_input_parser;
+ der::Parser response_bytes_parser;
+ if (!ocsp_response_parser.ReadConstructed(der::ContextSpecificConstructed(0),
+ &response_bytes_input_parser)) {
+ return false;
+ }
+ if (!response_bytes_input_parser.ReadSequence(&response_bytes_parser))
+ return false;
+ if (!response_bytes_parser.ReadTag(der::kOid, &response_type_oid))
+ return false;
+ if (!response_type_oid.Equals(der::Input(kOidPkixOcspBasic)))
+ return false;
+ if (!response_bytes_parser.ReadTag(der::kOctetString, &response_string))
+ return false;
+
+ der::Parser response_parser(response_string);
+ der::Parser basic_response_parser;
+ der::Parser response_data_parser;
+ der::Input sigalg_tlv;
+ if (!response_parser.ReadSequence(&basic_response_parser))
+ return false;
+ if (!basic_response_parser.ReadSequence(&response_data_parser))
+ return false;
+ if (!ParseOCSPResponseData(&response_data_parser, &(response->data)))
+ return false;
+ if (!basic_response_parser.ReadRawTLV(&sigalg_tlv))
+ return false;
+ response->signature_algorithm = SignatureAlgorithm::CreateFromDer(sigalg_tlv);
+ if (!basic_response_parser.ReadBitString(&(response->signature)))
+ return false;
+ der::Input certs_input;
+ bool certs_present;
+ if (!basic_response_parser.ReadOptionalTag(der::ContextSpecificConstructed(0),
+ &certs_input, &certs_present)) {
+ return false;
+ }
+
+ if (!certs_present)
+ return true;
+ der::Parser certs_input_parser(certs_input);
+ der::Parser certs_parser;
+ if (!certs_input_parser.ReadSequence(&certs_parser))
+ return false;
+ while (certs_parser.HasMore()) {
+ ParsedCertificate parsed_cert;
+ der::Input cert_tlv;
+ if (!certs_parser.ReadRawTLV(&cert_tlv))
+ return false;
+ if (!ParseCertificate(cert_tlv, &parsed_cert))
+ return false;
+ response->certs.push_back(parsed_cert);
+ }
+ return true;
+}
+
+} // namespace cert
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698