OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/trust_store_mac.h" | 5 #include "net/cert/internal/trust_store_mac.h" |
6 | 6 |
7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 ASSERT_TRUE(ReadTestCert("multi-root-A-by-B.pem", &a_by_b)); | 120 ASSERT_TRUE(ReadTestCert("multi-root-A-by-B.pem", &a_by_b)); |
121 ASSERT_TRUE(ReadTestCert("multi-root-B-by-C.pem", &b_by_c)); | 121 ASSERT_TRUE(ReadTestCert("multi-root-B-by-C.pem", &b_by_c)); |
122 ASSERT_TRUE(ReadTestCert("multi-root-B-by-F.pem", &b_by_f)); | 122 ASSERT_TRUE(ReadTestCert("multi-root-B-by-F.pem", &b_by_f)); |
123 ASSERT_TRUE(ReadTestCert("multi-root-C-by-D.pem", &c_by_d)); | 123 ASSERT_TRUE(ReadTestCert("multi-root-C-by-D.pem", &c_by_d)); |
124 ASSERT_TRUE(ReadTestCert("multi-root-C-by-E.pem", &c_by_e)); | 124 ASSERT_TRUE(ReadTestCert("multi-root-C-by-E.pem", &c_by_e)); |
125 ASSERT_TRUE(ReadTestCert("multi-root-F-by-E.pem", &f_by_e)); | 125 ASSERT_TRUE(ReadTestCert("multi-root-F-by-E.pem", &f_by_e)); |
126 ASSERT_TRUE(ReadTestCert("multi-root-D-by-D.pem", &d_by_d)); | 126 ASSERT_TRUE(ReadTestCert("multi-root-D-by-D.pem", &d_by_d)); |
127 ASSERT_TRUE(ReadTestCert("multi-root-E-by-E.pem", &e_by_e)); | 127 ASSERT_TRUE(ReadTestCert("multi-root-E-by-E.pem", &e_by_e)); |
128 | 128 |
129 base::ScopedCFTypeRef<CFDataRef> normalized_name_b = | 129 base::ScopedCFTypeRef<CFDataRef> normalized_name_b = |
130 TrustStoreMac::GetMacNormalizedIssuer(a_by_b); | 130 TrustStoreMac::GetMacNormalizedIssuer(a_by_b.get()); |
131 ASSERT_TRUE(normalized_name_b); | 131 ASSERT_TRUE(normalized_name_b); |
132 base::ScopedCFTypeRef<CFDataRef> normalized_name_c = | 132 base::ScopedCFTypeRef<CFDataRef> normalized_name_c = |
133 TrustStoreMac::GetMacNormalizedIssuer(b_by_c); | 133 TrustStoreMac::GetMacNormalizedIssuer(b_by_c.get()); |
134 ASSERT_TRUE(normalized_name_c); | 134 ASSERT_TRUE(normalized_name_c); |
135 base::ScopedCFTypeRef<CFDataRef> normalized_name_f = | 135 base::ScopedCFTypeRef<CFDataRef> normalized_name_f = |
136 TrustStoreMac::GetMacNormalizedIssuer(b_by_f); | 136 TrustStoreMac::GetMacNormalizedIssuer(b_by_f.get()); |
137 ASSERT_TRUE(normalized_name_f); | 137 ASSERT_TRUE(normalized_name_f); |
138 base::ScopedCFTypeRef<CFDataRef> normalized_name_d = | 138 base::ScopedCFTypeRef<CFDataRef> normalized_name_d = |
139 TrustStoreMac::GetMacNormalizedIssuer(c_by_d); | 139 TrustStoreMac::GetMacNormalizedIssuer(c_by_d.get()); |
140 ASSERT_TRUE(normalized_name_d); | 140 ASSERT_TRUE(normalized_name_d); |
141 base::ScopedCFTypeRef<CFDataRef> normalized_name_e = | 141 base::ScopedCFTypeRef<CFDataRef> normalized_name_e = |
142 TrustStoreMac::GetMacNormalizedIssuer(f_by_e); | 142 TrustStoreMac::GetMacNormalizedIssuer(f_by_e.get()); |
143 ASSERT_TRUE(normalized_name_e); | 143 ASSERT_TRUE(normalized_name_e); |
144 | 144 |
145 // Test that the matching keychain items are found, even though they aren't | 145 // Test that the matching keychain items are found, even though they aren't |
146 // trusted. | 146 // trusted. |
| 147 // TODO(eroman): These tests could be using TrustStore::SyncGetIssuersOf(). |
147 { | 148 { |
148 base::ScopedCFTypeRef<CFArrayRef> scoped_matching_items = | 149 base::ScopedCFTypeRef<CFArrayRef> scoped_matching_items = |
149 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( | 150 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( |
150 normalized_name_b.get()); | 151 normalized_name_b.get()); |
151 | 152 |
152 EXPECT_THAT(SecCertificateArrayAsDER(scoped_matching_items), | 153 EXPECT_THAT(SecCertificateArrayAsDER(scoped_matching_items), |
153 UnorderedElementsAreArray( | 154 UnorderedElementsAreArray( |
154 ParsedCertificateListAsDER({b_by_c, b_by_f}))); | 155 ParsedCertificateListAsDER({b_by_c, b_by_f}))); |
155 } | 156 } |
156 | 157 |
(...skipping 26 matching lines...) Expand all Loading... |
183 | 184 |
184 { | 185 { |
185 base::ScopedCFTypeRef<CFArrayRef> scoped_matching_items = | 186 base::ScopedCFTypeRef<CFArrayRef> scoped_matching_items = |
186 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( | 187 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( |
187 normalized_name_e.get()); | 188 normalized_name_e.get()); |
188 EXPECT_THAT( | 189 EXPECT_THAT( |
189 SecCertificateArrayAsDER(scoped_matching_items), | 190 SecCertificateArrayAsDER(scoped_matching_items), |
190 UnorderedElementsAreArray(ParsedCertificateListAsDER({e_by_e}))); | 191 UnorderedElementsAreArray(ParsedCertificateListAsDER({e_by_e}))); |
191 } | 192 } |
192 | 193 |
193 // None of the certs should return any matching TrustAnchors, since the test | 194 // Verify that none of the added certificates are considered trusted (since |
194 // certs in the keychain aren't trusted (unless someone manually added and | 195 // the test certs in the keychain aren't trusted, unless someone manually |
195 // trusted the test certs on the machine the test is being run on). | 196 // added and trusted the test certs on the machine the test is being run on). |
196 for (const auto& cert : | 197 for (const auto& cert : |
197 {a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e}) { | 198 {a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e}) { |
198 TrustAnchors matching_anchors; | 199 CertificateTrust trust = CertificateTrust::ForTrustAnchor(); |
199 trust_store.FindTrustAnchorsForCert(cert, &matching_anchors); | 200 trust_store.GetTrust(cert.get(), &trust); |
200 EXPECT_EQ(0u, matching_anchors.size()); | 201 EXPECT_EQ(CertificateTrustType::UNSPECIFIED, trust.type); |
201 } | 202 } |
202 } | 203 } |
203 | 204 |
204 // Test against all the certificates in the default keychains. Confirms that | 205 // Test against all the certificates in the default keychains. Confirms that |
205 // the computed trust value matches that of SecTrustEvaluate. | 206 // the computed trust value matches that of SecTrustEvaluate. |
206 TEST(TrustStoreMacTest, SystemCerts) { | 207 TEST(TrustStoreMacTest, SystemCerts) { |
207 // Get the list of all certificates in the user & system keychains. | 208 // Get the list of all certificates in the user & system keychains. |
208 // This may include both trusted and untrusted certificates. | 209 // This may include both trusted and untrusted certificates. |
209 // | 210 // |
210 // The output contains zero or more repetitions of: | 211 // The output contains zero or more repetitions of: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 ParseCertificateOptions options; | 256 ParseCertificateOptions options; |
256 // For https://crt.sh/?q=D3EEFBCBBCF49867838626E23BB59CA01E305DB7: | 257 // For https://crt.sh/?q=D3EEFBCBBCF49867838626E23BB59CA01E305DB7: |
257 options.allow_invalid_serial_numbers = true; | 258 options.allow_invalid_serial_numbers = true; |
258 scoped_refptr<ParsedCertificate> cert = ParsedCertificate::Create( | 259 scoped_refptr<ParsedCertificate> cert = ParsedCertificate::Create( |
259 x509_util::CreateCryptoBuffer(cert_der), options, &errors); | 260 x509_util::CreateCryptoBuffer(cert_der), options, &errors); |
260 if (!cert) { | 261 if (!cert) { |
261 LOG(WARNING) << "ParseCertificate::Create " << hash_text << " failed:\n" | 262 LOG(WARNING) << "ParseCertificate::Create " << hash_text << " failed:\n" |
262 << errors.ToDebugString(); | 263 << errors.ToDebugString(); |
263 continue; | 264 continue; |
264 } | 265 } |
| 266 // Check if this cert is considered a trust anchor by TrustStoreMac. |
| 267 CertificateTrust cert_trust; |
| 268 trust_store.GetTrust(cert, &cert_trust); |
| 269 bool is_trust_anchor = cert_trust.IsTrustAnchor(); |
265 | 270 |
| 271 // Check if this cert is considered a trust anchor by the OS. |
266 base::ScopedCFTypeRef<SecCertificateRef> cert_handle( | 272 base::ScopedCFTypeRef<SecCertificateRef> cert_handle( |
267 x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(), | 273 x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(), |
268 cert->der_cert().Length())); | 274 cert->der_cert().Length())); |
269 if (!cert_handle) { | 275 if (!cert_handle) { |
270 ADD_FAILURE() << "CreateOSCertHandleFromBytes " << hash_text; | 276 ADD_FAILURE() << "CreateOSCertHandleFromBytes " << hash_text; |
271 continue; | 277 continue; |
272 } | 278 } |
273 base::ScopedCFTypeRef<CFDataRef> mac_normalized_subject; | |
274 { | |
275 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
276 mac_normalized_subject.reset( | |
277 SecCertificateCopyNormalizedSubjectContent(cert_handle, nullptr)); | |
278 } | |
279 if (!mac_normalized_subject) { | |
280 ADD_FAILURE() << "SecCertificateCopyNormalizedSubjectContent " | |
281 << hash_text; | |
282 continue; | |
283 } | |
284 | |
285 // Check if this cert is considered a trust anchor by TrustStoreMac. | |
286 TrustAnchors trust_anchors; | |
287 trust_store.FindTrustAnchorsByMacNormalizedSubject(mac_normalized_subject, | |
288 &trust_anchors); | |
289 bool is_trust_anchor = false; | |
290 for (const auto& anchor : trust_anchors) { | |
291 ASSERT_TRUE(anchor->cert()); | |
292 if (anchor->cert()->der_cert() == cert->der_cert()) | |
293 is_trust_anchor = true; | |
294 } | |
295 | |
296 // Check if this cert is considered a trust anchor by the OS. | |
297 base::ScopedCFTypeRef<SecTrustRef> trust; | 279 base::ScopedCFTypeRef<SecTrustRef> trust; |
298 { | 280 { |
299 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | 281 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); |
300 ASSERT_EQ(noErr, | 282 ASSERT_EQ(noErr, |
301 SecTrustCreateWithCertificates(cert_handle, sec_policy, | 283 SecTrustCreateWithCertificates(cert_handle, sec_policy, |
302 trust.InitializeInto())); | 284 trust.InitializeInto())); |
303 ASSERT_EQ(noErr, | 285 ASSERT_EQ(noErr, |
304 SecTrustSetOptions( | 286 SecTrustSetOptions( |
305 trust, | 287 trust, |
306 kSecTrustOptionLeafIsCA | kSecTrustOptionAllowExpiredRoot)); | 288 kSecTrustOptionLeafIsCA | kSecTrustOptionAllowExpiredRoot)); |
307 | 289 |
308 SecTrustResultType trust_result; | 290 SecTrustResultType trust_result; |
309 ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); | 291 ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); |
310 bool expected_trust_anchor = | 292 bool expected_trust_anchor = |
311 ((trust_result == kSecTrustResultProceed) || | 293 ((trust_result == kSecTrustResultProceed) || |
312 (trust_result == kSecTrustResultUnspecified)) && | 294 (trust_result == kSecTrustResultUnspecified)) && |
313 (SecTrustGetCertificateCount(trust) == 1); | 295 (SecTrustGetCertificateCount(trust) == 1); |
314 EXPECT_EQ(expected_trust_anchor, is_trust_anchor); | 296 EXPECT_EQ(expected_trust_anchor, is_trust_anchor); |
315 } | 297 } |
316 } | 298 } |
317 } | 299 } |
318 | 300 |
319 } // namespace net | 301 } // namespace net |
OLD | NEW |