aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2017-07-25 12:07:59 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2017-07-25 12:07:59 +0200
commitc4fe089610dba3d6e8929f6e163538dfae0d18da (patch)
treec9d9b079aa47aa58b00804bbd080715ee7cb2e39
parent782b159ec4050a459f8aadf85b68fb2b15fbf1b2 (diff)
downloadmoa-id-spss-c4fe089610dba3d6e8929f6e163538dfae0d18da.tar.gz
moa-id-spss-c4fe089610dba3d6e8929f6e163538dfae0d18da.tar.bz2
moa-id-spss-c4fe089610dba3d6e8929f6e163538dfae0d18da.zip
betaversion for a workaround to solve problem with Java8 >= 141 and SHA1 certificates in certificate chain
-rw-r--r--id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOASSLAlgorithmConstraints.java175
-rw-r--r--id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOATrustManagerWrapper.java267
-rw-r--r--id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java4
-rw-r--r--id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/validation/MOASSLAlgorithmChecker.java226
4 files changed, 671 insertions, 1 deletions
diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOASSLAlgorithmConstraints.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOASSLAlgorithmConstraints.java
new file mode 100644
index 000000000..8f367598d
--- /dev/null
+++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/MOASSLAlgorithmConstraints.java
@@ -0,0 +1,175 @@
+/*
+ * 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.security.AlgorithmConstraints;
+import java.security.AlgorithmParameters;
+import java.security.CryptoPrimitive;
+import java.security.Key;
+import java.util.Set;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * @author tlenz
+ *
+ */
+public class MOASSLAlgorithmConstraints implements AlgorithmConstraints {
+
+ private AlgorithmConstraints userAlgConstraints = null;
+ private AlgorithmConstraints peerAlgConstraints = null;
+
+ private boolean enabledX509DisabledAlgConstraints = true;
+
+
+ static final AlgorithmConstraints DEFAULT = new MOASSLAlgorithmConstraints(null);
+
+
+ public MOASSLAlgorithmConstraints()
+ {
+
+ }
+
+
+ static final AlgorithmConstraints DEFAULT_SSL_ONLY = new MOASSLAlgorithmConstraints((SSLSocket)null, false);
+
+ MOASSLAlgorithmConstraints(AlgorithmConstraints paramAlgorithmConstraints)
+ {
+ this.userAlgConstraints = paramAlgorithmConstraints;
+
+ }
+
+
+ MOASSLAlgorithmConstraints(SSLSocket paramSSLSocket, boolean paramBoolean)
+ {
+ if (paramSSLSocket != null) {
+ this.userAlgConstraints = paramSSLSocket.getSSLParameters().getAlgorithmConstraints();
+
+ }
+
+ if (!(paramBoolean))
+ this.enabledX509DisabledAlgConstraints = false;
+ }
+
+
+ MOASSLAlgorithmConstraints(SSLEngine paramSSLEngine, boolean paramBoolean)
+ {
+ if (paramSSLEngine != null) {
+ this.userAlgConstraints = paramSSLEngine.getSSLParameters().getAlgorithmConstraints();
+
+ }
+
+ if (!(paramBoolean))
+ this.enabledX509DisabledAlgConstraints = false;
+ }
+
+ MOASSLAlgorithmConstraints(SSLSocket paramSSLSocket, String[] paramArrayOfString, boolean paramBoolean)
+ {
+ if (paramSSLSocket != null) {
+ this.userAlgConstraints = paramSSLSocket.getSSLParameters().getAlgorithmConstraints();
+
+ //this.peerAlgConstraints = new SupportedSignatureAlgorithmConstraints(paramArrayOfString);
+
+ }
+
+ if (!(paramBoolean))
+ this.enabledX509DisabledAlgConstraints = false;
+ }
+
+
+// MOASSLAlgorithmConstraints(SSLEngine paramSSLEngine, String[] paramArrayOfString, boolean paramBoolean)
+// {
+// if (paramSSLEngine != null) {
+// this.userAlgConstraints = paramSSLEngine.getSSLParameters().getAlgorithmConstraints();
+//
+// this.peerAlgConstraints = new SupportedSignatureAlgorithmConstraints(paramArrayOfString);
+//
+// }
+//
+// if (!(paramBoolean))
+// this.enabledX509DisabledAlgConstraints = false;
+// }
+
+
+ /* (non-Javadoc)
+ * @see java.security.AlgorithmConstraints#permits(java.util.Set, java.lang.String, java.security.AlgorithmParameters)
+ */
+ @Override
+ public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters) {
+ boolean bool = true;
+
+ if (this.peerAlgConstraints != null) {
+ bool = this.peerAlgConstraints.permits(primitives, algorithm, parameters);
+
+ }
+
+ if ((bool) && (this.userAlgConstraints != null)) {
+ bool = this.userAlgConstraints.permits(primitives, algorithm, parameters);
+
+ }
+
+ return bool;
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.AlgorithmConstraints#permits(java.util.Set, java.security.Key)
+ */
+ @Override
+ public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+ boolean bool = true;
+
+ if (this.peerAlgConstraints != null) {
+ bool = this.peerAlgConstraints.permits(primitives, key);
+ }
+
+ if ((bool) && (this.userAlgConstraints != null)) {
+ bool = this.userAlgConstraints.permits(primitives, key);
+ }
+
+ return bool;
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.AlgorithmConstraints#permits(java.util.Set, java.lang.String, java.security.Key, java.security.AlgorithmParameters)
+ */
+ @Override
+ public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) {
+ boolean bool = true;
+
+ if (this.peerAlgConstraints != null) {
+ bool = this.peerAlgConstraints.permits(primitives, algorithm, key, parameters);
+
+ }
+
+ if ((bool) && (this.userAlgConstraints != null)) {
+ bool = this.userAlgConstraints.permits(primitives, algorithm, key, parameters);
+
+ }
+
+ return bool;
+ }
+
+}
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);
+ }
+
+}
diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java
index 109390132..3e793e4d1 100644
--- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java
+++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/ssl/SSLUtils.java
@@ -147,6 +147,7 @@ public class SSLUtils {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kms, tms, null);
ssf = ctx.getSocketFactory();
+
// store SSLSocketFactory
sslSocketFactories.put(url, ssf);
@@ -259,7 +260,8 @@ public class SSLUtils {
MOAIDTrustManager.initializeLoggingContext();
MOAIDTrustManager tm = new MOAIDTrustManager(acceptedServerCertURL);
tm.init(cfg, profile);
- return new TrustManager[] {tm};
+ return new TrustManager[] {new MOATrustManagerWrapper(tm)};
+
}
}
diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/validation/MOASSLAlgorithmChecker.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/validation/MOASSLAlgorithmChecker.java
new file mode 100644
index 000000000..990b5d3b1
--- /dev/null
+++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/validation/MOASSLAlgorithmChecker.java
@@ -0,0 +1,226 @@
+/*
+ * 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.validation;
+
+import java.math.BigInteger;
+import java.security.AlgorithmConstraints;
+import java.security.AlgorithmParameters;
+import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.PKIXReason;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.x509.X509CertImpl;
+
+/**
+ * @author tlenz
+ *
+ */
+public class MOASSLAlgorithmChecker extends PKIXCertPathChecker {
+
+ private final AlgorithmConstraints constraints;
+ private final PublicKey trustedPubKey;
+ private PublicKey prevPubKey;
+ private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET = Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+ private static final Set<CryptoPrimitive> KU_PRIMITIVE_SET = Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE, CryptoPrimitive.KEY_ENCAPSULATION, CryptoPrimitive.PUBLIC_KEY_ENCRYPTION, CryptoPrimitive.KEY_AGREEMENT));
+
+ private static final DisabledAlgorithmConstraints certPathDefaultConstraints = new DisabledAlgorithmConstraints("jdk.certpath.disabledAlgorithms");
+
+ /**
+ *
+ */
+ public MOASSLAlgorithmChecker() {
+ this.prevPubKey = null;
+ this.trustedPubKey = null;
+ this.constraints = certPathDefaultConstraints;
+
+ }
+
+ public MOASSLAlgorithmChecker(AlgorithmConstraints paramAlgorithmConstraints) {
+ this.prevPubKey = null;
+ this.trustedPubKey = null;
+ this.constraints = paramAlgorithmConstraints;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.cert.PKIXCertPathChecker#init(boolean)
+ */
+ @Override
+ public void init(boolean forward) throws CertPathValidatorException {
+ if (!(forward)) {
+ if (this.trustedPubKey != null)
+ this.prevPubKey = this.trustedPubKey;
+
+ else
+ this.prevPubKey = null;
+
+ } else
+ throw new CertPathValidatorException("forward checking not supported");
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.cert.PKIXCertPathChecker#isForwardCheckingSupported()
+ */
+ @Override
+ public boolean isForwardCheckingSupported() {
+ return false;
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.cert.PKIXCertPathChecker#getSupportedExtensions()
+ */
+ @Override
+ public Set<String> getSupportedExtensions() {
+ return null;
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.cert.PKIXCertPathChecker#check(java.security.cert.Certificate, java.util.Collection)
+ */
+ @Override
+ public void check(Certificate cert, Collection<String> unresolvedCritExts) throws CertPathValidatorException {
+ if ((!(cert instanceof X509Certificate)) || (this.constraints == null)) {
+ return;
+
+ }
+
+ X509CertImpl localX509CertImpl = null;
+ try {
+ localX509CertImpl = sun.security.x509.X509CertImpl.toImpl((X509Certificate)cert);
+
+ } catch (CertificateException localCertificateException1) {
+ throw new CertPathValidatorException(localCertificateException1);
+
+ }
+
+ PublicKey localPublicKey = localX509CertImpl.getPublicKey();
+ String str = localX509CertImpl.getSigAlgName();
+
+
+ //check algorithms
+ AlgorithmParameters localAlgorithmParameters = null;
+ try {
+ sun.security.x509.AlgorithmId localAlgorithmId = null;
+ localAlgorithmId = (sun.security.x509.AlgorithmId)localX509CertImpl.get("x509.algorithm");
+ localAlgorithmParameters = localAlgorithmId.getParameters();
+
+ if (!(this.constraints.permits(SIGNATURE_PRIMITIVE_SET, str, localAlgorithmParameters))) {
+ throw new CertPathValidatorException("Algorithm constraints check failed: " + str, null, null, -1, CertPathValidatorException.BasicReason.ALGORITHM_CONSTRAINED);
+
+ }
+
+ } catch (CertificateParsingException localCertificateException2) {
+ throw new CertPathValidatorException(localCertificateException2);
+
+ }
+
+
+ //check key usage
+ boolean[] arrayOfBoolean = localX509CertImpl.getKeyUsage();
+ if ((arrayOfBoolean != null) && (arrayOfBoolean.length < 9))
+ throw new CertPathValidatorException("incorrect KeyUsage extension", null, null, -1, PKIXReason.INVALID_KEY_USAGE);
+
+ if (arrayOfBoolean != null) {
+ Set<CryptoPrimitive> cryptoPrimitives = EnumSet.noneOf(CryptoPrimitive.class);
+ if ((arrayOfBoolean[0] == true) || (arrayOfBoolean[1] == true) || (arrayOfBoolean[5] == true) || (arrayOfBoolean[6] == true)) {
+ cryptoPrimitives.add(CryptoPrimitive.SIGNATURE);
+
+ }
+
+ if (arrayOfBoolean[2] == true) {
+ cryptoPrimitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
+
+ }
+
+ if (arrayOfBoolean[3] == true) {
+ cryptoPrimitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
+
+ }
+
+ if (arrayOfBoolean[4] == true) {
+ cryptoPrimitives.add(CryptoPrimitive.KEY_AGREEMENT);
+
+ }
+
+ if ((!(cryptoPrimitives.isEmpty())) && (!(this.constraints.permits(cryptoPrimitives, localPublicKey)))) {
+ throw new CertPathValidatorException("algorithm constraints check failed", null, null, -1, CertPathValidatorException.BasicReason.ALGORITHM_CONSTRAINED);
+
+ }
+ }
+
+ //check pubKeys
+ if (this.prevPubKey != null) {
+ if ((str != null) && (!(this.constraints.permits(SIGNATURE_PRIMITIVE_SET, str, this.prevPubKey, localAlgorithmParameters)))) {
+ throw new CertPathValidatorException("Algorithm constraints check failed: " + str, null, null, -1, CertPathValidatorException.BasicReason.ALGORITHM_CONSTRAINED);
+
+ }
+
+ if ((localPublicKey instanceof DSAPublicKey) && (((DSAPublicKey)localPublicKey).getParams() == null)) {
+ if (!(this.prevPubKey instanceof DSAPublicKey)) {
+ throw new CertPathValidatorException("Input key is not of a appropriate type for inheriting parameters");
+
+ }
+
+ DSAParams localObject = ((DSAPublicKey)this.prevPubKey).getParams();
+ if (localObject == null) {
+ throw new CertPathValidatorException("Key parameters missing");
+
+ }
+
+ try {
+ BigInteger localBigInteger = ((DSAPublicKey)localPublicKey).getY();
+ KeyFactory localKeyFactory = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec localDSAPublicKeySpec = new DSAPublicKeySpec(localBigInteger, ((DSAParams)localObject).getP(), ((DSAParams)localObject).getQ(), ((DSAParams)localObject).getG());
+ localPublicKey = localKeyFactory.generatePublic(localDSAPublicKeySpec);
+
+ } catch (GeneralSecurityException localGeneralSecurityException) {
+ throw new CertPathValidatorException("Unable to generate key with inherited parameters: " + localGeneralSecurityException.getMessage(), localGeneralSecurityException);
+
+ }
+ }
+ }
+
+ this.prevPubKey = localPublicKey;
+ }
+
+
+}