Skip to content

Commit

Permalink
DynamicX509TrustManager used as a trustmanager of SSLContext which cr…
Browse files Browse the repository at this point in the history
…eates default SSLSocketFactory for HttpsURLConnections
  • Loading branch information
kwart committed Jul 4, 2012
1 parent 511c02c commit f1f1235
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 157 deletions.
3 changes: 3 additions & 0 deletions src/net/sf/jsignpdf/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.Set;

import net.sf.jsignpdf.types.HashAlgorithm;
import net.sf.jsignpdf.utils.ConfigProvider;
import net.sf.jsignpdf.utils.ResourceProvider;

/**
Expand Down Expand Up @@ -87,6 +88,8 @@ public class Constants {

public static final ResourceProvider RES = new ResourceProvider(ResourceBundle.getBundle(RESOURCE_BUNDLE_BASE));

public static final boolean RELAX_SSL_SECURITY = ConfigProvider.getInstance().getAsBool("relax.ssl.security");

/**
* Property name.
*/
Expand Down
7 changes: 6 additions & 1 deletion src/net/sf/jsignpdf/Signer.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import javax.swing.UIManager;
import javax.swing.WindowConstants;

import net.sf.jsignpdf.ssl.SSLInitializer;
import net.sf.jsignpdf.utils.ConfigProvider;
import net.sf.jsignpdf.utils.GuiUtils;
import net.sf.jsignpdf.utils.KeyStoreUtils;
Expand Down Expand Up @@ -87,7 +88,11 @@ private static void printHelp() {
* @param args
*/
public static void main(String[] args) {
// SSLInitializer.init();
try {
SSLInitializer.init();
} catch (Exception e) {
LOGGER.warn("Unable to re-configure SSL layer", e);
}

PKCS11Utils.registerProvider(ConfigProvider.getInstance().getProperty("pkcs11config.path"));

Expand Down
139 changes: 139 additions & 0 deletions src/net/sf/jsignpdf/ssl/DynamicX509TrustManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is 'JSignPdf, a free application for PDF signing'.
*
* The Initial Developer of the Original Code is Josef Cacek.
* Portions created by Josef Cacek are Copyright (C) Josef Cacek. All Rights Reserved.
*
* Contributor(s): Josef Cacek.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License, version 2.1 (the "LGPL License"), in which case the
* provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
*/
package net.sf.jsignpdf.ssl;

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.UUID;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import net.sf.jsignpdf.Constants;
import net.sf.jsignpdf.utils.KeyStoreUtils;

/**
* TrustManager which works with in-memory copy of cacerts truststore. If
* {@link Constants#RELAX_SSL_SECURITY} is true then it adds missing server
* certificates to the truststore.
*
* @author Josef Cacek
*/
public class DynamicX509TrustManager implements X509TrustManager {

private final KeyStore trustStore;
private final TrustManagerFactory trustManagerFactory;

private X509TrustManager trustManager;

/**
* Constructor.
*
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws CertificateException
* @throws IOException
*/
public DynamicX509TrustManager() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException {
this.trustStore = KeyStoreUtils.createTrustStore();
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
reloadTrustStore();
}

/**
* Checks client's cert-chain - no extra step here.
*
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[],
* java.lang.String)
*/
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
trustManager.checkClientTrusted(chain, authType);
}

/**
* Checks server's cert-chain. If check fails and
* {@link Constants#RELAX_SSL_SECURITY} is true then the first certificate
* from the chain is added to the truststore and the check is repeated.
*
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[],
* java.lang.String)
*/
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (Constants.RELAX_SSL_SECURITY) {
try {
trustManager.checkServerTrusted(chain, authType);
} catch (CertificateException cx) {
try {
trustStore.setCertificateEntry(UUID.randomUUID().toString(), chain[0]);
reloadTrustStore();
} catch (Exception e) {
throw new CertificateException("Unable to recreate TrustManager", e);
}
trustManager.checkServerTrusted(chain, authType);
}
} else {
trustManager.checkServerTrusted(chain, authType);
}
}

/* (non-Javadoc)
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
return trustManager.getAcceptedIssuers();
}

/**
* Reloads the in-memory trustore.
*
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
*/
private void reloadTrustStore() throws KeyStoreException, NoSuchAlgorithmException {
trustManagerFactory.init(trustStore);
// acquire X509 trust manager from factory
TrustManager tms[] = trustManagerFactory.getTrustManagers();
for (int i = 0; i < tms.length; i++) {
if (tms[i] instanceof X509TrustManager) {
trustManager = (X509TrustManager) tms[i];
return;
}
}

throw new NoSuchAlgorithmException("No X509TrustManager in TrustManagerFactory");
}

}
38 changes: 24 additions & 14 deletions src/net/sf/jsignpdf/ssl/SSLInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,29 @@
*/
package net.sf.jsignpdf.ssl;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import net.sf.jsignpdf.utils.ConfigProvider;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;

import net.sf.jsignpdf.Constants;

/**
*
* @author Josef Cacek
*/
public class SSLInitializer {

public static final void init() throws NoSuchAlgorithmException {
final ConfigProvider conf = ConfigProvider.getInstance();
if (conf.getAsBool("relax.ssl.security")) {
public static final void init() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException,
CertificateException, IOException {
if (Constants.RELAX_SSL_SECURITY) {
//Details for the properties - http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html
//Workaround for http://sourceforge.net/tracker/?func=detail&atid=1037906&aid=3491269&group_id=216921
System.setProperty("jsse.enableSNIExtension", "false");
Expand All @@ -50,16 +60,16 @@ public static final void init() throws NoSuchAlgorithmException {
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
System.setProperty("sun.security.ssl.allowLegacyHelloMessages", "true");

// SSLContext defaultSSLContext = SSLContext.getInstance("SSLv3");
//
// KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//// kmf.init();
// KeyManager[] keyManagers = kmf.getKeyManagers();
//
// //TODO orig trust manager
// TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).
// TrustManager[] trustManagers = new TrustManager[] { new UnsafeTrustManager(null) };
// defaultSSLContext.init(keyManagers, trustManagers, null);
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { new DynamicX509TrustManager() }, null);

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
}
}
50 changes: 0 additions & 50 deletions src/net/sf/jsignpdf/ssl/UnsafeHostnameVerifier.java

This file was deleted.

92 changes: 0 additions & 92 deletions src/net/sf/jsignpdf/ssl/UnsafeTrustManager.java

This file was deleted.

Loading

0 comments on commit f1f1235

Please sign in to comment.