aboutsummaryrefslogtreecommitdiff
path: root/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-11-04 09:51:26 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-11-04 09:51:26 +0100
commit72e86431b59c466673214d330bbd9baa295449cf (patch)
treef6e17783d0fe6250974e95c052b2c3afcf1bbd2e /id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java
parent518839d9ade1e97d878e494903e088a5b0cf0359 (diff)
downloadmoa-id-spss-72e86431b59c466673214d330bbd9baa295449cf.tar.gz
moa-id-spss-72e86431b59c466673214d330bbd9baa295449cf.tar.bz2
moa-id-spss-72e86431b59c466673214d330bbd9baa295449cf.zip
add hostname validation to httpclient 3.1, which is assumed by openSAML 2.x
Diffstat (limited to 'id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java')
-rw-r--r--id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java140
1 files changed, 115 insertions, 25 deletions
diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java
index 84743b8c7..5bcf915e8 100644
--- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java
+++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/MOAHttpProtocolSocketFactory.java
@@ -27,7 +27,12 @@ import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
@@ -35,6 +40,7 @@ import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException;
import at.gv.egovernment.moa.id.commons.utils.ssl.SSLConfigurationException;
@@ -51,34 +57,57 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
private SSLSocketFactory sslfactory = null;
+ private boolean verifyHostName = true;
+ /**
+ * SSL Protocol socket factory
+ *
+ * @param url
+ * @param trustStoreURL
+ * @param acceptedServerCertURL
+ * @param chainingMode Specifies the ChainingMode for SSL certificate trust validation
+ * @param checkRevocation Enables / Disables certificate revocation checks
+ * @param revocationMethodOrder
+ * @param verifyHostName Enables / Disables hostName verfication
+ * @throws MOAHttpProtocolSocketFactoryException
+ */
public MOAHttpProtocolSocketFactory (
String url,
String trustStoreURL,
String acceptedServerCertURL,
String chainingMode,
boolean checkRevocation,
- String[] revocationMethodOrder) throws MOAHttpProtocolSocketFactoryException {
+ String[] revocationMethodOrder,
+ boolean verifyHostName) throws MOAHttpProtocolSocketFactoryException {
internalInitialize(url, null, trustStoreURL, acceptedServerCertURL, chainingMode, checkRevocation, revocationMethodOrder);
+ this.verifyHostName = verifyHostName;
+
}
/**
- * @param string
- * @param certStoreDirectory
- * @param trustStoreDirectory
- * @param object
- * @param string2
- * @param b
- * @param strings
+ * SSL Protocol socket factory
+ *
+ * @param url
+ * @param certStoreDirectory
+ * @param trustStoreURL
+ * @param acceptedServerCertURL
+ * @param chainingMode Specifies the ChainingMode for SSL certificate trust validation
+ * @param checkRevocation Enables / Disables certificate revocation checks
+ * @param revocationMethodOrder
+ * @param verifyHostName Enables / Disables hostName verfication
+ * @throws MOAHttpProtocolSocketFactoryException
*/
public MOAHttpProtocolSocketFactory(String url, String certStoreDirectory, String trustStoreURL,
String acceptedServerCertURL,
String chainingMode,
boolean checkRevocation,
- String[] revocationMethodOrder) throws MOAHttpProtocolSocketFactoryException {
+ String[] revocationMethodOrder,
+ boolean verifyHostName) throws MOAHttpProtocolSocketFactoryException {
internalInitialize(url, certStoreDirectory, trustStoreURL, acceptedServerCertURL, chainingMode, checkRevocation, revocationMethodOrder);
+ this.verifyHostName = verifyHostName;
+
}
private void internalInitialize(String url, String certStoreDirectory, String trustStoreURL,
@@ -120,7 +149,7 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
*/
public Socket createSocket(String host, int port, InetAddress localAddress,
int localPort) throws IOException, UnknownHostException {
- return setEnabledSslCiphers(this.sslfactory.createSocket(host, port,
+ return setSecurityRequirements(this.sslfactory.createSocket(host, port,
localAddress, localPort));
}
@@ -130,7 +159,7 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
public Socket createSocket(String host, int port, InetAddress localAddress,
int localPort, HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
- return setEnabledSslCiphers(this.sslfactory.createSocket(host, port,
+ return setSecurityRequirements(this.sslfactory.createSocket(host, port,
localAddress, localPort));
}
@@ -139,7 +168,7 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
*/
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
- return setEnabledSslCiphers(this.sslfactory.createSocket(host, port));
+ return setSecurityRequirements(this.sslfactory.createSocket(host, port));
}
/* (non-Javadoc)
@@ -147,10 +176,73 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
*/
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
- return setEnabledSslCiphers(this.sslfactory.createSocket(socket, host,
+ return setSecurityRequirements(this.sslfactory.createSocket(socket, host,
port, autoClose));
}
+
+ private Socket setSecurityRequirements(Socket socket) throws SSLException {
+ if (socket instanceof SSLSocket) {
+ SSLSocket sslSocket = (SSLSocket)socket;
+
+ //verify Hostname
+ verifyHostName(sslSocket);
+
+ //set allowed SSL ciphers
+ sslSocket = setEnabledSslCiphers(sslSocket);
+
+ return sslSocket;
+ }
+
+ return socket;
+ }
+
+ /**
+ * Verify hostname against SSL server certificate
+ *
+ * @param sslSocket
+ * @throws SSLPeerUnverifiedException
+ */
+ private void verifyHostName(SSLSocket sslSocket) throws SSLException{
+ if (verifyHostName) {
+ SSLSession session = sslSocket.getSession();
+ String hostName = session.getPeerHost();
+ Certificate[] certs = null;
+
+ try {
+ certs = session.getPeerCertificates();
+ if (certs == null || certs.length < 1)
+ throw new SSLPeerUnverifiedException("No server certificates found!");
+
+ X509Certificate x509 = (X509Certificate)certs[0];
+ DefaultHostnameVerifier hostNameVerifier = new DefaultHostnameVerifier();
+ hostNameVerifier.verify(hostName, x509);
+
+ } catch (SSLPeerUnverifiedException e) {
+ Logger.error("Host:" + hostName + " sends no certificates for validation.", e);
+ throw e;
+
+ } catch (SSLException e) {
+ Logger.error("Hostname validation FAILED:" + hostName + " validation ", e);
+
+ //log certificates in case of Debug
+ if (Logger.isDebugEnabled() && certs != null) {
+ Logger.debug("Server certificate chain:");
+ for (int i = 0; i < certs.length; i++) {
+ Logger.debug("X509Certificate[" + i + "]=" + certs[i]);
+ }
+
+ }
+
+ throw e;
+
+ }
+
+ }
+
+ }
+
+
/**
* Enable only a specific subset of TLS cipher suites
* This subset can be set by 'https.cipherSuites' SystemProperty (z.B. -Dhttps.cipherSuites=...)
@@ -158,19 +250,17 @@ public class MOAHttpProtocolSocketFactory implements SecureProtocolSocketFactory
* @param sslSocket {@link SSLSocket}
* @return {@link SSLSocket} with Ciphersuites
*/
- private Socket setEnabledSslCiphers(Socket sslSocket) {
- if (sslSocket instanceof SSLSocket) {
- String systemProp = System.getProperty("https.cipherSuites");
- if (MiscUtil.isNotEmpty(systemProp)) {
- ((SSLSocket) sslSocket).setEnabledCipherSuites(systemProp.split(","));
-
- }
+ private SSLSocket setEnabledSslCiphers(SSLSocket sslSocket) {
+ String systemProp = System.getProperty("https.cipherSuites");
+ if (MiscUtil.isNotEmpty(systemProp)) {
+ sslSocket.setEnabledCipherSuites(systemProp.split(","));
+
+ }
- try {
- Logger.trace("Enabled SSL-Cipher: " + StringUtils.join(((SSLSocket) sslSocket).getEnabledCipherSuites(), ","));
- } catch (Exception e) {
- Logger.error(e);
- }
+ try {
+ Logger.trace("Enabled SSL-Cipher: " + StringUtils.join(((SSLSocket) sslSocket).getEnabledCipherSuites(), ","));
+ } catch (Exception e) {
+ Logger.error(e);
}
return sslSocket;