diff options
Diffstat (limited to 'id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java')
-rw-r--r-- | id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java new file mode 100644 index 000000000..c71d50161 --- /dev/null +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java @@ -0,0 +1,267 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.commons.utils.ssl; + +import java.lang.reflect.Constructor; +import java.net.Socket; +import java.security.AlgorithmConstraints; +import java.security.Timestamp; +import java.security.cert.CertPathValidatorException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.PKIXCertPathChecker; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.HashSet; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.net.ssl.X509TrustManager; + +import at.gv.egovernment.moa.id.commons.validation.MOASSLAlgorithmChecker; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import sun.security.provider.certpath.AlgorithmChecker; +import sun.security.util.DisabledAlgorithmConstraints; + +/** + * @author tlenz + * + */ +public class MOATrustManagerWrapper extends X509ExtendedTrustManager implements X509TrustManager { + + private X509TrustManager internalTrustManager = null; + + + /** + * + */ + public MOATrustManagerWrapper(X509TrustManager trustManger) { + this.internalTrustManager = trustManger; + + } + + + + /* (non-Javadoc) + * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String) + */ + @Override + public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) + throws CertificateException { + internalTrustManager.checkClientTrusted(paramArrayOfX509Certificate, paramString); + + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String) + */ + @Override + public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) + throws CertificateException { + internalTrustManager.checkServerTrusted(paramArrayOfX509Certificate, paramString); + + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() + */ + @Override + public X509Certificate[] getAcceptedIssuers() { + return internalTrustManager.getAcceptedIssuers(); + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509ExtendedTrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String, java.net.Socket) + */ + @Override + public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString, + Socket paramSocket) throws CertificateException { + internalTrustManager.checkClientTrusted(paramArrayOfX509Certificate, paramString); + + checkAdditionalTrust(paramArrayOfX509Certificate, paramString, paramSocket, true); + + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509ExtendedTrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.net.Socket) + */ + @Override + public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString, + Socket paramSocket) throws CertificateException { + + internalTrustManager.checkServerTrusted(paramArrayOfX509Certificate, paramString); + + checkAdditionalTrust(paramArrayOfX509Certificate, paramString, paramSocket, false); + + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509ExtendedTrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String, javax.net.ssl.SSLEngine) + */ + @Override + public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString, + SSLEngine paramSSLEngine) throws CertificateException { + internalTrustManager.checkClientTrusted(paramArrayOfX509Certificate, paramString); + + checkAdditionalTrust(paramArrayOfX509Certificate, paramString, paramSSLEngine, true); + + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509ExtendedTrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, javax.net.ssl.SSLEngine) + */ + @Override + public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString, + SSLEngine paramSSLEngine) throws CertificateException { + internalTrustManager.checkServerTrusted(paramArrayOfX509Certificate, paramString); + + checkAdditionalTrust(paramArrayOfX509Certificate, paramString, paramSSLEngine, false); + } + + + + private void checkAdditionalTrust(X509Certificate[] paramArrayOfX509Certificate, + String paramString, Socket paramSocket, boolean isClient) throws CertificateException { + if ((paramSocket == null) || (!(paramSocket.isConnected())) || (!(paramSocket instanceof SSLSocket))) { + return; + + } + + SSLSocket localSSLSocket = (SSLSocket)paramSocket; + SSLSession localSSLSession = localSSLSocket.getHandshakeSession(); + if (localSSLSession == null) { + throw new CertificateException("No handshake session"); + } + + String endpointIdenfificationAlgo = localSSLSocket.getSSLParameters().getEndpointIdentificationAlgorithm(); + if (MiscUtil.isNotEmpty(endpointIdenfificationAlgo)) { + String peerHost = localSSLSession.getPeerHost(); + checkIdentity(peerHost, paramArrayOfX509Certificate[0], endpointIdenfificationAlgo); + + } + + AlgorithmConstraints localSSLAlgorithmConstraints = new DisabledAlgorithmConstraints("jdk.certpath.disabledAlgorithms"); + checkAlgorithmConstraints(paramArrayOfX509Certificate, localSSLAlgorithmConstraints, isClient); + } + + private void checkAdditionalTrust(X509Certificate[] paramArrayOfX509Certificate, String paramString, + SSLEngine paramSSLEngine, boolean isClient) throws CertificateException { + if (paramSSLEngine != null) { + SSLSession localSSLSession = paramSSLEngine.getHandshakeSession(); + if (localSSLSession == null) { + throw new CertificateException("No handshake session"); + + } + + String str = paramSSLEngine.getSSLParameters().getEndpointIdentificationAlgorithm(); + if ((str != null) && (str.length() != 0)) { + String peerHost = localSSLSession.getPeerHost(); + checkIdentity(peerHost, paramArrayOfX509Certificate[0], str); + + } + + AlgorithmConstraints localSSLAlgorithmConstraints = new DisabledAlgorithmConstraints("jdk.certpath.disabledAlgorithms"); + checkAlgorithmConstraints(paramArrayOfX509Certificate, localSSLAlgorithmConstraints, isClient); + } + } + + private void checkAlgorithmConstraints(X509Certificate[] certificates, + java.security.AlgorithmConstraints algorithmConstraint, boolean isClient) throws CertificateException { + try { + int i = certificates.length - 1; + HashSet<X509Certificate> localHashSet = new HashSet<X509Certificate>(); + X509Certificate[] arrayOfX509Certificate = this.internalTrustManager.getAcceptedIssuers(); + + if ((arrayOfX509Certificate != null) && (arrayOfX509Certificate.length > 0)) { + Collections.addAll(localHashSet, arrayOfX509Certificate); + + } + + if (localHashSet.contains(certificates[i])) { + --i; + } + + if (i >= 0) { + PKIXCertPathChecker localAlgorithmChecker = null; + Class<?> algorithCheckerClass = null; + try { + algorithCheckerClass = Class.forName("sun.security.provider.certpath.AlgorithmChecker"); + Constructor<?> algorithCheckerConstructorJava8_141 = algorithCheckerClass.getConstructor(AlgorithmConstraints.class, Timestamp.class, String.class); + localAlgorithmChecker = (AlgorithmChecker) algorithCheckerConstructorJava8_141.newInstance(algorithmConstraint, (Timestamp)null, isClient?"tls client":"tls server"); + Logger.trace("Use SSL AlgorithmChecker from JAVA8 >= 141 ..."); + + } catch (Throwable e) { + try { + Constructor<?> algorithCheckerConstructorJava8_71 = algorithCheckerClass.getConstructor(AlgorithmConstraints.class); + localAlgorithmChecker = (AlgorithmChecker) algorithCheckerConstructorJava8_71.newInstance(algorithmConstraint); + + Logger.trace("Use SSL AlgorithmChecker from JAVA8 < 141 ..."); + + } catch (Throwable e1) { + Logger.error("Can NOT instance JAVA SSL AlgorithmChecker", e1); + Logger.error("USE ONE LEGACY VERSION OF ALGORITHM CHECKER ..."); + localAlgorithmChecker = new MOASSLAlgorithmChecker(); + + } + } + + + localAlgorithmChecker.init(false); + + for (int j = i; j >= 0; --j) { + X509Certificate localX509Certificate = certificates[j]; + + //localAlgorithmChecker.check((Certificate)localX509Certificate, Collections.emptySet()); + localAlgorithmChecker.check((Certificate)localX509Certificate, null); + } + } + } catch (CertPathValidatorException localCertPathValidatorException) { + throw new CertificateException("Certificates does not conform to algorithm constraints"); + + } + } + + private void checkIdentity(String peerHost, X509Certificate paramX509Certificate, String endpointIdenfificationAlgo) + throws CertificateException { + if (MiscUtil.isEmpty(endpointIdenfificationAlgo)) + return; + + if ((peerHost != null) && (peerHost.startsWith("[")) && (peerHost.endsWith("]"))) { + peerHost = peerHost.substring(1, peerHost.length() - 1); + + } + + if (endpointIdenfificationAlgo.equalsIgnoreCase("HTTPS")) { + sun.security.util.HostnameChecker.getInstance((byte)1).match(peerHost, paramX509Certificate); + + } else if ((endpointIdenfificationAlgo.equalsIgnoreCase("LDAP")) || (endpointIdenfificationAlgo.equalsIgnoreCase("LDAPS"))) { + sun.security.util.HostnameChecker.getInstance((byte)2).match(peerHost, paramX509Certificate); + + } else + throw new CertificateException("Unknown identification algorithm: " + endpointIdenfificationAlgo); + } + +} |