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

Side by Side Diff: net/cert/internal/parse_certificate_unittest.cc

Issue 1279963003: Add a function for parsing RFC 5280's "TBSCertificate". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_mapper
Patch Set: one more comment fix 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 unified diff | Download patch
« no previous file with comments | « net/cert/internal/parse_certificate.cc ('k') | net/cert/internal/test_helpers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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/cert/internal/parse_certificate.h" 5 #include "net/cert/internal/parse_certificate.h"
6 6
7 #include "net/cert/internal/test_helpers.h" 7 #include "net/cert/internal/test_helpers.h"
8 #include "net/der/input.h" 8 #include "net/der/input.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 10
11 namespace net { 11 namespace net {
12 12
13 namespace { 13 namespace {
14 14
15 std::string GetFilePath(const std::string file_name) { 15 std::string GetFilePath(const std::string file_name) {
16 return std::string("net/data/parse_certificate_unittest/") + file_name; 16 return std::string("net/data/parse_certificate_unittest/") + file_name;
17 } 17 }
18 18
19 // Loads certificate data and expectations from the PEM file |file_name|. 19 // Loads certificate data and expectations from the PEM file |file_name|.
20 // Verifies that parsing the Certificate succeeds, and each parsed field matches 20 // Verifies that parsing the Certificate succeeds, and each parsed field matches
21 // the expectations. 21 // the expectations.
22 void EnsureParsingCertificateSucceds(const std::string& file_name) { 22 void EnsureParsingCertificateSucceeds(const std::string& file_name) {
23 std::string data; 23 std::string data;
24 std::string expected_tbs_certificate; 24 std::string expected_tbs_certificate;
25 std::string expected_signature_algorithm; 25 std::string expected_signature_algorithm;
26 std::string expected_signature; 26 std::string expected_signature;
27 27
28 // Read the certificate data and test expectations from a single PEM file. 28 // Read the certificate data and test expectations from a single PEM file.
29 const PemBlockMapping mappings[] = { 29 const PemBlockMapping mappings[] = {
30 {"CERTIFICATE", &data}, 30 {"CERTIFICATE", &data},
31 {"SIGNATURE", &expected_signature}, 31 {"SIGNATURE", &expected_signature},
32 {"SIGNATURE ALGORITHM", &expected_signature_algorithm}, 32 {"SIGNATURE ALGORITHM", &expected_signature_algorithm},
(...skipping 26 matching lines...) Expand all
59 59
60 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); 60 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
61 61
62 // Parsing the Certificate should fail. 62 // Parsing the Certificate should fail.
63 ParsedCertificate parsed; 63 ParsedCertificate parsed;
64 ASSERT_FALSE(ParseCertificate(InputFromString(&data), &parsed)); 64 ASSERT_FALSE(ParseCertificate(InputFromString(&data), &parsed));
65 } 65 }
66 66
67 // Tests parsing a Certificate. 67 // Tests parsing a Certificate.
68 TEST(ParseCertificateTest, Version3) { 68 TEST(ParseCertificateTest, Version3) {
69 EnsureParsingCertificateSucceds("cert_version3.pem"); 69 EnsureParsingCertificateSucceeds("cert_version3.pem");
70 } 70 }
71 71
72 // Tests parsing a simplified Certificate-like structure (the sub-fields for 72 // Tests parsing a simplified Certificate-like structure (the sub-fields for
73 // algorithm and tbsCertificate are not actually valid, but ParseCertificate() 73 // algorithm and tbsCertificate are not actually valid, but ParseCertificate()
74 // doesn't check them) 74 // doesn't check them)
75 TEST(ParseCertificateTest, Skeleton) { 75 TEST(ParseCertificateTest, Skeleton) {
76 EnsureParsingCertificateSucceds("cert_skeleton.pem"); 76 EnsureParsingCertificateSucceeds("cert_skeleton.pem");
77 } 77 }
78 78
79 // Tests parsing a Certificate that is not a sequence fails. 79 // Tests parsing a Certificate that is not a sequence fails.
80 TEST(ParseCertificateTest, NotSequence) { 80 TEST(ParseCertificateTest, NotSequence) {
81 EnsureParsingCertificateFails("cert_not_sequence.pem"); 81 EnsureParsingCertificateFails("cert_not_sequence.pem");
82 } 82 }
83 83
84 // Tests that uncomsumed data is not allowed after the main SEQUENCE. 84 // Tests that uncomsumed data is not allowed after the main SEQUENCE.
85 TEST(ParseCertificateTest, DataAfterSignature) { 85 TEST(ParseCertificateTest, DataAfterSignature) {
86 EnsureParsingCertificateFails("cert_data_after_signature.pem"); 86 EnsureParsingCertificateFails("cert_data_after_signature.pem");
(...skipping 14 matching lines...) Expand all
101 TEST(ParseCertificateTest, EmptySequence) { 101 TEST(ParseCertificateTest, EmptySequence) {
102 EnsureParsingCertificateFails("cert_empty_sequence.pem"); 102 EnsureParsingCertificateFails("cert_empty_sequence.pem");
103 } 103 }
104 104
105 // Tests what happens when the signature algorithm is present, but has the wrong 105 // Tests what happens when the signature algorithm is present, but has the wrong
106 // tag. 106 // tag.
107 TEST(ParseCertificateTest, AlgorithmNotSequence) { 107 TEST(ParseCertificateTest, AlgorithmNotSequence) {
108 EnsureParsingCertificateFails("cert_algorithm_not_sequence.pem"); 108 EnsureParsingCertificateFails("cert_algorithm_not_sequence.pem");
109 } 109 }
110 110
111 // Loads tbsCertificate data and expectations from the PEM file |file_name|.
112 // Verifies that parsing the TBSCertificate succeeds, and each parsed field
113 // matches the expectations.
114 void EnsureParsingTbsSucceeds(const std::string& file_name,
115 CertificateVersion expected_version) {
116 std::string data;
117 std::string expected_serial_number;
118 std::string expected_signature_algorithm;
119 std::string expected_issuer;
120 std::string expected_validity;
121 std::string expected_subject;
122 std::string expected_spki;
123 std::string expected_issuer_unique_id;
124 std::string expected_subject_unique_id;
125 std::string expected_extensions;
126
127 // Read the certificate data and test expectations from a single PEM file.
128 const PemBlockMapping mappings[] = {
129 {"TBS CERTIFICATE", &data},
130 {"SIGNATURE ALGORITHM", &expected_signature_algorithm},
131 {"SERIAL NUMBER", &expected_serial_number},
132 {"ISSUER", &expected_issuer},
133 {"VALIDITY", &expected_validity},
134 {"SUBJECT", &expected_subject},
135 {"SPKI", &expected_spki},
136 {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true},
137 {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true},
138 {"EXTENSIONS", &expected_extensions, true},
139 };
140 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
141
142 // Parsing the TBSCertificate should succeed.
143 ParsedTbsCertificate parsed;
144 ASSERT_TRUE(ParseTbsCertificate(InputFromString(&data), &parsed));
145
146 // Ensure that the ParsedTbsCertificate matches expectations.
147 EXPECT_EQ(expected_version, parsed.version);
148
149 EXPECT_EQ(InputFromString(&expected_serial_number), parsed.serial_number);
150 EXPECT_EQ(InputFromString(&expected_signature_algorithm),
151 parsed.signature_algorithm_tlv);
152
153 EXPECT_EQ(InputFromString(&expected_issuer), parsed.issuer_tlv);
154 EXPECT_EQ(InputFromString(&expected_validity), parsed.validity_tlv);
155 EXPECT_EQ(InputFromString(&expected_subject), parsed.subject_tlv);
156 EXPECT_EQ(InputFromString(&expected_spki), parsed.spki_tlv);
157
158 EXPECT_EQ(InputFromString(&expected_issuer_unique_id),
159 parsed.issuer_unique_id.bytes());
160 EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id);
161 EXPECT_EQ(InputFromString(&expected_subject_unique_id),
162 parsed.subject_unique_id.bytes());
163 EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id);
164
165 EXPECT_EQ(InputFromString(&expected_extensions), parsed.extensions_tlv);
166 EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions);
167 }
168
169 // Loads certificate data from the PEM file |file_name| and verifies that the
170 // Certificate parsing succeed, however the TBSCertificate parsing fails.
171 void EnsureParsingTbsFails(const std::string& file_name) {
172 std::string data;
173
174 const PemBlockMapping mappings[] = {
175 {"TBS CERTIFICATE", &data},
176 };
177
178 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
179
180 // Parsing the TBSCertificate should fail.
181 ParsedTbsCertificate parsed;
182 ASSERT_FALSE(ParseTbsCertificate(InputFromString(&data), &parsed));
183 }
184
185 // Tests parsing a TBSCertificate for v3 that contains no optional fields.
186 TEST(ParseTbsCertificateTest, Version3NoOptionals) {
187 EnsureParsingTbsSucceeds("tbs_v3_no_optionals.pem", CertificateVersion::V3);
188 }
189
190 // Tests parsing a TBSCertificate for v3 that contains extensions.
191 TEST(ParseTbsCertificateTest, Version3WithExtensions) {
192 EnsureParsingTbsSucceeds("tbs_v3_extensions.pem", CertificateVersion::V3);
193 }
194
195 // Tests parsing a TBSCertificate for v3 that contains no optional fields, and
196 // has a negative serial number.
197 //
198 // CAs are not supposed to include negative serial numbers, however RFC 5280
199 // expects consumers to deal with it anyway).
200 TEST(ParseTbsCertificateTest, NegativeSerialNumber) {
201 EnsureParsingTbsSucceeds("tbs_negative_serial_number.pem",
202 CertificateVersion::V3);
203 }
204
205 // Tests parsing a TBSCertificate with a serial number that is 21 octets long
206 // (and the first byte is 0).
207 TEST(ParseTbCertificateTest, SerialNumber21OctetsLeading0) {
208 EnsureParsingTbsFails("tbs_serial_number_21_octets_leading_0.pem");
209 }
210
211 // Tests parsing a TBSCertificate with a serial number that is 26 octets long
212 // (and does not contain a leading 0).
213 TEST(ParseTbsCertificateTest, SerialNumber26Octets) {
214 EnsureParsingTbsFails("tbs_serial_number_26_octets.pem");
215 }
216
217 // Tests parsing a TBSCertificate which lacks a version number (causing it to
218 // default to v1).
219 TEST(ParseTbsCertificateTest, Version1) {
220 EnsureParsingTbsSucceeds("tbs_v1.pem", CertificateVersion::V1);
221 }
222
223 // The version was set to v1 explicitly rather than omitting the version field.
224 TEST(ParseTbsCertificateTest, ExplicitVersion1) {
225 EnsureParsingTbsFails("tbs_explicit_v1.pem");
226 }
227
228 // Extensions are not defined in version 1.
229 TEST(ParseTbsCertificateTest, Version1WithExtensions) {
230 EnsureParsingTbsFails("tbs_v1_extensions.pem");
231 }
232
233 // Extensions are not defined in version 2.
234 TEST(ParseTbsCertificateTest, Version2WithExtensions) {
235 EnsureParsingTbsFails("tbs_v2_extensions.pem");
236 }
237
238 // A boring version 2 certificate with none of the optional fields.
239 TEST(ParseTbsCertificateTest, Version2NoOptionals) {
240 EnsureParsingTbsSucceeds("tbs_v2_no_optionals.pem", CertificateVersion::V2);
241 }
242
243 // A version 2 certificate with an issuer unique ID field.
244 TEST(ParseTbsCertificateTest, Version2IssuerUniqueId) {
245 EnsureParsingTbsSucceeds("tbs_v2_issuer_unique_id.pem",
246 CertificateVersion::V2);
247 }
248
249 // A version 2 certificate with both a issuer and subject unique ID field.
250 TEST(ParseTbsCertificateTest, Version2IssuerAndSubjectUniqueId) {
251 EnsureParsingTbsSucceeds("tbs_v2_issuer_and_subject_unique_id.pem",
252 CertificateVersion::V2);
253 }
254
255 // A version 3 certificate with all of the optional fields (issuer unique id,
256 // subject unique id, and extensions).
257 TEST(ParseTbsCertificateTest, Version3AllOptionals) {
258 EnsureParsingTbsSucceeds("tbs_v3_all_optionals.pem", CertificateVersion::V3);
259 }
260
261 // The version was set to v4, which is unrecognized.
262 TEST(ParseTbsCertificateTest, Version4) {
263 EnsureParsingTbsFails("tbs_v4.pem");
264 }
265
266 // Tests that extraneous data after extensions in a v3 is rejected.
267 TEST(ParseTbsCertificateTest, Version3DataAfterExtensions) {
268 EnsureParsingTbsFails("tbs_v3_data_after_extensions.pem");
269 }
270
271 // Tests using a real-world certificate (whereas the other tests are fabricated
272 // (and in fact invalid) data.
273 TEST(ParseTbsCertificateTest, Version3Real) {
274 EnsureParsingTbsSucceeds("tbs_v3_real.pem", CertificateVersion::V3);
275 }
276
111 } // namespace 277 } // namespace
112 278
113 } // namespace net 279 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/internal/parse_certificate.cc ('k') | net/cert/internal/test_helpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698