aQute.bnd.url.HttpsVerification Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biz.aQute.bndlib Show documentation
Show all versions of biz.aQute.bndlib Show documentation
bndlib: A Swiss Army Knife for OSGi
package aQute.bnd.url;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import aQute.service.reporter.Reporter;
/**
* TODO Needs testing Can be used to override default verification of HTTPS. The
* 'trusted' property on this plugin must contain a list of issuer certificates
* that are trusted. If none are specified the verification is NOT done.
*/
@aQute.bnd.annotation.plugin.BndPlugin(name = "url.https.verification", parameters = HttpsVerification.Config.class)
public class HttpsVerification extends DefaultURLConnectionHandler {
private SSLSocketFactory factory;
private HostnameVerifier verifier;
private boolean verify = true;
private String certificatesPath;
private X509Certificate[] certificateChain;
interface Config {
String trusted();
}
public HttpsVerification() {
}
// http://stackoverflow.com/questions/24555890/using-a-custom-truststore-in-java-as-well-as-the-default-one
public HttpsVerification(String certificates, boolean hostnameVerify,
Reporter reporter) {
certificatesPath = certificates;
this.verify = hostnameVerify;
this.setReporter(reporter);
}
public HttpsVerification(X509Certificate[] certificateChain, boolean b, Reporter hc) {
this.certificateChain = certificateChain;
this.verify = b;
this.setReporter(hc);
}
/**
* Initialize the SSL Context, factory and verifier.
*
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws IOException
* @throws CertificateException
* @throws FileNotFoundException
*/
private synchronized void init() throws NoSuchAlgorithmException, KeyManagementException, FileNotFoundException,
CertificateException, IOException {
if (factory == null) {
List certificates = createCertificates(certificatesPath);
final X509Certificate trusted[] = certificates.toArray(new X509Certificate[0]);
TrustManager[] trustAllCerts = new TrustManager[] {
getTrustManager(trusted)
};
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustAllCerts, new SecureRandom());
factory = context.getSocketFactory();
//
// We can already verify the name through the matchers
// of the URL so we can ignore that for our connections
//
verifier = new HostnameVerifier() {
public boolean verify(String string, SSLSession session) {
return verify;
}
};
}
}
X509TrustManager getTrustManager(final X509Certificate[] trusted) {
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return trusted;
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
}
};
return tm;
}
/**
* Ensure Https verification is disabled or matches given certificates
*/
public void handle(URLConnection connection) throws Exception {
if (connection instanceof HttpsURLConnection && matches(connection)) {
HttpsURLConnection https = (HttpsURLConnection) connection;
init();
https.setSSLSocketFactory(factory);
https.setHostnameVerifier(verifier);
}
}
/**
* Set the properties
*/
@Override
public void setProperties(Map map) throws Exception {
super.setProperties(map);
certificatesPath = map.get("trusted");
}
List createCertificates(String paths)
throws FileNotFoundException, CertificateException, IOException {
List certificates = new ArrayList();
if (paths != null) {
for (String path : paths.split("\\s*,\\s*")) {
File file = new File(path); // This is a system specific path!
if (file.isFile()) {
InputStream inStream = new FileInputStream(file);
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
certificates.add(cert);
} finally {
inStream.close();
}
}
}
} else if (certificateChain != null) {
for (X509Certificate cert : certificateChain) {
certificates.add(cert);
}
}
return certificates;
}
@Override
public String toString() {
return "HttpsVerification [verify=" + verify + ", certificatesPath=" + certificatesPath + "]";
}
}