13e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom/* 23e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Copyright (C) 2011 The Android Open Source Project 33e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * 43e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 53e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * you may not use this file except in compliance with the License. 63e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * You may obtain a copy of the License at 73e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * 83e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 93e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * 103e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 113e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 123e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * See the License for the specific language governing permissions and 143e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * limitations under the License. 153e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom */ 163e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 173e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrompackage com.android.keychain.tests; 183e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 193e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.app.Activity; 203e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.content.Intent; 213e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.os.AsyncTask; 223e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.os.Bundle; 2365e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstromimport android.os.StrictMode; 243e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.security.KeyChain; 25f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstromimport android.security.KeyChainAliasCallback; 26f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstromimport android.security.KeyChainException; 273e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.text.method.ScrollingMovementMethod; 283e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.util.Log; 293e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.widget.TextView; 303e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.net.Socket; 313e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.net.URL; 323e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.security.KeyStore; 333e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.security.Principal; 343e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.security.PrivateKey; 353e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.security.cert.CertificateException; 363e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport java.security.cert.X509Certificate; 373e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.HttpsURLConnection; 383e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.KeyManager; 393e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.KeyManagerFactory; 403e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.SSLContext; 413e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.SSLSocketFactory; 423e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.TrustManager; 433e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.X509ExtendedKeyManager; 443e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport javax.net.ssl.X509TrustManager; 453e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport libcore.java.security.TestKeyStore; 463e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport libcore.javax.net.ssl.TestSSLContext; 47b56adc2162cecde6e6aa6561ad873bca29426d2fJesse Wilsonimport com.google.mockwebserver.MockResponse; 48b56adc2162cecde6e6aa6561ad873bca29426d2fJesse Wilsonimport com.google.mockwebserver.MockWebServer; 493e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 503e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom/** 513e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom * Simple activity based test that exercises the KeyChain API 523e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom */ 533e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrompublic class KeyChainTestActivity extends Activity { 543e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 553e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private static final String TAG = "KeyChainTestActivity"; 563e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 578be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private static final int REQUEST_CA_INSTALL = 1; 583e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 593e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private TextView mTextView; 603e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 6165e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom private TestKeyStore mTestKeyStore; 623e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 633e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private final Object mAliasLock = new Object(); 643e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private String mAlias; 653e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 663e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private final Object mGrantedLock = new Object(); 673e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private boolean mGranted; 683e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 693e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private void log(final String message) { 703e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom Log.d(TAG, message); 713e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom runOnUiThread(new Runnable() { 723e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public void run() { 733e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom mTextView.append(message + "\n"); 743e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 753e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom }); 763e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 773e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 783e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public void onCreate(Bundle savedInstanceState) { 793e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom super.onCreate(savedInstanceState); 803e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 8165e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 8265e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .detectDiskReads() 8365e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .detectDiskWrites() 8465e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .detectAll() 8565e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .penaltyLog() 8665e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .penaltyDeath() 8765e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .build()); 8865e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 8965e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .detectLeakedSqlLiteObjects() 9065e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .detectLeakedClosableObjects() 9165e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .penaltyLog() 9265e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .penaltyDeath() 9365e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom .build()); 9465e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom 953e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom mTextView = new TextView(this); 963e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom mTextView.setMovementMethod(new ScrollingMovementMethod()); 973e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom setContentView(mTextView); 983e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 993e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom log("Starting test..."); 1008be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom testKeyChainImproperUse(); 1013e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 10265e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom new SetupTestKeyStore().execute(); 1038be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 1048be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom 1058be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private void testKeyChainImproperUse() { 1063e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom try { 107bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom KeyChain.getPrivateKey(null, null); 1083e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throw new AssertionError(); 1093e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } catch (InterruptedException e) { 1105aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 111f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 1125aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 1135aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (NullPointerException expected) { 1145aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("KeyChain failed as expected with null argument."); 1155aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } 1165aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom 1175aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom try { 118bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom KeyChain.getPrivateKey(this, null); 1195aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(); 1205aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (InterruptedException e) { 1215aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 122f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 1235aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 1245aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (NullPointerException expected) { 1255aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("KeyChain failed as expected with null argument."); 1265aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } 1275aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom 1285aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom try { 129bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom KeyChain.getPrivateKey(null, ""); 1305aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(); 1315aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (InterruptedException e) { 1325aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 133f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 1345aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 1355aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (NullPointerException expected) { 1365aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("KeyChain failed as expected with null argument."); 1375aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } 1385aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom 1395aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom try { 140bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom KeyChain.getPrivateKey(this, ""); 1415aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(); 1425aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (InterruptedException e) { 1435aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 144f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 1455aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new AssertionError(e); 1463e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } catch (IllegalStateException expected) { 1473e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom log("KeyChain failed as expected on main thread."); 1483e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 1498be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 1503e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 15165e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom private class SetupTestKeyStore extends AsyncTask<Void, Void, Void> { 15265e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom @Override protected Void doInBackground(Void... params) { 15365e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom mTestKeyStore = TestKeyStore.getServer(); 15465e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom return null; 15565e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom } 15665e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom @Override protected void onPostExecute(Void result) { 15765e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom testCaInstall(); 15865e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom } 15965e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom } 16065e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom 1618be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private void testCaInstall() { 1628be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom try { 1638be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("Requesting install of server's CA..."); 16465e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom X509Certificate ca = mTestKeyStore.getRootCertificate("RSA"); 1658dde66b240e5777c3c831767914e9ef773384aacBrian Carlstrom Intent intent = KeyChain.createInstallIntent(); 1668dde66b240e5777c3c831767914e9ef773384aacBrian Carlstrom intent.putExtra(KeyChain.EXTRA_NAME, TAG); 1678dde66b240e5777c3c831767914e9ef773384aacBrian Carlstrom intent.putExtra(KeyChain.EXTRA_CERTIFICATE, ca.getEncoded()); 1688be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom startActivityForResult(intent, REQUEST_CA_INSTALL); 1698be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } catch (Exception e) { 1708be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom throw new AssertionError(e); 1718be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 1723e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 1733e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 1743e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 1758be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private class TestHttpsRequest extends AsyncTask<Void, Void, Void> { 1768be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom @Override protected Void doInBackground(Void... params) { 1778be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom try { 1788be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("Starting web server..."); 1798be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom URL url = startWebServer(); 1808be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("Making https request to " + url); 1818be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom makeHttpsRequest(url); 1828be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("Tests succeeded."); 1838be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom 1848be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom return null; 1858be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } catch (Exception e) { 1868be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom throw new AssertionError(e); 1878be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 1888be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 1898be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private URL startWebServer() throws Exception { 19065e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom KeyStore serverKeyStore = mTestKeyStore.keyStore; 19165e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom char[] serverKeyStorePassword = mTestKeyStore.storePassword; 1928be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom String kmfAlgoritm = KeyManagerFactory.getDefaultAlgorithm(); 1938be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgoritm); 1948be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom kmf.init(serverKeyStore, serverKeyStorePassword); 1958be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom SSLContext serverContext = SSLContext.getInstance("SSL"); 1968be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom serverContext.init(kmf.getKeyManagers(), 1978be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom new TrustManager[] { new TrustAllTrustManager() }, 1988be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom null); 1998be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom SSLSocketFactory sf = serverContext.getSocketFactory(); 2008be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom SSLSocketFactory needClientAuth = TestSSLContext.clientAuth(sf, false, true); 2018be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom MockWebServer server = new MockWebServer(); 2028be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom server.useHttps(needClientAuth, false); 2038be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom server.enqueue(new MockResponse().setBody("this response comes via HTTPS")); 2048be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom server.play(); 2058be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom return server.getUrl("/"); 2068be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 2078be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom private void makeHttpsRequest(URL url) throws Exception { 2088be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom SSLContext clientContext = SSLContext.getInstance("SSL"); 2098be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom clientContext.init(new KeyManager[] { new KeyChainKeyManager() }, null, null); 2108be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 2118be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom connection.setSSLSocketFactory(clientContext.getSocketFactory()); 2128be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom if (connection.getResponseCode() != 200) { 2138be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom throw new AssertionError(); 2143e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2153e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2163e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2173e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 2183e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private class KeyChainKeyManager extends X509ExtendedKeyManager { 2193e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public String chooseClientAlias(String[] keyTypes, 2203e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom Principal[] issuers, 2213e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom Socket socket) { 2223e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom log("KeyChainKeyManager chooseClientAlias..."); 2233e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 224f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom KeyChain.choosePrivateKeyAlias(KeyChainTestActivity.this, new AliasResponse(), 22565e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom keyTypes, issuers, 22665e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom socket.getInetAddress().getHostName(), socket.getPort(), 22765e649e856d88520ac04f5b16313a3f167e569e0Brian Carlstrom "My Test Certificate"); 2283e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom String alias; 2293e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom synchronized (mAliasLock) { 2303e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom while (mAlias == null) { 2313e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom try { 2323e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom mAliasLock.wait(); 2333e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } catch (InterruptedException ignored) { 2343e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2353e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2363e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom alias = mAlias; 2373e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2383e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom return alias; 2393e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2403e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public String chooseServerAlias(String keyType, 2413e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom Principal[] issuers, 2423e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom Socket socket) { 2433e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom // not a client SSLSocket callback 2443e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throw new UnsupportedOperationException(); 2453e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2463e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public X509Certificate[] getCertificateChain(String alias) { 2475aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom try { 2485aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("KeyChainKeyManager getCertificateChain..."); 249bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom X509Certificate[] certificateChain 250bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom = KeyChain.getCertificateChain(KeyChainTestActivity.this, alias); 251bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom if (certificateChain == null) { 252bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom log("Null certificate chain!"); 253bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom return null; 2545aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } 255aa14e89b1194c4d4054fcd8dbd0af9d08dd5715cBrian Carlstrom for (int i = 0; i < certificateChain.length; i++) { 256aa14e89b1194c4d4054fcd8dbd0af9d08dd5715cBrian Carlstrom log("certificate[" + i + "]=" + certificateChain[i]); 257aa14e89b1194c4d4054fcd8dbd0af9d08dd5715cBrian Carlstrom } 258bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom return certificateChain; 2595aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (InterruptedException e) { 2605aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom Thread.currentThread().interrupt(); 2615aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom return null; 262f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 2635aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new RuntimeException(e); 2643e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2653e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2663e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public String[] getClientAliases(String keyType, Principal[] issuers) { 2673e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom // not a client SSLSocket callback 2683e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throw new UnsupportedOperationException(); 2693e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2703e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public String[] getServerAliases(String keyType, Principal[] issuers) { 2713e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom // not a client SSLSocket callback 2723e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throw new UnsupportedOperationException(); 2733e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2743e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public PrivateKey getPrivateKey(String alias) { 2755aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom try { 2765aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("KeyChainKeyManager getPrivateKey..."); 277bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom PrivateKey privateKey = KeyChain.getPrivateKey(KeyChainTestActivity.this, 278bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom alias); 2795aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom log("privateKey=" + privateKey); 2805aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom return privateKey; 2815aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom } catch (InterruptedException e) { 2825aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom Thread.currentThread().interrupt(); 2835aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom return null; 284f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom } catch (KeyChainException e) { 2855aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom throw new RuntimeException(e); 2863e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2873e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2883e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 2893e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 290f5b50a4678120890d62bb07bb47cbd3f1ba4b243Brian Carlstrom private class AliasResponse implements KeyChainAliasCallback { 291bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom @Override public void alias(String alias) { 292bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom if (alias == null) { 293bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom log("AliasResponse empty!"); 294bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom log("Do you need to install some client certs with:"); 295bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom log(" adb shell am startservice -n " 296bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom + "com.android.keychain.tests/.KeyChainServiceTest"); 297bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom return; 298bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom } 299bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom log("Alias choosen '" + alias + "'"); 300bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom synchronized (mAliasLock) { 301bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom mAlias = alias; 302bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom mAliasLock.notifyAll(); 3038be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 3048be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 3058be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 3068be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom 3073e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom private static class TrustAllTrustManager implements X509TrustManager { 3083e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public void checkClientTrusted(X509Certificate[] chain, String authType) 3093e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throws CertificateException { 3103e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3113e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public void checkServerTrusted(X509Certificate[] chain, String authType) 3123e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throws CertificateException { 3133e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3143e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override public X509Certificate[] getAcceptedIssuers() { 3153e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom return null; 3163e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3173e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3183e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom 3193e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3203e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom switch (requestCode) { 3218be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom case REQUEST_CA_INSTALL: { 3228be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("onActivityResult REQUEST_CA_INSTALL..."); 3238be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom if (resultCode != RESULT_OK) { 3248be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom log("REQUEST_CA_INSTALL failed!"); 3258be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom return; 3268be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 3278be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom new TestHttpsRequest().execute(); 3288be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom break; 3298be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom } 3303e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom default: 3313e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom throw new IllegalStateException("requestCode == " + requestCode); 3323e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3333e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom } 3343e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom} 335