Skip to content

Instantly share code, notes, and snippets.

@hprange
Last active August 29, 2015 14:24
Show Gist options
  • Save hprange/816eb370f786c945ef10 to your computer and use it in GitHub Desktop.
Save hprange/816eb370f786c945ef10 to your computer and use it in GitHub Desktop.
Extensão do trust manager que faz a verificação se um cliente/servidor é confiável de duas formas: 1) a partir dos certificados disponibilizados pelo trust manager padrão do Java; 2) e a partir dos certificados presentes em uma pasta do sistema de arquivo que é definida por parâmetro.
/**
* Exemplo de uso do <code>X509TrustManagerCombinado</code>.
*/
public class App {
public static void main(String[] args) throws Exception {
// Configura o contexto SSL para utilizar um trust manager customizado
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { new X509TrustManagerCombinado(new File("/etc/ssl/certs")) }, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
}
}
package com.ssl.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.Socket;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.UUID;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedTrustManager;
import org.apache.commons.lang.ArrayUtils;
/**
* O <code>X509TrustManagerCombinado</code> é um trust manager que faz a verificação
* se um cliente/servidor é confiável de duas formas: 1) a partir dos certificados
* disponibilizados pelo trust manager padrão do Java; 2) e a partir dos certificados
* presentes em uma pasta do sistema de arquivo que é definida por parâmetro.
*
* @author <a href="mailto:hprange@gmail.com">Henrique Prange</a>
*/
public class X509TrustManagerCombinado extends X509ExtendedTrustManager {
private final X509ExtendedTrustManager trustManagerPadrao;
private final X509ExtendedTrustManager trustManagerCertificadosAdicionais;
public X509TrustManagerCombinado(File pastaCertificados) {
try {
trustManagerPadrao = inicializaTrustManagerPadrao();
trustManagerCertificadosAdicionais = inicializaTrustManagerCertificadosAdicionais(pastaCertificados);
} catch (Exception exception) {
throw new RuntimeException("Erro ao inicializar o X509TrustManagerCombinado.", exception);
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
trustManagerPadrao.checkClientTrusted(chain, authType);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkClientTrusted(chain, authType);
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
try {
trustManagerPadrao.checkClientTrusted(chain, authType, socket);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkClientTrusted(chain, authType, socket);
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
try {
trustManagerPadrao.checkClientTrusted(chain, authType, sslEngine);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkClientTrusted(chain, authType, sslEngine);
}
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
trustManagerPadrao.checkServerTrusted(chain, authType);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkServerTrusted(chain, authType);
}
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
try {
trustManagerPadrao.checkServerTrusted(chain, authType, socket);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkServerTrusted(chain, authType, socket);
}
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
try {
trustManagerPadrao.checkServerTrusted(chain, authType, sslEngine);
} catch (CertificateException excep) {
trustManagerCertificadosAdicionais.checkServerTrusted(chain, authType, sslEngine);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return (X509Certificate[]) ArrayUtils.addAll(trustManagerPadrao.getAcceptedIssuers(), trustManagerCertificadosAdicionais.getAcceptedIssuers());
}
private X509ExtendedTrustManager inicializaTrustManager(KeyStore keyStore) throws Exception {
TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmFactory.init(keyStore);
TrustManager tms[] = tmFactory.getTrustManagers();
for (int i = 0; i < tms.length; i++) {
if (tms[i] instanceof X509ExtendedTrustManager) {
return (X509ExtendedTrustManager) tms[i];
}
}
throw new Exception("Erro ao inicializar: não existe um X509TrustManager na TrustManagerFactory.");
}
private X509ExtendedTrustManager inicializaTrustManagerCertificadosAdicionais(File pastaCertificados) throws Exception {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
for (File certificado : pastaCertificados.listFiles()) {
InputStream in = null;
try {
in = new FileInputStream(certificado);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(in);
keyStore.setCertificateEntry(UUID.randomUUID().toString(), certificate);
} finally {
if (in != null) {
in.close();
}
}
}
return inicializaTrustManager(keyStore);
}
private X509ExtendedTrustManager inicializaTrustManagerPadrao() throws Exception {
return inicializaTrustManager(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment