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

Side by Side 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 4 years, 11 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/ocsp_parser.h"
6
7 namespace net {
8
9 namespace ct {
10
11 namespace {
12
13 bool ParseOCSPSingleResponse(der::Parser* parser, OCSPSingleResponse* data) {
14 der::Input cert_id;
15 if (!parser->ReadTag(der::kSequence, &cert_id))
16 return false;
17 data->cert_id = cert_id.AsString();
18 der::Tag status_tag;
19 der::Input status;
20 if (!parser->ReadTagAndValue(&status_tag, &status))
21 return false;
22 if (status_tag == der::ContextSpecificPrimitive(0)) {
23 data->cert_status = OCSP_CERT_GOOD;
24 } else if (status_tag == der::ContextSpecificPrimitive(1)) {
25 data->cert_status = OCSP_CERT_REVOKED;
26 der::Parser revoked_info_parser(status);
27 der::Input revocation_time;
28 der::Input revocation_reason;
29 if (!revoked_info_parser.ReadTag(der::kGeneralizedTime, &revocation_time))
30 return false;
31 if (!der::ParseGeneralizedTime(revocation_time, &(data->revocation_time)))
32 return false;
33 if (!revoked_info_parser.ReadTag(der::kEnumerated, &revocation_reason))
34 return false;
35 uint8_t revocation_reason_value;
36 if (!der::ParseUint8(revocation_reason, &revocation_reason_value))
37 return false;
38 data->revocation_reason =
39 static_cast<OCSPRevocationReason>(revocation_reason_value);
40 } else if (status_tag == der::ContextSpecificPrimitive(2)) {
41 data->cert_status = OCSP_CERT_UNKNOWN;
42 }
Ryan Sleevi 2015/12/30 18:55:18 BUG: Fail to handle other status tags.
svaldez 2015/12/30 19:31:37 Done.
43
44 der::Input this_update;
45 if (!parser->ReadTag(der::kGeneralizedTime, &this_update))
46 return false;
47 if (!der::ParseGeneralizedTime(this_update, &(data->this_update)))
48 return false;
49 der::Input next_update_input;
50 bool next_update_present;
51 if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(0),
52 &next_update_input, &next_update_present)) {
53 return false;
54 }
55
56 if (next_update_present) {
57 der::Parser next_update_parser(next_update_input);
58 der::Input next_update;
59 if (!next_update_parser.ReadTag(der::kGeneralizedTime, &next_update))
60 return false;
61 if (!der::ParseGeneralizedTime(next_update, &(data->next_update)))
62 return false;
63 }
64 der::Input extensions_input;
65 bool extensions_present;
66 if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(1),
67 &extensions_input, &extensions_present)) {
68 return false;
69 }
70
71 if (!extensions_present)
72 return true;
73 der::Parser extensions_input_parser(extensions_input);
74 der::Parser extensions_parser;
75 if (!extensions_input_parser.ReadSequence(&extensions_parser))
76 return false;
77 while (extensions_parser.HasMore()) {
78 ParsedExtension extension;
79 der::Input extension_tlv;
80 if (!extensions_parser.ReadRawTLV(&extension_tlv))
81 return false;
82 if (!ParseExtension(extension_tlv, &extension))
83 return false;
84 data->extensions.push_back(extension);
85 }
86 return true;
87 }
88
89 bool ParseOCSPResponseData(der::Parser* parser, OCSPResponseData* data) {
90 der::Input version_input;
91 bool version_present;
92 if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(0),
93 &version_input, &version_present)) {
94 return false;
95 }
96 if (version_present) {
Ryan Sleevi 2015/12/30 18:55:18 newline
svaldez 2015/12/30 19:31:37 Done.
97 der::Parser version_parser(version_input);
98 der::Input version;
99 if (!version_parser.ReadTag(der::kInteger, &version))
100 return false;
101 if (!der::ParseUint8(version, &(data->version)))
102 return false;
103 } else {
104 data->version = 0;
105 }
106
107 der::Tag id_tag;
108 der::Input responder_id;
109 if (!parser->ReadTagAndValue(&id_tag, &responder_id))
110 return false;
111 if (id_tag == der::ContextSpecificConstructed(1)) {
112 data->responder_id_name = responder_id.AsString();
113 } else if (id_tag == der::ContextSpecificConstructed(2)) {
114 der::Parser key_parser(responder_id);
115 der::Input responder_key;
116 if (!key_parser.ReadTag(der::kOctetString, &responder_key))
117 return false;
118 data->responder_id_key = responder_key.AsString();
119 } else {
120 return false;
121 }
122
123 der::Input produced_at;
124 if (!parser->ReadTag(der::kGeneralizedTime, &produced_at))
125 return false;
126 if (!der::ParseGeneralizedTime(produced_at, &(data->produced_at)))
127 return false;
128
129 der::Parser responses_parser;
130 if (!parser->ReadSequence(&responses_parser))
131 return false;
132 while (responses_parser.HasMore()) {
133 OCSPSingleResponse single_response;
134 der::Parser response_parser;
135 if (!responses_parser.ReadSequence(&response_parser))
136 return false;
137 if (!ParseOCSPSingleResponse(&response_parser, &single_response))
138 return false;
139 data->responses.push_back(single_response);
140 }
141
142 der::Input extensions_input;
143 bool extensions_present;
144 if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(1),
145 &extensions_input, &extensions_present)) {
146 return false;
147 }
148
149 if (!extensions_present)
150 return true;
151 der::Parser extensions_input_parser(extensions_input);
152 der::Parser extensions_parser;
153 if (!extensions_input_parser.ReadSequence(&extensions_parser))
154 return false;
155 while (extensions_parser.HasMore()) {
156 ParsedExtension extension;
157 der::Input extension_tlv;
158 if (!extensions_parser.ReadRawTLV(&extension_tlv))
159 return false;
160 if (!ParseExtension(extension_tlv, &extension))
161 return false;
162 data->extensions.push_back(extension);
163 }
164 return true;
165 }
166
167 } // namespace
168
169 OCSPSingleResponse::OCSPSingleResponse() {}
170 OCSPSingleResponse::~OCSPSingleResponse() {}
171
172 OCSPResponseData::OCSPResponseData() {}
173 OCSPResponseData::~OCSPResponseData() {}
174
175 OCSPResponse::OCSPResponse() {}
176 OCSPResponse::~OCSPResponse() {}
177
178 bool ParseOCSPResponse(const std::string& ocsp_response,
179 OCSPResponse* response) {
180 der::Parser parser(
181 der::Input(reinterpret_cast<const uint8_t*>(ocsp_response.data()),
182 ocsp_response.size()));
183 der::Input response_status;
184 der::Parser ocsp_response_parser;
185 if (!parser.ReadSequence(&ocsp_response_parser))
186 return false;
187 if (!ocsp_response_parser.ReadTag(der::kEnumerated, &response_status))
188 return false;
189 uint8_t response_status_value;
190 if (!der::ParseUint8(response_status, &response_status_value))
191 return false;
192 response->status = static_cast<OCSPResponseStatus>(response_status_value);
193 if (response->status != OCSP_SUCCESSFUL)
194 return true;
195
196 der::Input response_type_oid;
197 der::Input response_string;
198 der::Parser response_bytes_input_parser;
199 der::Parser response_bytes_parser;
200 if (!ocsp_response_parser.ReadConstructed(der::ContextSpecificConstructed(0),
201 &response_bytes_input_parser)) {
202 return false;
203 }
204 if (!response_bytes_input_parser.ReadSequence(&response_bytes_parser))
205 return false;
206 if (!response_bytes_parser.ReadTag(der::kOid, &response_type_oid))
207 return false;
208 if (!response_type_oid.Equals(der::Input(kOidPkixOcspBasic)))
209 return false;
210 if (!response_bytes_parser.ReadTag(der::kOctetString, &response_string))
211 return false;
212
213 der::Parser response_parser(response_string);
214 der::Parser basic_response_parser;
215 der::Parser response_data_parser;
216 der::Input sigalg_tlv;
217 if (!response_parser.ReadSequence(&basic_response_parser))
218 return false;
219 if (!basic_response_parser.ReadSequence(&response_data_parser))
220 return false;
221 if (!ParseOCSPResponseData(&response_data_parser, &(response->data)))
222 return false;
223 if (!basic_response_parser.ReadRawTLV(&sigalg_tlv))
224 return false;
225 response->signature_algorithm = SignatureAlgorithm::CreateFromDer(sigalg_tlv);
226 if (!basic_response_parser.ReadBitString(&(response->signature)))
227 return false;
228 der::Input certs_input;
229 bool certs_present;
230 if (!basic_response_parser.ReadOptionalTag(der::ContextSpecificConstructed(0),
231 &certs_input, &certs_present)) {
232 return false;
233 }
234
235 if (!certs_present)
236 return true;
237 der::Parser certs_input_parser(certs_input);
238 der::Parser certs_parser;
239 if (!certs_input_parser.ReadSequence(&certs_parser))
240 return false;
241 while (certs_parser.HasMore()) {
242 ParsedCertificate parsed_cert;
243 der::Input cert_tlv;
244 if (!certs_parser.ReadRawTLV(&cert_tlv))
245 return false;
246 if (!ParseCertificate(cert_tlv, &parsed_cert))
247 return false;
248 response->certs.push_back(parsed_cert);
249 }
250 return true;
251 }
252
253 } // namespace cert
254
255 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698