package com.hwlcn.ldap.util.ssl;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import com.hwlcn.core.annotation.NotMutable;
import com.hwlcn.core.annotation.ThreadSafety;
import com.hwlcn.ldap.util.ThreadSafetyLevel;
import static com.hwlcn.ldap.util.Debug.*;
import static com.hwlcn.ldap.util.Validator.*;
import static com.hwlcn.ldap.util.ssl.SSLMessages.*;
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class TrustStoreTrustManager
implements X509TrustManager, Serializable
{
private static final long serialVersionUID = -4093869102727719415L;
private final boolean examineValidityDates;
private final char[] trustStorePIN;
private final String trustStoreFile;
private final String trustStoreFormat;
public TrustStoreTrustManager(final File trustStoreFile)
{
this(trustStoreFile.getAbsolutePath(), null, null, true);
}
public TrustStoreTrustManager(final String trustStoreFile)
{
this(trustStoreFile, null, null, true);
}
public TrustStoreTrustManager(final File trustStoreFile,
final char[] trustStorePIN,
final String trustStoreFormat,
final boolean examineValidityDates)
{
this(trustStoreFile.getAbsolutePath(), trustStorePIN, trustStoreFormat,
examineValidityDates);
}
public TrustStoreTrustManager(final String trustStoreFile,
final char[] trustStorePIN,
final String trustStoreFormat,
final boolean examineValidityDates)
{
ensureNotNull(trustStoreFile);
this.trustStoreFile = trustStoreFile;
this.trustStorePIN = trustStorePIN;
this.examineValidityDates = examineValidityDates;
if (trustStoreFormat == null)
{
this.trustStoreFormat = KeyStore.getDefaultType();
}
else
{
this.trustStoreFormat = trustStoreFormat;
}
}
public String getTrustStoreFile()
{
return trustStoreFile;
}
public String getTrustStoreFormat()
{
return trustStoreFormat;
}
public boolean examineValidityDates()
{
return examineValidityDates;
}
private synchronized X509TrustManager[] getTrustManagers(
final X509Certificate[] chain)
throws CertificateException
{
if (examineValidityDates)
{
final Date d = new Date();
for (final X509Certificate c : chain)
{
c.checkValidity(d);
}
}
final File f = new File(trustStoreFile);
if (! f.exists())
{
throw new CertificateException(
ERR_TRUSTSTORE_NO_SUCH_FILE.get(trustStoreFile));
}
final KeyStore ks;
try
{
ks = KeyStore.getInstance(trustStoreFormat);
}
catch (Exception e)
{
debugException(e);
throw new CertificateException(
ERR_TRUSTSTORE_UNSUPPORTED_FORMAT.get(trustStoreFormat), e);
}
FileInputStream inputStream = null;
try
{
inputStream = new FileInputStream(f);
ks.load(inputStream, trustStorePIN);
}
catch (Exception e)
{
debugException(e);
throw new CertificateException(
ERR_TRUSTSTORE_CANNOT_LOAD.get(trustStoreFile, trustStoreFormat,
String.valueOf(e)),
e);
}
finally
{
if (inputStream != null)
{
try
{
inputStream.close();
}
catch (Exception e)
{
debugException(e);
}
}
}
try
{
final TrustManagerFactory factory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
factory.init(ks);
final TrustManager[] trustManagers = factory.getTrustManagers();
final X509TrustManager[] x509TrustManagers =
new X509TrustManager[trustManagers.length];
for (int i=0; i < trustManagers.length; i++)
{
x509TrustManagers[i] = (X509TrustManager) trustManagers[i];
}
return x509TrustManagers;
}
catch (Exception e)
{
debugException(e);
throw new CertificateException(
ERR_TRUSTSTORE_CANNOT_GET_TRUST_MANAGERS.get(trustStoreFile,
trustStoreFormat, String.valueOf(e)),
e);
}
}
public synchronized void checkClientTrusted(final X509Certificate[] chain,
final String authType)
throws CertificateException
{
for (final X509TrustManager m : getTrustManagers(chain))
{
m.checkClientTrusted(chain, authType);
}
}
public synchronized void checkServerTrusted(final X509Certificate[] chain,
final String authType)
throws CertificateException
{
for (final X509TrustManager m : getTrustManagers(chain))
{
m.checkServerTrusted(chain, authType);
}
}
public synchronized X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}