OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/cert_issuer_source_collection.h" |
| 6 |
| 7 //#include "net/cert/internal/cert_issuer_source_static.h" |
| 8 #include "base/bind.h" |
| 9 #include "net/cert/internal/cert_issuer_source_test_helpers.h" |
| 10 #include "net/cert/internal/parsed_certificate.h" |
| 11 #include "net/cert/internal/test_helpers.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "testing/gmock/include/gmock/gmock.h" |
| 14 |
| 15 namespace net { |
| 16 |
| 17 namespace { |
| 18 |
| 19 using ::testing::Invoke; |
| 20 using ::testing::SaveArg; |
| 21 using ::testing::SetArgPointee; |
| 22 using ::testing::StrictMock; |
| 23 using ::testing::Unused; |
| 24 using ::testing::Return; |
| 25 using ::testing::_; |
| 26 |
| 27 // XXX dupe from path_builder_unittest |
| 28 ::testing::AssertionResult ReadTestPem(const std::string& file_name, |
| 29 const std::string& block_name, |
| 30 std::string* result) { |
| 31 const PemBlockMapping mappings[] = { |
| 32 {block_name.c_str(), result}, |
| 33 }; |
| 34 |
| 35 return ReadTestDataFromPemFile(file_name, mappings); |
| 36 } |
| 37 |
| 38 // XXX dupe from path_builder_unittest |
| 39 ::testing::AssertionResult ReadTestCert( |
| 40 const std::string& file_name, |
| 41 scoped_refptr<ParsedCertificate>* result) { |
| 42 std::string der; |
| 43 ::testing::AssertionResult r = ReadTestPem( |
| 44 "net/data/ssl/certificates/" + file_name, "CERTIFICATE", &der); |
| 45 if (!r) |
| 46 return r; |
| 47 *result = ParsedCertificate::CreateFromCertificateCopy(der, {}); |
| 48 if (!*result) |
| 49 return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed"; |
| 50 return ::testing::AssertionSuccess(); |
| 51 } |
| 52 |
| 53 void NotCalled(CertIssuerSource::Request* request) { |
| 54 ADD_FAILURE() << "NotCalled was called"; |
| 55 } |
| 56 |
| 57 |
| 58 class CertIssuerSourceCollectionTest : public ::testing::Test { |
| 59 public: |
| 60 void SetUp() override { |
| 61 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert_)); |
| 62 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert2_)); |
| 63 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert3_)); |
| 64 } |
| 65 protected: |
| 66 scoped_refptr<ParsedCertificate> cert_; |
| 67 scoped_refptr<ParsedCertificate> cert2_; |
| 68 scoped_refptr<ParsedCertificate> cert3_; |
| 69 }; |
| 70 |
| 71 TEST_F(CertIssuerSourceCollectionTest, EmptyCollection) { |
| 72 CertIssuerSourceCollection collection; |
| 73 ParsedCertificateList issuers; |
| 74 collection.SyncGetIssuersOf(cert_.get(), &issuers); |
| 75 EXPECT_TRUE(issuers.empty()); |
| 76 |
| 77 std::unique_ptr<CertIssuerSource::Request> request; |
| 78 collection.AsyncGetIssuersOf(cert_.get(), base::Bind(&NotCalled), &request); |
| 79 EXPECT_EQ(nullptr, request); |
| 80 } |
| 81 |
| 82 TEST_F(CertIssuerSourceCollectionTest, SyncNoResults) { |
| 83 StrictMock<MockCertIssuerSource> source1; |
| 84 StrictMock<MockCertIssuerSource> source2; |
| 85 CertIssuerSourceCollection collection; |
| 86 collection.AddSource(&source1); |
| 87 collection.AddSource(&source2); |
| 88 |
| 89 ParsedCertificateList issuers; |
| 90 EXPECT_CALL(source1, SyncGetIssuersOf(cert_.get(), _)); |
| 91 EXPECT_CALL(source2, SyncGetIssuersOf(cert_.get(), _)); |
| 92 collection.SyncGetIssuersOf(cert_.get(), &issuers); |
| 93 EXPECT_TRUE(issuers.empty()); |
| 94 } |
| 95 |
| 96 TEST_F(CertIssuerSourceCollectionTest, SyncWithResults) { |
| 97 StrictMock<MockCertIssuerSource> source1; |
| 98 StrictMock<MockCertIssuerSource> source2; |
| 99 CertIssuerSourceCollection collection; |
| 100 collection.AddSource(&source1); |
| 101 collection.AddSource(&source2); |
| 102 |
| 103 scoped_refptr<ParsedCertificate> cert2 = cert2_; |
| 104 scoped_refptr<ParsedCertificate> cert3 = cert3_; |
| 105 ParsedCertificateList issuers; |
| 106 EXPECT_CALL(source1, SyncGetIssuersOf(cert_.get(), _)) |
| 107 .WillOnce(Invoke( |
| 108 [cert2](Unused, ParsedCertificateList* out) { out->push_back(cert2); }
)); |
| 109 EXPECT_CALL(source2, SyncGetIssuersOf(cert_.get(), _)) |
| 110 .WillOnce(Invoke( |
| 111 [cert3](Unused, ParsedCertificateList* out) { out->push_back(cert3); }
)); |
| 112 collection.SyncGetIssuersOf(cert_.get(), &issuers); |
| 113 EXPECT_EQ(ParsedCertificateList({cert2, cert3}), issuers); |
| 114 } |
| 115 |
| 116 TEST_F(CertIssuerSourceCollectionTest, AsyncNoAsyncSources) { |
| 117 StrictMock<MockCertIssuerSource> source1; |
| 118 StrictMock<MockCertIssuerSource> source2; |
| 119 CertIssuerSourceCollection collection; |
| 120 collection.AddSource(&source1); |
| 121 collection.AddSource(&source2); |
| 122 |
| 123 // When the sub-sources get AsyncGetIssuersOf calls, they don't set the output |
| 124 // Request param. |
| 125 EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _)); |
| 126 EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _)); |
| 127 std::unique_ptr<CertIssuerSource::Request> request; |
| 128 collection.AsyncGetIssuersOf(cert_.get(), base::Bind(&NotCalled), &request); |
| 129 // The collection should not set it's output Request either. |
| 130 EXPECT_EQ(nullptr, request); |
| 131 } |
| 132 |
| 133 TEST_F(CertIssuerSourceCollectionTest, AsyncReadSubResultsImmediately) { |
| 134 StrictMock<MockCertIssuerSource> source1; |
| 135 StrictMock<MockCertIssuerSource> source2; |
| 136 CertIssuerSourceCollection collection; |
| 137 collection.AddSource(&source1); |
| 138 collection.AddSource(&source2); |
| 139 |
| 140 |
| 141 // Set up expectations for the sub requests: |
| 142 |
| 143 CertIssuerSource::IssuerCallback sub_req1_callback; |
| 144 // Create a mock CertIssuerSource::Request for source1. |
| 145 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req1_owner( |
| 146 new StrictMock<MockCertIssuerSourceRequest>()); |
| 147 // Keep a raw pointer to the Request... |
| 148 StrictMock<MockCertIssuerSourceRequest>* sub_req1 = |
| 149 sub_req1_owner.get(); |
| 150 // Setup helper class to pass ownership of the Request to the |
| 151 // CertIssuerSourceCollection when it calls AsyncGetIssuersOf. |
| 152 CertIssuerSourceRequestMover sub_req1_mover(std::move(sub_req1_owner)); |
| 153 EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _)) |
| 154 .WillOnce(DoAll( |
| 155 SaveArg<1>(&sub_req1_callback), |
| 156 Invoke(&sub_req1_mover, &CertIssuerSourceRequestMover::MoveIt))); |
| 157 |
| 158 CertIssuerSource::IssuerCallback sub_req2_callback; |
| 159 // Create a mock CertIssuerSource::Request for source1. |
| 160 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req2_owner( |
| 161 new StrictMock<MockCertIssuerSourceRequest>()); |
| 162 // Keep a raw pointer to the Request... |
| 163 StrictMock<MockCertIssuerSourceRequest>* sub_req2 = |
| 164 sub_req2_owner.get(); |
| 165 // Setup helper class to pass ownership of the Request to the |
| 166 // CertIssuerSourceCollection when it calls AsyncGetIssuersOf. |
| 167 CertIssuerSourceRequestMover sub_req2_mover(std::move(sub_req1_owner)); |
| 168 EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _)) |
| 169 .WillOnce(DoAll( |
| 170 SaveArg<1>(&sub_req2_callback), |
| 171 Invoke(&sub_req2_mover, &CertIssuerSourceRequestMover::MoveIt))); |
| 172 |
| 173 // Do the collection request: |
| 174 std::unique_ptr<CertIssuerSource::Request> collection_request; |
| 175 StrictMock<MockIssuerCallback> mock_callback; |
| 176 collection.AsyncGetIssuersOf(cert_.get(), |
| 177 base::Bind(&MockIssuerCallback::Callback, |
| 178 base::Unretained(&mock_callback)), |
| 179 &collection_request); |
| 180 |
| 181 ASSERT_TRUE(collection_request); |
| 182 ASSERT_FALSE(sub_req1_callback.is_null()); |
| 183 ASSERT_FALSE(sub_req2_callback.is_null()); |
| 184 ::testing::Mock::VerifyAndClearExpectations(&source1); |
| 185 |
| 186 scoped_refptr<ParsedCertificate> req1cert1; |
| 187 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert1)); |
| 188 scoped_refptr<ParsedCertificate> req1cert2; |
| 189 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert2)); |
| 190 |
| 191 // source1 will return cert1 and cert2 |
| 192 EXPECT_CALL(*sub_req1, GetNext(_)) |
| 193 .WillOnce( |
| 194 DoAll(SetArgPointee<0>(req1cert1), Return(CompletionStatus::SYNC))) |
| 195 .WillOnce( |
| 196 DoAll(SetArgPointee<0>(req1cert2), Return(CompletionStatus::SYNC))) |
| 197 .WillOnce( |
| 198 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC))); |
| 199 EXPECT_CALL(mock_callback, Callback(collection_request.get())); |
| 200 |
| 201 sub_req1_callback.Run(sub_req1); |
| 202 ::testing::Mock::VerifyAndClearExpectations(&mock_callback); |
| 203 |
| 204 // Get first results from collection. |
| 205 scoped_refptr<ParsedCertificate> result_cert; |
| 206 CompletionStatus status = collection_request->GetNext(&result_cert); |
| 207 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 208 EXPECT_EQ(req1cert1, result_cert); |
| 209 status = collection_request->GetNext(&result_cert); |
| 210 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 211 EXPECT_EQ(req1cert2, result_cert); |
| 212 status = collection_request->GetNext(&result_cert); |
| 213 EXPECT_EQ(CompletionStatus::ASYNC, status); |
| 214 EXPECT_EQ(nullptr, result_cert); |
| 215 |
| 216 ::testing::Mock::VerifyAndClearExpectations(sub_req1); |
| 217 |
| 218 scoped_refptr<ParsedCertificate> req2cert1; |
| 219 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert1)); |
| 220 scoped_refptr<ParsedCertificate> req2cert2; |
| 221 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert2)); |
| 222 |
| 223 // source2 will return some certs, and signal completion. |
| 224 EXPECT_CALL(*sub_req2, GetNext(_)) |
| 225 .WillOnce( |
| 226 DoAll(SetArgPointee<0>(req2cert1), Return(CompletionStatus::SYNC))) |
| 227 .WillOnce( |
| 228 DoAll(SetArgPointee<0>(req2cert2), Return(CompletionStatus::SYNC))) |
| 229 .WillOnce( |
| 230 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC))); |
| 231 EXPECT_CALL(mock_callback, Callback(collection_request.get())); |
| 232 |
| 233 sub_req2_callback.Run(sub_req2); |
| 234 ::testing::Mock::VerifyAndClearExpectations(&mock_callback); |
| 235 |
| 236 // Get second set of results from collection. |
| 237 status = collection_request->GetNext(&result_cert); |
| 238 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 239 EXPECT_EQ(req2cert1, result_cert); |
| 240 status = collection_request->GetNext(&result_cert); |
| 241 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 242 EXPECT_EQ(req2cert2, result_cert); |
| 243 status = collection_request->GetNext(&result_cert); |
| 244 EXPECT_EQ(CompletionStatus::ASYNC, status); |
| 245 EXPECT_EQ(nullptr, result_cert); |
| 246 ::testing::Mock::VerifyAndClearExpectations(sub_req2); |
| 247 |
| 248 |
| 249 scoped_refptr<ParsedCertificate> req1cert3; |
| 250 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert3)); |
| 251 scoped_refptr<ParsedCertificate> req1cert4; |
| 252 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert4)); |
| 253 |
| 254 // source1 will return cert3 and cert4 and signal completion. |
| 255 EXPECT_CALL(*sub_req1, GetNext(_)) |
| 256 .WillOnce( |
| 257 DoAll(SetArgPointee<0>(req1cert3), Return(CompletionStatus::SYNC))) |
| 258 .WillOnce( |
| 259 DoAll(SetArgPointee<0>(req1cert4), Return(CompletionStatus::SYNC))) |
| 260 .WillOnce( |
| 261 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC))); |
| 262 EXPECT_CALL(mock_callback, Callback(collection_request.get())); |
| 263 |
| 264 sub_req1_callback.Run(sub_req1); |
| 265 ::testing::Mock::VerifyAndClearExpectations(sub_req1); |
| 266 ::testing::Mock::VerifyAndClearExpectations(&mock_callback); |
| 267 |
| 268 // Finally get the results from the CertIssuerSourceCollection. |
| 269 status = collection_request->GetNext(&result_cert); |
| 270 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 271 EXPECT_EQ(req1cert3, result_cert); |
| 272 |
| 273 status = collection_request->GetNext(&result_cert); |
| 274 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 275 EXPECT_EQ(req1cert4, result_cert); |
| 276 |
| 277 status = collection_request->GetNext(&result_cert); |
| 278 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 279 EXPECT_FALSE(result_cert); |
| 280 } |
| 281 |
| 282 |
| 283 TEST_F(CertIssuerSourceCollectionTest, AsyncFoo) { |
| 284 StrictMock<MockCertIssuerSource> source1; |
| 285 StrictMock<MockCertIssuerSource> source2; |
| 286 CertIssuerSourceCollection collection; |
| 287 collection.AddSource(&source1); |
| 288 collection.AddSource(&source2); |
| 289 |
| 290 |
| 291 // Set up expectations for the sub requests: |
| 292 |
| 293 CertIssuerSource::IssuerCallback sub_req1_callback; |
| 294 // Create a mock CertIssuerSource::Request for source1. |
| 295 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req1_owner( |
| 296 new StrictMock<MockCertIssuerSourceRequest>()); |
| 297 // Keep a raw pointer to the Request... |
| 298 StrictMock<MockCertIssuerSourceRequest>* sub_req1 = |
| 299 sub_req1_owner.get(); |
| 300 // Setup helper class to pass ownership of the Request to the |
| 301 // CertIssuerSourceCollection when it calls AsyncGetIssuersOf. |
| 302 CertIssuerSourceRequestMover sub_req1_mover(std::move(sub_req1_owner)); |
| 303 EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _)) |
| 304 .WillOnce(DoAll( |
| 305 SaveArg<1>(&sub_req1_callback), |
| 306 Invoke(&sub_req1_mover, &CertIssuerSourceRequestMover::MoveIt))); |
| 307 |
| 308 CertIssuerSource::IssuerCallback sub_req2_callback; |
| 309 // Create a mock CertIssuerSource::Request for source1. |
| 310 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req2_owner( |
| 311 new StrictMock<MockCertIssuerSourceRequest>()); |
| 312 // Keep a raw pointer to the Request... |
| 313 StrictMock<MockCertIssuerSourceRequest>* sub_req2 = |
| 314 sub_req2_owner.get(); |
| 315 // Setup helper class to pass ownership of the Request to the |
| 316 // CertIssuerSourceCollection when it calls AsyncGetIssuersOf. |
| 317 CertIssuerSourceRequestMover sub_req2_mover(std::move(sub_req1_owner)); |
| 318 EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _)) |
| 319 .WillOnce(DoAll( |
| 320 SaveArg<1>(&sub_req2_callback), |
| 321 Invoke(&sub_req2_mover, &CertIssuerSourceRequestMover::MoveIt))); |
| 322 |
| 323 // Do the collection request: |
| 324 std::unique_ptr<CertIssuerSource::Request> collection_request; |
| 325 StrictMock<MockIssuerCallback> mock_callback; |
| 326 collection.AsyncGetIssuersOf(cert_.get(), |
| 327 base::Bind(&MockIssuerCallback::Callback, |
| 328 base::Unretained(&mock_callback)), |
| 329 &collection_request); |
| 330 |
| 331 ASSERT_TRUE(collection_request); |
| 332 ASSERT_FALSE(sub_req1_callback.is_null()); |
| 333 ASSERT_FALSE(sub_req2_callback.is_null()); |
| 334 ::testing::Mock::VerifyAndClearExpectations(&source1); |
| 335 |
| 336 scoped_refptr<ParsedCertificate> req1cert1; |
| 337 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert1)); |
| 338 scoped_refptr<ParsedCertificate> req1cert2; |
| 339 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert2)); |
| 340 |
| 341 // source1 will return cert1 and cert2 |
| 342 EXPECT_CALL(*sub_req1, GetNext(_)) |
| 343 .WillOnce( |
| 344 DoAll(SetArgPointee<0>(req1cert1), Return(CompletionStatus::SYNC))) |
| 345 .WillOnce( |
| 346 DoAll(SetArgPointee<0>(req1cert2), Return(CompletionStatus::SYNC))) |
| 347 .WillOnce( |
| 348 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC))); |
| 349 // The collection callback should occur as soon as any results are |
| 350 // available. Don't get the results from it yet. |
| 351 EXPECT_CALL(mock_callback, Callback(collection_request.get())); |
| 352 |
| 353 sub_req1_callback.Run(sub_req1); |
| 354 ::testing::Mock::VerifyAndClearExpectations(sub_req1); |
| 355 ::testing::Mock::VerifyAndClearExpectations(&mock_callback); |
| 356 |
| 357 scoped_refptr<ParsedCertificate> req2cert1; |
| 358 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert1)); |
| 359 scoped_refptr<ParsedCertificate> req2cert2; |
| 360 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert2)); |
| 361 |
| 362 // source2 will return some certs, and signal completion. |
| 363 EXPECT_CALL(*sub_req2, GetNext(_)) |
| 364 .WillOnce( |
| 365 DoAll(SetArgPointee<0>(req2cert1), Return(CompletionStatus::SYNC))) |
| 366 .WillOnce( |
| 367 DoAll(SetArgPointee<0>(req2cert2), Return(CompletionStatus::SYNC))) |
| 368 .WillOnce( |
| 369 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC))); |
| 370 |
| 371 sub_req2_callback.Run(sub_req2); |
| 372 ::testing::Mock::VerifyAndClearExpectations(sub_req2); |
| 373 |
| 374 scoped_refptr<ParsedCertificate> req1cert3; |
| 375 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert3)); |
| 376 scoped_refptr<ParsedCertificate> req1cert4; |
| 377 ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert4)); |
| 378 |
| 379 // source1 will return cert3 and cert4 |
| 380 EXPECT_CALL(*sub_req1, GetNext(_)) |
| 381 .WillOnce( |
| 382 DoAll(SetArgPointee<0>(req1cert3), Return(CompletionStatus::SYNC))) |
| 383 .WillOnce( |
| 384 DoAll(SetArgPointee<0>(req1cert4), Return(CompletionStatus::SYNC))) |
| 385 .WillOnce( |
| 386 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC))); |
| 387 |
| 388 sub_req1_callback.Run(sub_req1); |
| 389 ::testing::Mock::VerifyAndClearExpectations(sub_req1); |
| 390 |
| 391 // Finally get the results from the CertIssuerSourceCollection. |
| 392 scoped_refptr<ParsedCertificate> result_cert; |
| 393 CompletionStatus status = collection_request->GetNext(&result_cert); |
| 394 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 395 EXPECT_EQ(req1cert1, result_cert); |
| 396 |
| 397 status = collection_request->GetNext(&result_cert); |
| 398 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 399 EXPECT_EQ(req1cert2, result_cert); |
| 400 |
| 401 status = collection_request->GetNext(&result_cert); |
| 402 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 403 EXPECT_EQ(req2cert1, result_cert); |
| 404 |
| 405 status = collection_request->GetNext(&result_cert); |
| 406 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 407 EXPECT_EQ(req2cert2, result_cert); |
| 408 |
| 409 status = collection_request->GetNext(&result_cert); |
| 410 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 411 EXPECT_EQ(req1cert3, result_cert); |
| 412 |
| 413 status = collection_request->GetNext(&result_cert); |
| 414 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 415 EXPECT_EQ(req1cert4, result_cert); |
| 416 |
| 417 status = collection_request->GetNext(&result_cert); |
| 418 EXPECT_EQ(CompletionStatus::SYNC, status); |
| 419 EXPECT_FALSE(result_cert); |
| 420 } |
| 421 |
| 422 // XXX more tests |
| 423 // |
| 424 } // namespace |
| 425 |
| 426 } // namespace net |
OLD | NEW |