TestSSLContext.java revision 0c131a2ca38465b7d1df4eaee63ac73ce4d5986d
1bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/*
2bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project
3bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
4bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * you may not use this file except in compliance with the License.
6bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * You may obtain a copy of the License at
7bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
8bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
10bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * See the License for the specific language governing permissions and
14bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * limitations under the License.
15bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */
16bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
17bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrompackage javax.net.ssl;
18bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
19bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.net.InetAddress;
20bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.net.InetSocketAddress;
21bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.KeyStore;
22204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstromimport java.security.Principal;
23bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.SecureRandom;
24bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.Security;
25e688a4123f165ed2905878e312b074b8c825d119Brian Carlstromimport java.security.cert.Certificate;
26bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.cert.X509Certificate;
27204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstromimport java.util.Collections;
280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport junit.framework.Assert;
29bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider;
30bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
31bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/**
32bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * TestSSLContext is a convenience class for other tests that
33bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * want a canned SSLContext and related state for testing so they
34bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * don't have to duplicate the logic.
35bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */
360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrompublic final class TestSSLContext extends Assert {
37bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public static final boolean IS_RI
390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
40bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public static final String PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "HarmonyJSSE";
41bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
42f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /*
430af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom     * The RI and Android have very different default SSLSession cache behaviors.
440af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom     * The RI keeps an unlimited number of SSLSesions around for 1 day.
45f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * Android keeps 10 SSLSessions forever.
460af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom     */
470af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom    public static final int EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 10;
480af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom    public static final int EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 100;
490af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom    public static final int EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT = (IS_RI) ? 86400 : 0;
50bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    static {
51bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        if (IS_RI) {
52bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            Security.addProvider(new BouncyCastleProvider());
53bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        }
54bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
55bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
56bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    /**
57bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * The Android SSLSocket and SSLServerSocket implementations are
58bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * based on a version of OpenSSL which includes support for RFC
59bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * 4507 session tickets. When using session tickets, the server
60bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * does not need to keep a cache mapping session IDs to SSL
61bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * sessions for reuse. Instead, the client presents the server
62bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * with a session ticket it received from the server earlier,
63bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * which is an SSL session encrypted by the server's secret
64bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * key. Since in this case the server does not need to keep a
65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * cache, some tests may find different results depending on
66bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * whether or not the session tickets are in use. These tests can
67bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * use this function to determine if loopback SSL connections are
68bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * expected to use session tickets and conditionalize their
69bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * results appropriately.
70bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     */
71bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public static boolean sslServerSocketSupportsSessionTickets () {
720c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // Disabled session tickets for better compatability b/2682876
730c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // return !IS_RI;
740c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        return false;
75bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
76bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
77bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final KeyStore keyStore;
78bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final char[] keyStorePassword;
79bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final SSLContext sslContext;
80bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final SSLServerSocket serverSocket;
81bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final InetAddress host;
82bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final int port;
83bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
84bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    private TestSSLContext(KeyStore keyStore,
85bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                           char[] keyStorePassword,
86bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                           SSLContext sslContext,
87bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                           SSLServerSocket serverSocket,
88bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                           InetAddress host,
89bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                           int port) {
90bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.keyStore = keyStore;
91bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.keyStorePassword = keyStorePassword;
92bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.sslContext = sslContext;
93bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.serverSocket = serverSocket;
94bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.host = host;
95bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.port = port;
96bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
97bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
98e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    /**
99e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * Usual TestSSLContext creation method, creates underlying
100e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * SSLContext with certificate and key as well as SSLServerSocket
101e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * listening provided host and port.
102e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     */
103bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public static TestSSLContext create() {
104204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        TestKeyStore testKeyStore = TestKeyStore.get();
105204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        return create(testKeyStore.keyStore, testKeyStore.keyStorePassword);
106bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
107bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
108e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    /**
109e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * TestSSLContext creation method that allows separate creation of key store
110e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     */
111204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    public static TestSSLContext create(KeyStore keyStore, char[] keyStorePassword) {
112bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        try {
113bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            SSLContext sslContext = createSSLContext(keyStore, keyStorePassword);
114bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
115bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            SSLServerSocket serverSocket = (SSLServerSocket)
116bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                sslContext.getServerSocketFactory().createServerSocket(0);
117bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            InetSocketAddress sa = (InetSocketAddress) serverSocket.getLocalSocketAddress();
118bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            InetAddress host = sa.getAddress();
119bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            int port = sa.getPort();
120bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
121204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            return new TestSSLContext(keyStore, keyStorePassword,
122bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                                      sslContext, serverSocket, host, port);
123bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        } catch (RuntimeException e) {
124bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            throw e;
125bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        } catch (Exception e) {
126bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            throw new RuntimeException(e);
127bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        }
128bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
129bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
130bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    /**
131e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * Create a client version of the server TestSSLContext. The
132e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * client will trust the server's certificate, but not contain any
133e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     * keys of its own.
134e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom     */
135e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    public static TestSSLContext createClient(TestSSLContext server) {
136e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        try {
137e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            KeyStore keyStore = KeyStore.getInstance("BKS");
138e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            keyStore.load(null, null);
139204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            for (String alias: Collections.list(server.keyStore.aliases())) {
140204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                if (!server.keyStore.isCertificateEntry(alias)) {
141204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                    continue;
142204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                }
143204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                Certificate cert = server.keyStore.getCertificate(alias);
144204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                keyStore.setCertificateEntry(alias, cert);
145204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
146e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
147e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            char[] keyStorePassword = server.keyStorePassword;
148e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
149e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            String tmfa = TrustManagerFactory.getDefaultAlgorithm();
150e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa);
151e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            tmf.init(keyStore);
152e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
153e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            SSLContext sslContext = SSLContext.getInstance("TLS");
154e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
155e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
156204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            return new TestSSLContext(keyStore, keyStorePassword,
157e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom                                      sslContext, null, null, -1);
158e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        } catch (RuntimeException e) {
159e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            throw e;
160e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        } catch (Exception e) {
161e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            throw new RuntimeException(e);
162e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        }
163e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    }
164e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
165e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    /**
166bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * Create a SSLContext with a KeyManager using the private key and
167bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * certificate chain from the given KeyStore and a TrustManager
168bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * using the certificates authorities from the same KeyStore.
169bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     */
1700c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public static final SSLContext createSSLContext(final KeyStore keyStore,
1710c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                                                    final char[] keyStorePassword)
172bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        throws Exception {
173bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String kmfa = KeyManagerFactory.getDefaultAlgorithm();
174bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa);
175bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        kmf.init(keyStore, keyStorePassword);
176bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
177bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String tmfa = TrustManagerFactory.getDefaultAlgorithm();
178bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa);
179bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        tmf.init(keyStore);
180bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
181bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        SSLContext context = SSLContext.getInstance("TLS");
182bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
183bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        return context;
184bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
185204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom
186204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    public static void assertCertificateInKeyStore(Principal principal,
187204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                                                   KeyStore keyStore) throws Exception {
188204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        String subjectName = principal.getName();
189204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        boolean found = false;
190204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        for (String alias: Collections.list(keyStore.aliases())) {
191204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            if (!keyStore.isCertificateEntry(alias)) {
192204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                continue;
193204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
194204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            X509Certificate keyStoreCertificate = (X509Certificate) keyStore.getCertificate(alias);
195204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            if (subjectName.equals(keyStoreCertificate.getSubjectDN().getName())) {
196204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                found = true;
197204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                break;
198204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
199204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        }
2000c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(found);
201204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    }
202204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom
203204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    public static void assertCertificateInKeyStore(Certificate certificate,
204204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                                                   KeyStore keyStore) throws Exception {
205204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        boolean found = false;
206204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        for (String alias: Collections.list(keyStore.aliases())) {
207204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            if (!keyStore.isCertificateEntry(alias)) {
208204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                continue;
209204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
210204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            Certificate keyStoreCertificate = keyStore.getCertificate(alias);
211204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            if (certificate.equals(keyStoreCertificate)) {
212204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                found = true;
213204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                break;
214204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
215204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        }
2160c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(found);
217204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    }
218bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom}
219