/*
* Copyright (c) 2011-2012 ICM Uniwersytet Warszawski All rights reserved.
* See LICENCE.txt file for licensing information.
*/
package eu.emi.security.authn.x509.helpers.trust;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.Timer;
import eu.emi.security.authn.x509.helpers.ObserversHandler;
/**
* Implementation of the {@link TrustAnchorStore} which uses JDK's {@link KeyStore}
* as a in-memory storage.
* @author K. Benedyczak
*/
public class JDKInMemoryTrustAnchorStore extends TimedTrustAnchorStoreBase
{
protected KeyStore keystore;
protected Set<TrustAnchor> anchors;
protected X509Certificate[] ca;
public JDKInMemoryTrustAnchorStore(KeyStore ks) throws KeyStoreException
{
this(ks, null, -1, new ObserversHandler());
}
protected JDKInMemoryTrustAnchorStore(KeyStore ks, Timer timer,
long updateInterval, ObserversHandler observers) throws KeyStoreException
{
super(timer, updateInterval, observers);
this.keystore = ks;
anchors = new HashSet<TrustAnchor>();
load();
}
protected void load() throws KeyStoreException
{
Enumeration<String> aliases = keystore.aliases();
anchors.clear();
while (aliases.hasMoreElements())
{
String alias = aliases.nextElement();
X509Certificate x509Cert = null;
if (keystore.isCertificateEntry(alias))
{
Certificate cert = keystore.getCertificate(alias);
if (!(cert instanceof X509Certificate))
continue;
x509Cert = (X509Certificate) cert;
} else if (keystore.isKeyEntry(alias))
{
//This is bit ugly: we treat the user's certificate from the key entry
//as trusted. This is the same behaviour as this implemented internally in JDK.
Certificate[] certs = keystore.getCertificateChain(alias);
if (!(certs[0] instanceof X509Certificate))
continue;
x509Cert = (X509Certificate) certs[0];
} else
{
continue; //shouldn't never happen
}
checkValidity("Unknown location (certificate retrieved from keystore)",
x509Cert, true);
anchors.add(new TrustAnchor(x509Cert, null));
}
ca = new X509Certificate[anchors.size()];
int i=0;
for (TrustAnchor anchor: anchors)
ca[i++] = anchor.getTrustedCert();
}
@Override
public Set<TrustAnchor> getTrustAnchors()
{
Set<TrustAnchor> ret = new HashSet<TrustAnchor>();
ret.addAll(anchors);
return ret;
}
@Override
public X509Certificate[] getTrustedCertificates()
{
return Arrays.copyOf(ca, ca.length);
}
public KeyStore getKeyStore()
{
return keystore;
}
@Override
protected void update()
{
//This implementation doesn't support updates
}
}