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