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

Side by Side Diff: net/base/asn1_util.cc

Issue 6993027: net: followup to codereview for cl/7096014 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 9 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/asn1_util.h" 5 #include "net/base/asn1_util.h"
6 6
7 namespace net { 7 namespace net {
8 8
9 namespace asn1 { 9 namespace asn1 {
10 10
11 bool ParseElement(base::StringPiece* in, 11 bool ParseElement(base::StringPiece* in,
12 unsigned tag_value, 12 unsigned tag_value,
13 base::StringPiece* out, 13 base::StringPiece* out,
14 unsigned *out_header_len) { 14 unsigned *out_header_len) {
15 const uint8* data = reinterpret_cast<const uint8*>(in->data()); 15 const uint8* data = reinterpret_cast<const uint8*>(in->data());
16 16
17 // We don't support kAny and kOptional at the same time.
18 if ((tag_value & kAny) && (tag_value & kOptional))
19 return false;
20
21 if (in->empty() && (tag_value & kOptional)) {
22 if (out_header_len)
23 *out_header_len = 0;
24 if (out)
25 *out = base::StringPiece();
26 return true;
27 }
28
17 if (in->size() < 2) 29 if (in->size() < 2)
18 return false; 30 return false;
19 31
20 if (tag_value != kAny && static_cast<unsigned char>(data[0]) != tag_value) 32 if (tag_value != kAny &&
33 static_cast<unsigned char>(data[0]) != (tag_value & 0xff)) {
34 if (tag_value & kOptional) {
35 if (out_header_len)
36 *out_header_len = 0;
37 if (out)
38 *out = base::StringPiece();
39 return true;
40 }
21 return false; 41 return false;
42 }
22 43
23 size_t len = 0; 44 size_t len = 0;
24 if ((data[1] & 0x80) == 0) { 45 if ((data[1] & 0x80) == 0) {
25 // short form length 46 // short form length
26 if (out_header_len) 47 if (out_header_len)
27 *out_header_len = 2; 48 *out_header_len = 2;
28 len = static_cast<size_t>(data[1]) + 2; 49 len = static_cast<size_t>(data[1]) + 2;
29 } else { 50 } else {
30 // long form length 51 // long form length
31 const unsigned num_bytes = data[1] & 0x7f; 52 const unsigned num_bytes = data[1] & 0x7f;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 unsigned tag_value, 85 unsigned tag_value,
65 base::StringPiece* out) { 86 base::StringPiece* out) {
66 unsigned header_len; 87 unsigned header_len;
67 if (!ParseElement(in, tag_value, out, &header_len)) 88 if (!ParseElement(in, tag_value, out, &header_len))
68 return false; 89 return false;
69 if (out) 90 if (out)
70 out->remove_prefix(header_len); 91 out->remove_prefix(header_len);
71 return true; 92 return true;
72 } 93 }
73 94
74 // SeekToSPKI changes |cert| so that it points to a suffix of the original 95 // SeekToSPKI changes |cert| so that it points to a suffix of the
75 // value where the suffix begins at the start of the ASN.1 SubjectPublicKeyInfo 96 // TBSCertificate where the suffix begins at the start of the ASN.1
76 // value. 97 // SubjectPublicKeyInfo value.
77 static bool SeekToSPKI(base::StringPiece* cert) { 98 static bool SeekToSPKI(base::StringPiece* cert) {
78 // From RFC 5280, section 4.1 99 // From RFC 5280, section 4.1
79 // Certificate ::= SEQUENCE { 100 // Certificate ::= SEQUENCE {
80 // tbsCertificate TBSCertificate, 101 // tbsCertificate TBSCertificate,
81 // signatureAlgorithm AlgorithmIdentifier, 102 // signatureAlgorithm AlgorithmIdentifier,
82 // signatureValue BIT STRING } 103 // signatureValue BIT STRING }
83 104
84 // TBSCertificate ::= SEQUENCE { 105 // TBSCertificate ::= SEQUENCE {
85 // version [0] EXPLICIT Version DEFAULT v1, 106 // version [0] EXPLICIT Version DEFAULT v1,
86 // serialNumber CertificateSerialNumber, 107 // serialNumber CertificateSerialNumber,
87 // signature AlgorithmIdentifier, 108 // signature AlgorithmIdentifier,
88 // issuer Name, 109 // issuer Name,
89 // validity Validity, 110 // validity Validity,
90 // subject Name, 111 // subject Name,
91 // subjectPublicKeyInfo SubjectPublicKeyInfo, 112 // subjectPublicKeyInfo SubjectPublicKeyInfo,
92 113
93 base::StringPiece certificate; 114 base::StringPiece certificate;
94 if (!GetElement(cert, kSEQUENCE, &certificate)) 115 if (!GetElement(cert, kSEQUENCE, &certificate))
95 return false; 116 return false;
96 117
118 // We don't allow junk after the certificate.
119 if (!cert->empty())
120 return false;
121
97 base::StringPiece tbs_certificate; 122 base::StringPiece tbs_certificate;
98 if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate)) 123 if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate))
99 return false; 124 return false;
100 125
101 // The version is optional, so a failure to parse it is fine. 126 if (!GetElement(&tbs_certificate,
102 GetElement(&tbs_certificate, 127 kOptional | kConstructed | kContextSpecific | 0,
103 kCompound | kContextSpecific | 0, 128 NULL)) {
104 NULL); 129 return false;
130 }
105 131
106 // serialNumber 132 // serialNumber
107 if (!GetElement(&tbs_certificate, kINTEGER, NULL)) 133 if (!GetElement(&tbs_certificate, kINTEGER, NULL))
108 return false; 134 return false;
109 // signature 135 // signature
110 if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) 136 if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
111 return false; 137 return false;
112 // issuer 138 // issuer
113 if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) 139 if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
114 return false; 140 return false;
(...skipping 28 matching lines...) Expand all
143 // ... 169 // ...
144 // subjectPublicKeyInfo SubjectPublicKeyInfo, 170 // subjectPublicKeyInfo SubjectPublicKeyInfo,
145 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 171 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
146 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 172 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
147 // extensions [3] EXPLICIT Extensions OPTIONAL 173 // extensions [3] EXPLICIT Extensions OPTIONAL
148 174
149 // subjectPublicKeyInfo 175 // subjectPublicKeyInfo
150 if (!GetElement(&cert, kSEQUENCE, NULL)) 176 if (!GetElement(&cert, kSEQUENCE, NULL))
151 return false; 177 return false;
152 // issuerUniqueID 178 // issuerUniqueID
153 GetElement(&cert, kCompound | kContextSpecific | 1, NULL); 179 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL))
180 return false;
154 // subjectUniqueID 181 // subjectUniqueID
155 GetElement(&cert, kCompound | kContextSpecific | 2, NULL); 182 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL))
183 return false;
156 184
157 base::StringPiece extensions_seq; 185 base::StringPiece extensions_seq;
158 if (!GetElement(&cert, kCompound | kContextSpecific | 3, 186 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3,
159 &extensions_seq)) { 187 &extensions_seq)) {
160 // If there are no extensions, then there are no CRL URLs. 188 return false;
189 }
190
191 if (extensions_seq.empty())
161 return true; 192 return true;
162 }
163 193
164 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 194 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
165 // Extension ::= SEQUENCE { 195 // Extension ::= SEQUENCE {
166 // extnID OBJECT IDENTIFIER, 196 // extnID OBJECT IDENTIFIER,
167 // critical BOOLEAN DEFAULT FALSE, 197 // critical BOOLEAN DEFAULT FALSE,
168 // extnValue OCTET STRING 198 // extnValue OCTET STRING
169 199
170 // |extensions_seq| was EXPLICITly tagged, so we still need to remove the 200 // |extensions_seq| was EXPLICITly tagged, so we still need to remove the
171 // ASN.1 SEQUENCE header. 201 // ASN.1 SEQUENCE header.
172 base::StringPiece extensions; 202 base::StringPiece extensions;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 base::StringPiece distribution_points; 241 base::StringPiece distribution_points;
212 if (!GetElement(&extension_value, kSEQUENCE, &distribution_points)) 242 if (!GetElement(&extension_value, kSEQUENCE, &distribution_points))
213 return false; 243 return false;
214 244
215 while (distribution_points.size() > 0) { 245 while (distribution_points.size() > 0) {
216 base::StringPiece distrib_point; 246 base::StringPiece distrib_point;
217 if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point)) 247 if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point))
218 return false; 248 return false;
219 249
220 base::StringPiece name; 250 base::StringPiece name;
221 if (!GetElement(&distrib_point, kContextSpecific | kCompound | 0, 251 if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0,
222 &name)) { 252 &name)) {
223 // If it doesn't contain a name then we skip it. 253 // If it doesn't contain a name then we skip it.
224 continue; 254 continue;
225 } 255 }
226 256
227 if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) { 257 if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) {
228 // If it contains a subset of reasons then we skip it. We aren't 258 // If it contains a subset of reasons then we skip it. We aren't
229 // interested in subsets of CRLs and the RFC states that there MUST be 259 // interested in subsets of CRLs and the RFC states that there MUST be
230 // a CRL that covers all reasons. 260 // a CRL that covers all reasons.
231 continue; 261 continue;
232 } 262 }
233 263
234 if (GetElement(&distrib_point, kContextSpecific | kCompound | 2, NULL)) { 264 if (GetElement(&distrib_point,
265 kContextSpecific | kConstructed | 2, NULL)) {
235 // If it contains a alternative issuer, then we skip it. 266 // If it contains a alternative issuer, then we skip it.
236 continue; 267 continue;
237 } 268 }
238 269
239 // DistributionPointName ::= CHOICE { 270 // DistributionPointName ::= CHOICE {
240 // fullName [0] GeneralNames, 271 // fullName [0] GeneralNames,
241 // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 272 // nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
242 base::StringPiece general_names; 273 base::StringPiece general_names;
243 if (!GetElement(&name, kContextSpecific | kCompound | 0, &general_names)) 274 if (!GetElement(&name,
275 kContextSpecific | kConstructed | 0, &general_names)) {
244 continue; 276 continue;
277 }
245 278
246 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 279 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
247 // GeneralName ::= CHOICE { 280 // GeneralName ::= CHOICE {
248 // ... 281 // ...
249 // uniformResourceIdentifier [6] IA5String, 282 // uniformResourceIdentifier [6] IA5String,
250 // ... 283 // ...
251 while (general_names.size() > 0) { 284 while (general_names.size() > 0) {
252 base::StringPiece url; 285 base::StringPiece url;
253 if (GetElement(&general_names, kContextSpecific | 6, &url)) { 286 if (GetElement(&general_names, kContextSpecific | 6, &url)) {
254 urls_out->push_back(url); 287 urls_out->push_back(url);
255 } else { 288 } else {
256 if (!GetElement(&general_names, kAny, NULL)) 289 if (!GetElement(&general_names, kAny, NULL)) {
290 urls_out->clear();
257 return false; 291 return false;
wtc 2011/06/07 18:17:54 I think some other "return false" statements also
292 }
258 } 293 }
259 } 294 }
260 } 295 }
261 } 296 }
262 297
263 return true; 298 return true;
264 } 299 }
265 300
266 } // namespace asn1 301 } // namespace asn1
267 302
268 } // namespace net 303 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698