package com.hwlcn.ldap.util.ssl; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.net.ssl.X509TrustManager; import com.hwlcn.core.annotation.NotMutable; import com.hwlcn.ldap.util.StaticUtils; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.util.ThreadSafetyLevel; import com.hwlcn.ldap.util.Validator; import static com.hwlcn.ldap.util.Debug.*; @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class AggregateTrustManager implements X509TrustManager { private static final X509Certificate[] NO_CERTIFICATES = new X509Certificate[0]; private final boolean requireAllAccepted; private final List<X509TrustManager> trustManagers; public AggregateTrustManager(final boolean requireAllAccepted, final X509TrustManager ... trustManagers) { this(requireAllAccepted, StaticUtils.toList(trustManagers)); } public AggregateTrustManager(final boolean requireAllAccepted, final Collection<X509TrustManager > trustManagers) { Validator.ensureNotNull(trustManagers); Validator.ensureFalse(trustManagers.isEmpty(), "The set of associated trust managers must not be empty."); this.requireAllAccepted = requireAllAccepted; this.trustManagers = Collections.unmodifiableList( new ArrayList<X509TrustManager>(trustManagers)); } public boolean requireAllAccepted() { return requireAllAccepted; } public List<X509TrustManager> getAssociatedTrustManagers() { return trustManagers; } public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { ArrayList<String> exceptionMessages = null; for (final X509TrustManager m : trustManagers) { try { m.checkClientTrusted(chain, authType); if (! requireAllAccepted) { return; } } catch (final CertificateException ce) { debugException(ce); if (requireAllAccepted) { throw ce; } else { if (exceptionMessages == null) { exceptionMessages = new ArrayList<String>(trustManagers.size()); } exceptionMessages.add(ce.getMessage()); } } } if ((exceptionMessages != null) && (! exceptionMessages.isEmpty())) { throw new CertificateException( StaticUtils.concatenateStrings(exceptionMessages)); } } public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { ArrayList<String> exceptionMessages = null; for (final X509TrustManager m : trustManagers) { try { m.checkServerTrusted(chain, authType); if (! requireAllAccepted) { return; } } catch (final CertificateException ce) { debugException(ce); if (requireAllAccepted) { throw ce; } else { if (exceptionMessages == null) { exceptionMessages = new ArrayList<String>(trustManagers.size()); } exceptionMessages.add(ce.getMessage()); } } } if ((exceptionMessages != null) && (! exceptionMessages.isEmpty())) { throw new CertificateException( StaticUtils.concatenateStrings(exceptionMessages)); } } public X509Certificate[] getAcceptedIssuers() { return NO_CERTIFICATES; } }