1 package org.eparapher.core.crypto.keystore;
2
3 import java.security.KeyStore;
4 import java.security.KeyStoreException;
5 import java.security.NoSuchAlgorithmException;
6 import java.security.PrivateKey;
7 import java.security.PublicKey;
8 import java.security.UnrecoverableKeyException;
9 import java.security.cert.Certificate;
10 import java.security.cert.TrustAnchor;
11 import java.security.cert.X509Certificate;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Enumeration;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Set;
18
19 import org.apache.log4j.Logger;
20 import org.eparapher.core.EParapherManager;
21 import org.eparapher.core.crypto.EPKeystoreManager;
22 import org.eparapher.core.crypto.KeystoreEntry;
23 import org.eparapher.core.crypto.cert.X509Util;
24
25
26 public abstract class GenericKeystore implements IUserKeystore {
27
28 private static Logger log = Logger.getLogger(GenericKeystore.class);
29
30 protected PrivateKey currentPrivateKey;
31 protected PublicKey currentPublicKey;
32
33 protected X509Certificate currentX509Certificate;
34 protected X509Certificate[] currentX509CertificateChain;
35
36 protected String currentalias;
37 protected boolean currentaliasselected;
38
39 protected KeyStore ks;
40 protected boolean loadedKeystore;
41
42 public boolean isKeystoreLoaded() {
43 if (ks!=null)
44 if (loadedKeystore)
45 return true;
46 return false;
47 }
48
49 protected GenericKeystore(){
50 this.loadedKeystore=false;
51 this.currentaliasselected = false;
52 }
53
54 public KeystoreEntry[] getKeystoreEntries() {
55
56 ArrayList<KeystoreEntry> certificatelist = new ArrayList<KeystoreEntry>();
57 if (isKeystoreLoaded()) {
58 try {
59 List<String> list = Collections.list(ks.aliases());
60 for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
61
62 String alias = (String) iterator.next();
63 X509Certificate[] currentCertChain = null;
64 if (ks.getCertificateChain(alias)!=null)
65 currentCertChain = X509Util.convertCertChaintoX509( ks.getCertificateChain(alias) );
66 else if (ks.getCertificate(alias)!=null)
67 currentCertChain = X509Util.convertCertChaintoX509( new Certificate[] {ks.getCertificate(alias)} );
68 if ( isX509validatedByFilter(currentCertChain) )
69 certificatelist.add( new KeystoreEntry( alias, currentCertChain, this ) );
70 }
71
72 return certificatelist.toArray(new KeystoreEntry[]{});
73 } catch (KeyStoreException kse) {
74 log.error("Error on reading keystore alias cert chain : " + kse.getMessage());
75 return null;
76 } catch (Exception e) {
77 log.error("Error on getting alias cert chain : " + e.getMessage());
78 return null;
79 }
80 }
81 else {
82 if (EPKeystoreManager.isPKCS11Used())
83 log.info("Token not present!!!");
84 else
85 log.info("Keystore not loaded!");
86 }
87 return null;
88 }
89
90 public KeystoreEntry[] getTrustedCertificates() {
91
92 KeystoreEntry[] certificatelist = null;
93 if (isKeystoreLoaded()) {
94 try {
95 int size = 0;
96 Enumeration<String> en = ks.aliases();
97 while (en.hasMoreElements())
98
99 if ( ks.isCertificateEntry((String) en.nextElement()) )
100 size++;
101
102 certificatelist = new KeystoreEntry[size];
103 int index=0;
104 List<String> list = Collections.list(ks.aliases());
105 Collections.sort(list);
106 for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
107 String alias = (String) iterator.next();
108 if ( ks.isCertificateEntry(alias) ) {
109 X509Certificate currentCert = (X509Certificate) ks.getCertificate(alias);
110 certificatelist[index++] = new KeystoreEntry( alias, currentCert, this );
111 } else if (ks.isKeyEntry(alias))
112 log.debug("Found a key entry in the truststore!");
113 }
114
115 return certificatelist;
116 } catch (KeyStoreException kse) {
117 log.error("Exception on reading aliases in truststore.",kse);
118 return null;
119 } catch (Exception e) {
120 log.error("Exception on reading aliases in truststore.",e);
121 return null;
122 }
123 }
124 else {
125 if (EPKeystoreManager.isPKCS11Used())
126 log.info("Token not present!!!");
127 else
128 log.info("Keystore not loaded!");
129 }
130 return null;
131 }
132
133 private boolean isX509validatedByFilter(X509Certificate[] currentCertChain) {
134
135 return true;
136 }
137
138
139
140
141
142 public boolean loadPublicInformation() {
143
144
145 if (!selectAlias())
146 return false;
147
148
149 try {
150 currentX509Certificate = (X509Certificate) ks.getCertificate(currentalias);
151 currentX509CertificateChain = X509Util.convertCertChaintoX509(ks.getCertificateChain(currentalias));
152 if (currentX509CertificateChain == null)
153 currentX509CertificateChain = new X509Certificate[] {currentX509Certificate};
154
155 return true;
156 } catch (KeyStoreException e) {
157 log.error("Certificate not accessible : " + e.getLocalizedMessage(),e);
158 }
159 return false;
160 }
161
162
163
164
165
166
167 public boolean loadPrivateKey(String secret) {
168 if ( isKeystoreLoaded() ) {
169
170 if (loadPublicInformation()) {
171
172
173 try {
174 if ( secret != null )
175 currentPrivateKey = (PrivateKey) ks.getKey( currentalias, secret.toCharArray() );
176 else
177 currentPrivateKey = (PrivateKey) ks.getKey( currentalias, null );
178 log.info("Using certificate " + currentX509Certificate.getSubjectDN() + " for signing");
179 if (currentPrivateKey != null)
180 return true;
181 } catch (KeyStoreException e) {
182 log.error("Private key not accessible : " + e.getLocalizedMessage());
183 } catch (NoSuchAlgorithmException e) {
184 log.error("Private key not accessible : " + e.getLocalizedMessage());
185 } catch (UnrecoverableKeyException e) {
186 log.error("Private key not accessible : " + e.getLocalizedMessage());
187 }
188 }
189 }
190 return false;
191 }
192
193 protected boolean selectAlias() {
194 boolean aliasExists = false;
195 if (currentaliasselected)
196 return true;
197 if ( isKeystoreLoaded() ) {
198
199 currentalias = EParapherManager.getInstance().getSettings().getPersonalStoreDefaultAlias();
200
201
202 try {
203 aliasExists = ks.containsAlias(currentalias);
204 } catch (KeyStoreException e) {
205 log.error("error on verifying alias in keystore",e);
206 }
207
208 if ( currentalias.equals("") ) {
209 log.info("Alias not set in conf : search for the first 'usable' certificate");
210 return autoSelectAlias();
211 } else if (!aliasExists) {
212 log.info("Alias not found in keystore : search for the first 'usable' certificate");
213 return autoSelectAlias();
214 } else {
215 currentaliasselected = true;
216 log.info("Using stored alias : '"+currentalias+"'");
217 }
218 }
219 else log.warn("Private Key not loaded : cannot find a usable alias!");
220
221 return aliasExists;
222 }
223
224 protected boolean autoSelectAlias() {
225 Enumeration<String> en;
226 boolean found = false;
227 try {
228
229 en = ks.aliases();
230 while (en.hasMoreElements()) {
231 String alias = (String) en.nextElement();
232 if ( ks.isKeyEntry(alias) ) {
233
234 currentalias = alias;
235 found = true;
236 }
237 }
238 if (found)
239 log.info(" -> Using alias '" + currentalias +"'");
240 } catch (KeyStoreException e) {
241 String msg = "Error while parsing Keystore..." + e.getLocalizedMessage();
242 EParapherManager.getInstance().getUI().errorMessage(msg,e);
243 log.error(msg, e);
244 }
245 if (!found) {
246 String message = "Couldn't find a usable alias in your keystore\r\n";
247 message += "Do you want to create a self signed certificate?";
248 if (EParapherManager.getInstance().getUI().askUserYesNo(message)) {
249 found = newcertificate();
250 }
251 }
252 currentaliasselected = found;
253 return found;
254 }
255
256 public boolean setDefaultAlias(String alias) {
257 if (currentalias != alias) {
258 currentalias = alias;
259 EParapherManager.getInstance().getSettings().setPersonalStoreDefaultAlias(alias);
260 loadPublicInformation();
261 currentaliasselected = true;
262 currentPrivateKey = null;
263 }
264 return true;
265 }
266
267 public String getDefaultAlias() {
268 return currentalias;
269 }
270
271
272
273 public boolean containsAlias(String alias){
274
275 if (ks!=null) {
276 try {
277 if (ks.containsAlias(alias))
278 return true;
279 } catch (KeyStoreException e) {
280 String msg = "No such algorithm with your provider " ;
281 log.error(msg, e);
282 }
283 }
284 return false;
285 }
286 public PrivateKey getPrivateKey() {
287 return currentPrivateKey;
288 }
289 public PublicKey getPublicKey() {
290 if (!loadedKeystore)
291 loadKeyStore();
292 if (currentaliasselected && currentPublicKey == null)
293 loadPublicInformation();
294 return currentPublicKey;
295 }
296 public X509Certificate getX509Certificate() {
297 if (!loadedKeystore)
298 loadKeyStore();
299 if (currentaliasselected && currentX509Certificate == null)
300 loadPublicInformation();
301 return currentX509Certificate;
302 }
303 public X509Certificate[] getX509CertificateChain() {
304 if (!loadedKeystore)
305 loadKeyStore();
306 if (currentaliasselected && currentX509Certificate == null)
307 loadPublicInformation();
308 return currentX509CertificateChain;
309 }
310 public String getProviderName() {
311 return ks.getProvider().getName();
312 }
313 public KeyStore getKeystore() {
314
315
316 return ks;
317 }
318
319 public boolean newcertificate() {
320 return EParapherManager.getInstance().getUI().askUserNewCertificate();
321 }
322
323 public Set<TrustAnchor> getTrustAnchors() {
324
325 log.warn("Need to implement getTrustAnchors");
326 return null;
327 }
328
329 }