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.
5 #include "android_webview/native/aw_contents_client_bridge.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/macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h"
14 #include "content/public/browser/client_certificate_delegate.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "jni/MockAwContentsClientBridge_jni.h"
17 #include "net/android/net_jni_registrar.h"
18 #include "net/ssl/ssl_cert_request_info.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
23 using base::android::AttachCurrentThread
;
24 using base::android::ScopedJavaLocalRef
;
25 using net::SSLCertRequestInfo
;
26 using net::SSLClientCertType
;
27 using net::X509Certificate
;
28 using testing::NotNull
;
31 namespace android_webview
{
35 // Tests the android_webview contents client bridge.
36 class AwContentsClientBridgeTest
: public Test
{
38 AwContentsClientBridgeTest() { }
40 // Callback method called when a cert is selected.
41 void CertSelected(X509Certificate
* cert
);
43 void SetUp() override
;
44 void TestCertType(SSLClientCertType type
, const std::string
& expected_name
);
45 // Create the TestBrowserThreads. Just instantiate the member variable.
46 content::TestBrowserThreadBundle thread_bundle_
;
47 base::android::ScopedJavaGlobalRef
<jobject
> jbridge_
;
48 scoped_ptr
<AwContentsClientBridge
> bridge_
;
49 scoped_refptr
<SSLCertRequestInfo
> cert_request_info_
;
50 X509Certificate
* selected_cert_
;
51 int cert_selected_callbacks_
;
55 class TestClientCertificateDelegate
56 : public content::ClientCertificateDelegate
{
58 explicit TestClientCertificateDelegate(AwContentsClientBridgeTest
* test
)
61 // content::ClientCertificateDelegate.
62 void ContinueWithCertificate(net::X509Certificate
* cert
) override
{
63 test_
->CertSelected(cert
);
68 AwContentsClientBridgeTest
* test_
;
70 DISALLOW_COPY_AND_ASSIGN(TestClientCertificateDelegate
);
75 void AwContentsClientBridgeTest::SetUp() {
76 env_
= AttachCurrentThread();
77 ASSERT_THAT(env_
, NotNull());
78 ASSERT_TRUE(android_webview::RegisterAwContentsClientBridge(env_
));
79 ASSERT_TRUE(RegisterNativesImpl(env_
));
80 ASSERT_TRUE(net::android::RegisterJni(env_
));
82 Java_MockAwContentsClientBridge_getAwContentsClientBridge(env_
).obj());
83 bridge_
.reset(new AwContentsClientBridge(env_
, jbridge_
.obj()));
84 selected_cert_
= NULL
;
85 cert_selected_callbacks_
= 0;
86 cert_request_info_
= new net::SSLCertRequestInfo
;
89 void AwContentsClientBridgeTest::CertSelected(X509Certificate
* cert
) {
90 selected_cert_
= cert
;
91 cert_selected_callbacks_
++;
94 TEST_F(AwContentsClientBridgeTest
, TestClientCertKeyTypesCorrectlyEncoded
) {
95 SSLClientCertType cert_types
[3] = {net::CLIENT_CERT_RSA_SIGN
,
96 net::CLIENT_CERT_DSS_SIGN
, net::CLIENT_CERT_ECDSA_SIGN
};
97 std::string expected_names
[3] = {"RSA", "DSA" ,"ECDSA"};
99 for(int i
= 0; i
< 3; i
++) {
100 TestCertType(cert_types
[i
], expected_names
[i
]);
104 void AwContentsClientBridgeTest::TestCertType(SSLClientCertType type
,
105 const std::string
& expected_name
) {
106 cert_request_info_
->cert_key_types
.clear();
107 cert_request_info_
->cert_key_types
.push_back(type
);
108 bridge_
->SelectClientCertificate(
109 cert_request_info_
.get(),
110 make_scoped_ptr(new TestClientCertificateDelegate(this)));
111 base::RunLoop().RunUntilIdle();
112 EXPECT_EQ(0, cert_selected_callbacks_
);
113 ScopedJavaLocalRef
<jobjectArray
> key_types
=
114 Java_MockAwContentsClientBridge_getKeyTypes(env_
, jbridge_
.obj());
115 std::vector
<std::string
> vec
;
116 base::android::AppendJavaStringArrayToStringVector(env_
,
119 EXPECT_EQ(1u, vec
.size());
120 EXPECT_EQ(expected_name
, vec
[0]);
123 // Verify that ProvideClientCertificateResponse works properly when the client
124 // responds with a null key.
125 TEST_F(AwContentsClientBridgeTest
,
126 TestProvideClientCertificateResponseCallsCallbackOnNullKey
) {
127 // Call SelectClientCertificate to create a callback id that mock java object
129 bridge_
->SelectClientCertificate(
130 cert_request_info_
.get(),
131 make_scoped_ptr(new TestClientCertificateDelegate(this)));
132 bridge_
->ProvideClientCertificateResponse(env_
, jbridge_
.obj(),
133 Java_MockAwContentsClientBridge_getRequestId(env_
, jbridge_
.obj()),
134 Java_MockAwContentsClientBridge_createTestCertChain(
135 env_
, jbridge_
.obj()).obj(),
137 base::RunLoop().RunUntilIdle();
138 EXPECT_EQ(NULL
, selected_cert_
);
139 EXPECT_EQ(1, cert_selected_callbacks_
);
142 // Verify that ProvideClientCertificateResponse calls the callback with
143 // NULL parameters when private key is not provided.
144 TEST_F(AwContentsClientBridgeTest
,
145 TestProvideClientCertificateResponseCallsCallbackOnNullChain
) {
146 // Call SelectClientCertificate to create a callback id that mock java object
148 bridge_
->SelectClientCertificate(
149 cert_request_info_
.get(),
150 make_scoped_ptr(new TestClientCertificateDelegate(this)));
152 Java_MockAwContentsClientBridge_getRequestId(env_
, jbridge_
.obj());
153 bridge_
->ProvideClientCertificateResponse(env_
, jbridge_
.obj(),
156 Java_MockAwContentsClientBridge_createTestPrivateKey(
157 env_
, jbridge_
.obj()).obj());
158 base::RunLoop().RunUntilIdle();
159 EXPECT_EQ(NULL
, selected_cert_
);
160 EXPECT_EQ(1, cert_selected_callbacks_
);