OLD | NEW |
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 "ios/web/net/crw_cert_verification_controller.h" | 5 #include "ios/web/net/crw_cert_verification_controller.h" |
6 | 6 |
7 #include "base/mac/bind_objc_block.h" | 7 #include "base/mac/bind_objc_block.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/test/ios/wait_util.h" | 9 #include "base/test/ios/wait_util.h" |
10 #include "ios/web/public/web_thread.h" | 10 #include "ios/web/public/web_thread.h" |
11 #include "ios/web/test/web_test.h" | 11 #include "ios/web/test/web_test.h" |
| 12 #import "ios/web/web_state/wk_web_view_security_util.h" |
12 #include "net/base/test_data_directory.h" | 13 #include "net/base/test_data_directory.h" |
13 #include "net/cert/mock_cert_verifier.h" | 14 #include "net/cert/mock_cert_verifier.h" |
14 #include "net/cert/x509_certificate.h" | 15 #include "net/cert/x509_certificate.h" |
15 #include "net/test/cert_test_util.h" | 16 #include "net/test/cert_test_util.h" |
16 #include "net/url_request/url_request_context.h" | 17 #include "net/url_request/url_request_context.h" |
17 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
18 | 19 |
19 namespace web { | 20 namespace web { |
20 | 21 |
21 namespace { | 22 namespace { |
(...skipping 18 matching lines...) Expand all Loading... |
40 })); | 41 })); |
41 | 42 |
42 controller_.reset([[CRWCertVerificationController alloc] | 43 controller_.reset([[CRWCertVerificationController alloc] |
43 initWithBrowserState:browser_state]); | 44 initWithBrowserState:browser_state]); |
44 valid_cert_ = net::ImportCertFromFile(net::GetTestCertsDirectory(), | 45 valid_cert_ = net::ImportCertFromFile(net::GetTestCertsDirectory(), |
45 kValidCertFileName); | 46 kValidCertFileName); |
46 ASSERT_TRUE(valid_cert_); | 47 ASSERT_TRUE(valid_cert_); |
47 invalid_cert_ = | 48 invalid_cert_ = |
48 net::ImportCertFromFile(net::GetTestCertsDirectory(), kCertFileName); | 49 net::ImportCertFromFile(net::GetTestCertsDirectory(), kCertFileName); |
49 ASSERT_TRUE(invalid_cert_); | 50 ASSERT_TRUE(invalid_cert_); |
| 51 valid_trust_ = web::CreateServerTrustFromChain(GetChain(valid_cert_), |
| 52 kValidCertHostName); |
| 53 invalid_trust_ = |
| 54 web::CreateServerTrustFromChain(GetChain(invalid_cert_), kHostName); |
50 } | 55 } |
51 | 56 |
52 void TearDown() override { | 57 void TearDown() override { |
53 [controller_ shutDown]; | 58 [controller_ shutDown]; |
54 web::WebTest::TearDown(); | 59 web::WebTest::TearDown(); |
55 } | 60 } |
56 | 61 |
57 // Returns NSArray of SecCertificateRef objects for the given |cert|. | 62 // Returns NSArray of SecCertificateRef objects for the given |cert|. |
58 NSArray* GetChain(const scoped_refptr<net::X509Certificate>& cert) const { | 63 NSArray* GetChain(const scoped_refptr<net::X509Certificate>& cert) const { |
59 NSMutableArray* result = [NSMutableArray | 64 NSMutableArray* result = [NSMutableArray |
60 arrayWithObject:static_cast<id>(cert->os_cert_handle())]; | 65 arrayWithObject:static_cast<id>(cert->os_cert_handle())]; |
61 for (SecCertificateRef intermediate : cert->GetIntermediateCertificates()) { | 66 for (SecCertificateRef intermediate : cert->GetIntermediateCertificates()) { |
62 [result addObject:static_cast<id>(intermediate)]; | 67 [result addObject:static_cast<id>(intermediate)]; |
63 } | 68 } |
64 return result; | 69 return result; |
65 } | 70 } |
66 | 71 |
67 // Synchronously returns result of decidePolicyForCert:host:completionHandler: | 72 // Synchronously returns result of |
68 // call. | 73 // decideLoadPolicyForTrust:host:completionHandler: call. |
69 void DecidePolicy(const scoped_refptr<net::X509Certificate>& cert, | 74 void DecidePolicy(SecTrustRef server_trust, |
70 NSString* host, | 75 NSString* host, |
71 web::CertAcceptPolicy* policy, | 76 web::CertAcceptPolicy* policy, |
72 net::CertStatus* status) { | 77 net::CertStatus* status) { |
73 __block bool completion_handler_called = false; | 78 __block bool completion_handler_called = false; |
74 [controller_ decidePolicyForCert:cert | 79 [controller_ |
75 host:host | 80 decideLoadPolicyForTrust:server_trust |
76 completionHandler:^(web::CertAcceptPolicy callback_policy, | 81 host:host |
77 net::CertStatus callback_status) { | 82 completionHandler:^(web::CertAcceptPolicy callback_policy, |
78 *policy = callback_policy; | 83 net::CertStatus callback_status) { |
79 *status = callback_status; | 84 *policy = callback_policy; |
80 completion_handler_called = true; | 85 *status = callback_status; |
81 }]; | 86 completion_handler_called = true; |
| 87 }]; |
82 base::test::ios::WaitUntilCondition(^{ | 88 base::test::ios::WaitUntilCondition(^{ |
83 return completion_handler_called; | 89 return completion_handler_called; |
84 }, base::MessageLoop::current(), base::TimeDelta()); | 90 }, base::MessageLoop::current(), base::TimeDelta()); |
85 } | 91 } |
86 | 92 |
87 // Synchronously returns result of | 93 // Synchronously returns result of |
88 // querySSLStatusForCertChain:host:completionHandler: call. | 94 // querySSLStatusForCertChain:host:completionHandler: call. |
89 void QueryStatus(NSArray* chain, | 95 void QueryStatus(NSArray* chain, |
90 NSString* host, | 96 NSString* host, |
91 SecurityStyle* style, | 97 SecurityStyle* style, |
92 net::CertStatus* status) { | 98 net::CertStatus* status) { |
93 __block bool completion_handler_called = false; | 99 __block bool completion_handler_called = false; |
94 [controller_ querySSLStatusForCertChain:chain | 100 [controller_ querySSLStatusForCertChain:chain |
95 host:host | 101 host:host |
96 completionHandler:^(SecurityStyle callback_style, | 102 completionHandler:^(SecurityStyle callback_style, |
97 net::CertStatus callback_status) { | 103 net::CertStatus callback_status) { |
98 *style = callback_style; | 104 *style = callback_style; |
99 *status = callback_status; | 105 *status = callback_status; |
100 completion_handler_called = true; | 106 completion_handler_called = true; |
101 }]; | 107 }]; |
102 base::test::ios::WaitUntilCondition(^{ | 108 base::test::ios::WaitUntilCondition(^{ |
103 return completion_handler_called; | 109 return completion_handler_called; |
104 }, base::MessageLoop::current(), base::TimeDelta()); | 110 }, base::MessageLoop::current(), base::TimeDelta()); |
105 } | 111 } |
106 | 112 |
107 scoped_refptr<net::X509Certificate> valid_cert_; | 113 scoped_refptr<net::X509Certificate> valid_cert_; |
108 scoped_refptr<net::X509Certificate> invalid_cert_; | 114 scoped_refptr<net::X509Certificate> invalid_cert_; |
| 115 base::ScopedCFTypeRef<SecTrustRef> valid_trust_; |
| 116 base::ScopedCFTypeRef<SecTrustRef> invalid_trust_; |
109 net::MockCertVerifier cert_verifier_; | 117 net::MockCertVerifier cert_verifier_; |
110 base::scoped_nsobject<CRWCertVerificationController> controller_; | 118 base::scoped_nsobject<CRWCertVerificationController> controller_; |
111 }; | 119 }; |
112 | 120 |
113 // Tests cert policy with a valid cert. | 121 // Tests cert policy with a valid trust. |
114 TEST_F(CRWCertVerificationControllerTest, PolicyForValidCert) { | 122 TEST_F(CRWCertVerificationControllerTest, PolicyForValidTrust) { |
115 net::CertVerifyResult verify_result; | 123 net::CertVerifyResult verify_result; |
116 verify_result.cert_status = net::CERT_STATUS_NO_REVOCATION_MECHANISM; | 124 verify_result.cert_status = net::CERT_STATUS_NO_REVOCATION_MECHANISM; |
117 verify_result.verified_cert = invalid_cert_; | 125 verify_result.verified_cert = invalid_cert_; |
118 cert_verifier_.AddResultForCertAndHost( | 126 cert_verifier_.AddResultForCertAndHost( |
119 invalid_cert_.get(), kHostName.UTF8String, verify_result, net::OK); | 127 invalid_cert_.get(), kHostName.UTF8String, verify_result, net::OK); |
| 128 |
120 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 129 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
121 net::CertStatus status; | 130 net::CertStatus status; |
122 DecidePolicy(invalid_cert_, kHostName, &policy, &status); | 131 DecidePolicy(valid_trust_, kValidCertHostName, &policy, &status); |
123 EXPECT_EQ(CERT_ACCEPT_POLICY_ALLOW, policy); | 132 EXPECT_EQ(CERT_ACCEPT_POLICY_ALLOW, policy); |
124 EXPECT_EQ(verify_result.cert_status, status); | 133 EXPECT_FALSE(status); |
125 } | 134 } |
126 | 135 |
127 // Tests cert policy with an invalid cert. | 136 // Tests cert policy with an invalid trust not accepted by user. |
128 TEST_F(CRWCertVerificationControllerTest, PolicyForInvalidCert) { | 137 TEST_F(CRWCertVerificationControllerTest, PolicyForInvalidTrust) { |
| 138 net::CertVerifyResult result; |
| 139 result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID; |
| 140 result.verified_cert = invalid_cert_; |
| 141 cert_verifier_.AddResultForCertAndHost(invalid_cert_.get(), |
| 142 [kHostName UTF8String], result, |
| 143 net::ERR_CERT_COMMON_NAME_INVALID); |
| 144 |
129 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 145 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
130 net::CertStatus status; | 146 net::CertStatus status; |
131 DecidePolicy(invalid_cert_, kHostName, &policy, &status); | 147 DecidePolicy(invalid_trust_, kHostName, &policy, &status); |
132 EXPECT_EQ(CERT_ACCEPT_POLICY_RECOVERABLE_ERROR, policy); | 148 EXPECT_EQ(CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_NOT_ACCEPTED_BY_USER, policy); |
| 149 EXPECT_EQ(net::CERT_STATUS_COMMON_NAME_INVALID, status); |
133 } | 150 } |
134 | 151 |
135 // Tests cert policy with null cert. | 152 // Tests cert policy with an invalid trust accepted by user. |
136 TEST_F(CRWCertVerificationControllerTest, PolicyForNullCert) { | 153 TEST_F(CRWCertVerificationControllerTest, PolicyForInvalidTrustAcceptedByUser) { |
| 154 net::CertVerifyResult result; |
| 155 result.cert_status = net::CERT_STATUS_DATE_INVALID; |
| 156 result.verified_cert = invalid_cert_; |
| 157 cert_verifier_.AddResultForCertAndHost(invalid_cert_.get(), |
| 158 [kHostName UTF8String], result, |
| 159 net::ERR_CERT_DATE_INVALID); |
| 160 |
| 161 [controller_ allowCert:invalid_cert_.get() |
| 162 forHost:kHostName |
| 163 status:net::CERT_STATUS_ALL_ERRORS]; |
137 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 164 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
138 net::CertStatus status; | 165 net::CertStatus status; |
| 166 DecidePolicy(invalid_trust_, kHostName, &policy, &status); |
| 167 EXPECT_EQ(CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_ACCEPTED_BY_USER, policy); |
| 168 EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, status); |
| 169 } |
| 170 |
| 171 // Tests cert policy with null trust. |
| 172 TEST_F(CRWCertVerificationControllerTest, PolicyForNullTrust) { |
| 173 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_ALLOW; |
| 174 net::CertStatus status; |
139 DecidePolicy(nullptr, kHostName, &policy, &status); | 175 DecidePolicy(nullptr, kHostName, &policy, &status); |
140 EXPECT_EQ(CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR, policy); | 176 EXPECT_EQ(CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR, policy); |
| 177 EXPECT_FALSE(status); |
141 } | 178 } |
142 | 179 |
143 // Tests cert policy with null cert and null host. | 180 // Tests cert policy with invalid trust and null host. |
144 TEST_F(CRWCertVerificationControllerTest, PolicyForNullHost) { | 181 TEST_F(CRWCertVerificationControllerTest, PolicyForNullHost) { |
145 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; | 182 web::CertAcceptPolicy policy = CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR; |
146 net::CertStatus status; | 183 net::CertStatus status; |
147 DecidePolicy(invalid_cert_, nil, &policy, &status); | 184 DecidePolicy(invalid_trust_, nil, &policy, &status); |
148 EXPECT_EQ(CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR, policy); | 185 EXPECT_EQ(CERT_ACCEPT_POLICY_RECOVERABLE_ERROR_NOT_ACCEPTED_BY_USER, policy); |
| 186 EXPECT_FALSE(status); |
149 } | 187 } |
150 | 188 |
151 // Tests SSL status with valid chain. | 189 // Tests SSL status with valid chain. |
152 TEST_F(CRWCertVerificationControllerTest, SSLStatusForValidChain) { | 190 TEST_F(CRWCertVerificationControllerTest, SSLStatusForValidChain) { |
153 SecurityStyle style = SECURITY_STYLE_UNKNOWN; | 191 SecurityStyle style = SECURITY_STYLE_UNKNOWN; |
154 net::CertStatus status = net::CERT_STATUS_ALL_ERRORS; | 192 net::CertStatus status = net::CERT_STATUS_ALL_ERRORS; |
155 | 193 |
156 QueryStatus(GetChain(valid_cert_), kValidCertHostName, &style, &status); | 194 QueryStatus(GetChain(valid_cert_), kValidCertHostName, &style, &status); |
157 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, style); | 195 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, style); |
158 EXPECT_FALSE(status); | 196 EXPECT_FALSE(status); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 | 242 |
205 SecurityStyle style = SECURITY_STYLE_UNKNOWN; | 243 SecurityStyle style = SECURITY_STYLE_UNKNOWN; |
206 net::CertStatus status = net::CERT_STATUS_ALL_ERRORS; | 244 net::CertStatus status = net::CERT_STATUS_ALL_ERRORS; |
207 | 245 |
208 QueryStatus(GetChain(invalid_cert_), kHostName, &style, &status); | 246 QueryStatus(GetChain(invalid_cert_), kHostName, &style, &status); |
209 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, style); | 247 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, style); |
210 EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, status); | 248 EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, status); |
211 } | 249 } |
212 | 250 |
213 } // namespace web | 251 } // namespace web |
OLD | NEW |