aw_contents_client_bridge_unittest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2014 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. #include "android_webview/browser/aw_contents_client_bridge.h"
  5. #include <memory>
  6. #include "android_webview/test/android_webview_unittests_jni/MockAwContentsClientBridge_jni.h"
  7. #include "base/android/jni_android.h"
  8. #include "base/android/jni_array.h"
  9. #include "base/android/scoped_java_ref.h"
  10. #include "base/bind.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/run_loop.h"
  14. #include "content/public/browser/client_certificate_delegate.h"
  15. #include "content/public/test/browser_task_environment.h"
  16. #include "net/cert/x509_certificate.h"
  17. #include "net/ssl/ssl_cert_request_info.h"
  18. #include "net/ssl/ssl_private_key.h"
  19. #include "testing/gmock/include/gmock/gmock.h"
  20. #include "testing/gtest/include/gtest/gtest.h"
  21. using base::android::AttachCurrentThread;
  22. using base::android::ScopedJavaLocalRef;
  23. using net::SSLCertRequestInfo;
  24. using net::SSLClientCertType;
  25. using net::SSLPrivateKey;
  26. using net::X509Certificate;
  27. using testing::NotNull;
  28. using testing::Test;
  29. namespace android_webview {
  30. namespace {
  31. // Tests the android_webview contents client bridge.
  32. class AwContentsClientBridgeTest : public Test {
  33. public:
  34. AwContentsClientBridgeTest() {}
  35. // Callback method called when a cert is selected.
  36. void CertSelected(scoped_refptr<X509Certificate> cert,
  37. scoped_refptr<SSLPrivateKey> key);
  38. protected:
  39. void SetUp() override;
  40. void TestCertType(SSLClientCertType type, const std::string& expected_name);
  41. // Create the TestBrowserThreads. Just instantiate the member variable.
  42. content::BrowserTaskEnvironment task_environment_;
  43. base::android::ScopedJavaGlobalRef<jobject> jbridge_;
  44. std::unique_ptr<AwContentsClientBridge> bridge_;
  45. scoped_refptr<SSLCertRequestInfo> cert_request_info_;
  46. scoped_refptr<X509Certificate> selected_cert_;
  47. scoped_refptr<SSLPrivateKey> selected_key_;
  48. int cert_selected_callbacks_;
  49. raw_ptr<JNIEnv> env_;
  50. };
  51. class TestClientCertificateDelegate
  52. : public content::ClientCertificateDelegate {
  53. public:
  54. explicit TestClientCertificateDelegate(AwContentsClientBridgeTest* test)
  55. : test_(test) {}
  56. TestClientCertificateDelegate(const TestClientCertificateDelegate&) = delete;
  57. TestClientCertificateDelegate& operator=(
  58. const TestClientCertificateDelegate&) = delete;
  59. // content::ClientCertificateDelegate.
  60. void ContinueWithCertificate(scoped_refptr<net::X509Certificate> cert,
  61. scoped_refptr<net::SSLPrivateKey> key) override {
  62. test_->CertSelected(std::move(cert), std::move(key));
  63. test_ = nullptr;
  64. }
  65. private:
  66. raw_ptr<AwContentsClientBridgeTest> test_;
  67. };
  68. } // namespace
  69. void AwContentsClientBridgeTest::SetUp() {
  70. env_ = AttachCurrentThread();
  71. ASSERT_THAT(env_, NotNull());
  72. jbridge_.Reset(
  73. env_,
  74. Java_MockAwContentsClientBridge_getAwContentsClientBridge(env_).obj());
  75. bridge_ = std::make_unique<AwContentsClientBridge>(env_, jbridge_);
  76. selected_cert_ = nullptr;
  77. cert_selected_callbacks_ = 0;
  78. cert_request_info_ = base::MakeRefCounted<net::SSLCertRequestInfo>();
  79. }
  80. void AwContentsClientBridgeTest::CertSelected(
  81. scoped_refptr<X509Certificate> cert,
  82. scoped_refptr<SSLPrivateKey> key) {
  83. selected_cert_ = std::move(cert);
  84. selected_key_ = std::move(key);
  85. cert_selected_callbacks_++;
  86. }
  87. TEST_F(AwContentsClientBridgeTest, TestClientCertKeyTypesCorrectlyEncoded) {
  88. SSLClientCertType cert_types[2] = {net::CLIENT_CERT_RSA_SIGN,
  89. net::CLIENT_CERT_ECDSA_SIGN};
  90. std::string expected_names[2] = {"RSA", "ECDSA"};
  91. for (int i = 0; i < 2; i++) {
  92. TestCertType(cert_types[i], expected_names[i]);
  93. }
  94. }
  95. void AwContentsClientBridgeTest::TestCertType(
  96. SSLClientCertType type,
  97. const std::string& expected_name) {
  98. cert_request_info_->cert_key_types.clear();
  99. cert_request_info_->cert_key_types.push_back(type);
  100. bridge_->SelectClientCertificate(
  101. cert_request_info_.get(),
  102. std::make_unique<TestClientCertificateDelegate>(this));
  103. base::RunLoop().RunUntilIdle();
  104. EXPECT_EQ(0, cert_selected_callbacks_);
  105. ScopedJavaLocalRef<jobjectArray> key_types =
  106. Java_MockAwContentsClientBridge_getKeyTypes(env_, jbridge_);
  107. std::vector<std::string> vec;
  108. base::android::AppendJavaStringArrayToStringVector(env_, key_types, &vec);
  109. EXPECT_EQ(1u, vec.size());
  110. EXPECT_EQ(expected_name, vec[0]);
  111. }
  112. // Verify that ProvideClientCertificateResponse works properly when the client
  113. // responds with a null key.
  114. TEST_F(AwContentsClientBridgeTest,
  115. TestProvideClientCertificateResponseCallsCallbackOnNullKey) {
  116. // Call SelectClientCertificate to create a callback id that mock java object
  117. // can call on.
  118. bridge_->SelectClientCertificate(
  119. cert_request_info_.get(),
  120. base::WrapUnique(new TestClientCertificateDelegate(this)));
  121. bridge_->ProvideClientCertificateResponse(
  122. env_, jbridge_,
  123. Java_MockAwContentsClientBridge_getRequestId(env_, jbridge_),
  124. Java_MockAwContentsClientBridge_createTestCertChain(env_, jbridge_),
  125. nullptr);
  126. base::RunLoop().RunUntilIdle();
  127. EXPECT_EQ(nullptr, selected_cert_.get());
  128. EXPECT_EQ(nullptr, selected_key_.get());
  129. EXPECT_EQ(1, cert_selected_callbacks_);
  130. }
  131. // Verify that ProvideClientCertificateResponse calls the callback with
  132. // null parameters when private key is not provided.
  133. TEST_F(AwContentsClientBridgeTest,
  134. TestProvideClientCertificateResponseCallsCallbackOnNullChain) {
  135. // Call SelectClientCertificate to create a callback id that mock java object
  136. // can call on.
  137. bridge_->SelectClientCertificate(
  138. cert_request_info_.get(),
  139. base::WrapUnique(new TestClientCertificateDelegate(this)));
  140. int requestId = Java_MockAwContentsClientBridge_getRequestId(env_, jbridge_);
  141. bridge_->ProvideClientCertificateResponse(env_, jbridge_, requestId, nullptr,
  142. nullptr);
  143. base::RunLoop().RunUntilIdle();
  144. EXPECT_EQ(nullptr, selected_cert_.get());
  145. EXPECT_EQ(nullptr, selected_key_.get());
  146. EXPECT_EQ(1, cert_selected_callbacks_);
  147. }
  148. } // namespace android_webview