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

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

Issue 1414923007: Add initial code for verifying a certificate chain. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@test_driver
Patch Set: ifdef out the tests on ios 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 unified diff | Download patch
« no previous file with comments | « net/cert/internal/verify_certificate_chain.cc ('k') | net/net.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/internal/verify_certificate_chain.h"
6
7 #include "base/base_paths.h"
8 #include "base/files/file_util.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "net/cert/internal/parse_certificate.h"
14 #include "net/cert/internal/signature_policy.h"
15 #include "net/cert/internal/test_helpers.h"
16 #include "net/cert/pem_tokenizer.h"
17 #include "net/der/input.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 // TODO(eroman): Because VerifySignedData() is only implemented for BoringSSL
21 // these tests also depend on BoringSSL.
22 #if defined(USE_OPENSSL)
23
24 namespace net {
25
26 namespace {
27
28 // Reads a data file from the unit-test data.
29 std::string ReadTestFileToString(const std::string& file_name) {
30 // Compute the full path, relative to the src/ directory.
31 base::FilePath src_root;
32 PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
33 base::FilePath filepath = src_root.AppendASCII(
34 std::string("net/data/verify_certificate_chain_unittest/") + file_name);
35
36 // Read the full contents of the file.
37 std::string file_data;
38 if (!base::ReadFileToString(filepath, &file_data)) {
39 ADD_FAILURE() << "Couldn't read file: " << filepath.value();
40 return std::string();
41 }
42
43 return file_data;
44 }
45
46 // Adds the certificate |cert_der| as a trust anchor to |trust_store|.
47 void AddCertificateToTrustStore(const std::string& cert_der,
48 TrustStore* trust_store) {
49 ParsedCertificate cert;
50 ASSERT_TRUE(ParseCertificate(InputFromString(&cert_der), &cert));
51
52 ParsedTbsCertificate tbs;
53 ASSERT_TRUE(ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs));
54 TrustAnchor anchor = {tbs.spki_tlv.AsString(), tbs.subject_tlv.AsString()};
55 trust_store->anchors.push_back(anchor);
56 }
57
58 // Reads a test case from |file_name|. Test cases are comprised of a
59 // certificate chain, trust store, a timestamp to validate at, and the
60 // expected result of verification.
61 void ReadTestFromFile(const std::string& file_name,
62 std::vector<std::string>* chain,
63 TrustStore* trust_store,
64 der::GeneralizedTime* time,
65 bool* verify_result) {
66 chain->clear();
67 *trust_store = TrustStore();
68
69 std::string file_data = ReadTestFileToString(file_name);
70
71 std::vector<std::string> pem_headers;
72
73 const char kCertificateHeader[] = "CERTIFICATE";
74 const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE";
75 const char kTimeHeader[] = "TIME";
76 const char kResultHeader[] = "VERIFY_RESULT";
77
78 pem_headers.push_back(kCertificateHeader);
79 pem_headers.push_back(kTrustedCertificateHeader);
80 pem_headers.push_back(kTimeHeader);
81 pem_headers.push_back(kResultHeader);
82
83 bool has_time = false;
84 bool has_result = false;
85
86 PEMTokenizer pem_tokenizer(file_data, pem_headers);
87 while (pem_tokenizer.GetNext()) {
88 const std::string& block_type = pem_tokenizer.block_type();
89 const std::string& block_data = pem_tokenizer.data();
90
91 if (block_type == kCertificateHeader) {
92 chain->push_back(block_data);
93 } else if (block_type == kTrustedCertificateHeader) {
94 AddCertificateToTrustStore(block_data, trust_store);
95 } else if (block_type == kTimeHeader) {
96 ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
97 has_time = true;
98 ASSERT_TRUE(der::ParseUTCTime(InputFromString(&block_data), time));
99 } else if (block_type == kResultHeader) {
100 ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader;
101 ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL")
102 << "Unrecognized result: " << block_data;
103 has_result = true;
104 *verify_result = block_data == "SUCCESS";
105 }
106 }
107
108 ASSERT_TRUE(has_time);
109 ASSERT_TRUE(has_result);
110 }
111
112 void RunTest(const char* file_name) {
113 std::vector<std::string> chain;
114 TrustStore trust_store;
115 der::GeneralizedTime time;
116 bool expected_result;
117
118 ReadTestFromFile(file_name, &chain, &trust_store, &time, &expected_result);
119
120 std::vector<der::Input> input_chain;
121 for (const auto& cert_str : chain)
122 input_chain.push_back(InputFromString(&cert_str));
123
124 SimpleSignaturePolicy signature_policy(2048);
125
126 bool result =
127 VerifyCertificateChain(input_chain, trust_store, &signature_policy, time);
128
129 ASSERT_EQ(expected_result, result);
130 }
131
132 TEST(VerifyCertificateChainTest, TargetAndIntermediary) {
133 RunTest("target-and-intermediary.pem");
134 }
135
136 TEST(VerifyCertificateChainTest, UnknownRoot) {
137 RunTest("unknown-root.pem");
138 }
139
140 TEST(VerifyCertificateChainTest, IntermediaryLacksBasicConstraints) {
141 RunTest("intermediary-lacks-basic-constraints.pem");
142 }
143
144 TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsCaFalse) {
145 RunTest("intermediary-basic-constraints-ca-false.pem");
146 }
147
148 TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsNotCritical) {
149 RunTest("intermediary-basic-constraints-not-critical.pem");
150 }
151
152 TEST(VerifyCertificateChainTest, IntermediaryLacksSigningKeyUsage) {
153 RunTest("intermediary-lacks-signing-key-usage.pem");
154 }
155
156 TEST(VerifyCertificateChainTest, IntermediaryUnknownCriticalExtension) {
157 RunTest("intermediary-unknown-critical-extension.pem");
158 }
159
160 TEST(VerifyCertificateChainTest, IntermediaryUnknownNonCriticalExtension) {
161 RunTest("intermediary-unknown-non-critical-extension.pem");
162 }
163
164 TEST(VerifyCertificateChainTest, ViolatesBasicConstraintsPathlen0) {
165 RunTest("violates-basic-constraints-pathlen-0.pem");
166 }
167
168 TEST(VerifyCertificateChainTest, BasicConstraintsPathlen0SelfIssued) {
169 RunTest("basic-constraints-pathlen-0-self-issued.pem");
170 }
171
172 TEST(VerifyCertificateChainTest, TargetSignedWithMd5) {
173 RunTest("target-signed-with-md5.pem");
174 }
175
176 TEST(VerifyCertificateChainTest, IntermediarySignedWithMd5) {
177 RunTest("intermediary-signed-with-md5.pem");
178 }
179
180 TEST(VerifyCertificateChainTest, TargetWrongSignature) {
181 RunTest("target-wrong-signature.pem");
182 }
183
184 TEST(VerifyCertificateChainTest, TargetSignedBy512bitRsa) {
185 RunTest("target-signed-by-512bit-rsa.pem");
186 }
187
188 TEST(VerifyCertificateChainTest, TargetSignedUsingEcdsa) {
189 RunTest("target-signed-using-ecdsa.pem");
190 }
191
192 TEST(VerifyCertificateChainTest, ExpiredIntermediary) {
193 RunTest("expired-intermediary.pem");
194 }
195
196 TEST(VerifyCertificateChainTest, ExpiredTarget) {
197 RunTest("expired-target.pem");
198 }
199
200 TEST(VerifyCertificateChainTest, ExpiredTargetNotBefore) {
201 RunTest("expired-target-notBefore.pem");
202 }
203
204 TEST(VerifyCertificateChainTest, TargetNotEndEntity) {
205 RunTest("target-not-end-entity.pem");
206 }
207
208 TEST(VerifyCertificateChainTest, TargetHasKeyCertSignButNotCa) {
209 RunTest("target-has-keycertsign-but-not-ca.pem");
210 }
211
212 TEST(VerifyCertificateChainTest, TargetHasPathlenButNotCa) {
213 RunTest("target-has-pathlen-but-not-ca.pem");
214 }
215
216 TEST(VerifyCertificateChainTest, TargetUnknownCriticalExtension) {
217 RunTest("target-unknown-critical-extension.pem");
218 }
219
220 // Tests that verifying a chain with no certificates fails.
221 TEST(VerifyCertificateChainTest, EmptyChainIsInvalid) {
222 TrustStore trust_store;
223 der::GeneralizedTime time;
224 std::vector<der::Input> chain;
225 SimpleSignaturePolicy signature_policy(2048);
226
227 ASSERT_FALSE(
228 VerifyCertificateChain(chain, trust_store, &signature_policy, time));
229 }
230
231 // TODO(eroman): Add test that invalidate validity dates where the day or month
232 // ordinal not in range, like "March 39, 2016" are rejected.
233
234 } // namespace
235
236 } // namespace net
237
238 #endif
OLDNEW
« no previous file with comments | « net/cert/internal/verify_certificate_chain.cc ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698