KeyChainTestActivity.java revision b56adc2162cecde6e6aa6561ad873bca29426d2f
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;
235aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstromimport android.os.RemoteException;
248be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstromimport android.security.Credentials;
253e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstromimport android.security.KeyChain;
26bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstromimport android.security.KeyChainAliasResponse;
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
613e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    private KeyChain mKeyChain;
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
813e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        mTextView = new TextView(this);
823e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        mTextView.setMovementMethod(new ScrollingMovementMethod());
833e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        setContentView(mTextView);
843e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
853e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        log("Starting test...");
868be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        testKeyChainImproperUse();
873e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
888be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        testCaInstall();
898be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    }
908be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom
918be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    private void testKeyChainImproperUse() {
923e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        try {
93bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            KeyChain.getPrivateKey(null, null);
943e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            throw new AssertionError();
953e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        } catch (InterruptedException e) {
965aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
975aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (RemoteException e) {
985aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
995aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (NullPointerException expected) {
1005aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            log("KeyChain failed as expected with null argument.");
1015aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        }
1025aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom
1035aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        try {
104bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            KeyChain.getPrivateKey(this, null);
1055aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError();
1065aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (InterruptedException e) {
1075aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1085aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (RemoteException e) {
1095aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1105aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (NullPointerException expected) {
1115aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            log("KeyChain failed as expected with null argument.");
1125aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        }
1135aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom
1145aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        try {
115bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            KeyChain.getPrivateKey(null, "");
1165aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError();
1175aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (InterruptedException e) {
1185aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1195aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (RemoteException e) {
1205aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1215aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (NullPointerException expected) {
1225aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            log("KeyChain failed as expected with null argument.");
1235aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        }
1245aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom
1255aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        try {
126bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            KeyChain.getPrivateKey(this, "");
1275aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError();
1285aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (InterruptedException e) {
1295aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1305aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom        } catch (RemoteException e) {
1315aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            throw new AssertionError(e);
1323e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        } catch (IllegalStateException expected) {
1333e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            log("KeyChain failed as expected on main thread.");
1343e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
1358be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    }
1363e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
1378be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    private void testCaInstall() {
1388be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        try {
1398be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            log("Requesting install of server's CA...");
1408be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            X509Certificate ca = TestKeyStore.getServer().getRootCertificate("RSA");
1418be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            Intent intent = new Intent("android.credentials.INSTALL");
1428be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            intent.putExtra("name", TAG); // "name" = CredentialHelper.CERT_NAME_KEY
143cf8dab6d84729b567b9f373e8f5dec5a4f46b0b3Brian Carlstrom            intent.putExtra(Credentials.CERTIFICATE, Credentials.convertToPem(ca));
1448be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            startActivityForResult(intent, REQUEST_CA_INSTALL);
1458be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        } catch (Exception e) {
1468be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            throw new AssertionError(e);
1478be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        }
1483e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
1493e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
1503e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
1518be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    private class TestHttpsRequest extends AsyncTask<Void, Void, Void> {
1528be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        @Override protected Void doInBackground(Void... params) {
1538be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            try {
1548be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                log("Starting web server...");
1558be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                URL url = startWebServer();
1568be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                log("Making https request to " + url);
1578be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                makeHttpsRequest(url);
1588be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                log("Tests succeeded.");
1598be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom
1608be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                return null;
1618be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            } catch (Exception e) {
1628be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                throw new AssertionError(e);
1638be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            }
1648be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        }
1658be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        private URL startWebServer() throws Exception {
1668be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            KeyStore serverKeyStore = TestKeyStore.getServer().keyStore;
1678be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            char[] serverKeyStorePassword = TestKeyStore.getServer().storePassword;
1688be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            String kmfAlgoritm = KeyManagerFactory.getDefaultAlgorithm();
1698be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgoritm);
1708be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            kmf.init(serverKeyStore, serverKeyStorePassword);
1718be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            SSLContext serverContext = SSLContext.getInstance("SSL");
1728be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            serverContext.init(kmf.getKeyManagers(),
1738be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                               new TrustManager[] { new TrustAllTrustManager() },
1748be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                               null);
1758be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            SSLSocketFactory sf = serverContext.getSocketFactory();
1768be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            SSLSocketFactory needClientAuth = TestSSLContext.clientAuth(sf, false, true);
1778be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            MockWebServer server = new MockWebServer();
1788be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            server.useHttps(needClientAuth, false);
1798be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
1808be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            server.play();
1818be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            return server.getUrl("/");
1828be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        }
1838be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        private void makeHttpsRequest(URL url) throws Exception {
1848be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            SSLContext clientContext = SSLContext.getInstance("SSL");
1858be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            clientContext.init(new KeyManager[] { new KeyChainKeyManager() }, null, null);
1868be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
1878be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            connection.setSSLSocketFactory(clientContext.getSocketFactory());
1888be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            if (connection.getResponseCode() != 200) {
1898be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                throw new AssertionError();
1903e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            }
1913e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
1923e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
1933e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
1943e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    private class KeyChainKeyManager extends X509ExtendedKeyManager {
1953e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public String chooseClientAlias(String[] keyTypes,
1963e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                                                  Principal[] issuers,
1973e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                                                  Socket socket) {
1983e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            log("KeyChainKeyManager chooseClientAlias...");
1993e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
200bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            KeyChain.choosePrivateKeyAlias(KeyChainTestActivity.this, new AliasResponse());
2013e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            String alias;
2023e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            synchronized (mAliasLock) {
2033e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                while (mAlias == null) {
2043e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                    try {
2053e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                        mAliasLock.wait();
2063e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                    } catch (InterruptedException ignored) {
2073e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                    }
2083e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                }
2093e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                alias = mAlias;
2103e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            }
2113e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            return alias;
2123e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2133e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public String chooseServerAlias(String keyType,
2143e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                                                  Principal[] issuers,
2153e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                                                  Socket socket) {
2163e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            // not a client SSLSocket callback
2173e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            throw new UnsupportedOperationException();
2183e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2193e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public X509Certificate[] getCertificateChain(String alias) {
2205aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            try {
2215aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                log("KeyChainKeyManager getCertificateChain...");
222bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                X509Certificate[] certificateChain
223bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                        = KeyChain.getCertificateChain(KeyChainTestActivity.this, alias);
224bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                if (certificateChain == null) {
225bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                    log("Null certificate chain!");
226bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                    return null;
2275aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                }
228bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                log("certificate=" + certificateChain[0]);
229bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                return certificateChain;
2305aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            } catch (InterruptedException e) {
2315aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                Thread.currentThread().interrupt();
2325aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                return null;
2335aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            } catch (RemoteException e) {
2345aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                throw new RuntimeException(e);
2353e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            }
2363e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2373e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public String[] getClientAliases(String keyType, Principal[] issuers) {
2383e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            // not a client SSLSocket callback
2393e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            throw new UnsupportedOperationException();
2403e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2413e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public String[] getServerAliases(String keyType, Principal[] issuers) {
2423e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            // not a client SSLSocket callback
2433e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            throw new UnsupportedOperationException();
2443e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2453e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public PrivateKey getPrivateKey(String alias) {
2465aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            try {
2475aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                log("KeyChainKeyManager getPrivateKey...");
248bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                PrivateKey privateKey = KeyChain.getPrivateKey(KeyChainTestActivity.this,
249bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                                                                         alias);
2505aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                log("privateKey=" + privateKey);
2515aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                return privateKey;
2525aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            } catch (InterruptedException e) {
2535aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                Thread.currentThread().interrupt();
2545aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                return null;
2555aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom            } catch (RemoteException e) {
2565aeadd9be22ea51ea2d638f7090618448ecc8ac7Brian Carlstrom                throw new RuntimeException(e);
2573e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            }
2583e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2593e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
2603e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
261bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom    private class AliasResponse implements KeyChainAliasResponse {
262bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom        @Override public void alias(String alias) {
263bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            if (alias == null) {
264bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                log("AliasResponse empty!");
265bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                log("Do you need to install some client certs with:");
266bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                log("    adb shell am startservice -n "
267bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                    + "com.android.keychain.tests/.KeyChainServiceTest");
268bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                return;
269bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            }
270bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            log("Alias choosen '" + alias + "'");
271bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom            synchronized (mAliasLock) {
272bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                mAlias = alias;
273bb04f703be50794c41e453e82c70e354a545ea54Brian Carlstrom                mAliasLock.notifyAll();
2748be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            }
2758be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom        }
2768be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom    }
2778be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom
2783e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    private static class TrustAllTrustManager implements X509TrustManager {
2793e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
2803e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                throws CertificateException {
2813e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2823e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
2833e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                throws CertificateException {
2843e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2853e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        @Override public X509Certificate[] getAcceptedIssuers() {
2863e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            return null;
2873e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
2883e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
2893e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom
2903e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
2913e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        switch (requestCode) {
2928be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            case REQUEST_CA_INSTALL: {
2938be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                log("onActivityResult REQUEST_CA_INSTALL...");
2948be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                if (resultCode != RESULT_OK) {
2958be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                    log("REQUEST_CA_INSTALL failed!");
2968be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                    return;
2978be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                }
2988be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                new TestHttpsRequest().execute();
2998be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom                break;
3008be0660196926b8f0a571f218711cf1b34fbaba2Brian Carlstrom            }
3013e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom            default:
3023e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom                throw new IllegalStateException("requestCode == " + requestCode);
3033e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom        }
3043e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom    }
3053e6251dedc92654476c70bdc413f24a4b31ce6a4Brian Carlstrom}
306