/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.core;

import junit.framework.TestCase;

import org.apache.commons.codec.binary.Base64;
import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
import org.apache.harmony.xnet.provider.jsse.FileClientSessionCache;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.KeyManagementException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * SSL integration tests that hit real servers.
 */
public class SSLSocketTest extends TestCase {

    private static SSLSocketFactory clientFactory =
            (SSLSocketFactory) SSLSocketFactory.getDefault();

    /**
     * Does a number of HTTPS requests on some host and consumes the response.
     * We don't use the HttpsUrlConnection class, but do this on our own
     * with the SSLSocket class. This gives us a chance to test the basic
     * behavior of SSL.
     *
     * @param host      The host name the request is being sent to.
     * @param port      The port the request is being sent to.
     * @param path      The path being requested (e.g. "/index.html").
     * @param outerLoop The number of times we reconnect and do the request.
     * @param innerLoop The number of times we do the request for each
     *                  connection (using HTTP keep-alive).
     * @param delay     The delay after each request (in seconds).
     * @throws IOException When a problem occurs.
     */
    private void fetch(SSLSocketFactory socketFactory, String host, int port,
            boolean secure, String path, int outerLoop, int innerLoop,
            int delay, int timeout) throws IOException {
        InetSocketAddress address = new InetSocketAddress(host, port);

        for (int i = 0; i < outerLoop; i++) {
            // Connect to the remote host
            Socket socket = secure ? socketFactory.createSocket()
                    : new Socket();
            if (timeout >= 0) {
                socket.setKeepAlive(true);
                socket.setSoTimeout(timeout * 1000);
            }
            socket.connect(address);

            // Get the streams
            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output);

            try {
                DataInputStream input = new DataInputStream(socket.getInputStream());
                try {
                    for (int j = 0; j < innerLoop; j++) {
                        android.util.Log.d("SSLSocketTest",
                                "GET https://" + host + path + " HTTP/1.1");

                        // Send a request
                        writer.println("GET https://" + host + path + " HTTP/1.1\r");
                        writer.println("Host: " + host + "\r");
                        writer.println("Connection: " +
                                (j == innerLoop - 1 ? "Close" : "Keep-Alive")
                                + "\r");
                        writer.println("\r");
                        writer.flush();

                        int length = -1;
                        boolean chunked = false;

                        String line = input.readLine();

                        if (line == null) {
                            throw new IOException("No response from server");
                            // android.util.Log.d("SSLSocketTest", "No response from server");
                        }

                        // Consume the headers, check content length and encoding type
                        while (line != null && line.length() != 0) {
//                    System.out.println(line);
                            int dot = line.indexOf(':');
                            if (dot != -1) {
                                String key = line.substring(0, dot).trim();
                                String value = line.substring(dot + 1).trim();

                                if ("Content-Length".equalsIgnoreCase(key)) {
                                    length = Integer.valueOf(value);
                                } else if ("Transfer-Encoding".equalsIgnoreCase(key)) {
                                    chunked = "Chunked".equalsIgnoreCase(value);
                                }

                            }
                            line = input.readLine();
                        }

                        assertTrue("Need either content length or chunked encoding", length != -1
                                || chunked);

                        // Consume the content itself
                        if (chunked) {
                            length = Integer.parseInt(input.readLine(), 16);
                            while (length != 0) {
                                byte[] buffer = new byte[length];
                                input.readFully(buffer);
                                input.readLine();
                                length = Integer.parseInt(input.readLine(), 16);
                            }
                            input.readLine();
                        } else {
                            byte[] buffer = new byte[length];
                            input.readFully(buffer);
                        }

                        // Sleep for the given number of seconds
                        try {
                            Thread.sleep(delay * 1000);
                        } catch (InterruptedException ex) {
                            // Shut up!
                        }
                    }
                } finally {
                    input.close();
                }
            } finally {
                writer.close();
            }
            // Close the connection
            socket.close();
        }
    }

    /**
     * Invokes fetch() with the default socket factory.
     */
    private void fetch(String host, int port, boolean secure, String path,
            int outerLoop, int innerLoop,
            int delay, int timeout) throws IOException {
        fetch(clientFactory, host, port, secure, path, outerLoop, innerLoop,
                delay, timeout);
    }

    /**
     * Does a single request for each of the hosts. Consumes the response.
     *
     * @throws IOException If a problem occurs.
     */
    public void testSimple() throws IOException {
        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 1, 0, 60);
        fetch("mail.google.com", 443, true, "/mail/", 1, 1, 0, 60);
        fetch("www.paypal.com", 443, true, "/", 1, 1, 0, 60);
        fetch("www.yellownet.ch", 443, true, "/", 1, 1, 0, 60);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * closed in between.
     *
     * @throws IOException If a problem occurs.
     */
    public void testRepeatedClose() throws IOException {
        fetch("www.fortify.net", 443, true, "/sslcheck.html", 10, 1, 0, 60);
        fetch("mail.google.com", 443, true, "/mail/", 10, 1, 0, 60);
        fetch("www.paypal.com", 443, true, "/", 10, 1, 0, 60);
        fetch("www.yellownet.ch", 443, true, "/", 10, 1, 0, 60);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * kept alive in between.
     *
     * @throws IOException If a problem occurs.
     */
    public void testRepeatedKeepAlive() throws IOException {
        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 10, 0, 60);
        fetch("mail.google.com", 443, true, "/mail/", 1, 10, 0, 60);

        // These two don't accept keep-alive
        // fetch("www.paypal.com", 443, "/", 1, 10);
        // fetch("www.yellownet.ch", 443, "/", 1, 10);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * closed in between. Waits a couple of seconds after each request, but
     * stays within a reasonable timeout. Expectation is that the connection
     * stays open.
     *
     * @throws IOException If a problem occurs.
     */
    public void testShortTimeout() throws IOException {
        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 10, 5, 60);
        fetch("mail.google.com", 443, true, "/mail/", 1, 10, 5, 60);

        // These two don't accept keep-alive
        // fetch("www.paypal.com", 443, "/", 1, 10);
        // fetch("www.yellownet.ch", 443, "/", 1, 10);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * kept alive in between. Waits a longer time after each request.
     * Expectation is that the host closes the connection.
     */
    public void testLongTimeout() {
        // Seems to have a veeeery long timeout.
        // fetch("www.fortify.net", 443, "/sslcheck.html", 1, 2, 60);

        // Google has a 60s timeout, so 90s of waiting should trigger it.
        try {
            fetch("mail.google.com", 443, true, "/mail/", 1, 2, 90, 180);
            fail("Oops - timeout expected.");
        } catch (IOException ex) {
            // Expected.
        }

        // These two don't accept keep-alive
        // fetch("www.paypal.com", 443, "/", 1, 10);
        // fetch("www.yellownet.ch", 443, "/", 1, 10);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * closed in between. Waits a longer time after each request. Expectation is
     * that the host closes the connection.
     */
    // These two need manual interaction to reproduce...
    public void xxtestBrokenConnection() {
        try {
            fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 2, 60, 60);
            fail("Oops - timeout expected.");
        } catch (IOException ex) {
            android.util.Log.d("SSLSocketTest", "Exception", ex);
            // Expected.
        }

        // These two don't accept keep-alive
        // fetch("www.paypal.com", 443, "/", 1, 10);
        // fetch("www.yellownet.ch", 443, "/", 1, 10);
    }

    /**
     * Does repeated requests for each of the hosts, with the connection being
     * closed in between. Waits a longer time after each request. Expectation is
     * that the host closes the connection.
     */
    // These two need manual interaction to reproduce...
    public void xxtestBrokenConnection2() {
        try {
            fetch("www.heise.de", 80, false, "/index.html", 1, 2, 60, 60);
            fail("Oops - timeout expected.");
        } catch (IOException ex) {
            android.util.Log.d("SSLSocketTest", "Exception", ex);
            // Expected.
        }

        // These two don't accept keep-alive
        // fetch("www.paypal.com", 443, "/", 1, 10);
        // fetch("www.yellownet.ch", 443, "/", 1, 10);
    }

    /**
     * Regression test for 865926: SSLContext.init() should
     * use default values for null arguments.
     */
    public void testContextInitNullArgs() throws Exception {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, null, null);
    }

    /**
     * Regression test for 963650: javax.net.ssl.KeyManager has no implemented
     * (documented?) algorithms.
     */
    public void testDefaultAlgorithms() throws Exception {
            SSLContext ctx = SSLContext.getInstance("TLS");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
            KeyStore ks = KeyStore.getInstance("BKS");

            assertEquals("X509", kmf.getAlgorithm());
            assertEquals("X509", KeyManagerFactory.getDefaultAlgorithm());

            assertEquals("BKS", ks.getType());
            assertEquals("BKS", KeyStore.getDefaultType());
    }

    /**
     * Regression test for problem where close() resulted in a hand if
     * a different thread was sitting in a blocking read or write.
     */
    public void testMultithreadedClose() throws Exception {
            InetSocketAddress address = new InetSocketAddress("www.fortify.net", 443);
            final Socket socket = clientFactory.createSocket();
            socket.connect(address);

            Thread reader = new Thread() {
                @Override
                public void run() {
                    try {
                        byte[] buffer = new byte[512];
                        InputStream stream = socket.getInputStream();
                        socket.getInputStream().read(buffer);
                    } catch (Exception ex) {
                        android.util.Log.d("SSLSocketTest",
                                "testMultithreadedClose() reader got " + ex.toString());
                    }
                }
            };

            Thread closer = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(5000);
                        socket.close();
                    } catch (Exception ex) {
                        android.util.Log.d("SSLSocketTest",
                                "testMultithreadedClose() closer got " + ex.toString());
                    }
                }
            };

            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() starting reader...");
            reader.start();
            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() starting closer...");
            closer.start();

            long t1 = System.currentTimeMillis();
            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() joining reader...");
            reader.join(30000);
            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() joining closer...");
            closer.join(30000);
            long t2 = System.currentTimeMillis();

            assertTrue("Concurrent close() hangs", t2 - t1 < 30000);
    }

    private int multithreadedFetchRuns;

    private int multithreadedFetchWins;

    private Random multithreadedFetchRandom = new Random();

    /**
     * Regression test for problem where multiple threads with multiple SSL
     * connection would cause problems due to either missing native locking
     * or the slowness of the SSL connections.
     */
    public void testMultithreadedFetch() {
        Thread[] threads = new Thread[10];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        try {
                            multithreadedFetchRuns++;
                            switch (multithreadedFetchRandom.nextInt(4)) {
                                case 0: {
                                    fetch("www.fortify.net", 443,
                                            true, "/sslcheck.html", 1, 1, 0, 60);
                                    break;
                                }

                                case 1: {
                                    fetch("mail.google.com", 443, true, "/mail/", 1, 1, 0, 60);
                                    break;
                                }

                                case 2: {
                                    fetch("www.paypal.com", 443, true, "/", 1, 1, 0, 60);
                                    break;
                                }

                                case 3: {
                                    fetch("www.yellownet.ch", 443, true, "/", 1, 1, 0, 60);
                                    break;
                                }
                            }
                            multithreadedFetchWins++;
                        } catch (Exception ex) {
                            android.util.Log.d("SSLSocketTest",
                                    "testMultithreadedFetch() got Exception", ex);
                        }
                    }
                }
            };
            threads[i].start();

            android.util.Log.d("SSLSocketTest", "testMultithreadedFetch() started thread #" + i);
        }

        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
                android.util.Log.d("SSLSocketTest", "testMultithreadedFetch() joined thread #" + i);
            } catch (InterruptedException ex) {
                // Not interested.
            }
        }

        assertTrue("At least 95% of multithreaded SSL connections must succeed",
                multithreadedFetchWins >= (multithreadedFetchRuns * 95) / 100);
    }

    // -------------------------------------------------------------------------
    // Regression test for #1204316: Missing client cert unit test. Passes on
    // both Android and the RI. To use on the RI, install Apache Commons and
    // replace the references to the base64-encoded keys by the JKS versions.
    // -------------------------------------------------------------------------
    
    /** 
     * Defines the keystore contents for the server, JKS version. Holds just a
     * single self-generated key. The subject name is "Test Server".
     */
    private static final String SERVER_KEYS_JKS = 
        "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";

    /** 
     * Defines the keystore contents for the server, BKS version. Holds just a
     * single self-generated key. The subject name is "Test Server".
     */
    private static final String SERVER_KEYS_BKS = 
        "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";
    
    /** 
     * Defines the keystore contents for the client, JKS version. Holds just a
     * single self-generated key. The subject name is "Test Client".
     */
    private static final String CLIENT_KEYS_JKS = 
        "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";

    /** 
     * Defines the keystore contents for the client, BKS version. Holds just a
     * single self-generated key. The subject name is "Test Client".
     */
    private static final String CLIENT_KEYS_BKS = 
        "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41" +
        "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" +
        "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" +
        "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw" +
        "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" +
        "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu" +
        "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva" +
        "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD" +
        "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG" +
        "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F" +
        "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg" +
        "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx" +
        "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi" +
        "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD" +
        "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO" +
        "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz" +
        "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5" +
        "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8" +
        "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1" +
        "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9" +
        "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB" +
        "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9" +
        "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef" +
        "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw=";    
    /** 
     * Defines the password for the keystore.
     */
    private static final String PASSWORD = "android";
            
    /** 
     * Implements basically a dummy TrustManager. It stores the certificate
     * chain it sees, so it can later be queried.
     */
    class TestTrustManager implements X509TrustManager {
        
        private X509Certificate[] chain;
        
        private String authType;
        
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
            this.chain = chain;
            this.authType = authType;
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) {
            this.chain = chain;
            this.authType = authType;
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }

        public X509Certificate[] getChain() {
            return chain;
        }
        
        public String getAuthType() {
            return authType;
        }
        
    }
    
    /** 
     * Implements a test SSL socket server. It wait for a connection on a given
     * port, requests client authentication (if specified), and read 256 bytes
     * from the socket. 
     */
    class TestServer implements Runnable {

        public static final int CLIENT_AUTH_NONE = 0;

        public static final int CLIENT_AUTH_WANTED = 1;

        public static final int CLIENT_AUTH_NEEDED = 2;
        
        private TestTrustManager trustManager;

        private Exception exception;

        private int port;
        
        private int clientAuth;
        
        private boolean provideKeys;

        public TestServer(int port, boolean provideKeys, int clientAuth) {
            this.port = port;
            this.clientAuth = clientAuth;
            this.provideKeys = provideKeys;
            
            trustManager = new TestTrustManager(); 
        }
        
        public void run() {
            try {
                KeyManager[] keyManagers = provideKeys
                        ? getKeyManagers(SERVER_KEYS_BKS) : null;
                TrustManager[] trustManagers = new TrustManager[] {
                        trustManager };

                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(keyManagers, trustManagers, null);
                
                SSLServerSocket serverSocket
                        = (SSLServerSocket) sslContext.getServerSocketFactory()
                        .createServerSocket();
                
                if (clientAuth == CLIENT_AUTH_WANTED) {
                    serverSocket.setWantClientAuth(true);
                } else if (clientAuth == CLIENT_AUTH_NEEDED) {
                    serverSocket.setNeedClientAuth(true);
                } else {
                    serverSocket.setWantClientAuth(false);
                }
                
                serverSocket.bind(new InetSocketAddress(port));
                
                SSLSocket clientSocket = (SSLSocket) serverSocket.accept();

                InputStream stream = clientSocket.getInputStream();

                for (int i = 0; i < 256; i++) {
                    int j = stream.read();
                    if (i != j) {
                        throw new RuntimeException("Error reading socket,"
                                + " expected " + i + ", got " + j);
                    }
                }
                
                stream.close();
                clientSocket.close();
                serverSocket.close();
                
            } catch (Exception ex) {
                exception = ex;
            }
        }

        public Exception getException() {
            return exception;
        }
        
        public X509Certificate[] getChain() {
            return trustManager.getChain();
        }
        
    }

    /** 
     * Implements a test SSL socket client. It open a connection to localhost on
     * a given port and writes 256 bytes to the socket. 
     */
    class TestClient implements Runnable {
        
        private TestTrustManager trustManager;

        private Exception exception;
        
        private int port;
        
        private boolean provideKeys;
        
        public TestClient(int port, boolean provideKeys) {
            this.port = port;
            this.provideKeys = provideKeys;
            
            trustManager = new TestTrustManager(); 
        }
        
        public void run() {
            try {
                KeyManager[] keyManagers = provideKeys
                        ? getKeyManagers(CLIENT_KEYS_BKS) : null;
                TrustManager[] trustManagers = new TrustManager[] {
                        trustManager };

                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(keyManagers, trustManagers, null);
                
                SSLSocket socket = (SSLSocket) sslContext.getSocketFactory()
                        .createSocket();

                socket.connect(new InetSocketAddress(port));
                socket.startHandshake();

                OutputStream stream = socket.getOutputStream();
                
                for (int i = 0; i < 256; i++) {
                    stream.write(i);
                }
                
                stream.flush();
                stream.close();
                socket.close();
                
            } catch (Exception ex) {
                exception = ex;
            }
        }

        public Exception getException() {
            return exception;
        }

        public X509Certificate[] getChain() {
            return trustManager.getChain();
        }
        
    }
    
    /**
     * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
     * for the result.
     */
    private KeyManager[] getKeyManagers(String keys) throws Exception {
        byte[] bytes = new Base64().decode(keys.getBytes());                    
        InputStream inputStream = new ByteArrayInputStream(bytes);
        
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(inputStream, PASSWORD.toCharArray());
        inputStream.close();
        
        String algorithm = KeyManagerFactory.getDefaultAlgorithm();
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
        keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
        
        return keyManagerFactory.getKeyManagers();
    }

    /**
     * Implements the actual test case. Launches a server and a client, requires
     * client authentication and checks the certificates afterwards (not in the
     * usual sense, we just make sure that we got the expected certificates,
     * because our self-signed test certificates are not valid.)
     */
    public void testClientAuth() {
        try {
            TestServer server = new TestServer(8088, true, TestServer.CLIENT_AUTH_WANTED);
            TestClient client = new TestClient(8088, true);
            
            Thread serverThread = new Thread(server);
            Thread clientThread = new Thread(client);
            
            serverThread.start();
            clientThread.start();
            
            serverThread.join();
            clientThread.join();
            
            // The server must have completed without an exception.
            if (server.getException() != null) {
                throw new RuntimeException(server.getException());
            }

            // The client must have completed without an exception.
            if (client.getException() != null) {
                throw new RuntimeException(client.getException());
            }
            
            // Caution: The clientChain is the certificate chain from our
            // client object. It contains the server certificates, of course!
            X509Certificate[] clientChain = client.getChain();
            assertTrue("Client cert chain must not be null", clientChain != null);
            assertTrue("Client cert chain must not be empty", clientChain.length != 0);
            assertEquals("CN=Test Server, OU=Android, O=Google, L=MTV, ST=California, C=US", clientChain[0].getSubjectDN().toString());
            // Important part ------^
            
            // Caution: The serverChain is the certificate chain from our
            // server object. It contains the client certificates, of course!
            X509Certificate[] serverChain = server.getChain();
            assertTrue("Server cert chain must not be null", serverChain != null);
            assertTrue("Server cert chain must not be empty", serverChain.length != 0);
            assertEquals("CN=Test Client, OU=Android, O=Google, L=MTV, ST=California, C=US", serverChain[0].getSubjectDN().toString());
            // Important part ------^
            
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    // -------------------------------------------------------------------------
    private SSLSocket handshakeSocket;

    private Exception handshakeException;

    
    public void testSSLHandshakeHangTimeout() {
        
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    SSLSocket socket = (SSLSocket)clientFactory.createSocket(
                            "www.heise.de", 80);
                    socket.setSoTimeout(5000);
                    socket.startHandshake();
                    socket.close();
                } catch (Exception ex) {
                    handshakeException = ex;
                }
            }
        };
        
        thread.start();
        
        try {
            thread.join(10000);
        } catch (InterruptedException ex) {
            // Ignore.
        }
        
        if (handshakeException == null) {
            fail("SSL handshake should have failed.");
        }
    }

    public void testSSLHandshakeHangClose() {
        
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    handshakeSocket = (SSLSocket)clientFactory.createSocket(
                            "www.heise.de", 80);
                    handshakeSocket.startHandshake();
                } catch (Exception ex) {
                    handshakeException = ex;
                }
            }
        };
        
        thread.start();

        
        try {
            Thread.sleep(5000);
            try {
                handshakeSocket.close();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }

            thread.join(5000);
        } catch (InterruptedException ex) {
            // Ignore.
        }
        
        if (handshakeException == null) {
            fail("SSL handshake should have failed.");
        }
    }

    /**
     * Tests our in-memory and persistent caching support.
     */
    public void testClientSessionCaching() throws IOException,
            KeyManagementException {
        SSLContextImpl context = new SSLContextImpl();

        // Cache size = 2.
        FakeClientSessionCache fakeCache = new FakeClientSessionCache();
        context.engineInit(null, null, null, fakeCache, null);
        SSLSocketFactory socketFactory = context.engineGetSocketFactory();
        context.engineGetClientSessionContext().setSessionCacheSize(2);
        makeRequests(socketFactory);
        List<String> smallCacheOps = Arrays.asList(
                "get www.fortify.net",
                "put www.fortify.net",
                "get www.paypal.com",
                "put www.paypal.com",
                "get www.yellownet.ch",
                "put www.yellownet.ch",

                // At this point, all in-memory cache requests should miss,
                // but the sessions will still be in the persistent cache.
                "get www.fortify.net",
                "get www.paypal.com",
                "get www.yellownet.ch"
        );
        assertEquals(smallCacheOps, fakeCache.ops);

        // Cache size = 3.
        fakeCache = new FakeClientSessionCache();
        context.engineInit(null, null, null, fakeCache, null);
        socketFactory = context.engineGetSocketFactory();
        context.engineGetClientSessionContext().setSessionCacheSize(3);
        makeRequests(socketFactory);
        List<String> bigCacheOps = Arrays.asList(
                "get www.fortify.net",
                "put www.fortify.net",
                "get www.paypal.com",
                "put www.paypal.com",
                "get www.yellownet.ch",
                "put www.yellownet.ch"

                // At this point, all results should be in the in-memory
                // cache, and the persistent cache shouldn't be hit anymore.
        );
        assertEquals(bigCacheOps, fakeCache.ops);

        // Cache size = 4.
        fakeCache = new FakeClientSessionCache();
        context.engineInit(null, null, null, fakeCache, null);
        socketFactory = context.engineGetSocketFactory();
        context.engineGetClientSessionContext().setSessionCacheSize(4);
        makeRequests(socketFactory);
        assertEquals(bigCacheOps, fakeCache.ops);
    }

    /**
     * Executes sequence of requests twice using given socket factory.
     */
    private void makeRequests(SSLSocketFactory socketFactory)
            throws IOException {
        for (int i = 0; i < 2; i++) {
            fetch(socketFactory, "www.fortify.net", 443, true, "/sslcheck.html",
                    1, 1, 0, 60);
            fetch(socketFactory, "www.paypal.com", 443, true, "/",
                    1, 1, 0, 60);
            fetch(socketFactory, "www.yellownet.ch", 443, true, "/",
                    1, 1, 0, 60);
        }
    }

    /**
     * Fake in the sense that it doesn't actually persist anything.
     */
    static class FakeClientSessionCache implements SSLClientSessionCache {

        List<String> ops = new ArrayList<String>();
        Map<String, byte[]> sessions = new HashMap<String, byte[]>();

        public byte[] getSessionData(String host, int port) {
            ops.add("get " + host);
            return sessions.get(host);
        }

        public void putSessionData(SSLSession session, byte[] sessionData) {
            String host = session.getPeerHost();
            System.err.println("length: " + sessionData.length);
            ops.add("put " + host);
            sessions.put(host, sessionData);
        }
    }

    public void testFileBasedClientSessionCache() throws IOException,
            KeyManagementException {
        SSLContextImpl context = new SSLContextImpl();
        String tmpDir = System.getProperty("java.io.tmpdir");
        if (tmpDir == null) {
            fail("Please set 'java.io.tmpdir' system property.");
        }
        File cacheDir = new File(tmpDir
                + "/" + SSLSocketTest.class.getName() + "/cache");
        deleteDir(cacheDir);
        SSLClientSessionCache fileCache
                = FileClientSessionCache.usingDirectory(cacheDir);
        try {
            ClientSessionCacheProxy cacheProxy
                    = new ClientSessionCacheProxy(fileCache);
            context.engineInit(null, null, null, cacheProxy, null);
            SSLSocketFactory socketFactory = context.engineGetSocketFactory();
            context.engineGetClientSessionContext().setSessionCacheSize(1);
            makeRequests(socketFactory);
            List<String> expected = Arrays.asList(
                    "unsuccessful get www.fortify.net",
                    "put www.fortify.net",
                    "unsuccessful get www.paypal.com",
                    "put www.paypal.com",
                    "unsuccessful get www.yellownet.ch",
                    "put www.yellownet.ch",

                    // At this point, all in-memory cache requests should miss,
                    // but the sessions will still be in the persistent cache.
                    "successful get www.fortify.net",
                    "successful get www.paypal.com",
                    "successful get www.yellownet.ch"
            );
            assertEquals(expected, cacheProxy.ops);

            // Try again now that file-based cache is populated.
            fileCache = FileClientSessionCache.usingDirectory(cacheDir);
            cacheProxy = new ClientSessionCacheProxy(fileCache);
            context.engineInit(null, null, null, cacheProxy, null);
            socketFactory = context.engineGetSocketFactory();
            context.engineGetClientSessionContext().setSessionCacheSize(1);
            makeRequests(socketFactory);
            expected = Arrays.asList(
                    "successful get www.fortify.net",
                    "successful get www.paypal.com",
                    "successful get www.yellownet.ch",
                    "successful get www.fortify.net",
                    "successful get www.paypal.com",
                    "successful get www.yellownet.ch"
            );
            assertEquals(expected, cacheProxy.ops);
        } finally {
            deleteDir(cacheDir);
        }
    }

    private static void deleteDir(File directory) {
        if (!directory.exists()) {
            return;
        }
        for (File file : directory.listFiles()) {
            file.delete();
        }
        directory.delete();
    }

    static class ClientSessionCacheProxy implements SSLClientSessionCache {

        final SSLClientSessionCache delegate;
        final List<String> ops = new ArrayList<String>();

        ClientSessionCacheProxy(SSLClientSessionCache delegate) {
            this.delegate = delegate;
        }

        public byte[] getSessionData(String host, int port) {
            byte[] sessionData = delegate.getSessionData(host, port);
            ops.add((sessionData == null ? "unsuccessful" : "successful")
                    + " get " + host);
            return sessionData;
        }

        public void putSessionData(SSLSession session, byte[] sessionData) {
            delegate.putSessionData(session, sessionData);
            ops.add("put " + session.getPeerHost());
        }
    }

    public static void main(String[] args) throws KeyManagementException, IOException {
        new SSLSocketTest().testFileBasedClientSessionCache();
    }
}
