blob: de5f9e8eb31feab25f4deb321ada22c0cfb02ace [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/web/net/cert_verifier_block_adapter.h"
#include "base/message_loop/message_loop.h"
#include "base/test/ios/wait_util.h"
#include "ios/web/public/test/test_web_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/crl_set.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/log/net_log.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/platform_test.h"
namespace web {
namespace {
// Test cert filename.
const char kCertFileName[] = "ok_cert.pem";
// Test hostname for CertVerifier.
const char kHostName[] = "www.example.com";
} // namespace
// Test fixture to test CertVerifierBlockAdapter class.
class CertVerifierBlockAdapterTest : public PlatformTest {
protected:
void SetUp() override {
PlatformTest::SetUp();
cert_ =
net::ImportCertFromFile(net::GetTestCertsDirectory(), kCertFileName);
ASSERT_TRUE(cert_);
}
// Performs synchronous verification.
void Verify(CertVerifierBlockAdapter* cert_verifier_adapter,
CertVerifierBlockAdapter::Params params,
net::CertVerifyResult* result,
int* error) {
__block bool verification_completed = false;
cert_verifier_adapter->Verify(
params, ^(net::CertVerifyResult callback_result, int callback_error) {
*result = callback_result;
*error = callback_error;
verification_completed = true;
});
base::test::ios::WaitUntilCondition(^{
return verification_completed;
}, base::MessageLoop::current(), base::TimeDelta());
}
web::TestWebThreadBundle thread_bundle_;
scoped_refptr<net::X509Certificate> cert_;
net::NetLog net_log_;
};
// Tests |Verify| with default params and synchronous verification.
TEST_F(CertVerifierBlockAdapterTest, DefaultParamsAndSync) {
// Set up verifier mock.
net::MockCertVerifier verifier;
CertVerifierBlockAdapter test_adapter(&verifier, &net_log_);
const int kExpectedError = net::ERR_CERT_AUTHORITY_INVALID;
net::CertVerifyResult expected_result;
expected_result.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
expected_result.verified_cert = cert_;
verifier.AddResultForCertAndHost(cert_.get(), kHostName, expected_result,
kExpectedError);
// Call |Verify|.
net::CertVerifyResult actual_result;
int actual_error = -1;
CertVerifierBlockAdapter::Params params(cert_.get(), kHostName);
Verify(&test_adapter, params, &actual_result, &actual_error);
// Ensure that Verification results are correct.
EXPECT_EQ(kExpectedError, actual_error);
EXPECT_EQ(expected_result.cert_status, actual_result.cert_status);
}
// Tests |Verify| with default params and asynchronous verification using real
// net::CertVerifier and ok_cert.pem cert.
TEST_F(CertVerifierBlockAdapterTest, DefaultParamsAndAsync) {
// Call |Verify|.
std::unique_ptr<net::CertVerifier> verifier(
net::CertVerifier::CreateDefault());
CertVerifierBlockAdapter test_adapter(verifier.get(), &net_log_);
CertVerifierBlockAdapter::Params params(cert_.get(), kHostName);
net::CertVerifyResult actual_result;
int actual_error = -1;
Verify(&test_adapter, params, &actual_result, &actual_error);
// Ensure that Verification results are correct.
EXPECT_FALSE(actual_result.is_issued_by_known_root);
EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID, actual_error);
}
// Tests |Verify| with invalid cert argument.
TEST_F(CertVerifierBlockAdapterTest, InvalidCert) {
// Call |Verify|.
net::MockCertVerifier verifier;
CertVerifierBlockAdapter test_adapter(&verifier, &net_log_);
net::CertVerifyResult actual_result;
int actual_error = -1;
CertVerifierBlockAdapter::Params params(nullptr, kHostName);
Verify(&test_adapter, params, &actual_result, &actual_error);
// Ensure that Verification results are correct.
EXPECT_EQ(net::ERR_INVALID_ARGUMENT, actual_error);
}
// Tests |Verify| with invalid hostname argument.
TEST_F(CertVerifierBlockAdapterTest, InvalidHostname) {
// Call |Verify|.
net::MockCertVerifier verifier;
CertVerifierBlockAdapter test_adapter(&verifier, &net_log_);
net::CertVerifyResult actual_result;
int actual_error = -1;
CertVerifierBlockAdapter::Params params(cert_.get(), std::string());
Verify(&test_adapter, params, &actual_result, &actual_error);
// Ensure that Verification results are correct.
EXPECT_EQ(net::ERR_INVALID_ARGUMENT, actual_error);
}
// Tests |Verify| with synchronous error.
TEST_F(CertVerifierBlockAdapterTest, DefaultParamsAndSyncError) {
// Set up expectation.
net::MockCertVerifier verifier;
CertVerifierBlockAdapter test_adapter(&verifier, &net_log_);
const int kExpectedError = net::ERR_INSUFFICIENT_RESOURCES;
net::CertVerifyResult expected_result;
expected_result.verified_cert = cert_;
verifier.AddResultForCertAndHost(cert_.get(), kHostName, expected_result,
kExpectedError);
// Call |Verify|.
net::CertVerifyResult actual_result;
int actual_error = -1;
CertVerifierBlockAdapter::Params params(cert_.get(), kHostName);
Verify(&test_adapter, params, &actual_result, &actual_error);
// Ensure that Verification results are correct.
EXPECT_EQ(kExpectedError, actual_error);
}
// Tests that the completion handler passed to |Verify()| is called, even if the
// adapter is destroyed.
TEST_F(CertVerifierBlockAdapterTest, CompletionHandlerIsAlwaysCalled) {
std::unique_ptr<net::CertVerifier> verifier(
net::CertVerifier::CreateDefault());
std::unique_ptr<CertVerifierBlockAdapter> test_adapter(
new CertVerifierBlockAdapter(verifier.get(), &net_log_));
// Call |Verify| and destroy the adapter.
CertVerifierBlockAdapter::Params params(cert_.get(), kHostName);
__block bool verification_completed = false;
test_adapter->Verify(params, ^(net::CertVerifyResult, int) {
verification_completed = true;
});
test_adapter.reset();
// Make sure that the completion handler is called.
base::test::ios::WaitUntilCondition(^{
return verification_completed;
}, base::MessageLoop::current(), base::TimeDelta());
}
} // namespace web