1860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root/*
2860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Copyright (C) 2011 The Android Open Source Project
3860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
4860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * you may not use this file except in compliance with the License.
6860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * You may obtain a copy of the License at
7860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
8860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
10860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Unless required by applicable law or agreed to in writing, software
11860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * See the License for the specific language governing permissions and
14860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * limitations under the License.
15860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root */
16860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt;
18860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
19bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.io.ByteArrayInputStream;
20bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.io.ByteArrayOutputStream;
21860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.File;
22bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.io.FileInputStream;
23860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.FileOutputStream;
24bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.io.IOException;
25bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.io.InputStream;
26860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.OutputStream;
27860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.KeyStore;
28a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.security.KeyStore.PrivateKeyEntry;
29a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.security.KeyStore.TrustedCertificateEntry;
30860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.PrivateKey;
31860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.PublicKey;
32a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.security.cert.Certificate;
33bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubinimport java.security.cert.CertificateFactory;
34860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.cert.X509Certificate;
35860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.Arrays;
36860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.HashSet;
37860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.List;
38f9b921df499721bcc2a37fd073485811d0cabe60Kenny Rootimport java.util.Random;
39860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.Set;
40a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.Callable;
41a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.ExecutorService;
42a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.Executors;
43a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.Future;
44a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.TimeUnit;
45a7682713687ac2e209063324597134d48b1955d3Kenny Rootimport java.util.concurrent.TimeoutException;
46860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport javax.security.auth.x500.X500Principal;
47860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport junit.framework.TestCase;
48860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport libcore.java.security.TestKeyStore;
49860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
50860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpublic class TrustedCertificateStoreTest extends TestCase {
51f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private static final Random tempFileRandom = new Random();
52860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
53f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private final File dirTest = new File(System.getProperty("java.io.tmpdir", "."),
54f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root            "cert-store-test" + tempFileRandom.nextInt());
55f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private final File dirSystem = new File(dirTest, "system");
56f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private final File dirAdded = new File(dirTest, "added");
57f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private final File dirDeleted = new File(dirTest, "removed");
58860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
59860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate CA1;
60860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate CA2;
61860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
62860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static KeyStore.PrivateKeyEntry PRIVATE;
63860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate[] CHAIN;
64860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
65860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate CA3_WITH_CA1_SUBJECT;
66860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CA1;
67860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CA2;
68860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CA1;
69860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CA2;
70860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
71860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CHAIN0;
72860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CHAIN1;
73860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CHAIN2;
74860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CHAIN0;
75860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CHAIN1;
76860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CHAIN2;
77860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
78860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CA3;
79860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_SYSTEM_CA3_COLLISION;
80860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CA3;
81860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String ALIAS_USER_CA3_COLLISION;
82860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
83a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate CERTLOOP_EE;
84a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate CERTLOOP_CA1;
85a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate CERTLOOP_CA2;
86a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String ALIAS_USER_CERTLOOP_EE;
87a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String ALIAS_USER_CERTLOOP_CA1;
88a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String ALIAS_USER_CERTLOOP_CA2;
89a7682713687ac2e209063324597134d48b1955d3Kenny Root
908a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate MULTIPLE_ISSUERS_CA1;
918a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate MULTIPLE_ISSUERS_CA1_CROSS;
928a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate MULTIPLE_ISSUERS_CA2;
938a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate MULTIPLE_ISSUERS_EE;
948a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String ALIAS_MULTIPLE_ISSUERS_CA1;
958a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String ALIAS_MULTIPLE_ISSUERS_CA1_CROSS;
968a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String ALIAS_MULTIPLE_ISSUERS_CA2;
978a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String ALIAS_MULTIPLE_ISSUERS_EE;
988a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
99860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate getCa1() {
100860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
101860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CA1;
102860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
103860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate getCa2() {
104860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
105860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CA2;
106860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
107860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
108860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static KeyStore.PrivateKeyEntry getPrivate() {
109860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
110860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return PRIVATE;
111860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
112860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate[] getChain() {
113860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
114860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CHAIN;
115860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
116860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
117860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static X509Certificate getCa3WithCa1Subject() {
118860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
119860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CA3_WITH_CA1_SUBJECT;
120860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
121860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
122860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemCa1() {
123860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
124860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CA1;
125860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
126860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemCa2() {
127860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
128860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CA2;
129860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
130860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserCa1() {
131860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
132860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CA1;
133860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
134860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserCa2() {
135860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
136860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CA2;
137860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
138860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
139860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemChain0() {
140860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
141860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CHAIN0;
142860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
143860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemChain1() {
144860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
145860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CHAIN1;
146860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
147860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemChain2() {
148860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
149860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CHAIN2;
150860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
151860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserChain0() {
152860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
153860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CHAIN0;
154860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
155860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserChain1() {
156860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
157860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CHAIN1;
158860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
159860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserChain2() {
160860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
161860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CHAIN2;
162860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
163860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
164860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemCa3() {
165860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
166860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CA3;
167860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
168860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasSystemCa3Collision() {
169860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
170860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_SYSTEM_CA3_COLLISION;
171860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
172860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserCa3() {
173860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
174860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CA3;
175860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
176860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String getAliasUserCa3Collision() {
177860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
178860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return ALIAS_USER_CA3_COLLISION;
179860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
180a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate getCertLoopEe() {
181a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
182a7682713687ac2e209063324597134d48b1955d3Kenny Root        return CERTLOOP_EE;
183a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
184a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate getCertLoopCa1() {
185a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
186a7682713687ac2e209063324597134d48b1955d3Kenny Root        return CERTLOOP_CA1;
187a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
188a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static X509Certificate getCertLoopCa2() {
189a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
190a7682713687ac2e209063324597134d48b1955d3Kenny Root        return CERTLOOP_CA2;
191a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
192a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String getAliasCertLoopEe() {
193a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
194a7682713687ac2e209063324597134d48b1955d3Kenny Root        return ALIAS_USER_CERTLOOP_EE;
195a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
196a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String getAliasCertLoopCa1() {
197a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
198a7682713687ac2e209063324597134d48b1955d3Kenny Root        return ALIAS_USER_CERTLOOP_CA1;
199a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
200a7682713687ac2e209063324597134d48b1955d3Kenny Root    private static String getAliasCertLoopCa2() {
201a7682713687ac2e209063324597134d48b1955d3Kenny Root        initCerts();
202a7682713687ac2e209063324597134d48b1955d3Kenny Root        return ALIAS_USER_CERTLOOP_CA2;
203a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
2048a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String getAliasMultipleIssuersCa1() {
2058a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2068a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return ALIAS_MULTIPLE_ISSUERS_CA1;
2078a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2088a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String getAliasMultipleIssuersCa2() {
2098a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2108a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return ALIAS_MULTIPLE_ISSUERS_CA2;
2118a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2128a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String getAliasMultipleIssuersCa1Cross() {
2138a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2148a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return ALIAS_MULTIPLE_ISSUERS_CA1_CROSS;
2158a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2168a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static String getAliasMultipleIssuersEe() {
2178a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2188a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return ALIAS_MULTIPLE_ISSUERS_EE;
2198a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2208a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate getMultipleIssuersCa1() {
2218a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2228a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return MULTIPLE_ISSUERS_CA1;
2238a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2248a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate getMultipleIssuersCa2() {
2258a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2268a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return MULTIPLE_ISSUERS_CA2;
2278a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2288a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate getMultipleIssuersCa1Cross() {
2298a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2308a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return MULTIPLE_ISSUERS_CA1_CROSS;
2318a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
2328a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    private static X509Certificate getMultipleIssuersEe() {
2338a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        initCerts();
2348a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        return MULTIPLE_ISSUERS_EE;
2358a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
236860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
237860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
238860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Lazily create shared test certificates.
239860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
240860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static synchronized void initCerts() {
241860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (CA1 != null) {
242860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return;
243860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
244860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
245860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CA1 = TestKeyStore.getClient().getRootCertificate("RSA");
246860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CA2 = TestKeyStore.getClientCA2().getRootCertificate("RSA");
247860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            PRIVATE = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
248860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CHAIN = (X509Certificate[]) PRIVATE.getCertificateChain();
249860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CA3_WITH_CA1_SUBJECT = new TestKeyStore.Builder()
250860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    .aliasPrefix("unused")
251860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    .subject(CA1.getSubjectX500Principal())
252860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    .ca(true)
253860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    .build().getRootCertificate("RSA");
254860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
255860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
256860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CA1 = alias(false, CA1, 0);
257860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CA2 = alias(false, CA2, 0);
258860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CA1 = alias(true, CA1, 0);
259860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CA2 = alias(true, CA2, 0);
260860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
261860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CHAIN0 = alias(false, getChain()[0], 0);
262860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CHAIN1 = alias(false, getChain()[1], 0);
263860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CHAIN2 = alias(false, getChain()[2], 0);
264860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CHAIN0 = alias(true, getChain()[0], 0);
265860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CHAIN1 = alias(true, getChain()[1], 0);
266860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CHAIN2 = alias(true, getChain()[2], 0);
267860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
268860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CA3 = alias(false, CA3_WITH_CA1_SUBJECT, 0);
269860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_SYSTEM_CA3_COLLISION = alias(false, CA3_WITH_CA1_SUBJECT, 1);
270860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CA3 = alias(true, CA3_WITH_CA1_SUBJECT, 0);
271860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ALIAS_USER_CA3_COLLISION = alias(true, CA3_WITH_CA1_SUBJECT, 1);
272a7682713687ac2e209063324597134d48b1955d3Kenny Root
273a7682713687ac2e209063324597134d48b1955d3Kenny Root            /*
274a7682713687ac2e209063324597134d48b1955d3Kenny Root             * The construction below is to build a certificate chain that has a loop
275a7682713687ac2e209063324597134d48b1955d3Kenny Root             * in it:
276a7682713687ac2e209063324597134d48b1955d3Kenny Root             *
277a7682713687ac2e209063324597134d48b1955d3Kenny Root             *   EE ---> CA1 ---> CA2 ---+
278a7682713687ac2e209063324597134d48b1955d3Kenny Root             *            ^              |
279a7682713687ac2e209063324597134d48b1955d3Kenny Root             *            |              |
280a7682713687ac2e209063324597134d48b1955d3Kenny Root             *            +--------------+
281a7682713687ac2e209063324597134d48b1955d3Kenny Root             */
282a7682713687ac2e209063324597134d48b1955d3Kenny Root            TestKeyStore certLoopTempCa1 = new TestKeyStore.Builder()
283a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .keyAlgorithms("RSA")
284a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .aliasPrefix("certloop-ca1")
285a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .subject("CN=certloop-ca1")
286a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .ca(true)
287a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .build();
288a7682713687ac2e209063324597134d48b1955d3Kenny Root            Certificate certLoopTempCaCert1 = ((TrustedCertificateEntry) certLoopTempCa1
289a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ca1-public-RSA")).getTrustedCertificate();
290a7682713687ac2e209063324597134d48b1955d3Kenny Root            PrivateKeyEntry certLoopCaKey1 = (PrivateKeyEntry) certLoopTempCa1
291a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ca1-private-RSA");
292a7682713687ac2e209063324597134d48b1955d3Kenny Root
293a7682713687ac2e209063324597134d48b1955d3Kenny Root            TestKeyStore certLoopCa2 = new TestKeyStore.Builder()
294a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .keyAlgorithms("RSA")
295a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .aliasPrefix("certloop-ca2")
296a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .subject("CN=certloop-ca2")
297a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .rootCa(certLoopTempCaCert1)
298a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .signer(certLoopCaKey1)
299a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .ca(true)
300a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .build();
301a7682713687ac2e209063324597134d48b1955d3Kenny Root            CERTLOOP_CA2 = (X509Certificate) ((TrustedCertificateEntry) certLoopCa2
302a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ca2-public-RSA")).getTrustedCertificate();
303a7682713687ac2e209063324597134d48b1955d3Kenny Root            ALIAS_USER_CERTLOOP_CA2 = alias(true, CERTLOOP_CA2, 0);
304a7682713687ac2e209063324597134d48b1955d3Kenny Root            PrivateKeyEntry certLoopCaKey2 = (PrivateKeyEntry) certLoopCa2
305a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ca2-private-RSA");
306a7682713687ac2e209063324597134d48b1955d3Kenny Root
307a7682713687ac2e209063324597134d48b1955d3Kenny Root            TestKeyStore certLoopCa1 = new TestKeyStore.Builder()
308a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .keyAlgorithms("RSA")
309a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .aliasPrefix("certloop-ca1")
310a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .subject("CN=certloop-ca1")
311a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .privateEntry(certLoopCaKey1)
312a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .rootCa(CERTLOOP_CA2)
313a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .signer(certLoopCaKey2)
314a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .ca(true)
315a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .build();
316a7682713687ac2e209063324597134d48b1955d3Kenny Root            CERTLOOP_CA1 = (X509Certificate) ((TrustedCertificateEntry) certLoopCa1
317a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ca1-public-RSA")).getTrustedCertificate();
318a7682713687ac2e209063324597134d48b1955d3Kenny Root            ALIAS_USER_CERTLOOP_CA1 = alias(true, CERTLOOP_CA1, 0);
319a7682713687ac2e209063324597134d48b1955d3Kenny Root
320a7682713687ac2e209063324597134d48b1955d3Kenny Root            TestKeyStore certLoopEe = new TestKeyStore.Builder()
321a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .keyAlgorithms("RSA")
322a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .aliasPrefix("certloop-ee")
323a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .subject("CN=certloop-ee")
324a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .rootCa(CERTLOOP_CA1)
325a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .signer(certLoopCaKey1)
326a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .build();
327a7682713687ac2e209063324597134d48b1955d3Kenny Root            CERTLOOP_EE = (X509Certificate) ((TrustedCertificateEntry) certLoopEe
328a7682713687ac2e209063324597134d48b1955d3Kenny Root                    .getEntryByAlias("certloop-ee-public-RSA")).getTrustedCertificate();
329a7682713687ac2e209063324597134d48b1955d3Kenny Root            ALIAS_USER_CERTLOOP_EE = alias(true, CERTLOOP_EE, 0);
3308a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
3318a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            /*
3328a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             * The construction below creates a certificate with multiple possible issuer certs.
3338a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             *
3348a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             *    EE ----> CA1 ---> CA2
3358a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             *
3368a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             *    Where CA1 also exists in a self-issued form.
3378a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker             */
3388a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            TestKeyStore multipleIssuersCa1 = new TestKeyStore.Builder()
3398a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .keyAlgorithms("RSA")
3408a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .aliasPrefix("multiple-issuers-ca1")
3418a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .subject("CN=multiple-issuers-ca1")
3428a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .ca(true)
3438a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .build();
3448a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            MULTIPLE_ISSUERS_CA1 = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa1
3458a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getEntryByAlias("multiple-issuers-ca1-public-RSA")).getTrustedCertificate();
3468a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            ALIAS_MULTIPLE_ISSUERS_CA1 = alias(false, MULTIPLE_ISSUERS_CA1, 0);
3478a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            PrivateKeyEntry multipleIssuersCa1Key = (PrivateKeyEntry) multipleIssuersCa1
3488a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getEntryByAlias("multiple-issuers-ca1-private-RSA");
3498a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
3508a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            TestKeyStore multipleIssuersCa2 = new TestKeyStore.Builder()
3518a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .keyAlgorithms("RSA")
3528a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .aliasPrefix("multiple-issuers-ca2")
3538a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .subject("CN=multiple-issuers-ca2")
3548a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .ca(true)
3558a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .build();
3568a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            MULTIPLE_ISSUERS_CA2 = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa2
3578a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getEntryByAlias("multiple-issuers-ca2-public-RSA")).getTrustedCertificate();
3588a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            ALIAS_MULTIPLE_ISSUERS_CA2 = alias(false, MULTIPLE_ISSUERS_CA2, 0);
3598a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            PrivateKeyEntry multipleIssuersCa2Key = (PrivateKeyEntry) multipleIssuersCa2
3608a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getEntryByAlias("multiple-issuers-ca2-private-RSA");
3618a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
3628a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            TestKeyStore multipleIssuersCa1SignedByCa2 = new TestKeyStore.Builder()
3638a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .keyAlgorithms("RSA")
3648a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .aliasPrefix("multiple-issuers-ca1")
3658a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .subject("CN=multiple-issuers-ca1")
3668a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .privateEntry(multipleIssuersCa1Key)
3678a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .rootCa(MULTIPLE_ISSUERS_CA2)
3688a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .signer(multipleIssuersCa2Key)
3698a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .ca(true)
3708a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .build();
3718a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            MULTIPLE_ISSUERS_CA1_CROSS =
3728a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa1SignedByCa2
3738a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                            .getEntryByAlias("multiple-issuers-ca1-public-RSA"))
3748a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getTrustedCertificate();
3758a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            ALIAS_MULTIPLE_ISSUERS_CA1_CROSS = alias(false, MULTIPLE_ISSUERS_CA1_CROSS, 1);
3768a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
3778a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            TestKeyStore multipleIssuersEe = new TestKeyStore.Builder()
3788a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .keyAlgorithms("RSA")
3798a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .aliasPrefix("multiple-issuers-ee")
3808a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .subject("CN=multiple-issuers-ee")
3818a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .rootCa(MULTIPLE_ISSUERS_CA1)
3828a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .signer(multipleIssuersCa1Key)
3838a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .build();
3848a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            MULTIPLE_ISSUERS_EE = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersEe
3858a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                    .getEntryByAlias("multiple-issuers-ee-public-RSA")).getTrustedCertificate();
3868a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker            ALIAS_MULTIPLE_ISSUERS_EE = alias(false, MULTIPLE_ISSUERS_EE, 0);
387860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (Exception e) {
388860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throw new RuntimeException(e);
389860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
390860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
391860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
392860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private TrustedCertificateStore store;
393860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
394860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    @Override protected void setUp() {
395860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        setupStore();
396860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
397860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
398860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void setupStore() {
399f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        dirSystem.mkdirs();
400f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        cleanStore();
401860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        createStore();
402860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
403860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
404860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void createStore() {
405f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        store = new TrustedCertificateStore(dirSystem, dirAdded, dirDeleted);
406860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
407860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
408860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    @Override protected void tearDown() {
409860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cleanStore();
410860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
411860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
412860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void cleanStore() {
413f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        for (File dir : new File[] { dirSystem, dirAdded, dirDeleted, dirTest }) {
414860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            File[] files = dir.listFiles();
415860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (files == null) {
416860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                continue;
417860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
418860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            for (File file : files) {
419caff440a68516301f64d27e5edfcd18deb49c2afKenny Root                assertTrue("Should delete " + file.getPath(), file.delete());
420860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
421860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
422860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store = null;
423860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
424860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
425860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void resetStore() {
426860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cleanStore();
427860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        setupStore();
428860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
429860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
430860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testEmptyDirectories() throws Exception {
431860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
432860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
433860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
434860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testOneSystemOneDeleted() throws Exception {
435860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
436860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
437860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
438860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
439860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
440860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
441860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testTwoSystemTwoDeleted() throws Exception {
442860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
443860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
444860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa2(), getAliasSystemCa2());
445860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa2());
446860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
447860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
448860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa2(), getAliasSystemCa2());
449860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
450860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
451860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testPartialFileIsIgnored() throws Exception {
452860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        File file = file(getAliasSystemCa1());
453f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        file.getParentFile().mkdirs();
454860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        OutputStream os = new FileOutputStream(file);
455860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        os.write(0);
456860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        os.close();
457860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(file.exists());
458860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
459860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(file.exists());
460860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
461860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
462860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertEmpty() throws Exception {
463860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
464860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            store.getCertificate(null);
465860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
466860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
467860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
468860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCertificate(""));
469860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
470860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
471860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            store.getCreationDate(null);
472860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
473860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
474860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
475860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCreationDate(""));
476860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
477860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Set<String> s = store.aliases();
478860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNotNull(s);
479860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(s.isEmpty());
480860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases();
481860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
482860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Set<String> u = store.userAliases();
483860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNotNull(u);
484860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(u.isEmpty());
485860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
486860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
487860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            store.containsAlias(null);
488860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
489860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
490860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
491860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.containsAlias(""));
492860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
493860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCertificateAlias(null));
494860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCertificateAlias(getCa1()));
495860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
496860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
49703804497fead7f3e1cb21bf1125ca9e027159920Kenny Root            store.getTrustAnchor(null);
498860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
499860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
500860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
50103804497fead7f3e1cb21bf1125ca9e027159920Kenny Root        assertNull(store.getTrustAnchor(getCa1()));
502860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
503860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
504860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            store.findIssuer(null);
505860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
506860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
507860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
508860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.findIssuer(getCa1()));
509860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
510860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
511860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            store.installCertificate(null);
512860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
513860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
514860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
515860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
516860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(null);
517860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry("");
518860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
519f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        String[] userFiles = dirAdded.list();
520860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(userFiles == null || userFiles.length == 0);
521860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
522860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
523860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testTwoSystem() throws Exception {
524860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasSystemCa1(),
525860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa2(), getAliasSystemCa2());
526860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
527860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
528860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testTwoUser() throws Exception {
529860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasUserCa1(),
530860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa2(), getAliasUserCa2());
531860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
532860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
533860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testOneSystemOneUser() throws Exception {
534860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasSystemCa1(),
535860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa2(), getAliasUserCa2());
536860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
537860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
538860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testTwoSystemSameSubject() throws Exception {
539860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasSystemCa1(),
540860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa3WithCa1Subject(), getAliasSystemCa3Collision());
541860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
542860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
543860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testTwoUserSameSubject() throws Exception {
544860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasUserCa1(),
545860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa3WithCa1Subject(), getAliasUserCa3Collision());
546860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
547860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasUserCa1());
548860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasUserCa1());
549860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTombstone(getAliasUserCa1());
550860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3Collision());
551860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa3Collision());
552860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
553860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasUserCa3Collision());
554860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa3WithCa1Subject(), getAliasUserCa3Collision());
555860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNoTombstone(getAliasUserCa3Collision());
556860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNoTombstone(getAliasUserCa1());
557860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
558860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
559860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
560860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testOneSystemOneUserSameSubject() throws Exception {
561860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasSystemCa1(),
562860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa3WithCa1Subject(), getAliasUserCa3());
563860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testTwo(getCa1(), getAliasUserCa1(),
564860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                getCa3WithCa1Subject(), getAliasSystemCa3());
565860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
566860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
567860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void testTwo(X509Certificate x1, String alias1,
568860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                         X509Certificate x2, String alias2) {
569860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(x1, alias1);
570860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(x2, alias2);
571860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(x1, alias1);
572860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(x2, alias2);
573860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(alias1, alias2);
574860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
575860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
576860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
577860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testOneSystemOneUserOneDeleted() throws Exception {
578860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
579860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa2());
580860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
581860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
582860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa2(), getAliasUserCa2());
583860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa2());
584860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
585860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
586860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testOneSystemOneUserOneDeletedSameSubject() throws Exception {
587860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
588860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa3WithCa1Subject());
589860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
590860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
591860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3());
592860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa3());
593860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
594860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
595860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testUserMaskingSystem() throws Exception {
596860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
597860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasUserCa1());
598860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertMasked(getCa1(), getAliasSystemCa1());
599860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasUserCa1());
600860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1(), getAliasUserCa1());
601860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
602860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
603860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testChain() throws Exception {
604860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testChain(getAliasSystemChain1(), getAliasSystemChain2());
605860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testChain(getAliasSystemChain1(), getAliasUserChain2());
606860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testChain(getAliasUserChain1(), getAliasSystemCa1());
607860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testChain(getAliasUserChain1(), getAliasUserChain2());
608860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
609860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
610860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void testChain(String alias1, String alias2) throws Exception {
611860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getChain()[1], alias1);
612860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getChain()[2], alias2);
613860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertIntermediateCa(getChain()[1], alias1);
614860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getChain()[2], alias2);
615860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(alias1, alias2);
616860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(getChain()[2], store.findIssuer(getChain()[1]));
617860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(getChain()[1], store.findIssuer(getChain()[0]));
618860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
619860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        X509Certificate[] expected = getChain();
620860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        List<X509Certificate> actualList = store.getCertificateChain(expected[0]);
621860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
622860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("Generated CA list should be same length", expected.length, actualList.size());
623860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        for (int i = 0; i < expected.length; i++) {
624860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals("Chain value should be the same for position " + i, expected[i],
625860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    actualList.get(i));
626860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
627860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        resetStore();
628860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
629860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
630860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testMissingSystemDirectory() throws Exception {
631860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cleanStore();
632860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        createStore();
633860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
634860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
635860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
636860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testWithExistingUserDirectories() throws Exception {
637f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        dirAdded.mkdirs();
638f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root        dirDeleted.mkdirs();
639860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
640860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasSystemCa1());
641860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1());
642860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
643860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
644860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testIsTrustAnchorWithReissuedgetCa() throws Exception {
645860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        PublicKey publicKey = getPrivate().getCertificate().getPublicKey();
646860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        PrivateKey privateKey = getPrivate().getPrivateKey();
647860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String name = "CN=CA4";
648860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        X509Certificate ca1 = TestKeyStore.createCa(publicKey, privateKey, name);
649860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Thread.sleep(1 * 1000); // wait to ensure CAs vary by expiration
650860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        X509Certificate ca2 = TestKeyStore.createCa(publicKey, privateKey, name);
651860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(ca1.equals(ca2));
652860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
653860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String systemAlias = alias(false, ca1, 0);
654860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(ca1, systemAlias);
655860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(ca1, systemAlias);
65603804497fead7f3e1cb21bf1125ca9e027159920Kenny Root        assertEquals(ca1, store.getTrustAnchor(ca2));
657860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(ca1, store.findIssuer(ca2));
658860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        resetStore();
659860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
660860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String userAlias = alias(true, ca1, 0);
661860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(ca1);
662860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(ca1, userAlias);
66303804497fead7f3e1cb21bf1125ca9e027159920Kenny Root        assertNotNull(store.getTrustAnchor(ca2));
664860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(ca1, store.findIssuer(ca2));
665860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        resetStore();
666860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
667860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
668860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testInstallEmpty() throws Exception {
669860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa1());
670860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasUserCa1());
671860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa1());
672860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
673860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // reinstalling should not change anything
674860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa1());
675860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasUserCa1());
676860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa1());
677860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
678860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
679860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testInstallEmptySystemExists() throws Exception {
680860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
681860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasSystemCa1());
682860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1());
683860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
684860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // reinstalling should not affect system CA
685860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa1());
686860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasSystemCa1());
687860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1());
688860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
689860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
690860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
691860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testInstallEmptyDeletedSystemExists() throws Exception {
692860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
693860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
694860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
695860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
696860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
697860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // installing should restore deleted system CA
698860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa1());
699860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasSystemCa1());
700860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1());
701860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
702860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
703860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testDeleteEmpty() throws Exception {
704860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
705860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
706860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
707860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
708860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
709860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testDeleteUser() throws Exception {
710860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.installCertificate(getCa1());
711860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasUserCa1());
712860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasUserCa1());
713860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
714860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasUserCa1());
715860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
716860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasUserCa1());
717860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNoTombstone(getAliasUserCa1());
718860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
719860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
720860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testDeleteSystem() throws Exception {
721860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
722860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertRootCa(getCa1(), getAliasSystemCa1());
723860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertAliases(getAliasSystemCa1());
724860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
725860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
726860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
727860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
728860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
729860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // deleting again should not change anything
730860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasSystemCa1());
731860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEmpty();
732860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertDeleted(getCa1(), getAliasSystemCa1());
733860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
734860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
735a7682713687ac2e209063324597134d48b1955d3Kenny Root    public void testGetLoopedCert() throws Exception {
736a7682713687ac2e209063324597134d48b1955d3Kenny Root        install(getCertLoopEe(), getAliasCertLoopEe());
737a7682713687ac2e209063324597134d48b1955d3Kenny Root        install(getCertLoopCa1(), getAliasCertLoopCa1());
738a7682713687ac2e209063324597134d48b1955d3Kenny Root        install(getCertLoopCa2(), getAliasCertLoopCa2());
739a7682713687ac2e209063324597134d48b1955d3Kenny Root
740a7682713687ac2e209063324597134d48b1955d3Kenny Root        ExecutorService executor = Executors.newSingleThreadExecutor();
741a7682713687ac2e209063324597134d48b1955d3Kenny Root        Future<List<X509Certificate>> future = executor
742a7682713687ac2e209063324597134d48b1955d3Kenny Root                .submit(new Callable<List<X509Certificate>>() {
743a7682713687ac2e209063324597134d48b1955d3Kenny Root                    @Override
744a7682713687ac2e209063324597134d48b1955d3Kenny Root                    public List<X509Certificate> call() throws Exception {
745a7682713687ac2e209063324597134d48b1955d3Kenny Root                        return store.getCertificateChain(getCertLoopEe());
746a7682713687ac2e209063324597134d48b1955d3Kenny Root                    }
747a7682713687ac2e209063324597134d48b1955d3Kenny Root                });
748a7682713687ac2e209063324597134d48b1955d3Kenny Root        executor.shutdown();
749a7682713687ac2e209063324597134d48b1955d3Kenny Root        final List<X509Certificate> certs;
750a7682713687ac2e209063324597134d48b1955d3Kenny Root        try {
751a7682713687ac2e209063324597134d48b1955d3Kenny Root            certs = future.get(10, TimeUnit.SECONDS);
752a7682713687ac2e209063324597134d48b1955d3Kenny Root        } catch (TimeoutException e) {
753a7682713687ac2e209063324597134d48b1955d3Kenny Root            fail("Could not finish building chain; possibly confused by loops");
754a7682713687ac2e209063324597134d48b1955d3Kenny Root            return; // Not actually reached.
755a7682713687ac2e209063324597134d48b1955d3Kenny Root        }
756a7682713687ac2e209063324597134d48b1955d3Kenny Root        assertEquals(3, certs.size());
757a7682713687ac2e209063324597134d48b1955d3Kenny Root        assertEquals(getCertLoopEe(), certs.get(0));
758a7682713687ac2e209063324597134d48b1955d3Kenny Root        assertEquals(getCertLoopCa1(), certs.get(1));
759a7682713687ac2e209063324597134d48b1955d3Kenny Root        assertEquals(getCertLoopCa2(), certs.get(2));
760a7682713687ac2e209063324597134d48b1955d3Kenny Root    }
761a7682713687ac2e209063324597134d48b1955d3Kenny Root
762860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testIsUserAddedCertificate() throws Exception {
763860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa1()));
764860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa2()));
765860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasSystemCa1());
766860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa1()));
767860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa2()));
768860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa1(), getAliasUserCa1());
769860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(store.isUserAddedCertificate(getCa1()));
770860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa2()));
771860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        install(getCa2(), getAliasUserCa2());
772860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(store.isUserAddedCertificate(getCa1()));
773860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(store.isUserAddedCertificate(getCa2()));
774860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasUserCa1());
775860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa1()));
776860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(store.isUserAddedCertificate(getCa2()));
777860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        store.deleteCertificateEntry(getAliasUserCa2());
778860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa1()));
779860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.isUserAddedCertificate(getCa2()));
780860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
781860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
782bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    public void testSystemCaCertsUseCorrectFileNames() throws Exception {
783bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        TrustedCertificateStore store = new TrustedCertificateStore();
784bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
785bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        // Assert that all the certificates in the system cacerts directory are stored in files with
786bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        // expected names.
787bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
788bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        File dir = new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
789bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        int systemCertFileCount = 0;
790bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        for (File actualFile : listFilesNoNull(dir)) {
791bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            if (!actualFile.isFile()) {
792bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                continue;
793bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            }
794bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            systemCertFileCount++;
795bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(
796bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                    new ByteArrayInputStream(readFully(actualFile)));
797bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
798bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            File expectedFile = store.getCertificateFile(dir, cert);
799bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            assertEquals("System certificate stored in the wrong file",
800bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                    expectedFile.getAbsolutePath(), actualFile.getAbsolutePath());
801bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
802bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // The two statements below indirectly assert that the certificate can be looked up
803bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // from a file (hopefully the same one as the expectedFile above). As opposed to
804bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // getCertifiacteFile above, these are the actual methods used when verifying chain of
805bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // trust. Thus, we assert that they work as expected for all system certificates.
806bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            assertNotNull("Issuer certificate not found for system certificate " + actualFile,
807bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                    store.findIssuer(cert));
808bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            assertNotNull("Trust anchor not found for system certificate " + actualFile,
809bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                    store.getTrustAnchor(cert));
810bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        }
811bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
812bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        // Assert that all files corresponding to all system certs/aliases known to the store are
813bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        // present.
814bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        int systemCertAliasCount = 0;
815bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        for (String alias : store.aliases()) {
816bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            if (!TrustedCertificateStore.isSystem(alias)) {
817bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                continue;
818bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            }
819bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            systemCertAliasCount++;
820bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // Checking that the certificate is stored in a file is extraneous given the current
821bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // implementation of the class under test. We do it just in case the implementation
822bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            // changes.
823bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            X509Certificate cert = (X509Certificate) store.getCertificate(alias);
824bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            File expectedFile = store.getCertificateFile(dir, cert);
825bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            if (!expectedFile.isFile()) {
826bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                fail("Missing certificate file for alias " + alias
827bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                        + ": " + expectedFile.getAbsolutePath());
828bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            }
829bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        }
830bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
831bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        assertEquals("Number of system cert files and aliases doesn't match",
832bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                systemCertFileCount, systemCertAliasCount);
833bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    }
834bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
8358a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    public void testMultipleIssuers() throws Exception {
8368a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        Set<X509Certificate> result;
8378a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        install(getMultipleIssuersCa1(), getAliasMultipleIssuersCa1());
8388a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        result = store.findAllIssuers(getMultipleIssuersEe());
8398a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        assertEquals("Unexpected number of issuers found", 1, result.size());
8408a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        assertTrue("findAllIssuers does not contain expected issuer",
8418a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                result.contains(getMultipleIssuersCa1()));
8428a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        install(getMultipleIssuersCa1Cross(), getAliasMultipleIssuersCa1Cross());
8438a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        result = store.findAllIssuers(getMultipleIssuersEe());
8448a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        assertEquals("findAllIssuers did not return all issuers", 2, result.size());
8458a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        assertTrue("findAllIssuers does not contain CA1",
8468a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                result.contains(getMultipleIssuersCa1()));
8478a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker        assertTrue("findAllIssuers does not contain CA1 signed by CA2",
8488a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker                result.contains(getMultipleIssuersCa1Cross()));
8498a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker    }
8508a54958e04339833f7320c9ab8bd542c0d2e3d7dChad Brubaker
851bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    private static File[] listFilesNoNull(File dir) {
852bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        File[] files = dir.listFiles();
853bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        return (files != null) ? files : new File[0];
854bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    }
855bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
856bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    private static byte[] readFully(File file) throws IOException {
857bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        InputStream in = null;
858bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        try {
859bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            in = new FileInputStream(file);
860bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            ByteArrayOutputStream out = new ByteArrayOutputStream();
861bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            byte[] buf = new byte[16384];
862bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            int chunkSize;
863bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            while ((chunkSize = in.read(buf)) != -1) {
864bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                out.write(buf, 0, chunkSize);
865bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            }
866bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            return out.toByteArray();
867bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        } finally {
868bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            if (in != null) {
869bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin                in.close();
870bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin            }
871bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin        }
872bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin    }
873bfaa60ea2aaa29531a003985920fd7f93f7bf975Alex Klyubin
874860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertRootCa(X509Certificate x, String alias) {
875860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertIntermediateCa(x, alias);
876860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(x, store.findIssuer(x));
877860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
878860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
879860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertTrusted(X509Certificate x, String alias) {
880860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(x, store.getCertificate(alias));
881860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(file(alias).lastModified(), store.getCreationDate(alias).getTime());
882860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(store.containsAlias(alias));
88303804497fead7f3e1cb21bf1125ca9e027159920Kenny Root        assertEquals(x, store.getTrustAnchor(x));
884860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
885860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
886860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertIntermediateCa(X509Certificate x, String alias) {
887860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrusted(x, alias);
888860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(alias, store.getCertificateAlias(x));
889860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
890860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
891860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertMasked(X509Certificate x, String alias) {
892860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrusted(x, alias);
893860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(alias.equals(store.getCertificateAlias(x)));
894860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
895860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
896860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertDeleted(X509Certificate x, String alias) {
897860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCertificate(alias));
898860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(store.containsAlias(alias));
899860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(store.getCertificateAlias(x));
90003804497fead7f3e1cb21bf1125ca9e027159920Kenny Root        assertNull(store.getTrustAnchor(x));
901860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(store.allSystemAliases().contains(alias),
902860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                     store.getCertificate(alias, true) != null);
903860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
904860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
905860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertTombstone(String alias) {
906860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(TrustedCertificateStore.isUser(alias));
907860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        File file = file(alias);
908860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(file.exists());
909860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(0, file.length());
910860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
911860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
912860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertNoTombstone(String alias) {
913860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(TrustedCertificateStore.isUser(alias));
914860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(file(alias).exists());
915860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
916860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
917860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void assertAliases(String... aliases) {
918860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Set<String> expected = new HashSet<String>(Arrays.asList(aliases));
919860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Set<String> actual = new HashSet<String>();
920860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        for (String alias : store.aliases()) {
921860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            boolean system = TrustedCertificateStore.isSystem(alias);
922860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            boolean user = TrustedCertificateStore.isUser(alias);
923860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (system || user) {
924860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(system, store.allSystemAliases().contains(alias));
925860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(user, store.userAliases().contains(alias));
926860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                actual.add(alias);
927860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } else {
928860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throw new AssertionError(alias);
929860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
930860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
931860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(expected, actual);
932860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
933860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
934860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
935860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * format a certificate alias
936860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
937860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static String alias(boolean user, X509Certificate x, int index) {
938860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String prefix = user ? "user:" : "system:";
939860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
940860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        X500Principal subject = x.getSubjectX500Principal();
941860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        int intHash = NativeCrypto.X509_NAME_hash_old(subject);
942e279a9854d15d20a0b3807fe96f0805b43cd4daePrzemyslaw Szczepaniak        String strHash = Hex.intToHexString(intHash, 8);
943860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
944860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return prefix + strHash + '.' + index;
945860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
946860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
947860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
948860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Install certificate under specified alias
949860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
950f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private void install(X509Certificate x, String alias) {
951860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
952860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            File file = file(alias);
953860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            file.getParentFile().mkdirs();
954860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            OutputStream out = new FileOutputStream(file);
955860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            out.write(x.getEncoded());
956860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            out.close();
957860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (Exception e) {
958860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throw new RuntimeException(e);
959860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
960860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
961860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
962860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
963860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Compute file for an alias
964860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
965f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root    private File file(String alias) {
966860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        File dir;
967860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (TrustedCertificateStore.isSystem(alias)) {
968f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root            dir = dirSystem;
969860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } else if (TrustedCertificateStore.isUser(alias)) {
970f9b921df499721bcc2a37fd073485811d0cabe60Kenny Root            dir = dirAdded;
971860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } else {
972860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throw new IllegalArgumentException(alias);
973860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
974860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
975860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        int index = alias.lastIndexOf(":");
976860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (index == -1) {
977860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throw new IllegalArgumentException(alias);
978860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
979860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String filename = alias.substring(index+1);
980860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
981860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return new File(dir, filename);
982860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
983860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root}
984