summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
commit759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f (patch)
tree2132024fc058b1ef5338bf50df575a3244cc3f9f /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils
parent4f15bdc45b08724d20c66c9fd74ea6a43a03c32f (diff)
downloadEAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.gz
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.bz2
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.zip
common EGIZ code-style refactoring
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java430
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java104
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java106
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java201
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java247
5 files changed, 578 insertions, 510 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java
index acc5357e..ea361f11 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java
@@ -1,36 +1,32 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 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:
+ * Licensed under the EUPL, Version 1.2 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:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * 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.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * 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.egiz.eaaf.modules.pvp2.impl.utils;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.RSAPrivateKey;
-
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
+import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.KeyStoreX509CredentialAdapter;
import org.apache.commons.lang3.StringUtils;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.UsageType;
@@ -40,186 +36,210 @@ import org.opensaml.xml.signature.SignatureConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils;
-import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;
-import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.KeyStoreX509CredentialAdapter;
-
public abstract class AbstractCredentialProvider {
-
- private static final Logger log = LoggerFactory.getLogger(AbstractCredentialProvider.class);
-
- private KeyStore keyStore = null;
-
- /**
- * Get a friendlyName for this keyStore implementation
- * This friendlyName is used for logging
- *
- * @return keyStore friendlyName
- */
- public abstract String getFriendlyName();
-
- /**
- * Get KeyStore
- *
- * @return URL to the keyStore
- * @throws EAAFException
- */
- public abstract String getKeyStoreFilePath() throws EAAFException;
-
- /**
- * Get keyStore password
- *
- * @return Password of the keyStore
- */
- public abstract String getKeyStorePassword();
-
- /**
- * Get alias of key for metadata signing
- *
- * @return key alias
- */
- public abstract String getMetadataKeyAlias();
-
- /**
- * Get password of key for metadata signing
- *
- * @return key password
- */
- public abstract String getMetadataKeyPassword();
-
- /**
- * Get alias of key for request/response signing
- *
- * @return key alias
- */
- public abstract String getSignatureKeyAlias();
-
- /**
- * Get password of key for request/response signing
- *
- * @return key password
- */
- public abstract String getSignatureKeyPassword();
-
- /**
- * Get alias of key for IDP response encryption
- *
- * @return key alias
- */
- public abstract String getEncryptionKeyAlias();
-
- /**
- * Get password of key for IDP response encryption
- *
- * @return key password
- */
- public abstract String getEncryptionKeyPassword();
-
-
- public X509Credential getIDPMetaDataSigningCredential()
- throws CredentialsNotAvailableException {
- try {
-
- if (keyStore == null)
- keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(),
- getKeyStorePassword());
-
- KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(
- keyStore, getMetadataKeyAlias(), getMetadataKeyPassword().toCharArray());
-
- credentials.setUsageType(UsageType.SIGNING);
- if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
- log.error(getFriendlyName() + " Metadata Signing credentials is not found or contains no PrivateKey.");
- throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Signing credentials (Alias: "
- + getMetadataKeyAlias() + ") is not found or contains no PrivateKey."});
-
- }
- return credentials;
- } catch (Exception e) {
- log.error("Failed to generate " + getFriendlyName() + " Metadata Signing credentials");
- e.printStackTrace();
- throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e);
- }
- }
-
- public X509Credential getIDPAssertionSigningCredential()
- throws CredentialsNotAvailableException {
- try {
- if (keyStore == null)
- keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(),
- getKeyStorePassword());
-
- KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(
- keyStore, getSignatureKeyAlias(), getSignatureKeyPassword().toCharArray());
-
- credentials.setUsageType(UsageType.SIGNING);
- if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
- log.error(getFriendlyName() + " Assertion Signing credentials is not found or contains no PrivateKey.");
- throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Signing credentials (Alias: "
- + getSignatureKeyAlias() + ") is not found or contains no PrivateKey."});
-
- }
-
- return (X509Credential) credentials;
- } catch (Exception e) {
- log.error("Failed to generate " + getFriendlyName() + " Assertion Signing credentials");
- e.printStackTrace();
- throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e);
- }
- }
-
- public X509Credential getIDPAssertionEncryptionCredential()
- throws CredentialsNotAvailableException {
- try {
- if (keyStore == null)
- keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(),
- getKeyStorePassword());
-
- //if no encryption key is configured return null
- if (StringUtils.isEmpty(getEncryptionKeyAlias()))
- return null;
-
- KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(
- keyStore, getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
-
- credentials.setUsageType(UsageType.ENCRYPTION);
-
- if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
- log.error(getFriendlyName() + " Assertion Encryption credentials is not found or contains no PrivateKey.");
- throw new CredentialsNotAvailableException("config.27", new Object[]{getFriendlyName() + " Assertion Encryption credentials (Alias: "
- + getEncryptionKeyAlias() + ") is not found or contains no PrivateKey."});
-
- }
-
- return (X509Credential) credentials;
-
- } catch (Exception e) {
- log.error("Failed to generate " + getFriendlyName() + " Assertion Encryption credentials");
- e.printStackTrace();
- throw new CredentialsNotAvailableException("config.27", new Object[]{e.getMessage()}, e);
- }
- }
-
- public static Signature getIDPSignature(Credential credentials) {
- PrivateKey privatekey = credentials.getPrivateKey();
- Signature signer = SAML2Utils.createSAMLObject(Signature.class);
-
- if (privatekey instanceof RSAPrivateKey) {
- signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
-
- } else if (privatekey instanceof ECPrivateKey) {
- signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256);
-
- } else {
- log.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId() + " credential.");
-
-
- }
-
- signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
- signer.setSigningCredential(credentials);
- return signer;
-
- }
+
+ private static final Logger log = LoggerFactory.getLogger(AbstractCredentialProvider.class);
+
+ private KeyStore keyStore = null;
+
+ /**
+ * Get a friendlyName for this keyStore implementation This friendlyName is used for logging.
+ *
+ * @return keyStore friendlyName
+ */
+ public abstract String getFriendlyName();
+
+ /**
+ * Get KeyStore.
+ *
+ * @return URL to the keyStore
+ * @throws EaafException In case of an invalid filepath
+ */
+ public abstract String getKeyStoreFilePath() throws EaafException;
+
+ /**
+ * Get keyStore password.
+ *
+ * @return Password of the keyStore
+ */
+ public abstract String getKeyStorePassword();
+
+ /**
+ * Get alias of key for metadata signing.
+ *
+ * @return key alias
+ */
+ public abstract String getMetadataKeyAlias();
+
+ /**
+ * Get password of key for metadata signing.
+ *
+ * @return key password
+ */
+ public abstract String getMetadataKeyPassword();
+
+ /**
+ * Get alias of key for request/response signing.
+ *
+ * @return key alias
+ */
+ public abstract String getSignatureKeyAlias();
+
+ /**
+ * Get password of key for request/response signing.
+ *
+ * @return key password
+ */
+ public abstract String getSignatureKeyPassword();
+
+ /**
+ * Get alias of key for IDP response encryption.
+ *
+ * @return key alias
+ */
+ public abstract String getEncryptionKeyAlias();
+
+ /**
+ * Get password of key for IDP response encryption.
+ *
+ * @return key password
+ */
+ public abstract String getEncryptionKeyPassword();
+
+
+ /**
+ * Get Credentials to sign metadata.
+ *
+ * @return Credentials
+ * @throws CredentialsNotAvailableException In case of a credential error
+ */
+ public X509Credential getIdpMetaDataSigningCredential() throws CredentialsNotAvailableException {
+ try {
+
+ if (keyStore == null) {
+ keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword());
+ }
+
+ final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore,
+ getMetadataKeyAlias(), getMetadataKeyPassword().toCharArray());
+
+ credentials.setUsageType(UsageType.SIGNING);
+ if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
+ log.error(getFriendlyName()
+ + " Metadata Signing credentials is not found or contains no PrivateKey.");
+ throw new CredentialsNotAvailableException("config.27",
+ new Object[] {getFriendlyName() + " Assertion Signing credentials (Alias: "
+ + getMetadataKeyAlias() + ") is not found or contains no PrivateKey."});
+
+ }
+ return credentials;
+ } catch (final Exception e) {
+ log.error("Failed to generate " + getFriendlyName() + " Metadata Signing credentials");
+ e.printStackTrace();
+ throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+ /**
+ * Get Credentials to sign Assertion.
+ *
+ * @return Credentials
+ * @throws CredentialsNotAvailableException In case of a credential error
+ */
+ public X509Credential getIdpAssertionSigningCredential() throws CredentialsNotAvailableException {
+ try {
+ if (keyStore == null) {
+ keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword());
+ }
+
+ final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore,
+ getSignatureKeyAlias(), getSignatureKeyPassword().toCharArray());
+
+ credentials.setUsageType(UsageType.SIGNING);
+ if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
+ log.error(getFriendlyName()
+ + " Assertion Signing credentials is not found or contains no PrivateKey.");
+ throw new CredentialsNotAvailableException("config.27",
+ new Object[] {getFriendlyName() + " Assertion Signing credentials (Alias: "
+ + getSignatureKeyAlias() + ") is not found or contains no PrivateKey."});
+
+ }
+
+ return credentials;
+ } catch (final Exception e) {
+ log.error("Failed to generate " + getFriendlyName() + " Assertion Signing credentials");
+ e.printStackTrace();
+ throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+ /**
+ * Get Credentials to encrypt assertion.
+ *
+ * @return Credentials
+ * @throws CredentialsNotAvailableException In case of a credential error
+ */
+ public X509Credential getIdpAssertionEncryptionCredential()
+ throws CredentialsNotAvailableException {
+ try {
+ if (keyStore == null) {
+ keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), getKeyStorePassword());
+ }
+
+ // if no encryption key is configured return null
+ if (StringUtils.isEmpty(getEncryptionKeyAlias())) {
+ return null;
+ }
+
+ final KeyStoreX509CredentialAdapter credentials = new KeyStoreX509CredentialAdapter(keyStore,
+ getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
+
+ credentials.setUsageType(UsageType.ENCRYPTION);
+
+ if (credentials.getPrivateKey() == null && credentials.getSecretKey() == null) {
+ log.error(getFriendlyName()
+ + " Assertion Encryption credentials is not found or contains no PrivateKey.");
+ throw new CredentialsNotAvailableException("config.27",
+ new Object[] {getFriendlyName() + " Assertion Encryption credentials (Alias: "
+ + getEncryptionKeyAlias() + ") is not found or contains no PrivateKey."});
+
+ }
+
+ return credentials;
+
+ } catch (final Exception e) {
+ log.error("Failed to generate " + getFriendlyName() + " Assertion Encryption credentials");
+ e.printStackTrace();
+ throw new CredentialsNotAvailableException("config.27", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+ /**
+ * Get an XML signature object.
+ *
+ * @param credentials Credentials for signing
+ * @return OpenSAML Signature object
+ */
+ public static Signature getIdpSignature(final Credential credentials) {
+ final PrivateKey privatekey = credentials.getPrivateKey();
+ final Signature signer = Saml2Utils.createSamlObject(Signature.class);
+
+ if (privatekey instanceof RSAPrivateKey) {
+ signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
+
+ } else if (privatekey instanceof ECPrivateKey) {
+ signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256);
+
+ } else {
+ log.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId()
+ + " credential.");
+
+
+ }
+
+ signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+ signer.setSigningCredential(credentials);
+ return signer;
+
+ }
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java
deleted file mode 100644
index 8e7183d3..00000000
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QAALevelVerifier.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 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:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * 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.egiz.eaaf.modules.pvp2.impl.utils;
-
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
-import at.gv.egiz.eaaf.modules.pvp2.exception.QAANotAllowedException;
-
-/**
- * @author tlenz
- *
- */
-public class QAALevelVerifier {
-
- private static final Logger log = LoggerFactory.getLogger(QAALevelVerifier.class);
-
- private static boolean verifyQAALevel(String qaaAuth, String requiredLoA, String matchingMode) throws QAANotAllowedException {
- //to MINIMUM machting
- if (EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM.equals(matchingMode)) {
- log.trace("Perfom LoA matching in 'MINIMUM' mode ... ");
- if (EAAFConstants.EIDAS_LOA_LOW.equals(requiredLoA) &&
- (EAAFConstants.EIDAS_LOA_LOW.equals(qaaAuth) ||
- EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) ||
- EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))
- )
- return true;
-
- else if (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(requiredLoA) &&
- (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth) ||
- EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))
- )
- return true;
-
- else if (EAAFConstants.EIDAS_LOA_HIGH.equals(requiredLoA) && EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))
- return true;
-
- } else if (EAAFConstants.EIDAS_LOA_MATCHING_EXACT.equals(matchingMode)) {
- //to EXACT matching
- log.trace("Perfom LoA matching in 'EXACT' mode ... ");
- if (qaaAuth.equals(requiredLoA)) {
- log.debug("Required LoA fits LoA from authentication. Continue auth process ... ");
- return true;
-
- }
-
- } else {
- log.warn("LoA matching-mode:" + matchingMode + " is NOT supported by this implementation");
- throw new QAANotAllowedException(qaaAuth, requiredLoA, matchingMode);
-
- }
-
- return false;
-
- }
-
- public static void verifyQAALevel(String qaaAuth, List<String> requiredLoAs, String matchingMode) throws QAANotAllowedException {
- log.trace("Starting LoA verification: authLoA: " + qaaAuth
- + " requiredLoA: " + StringUtils.join(requiredLoAs, "|")
- + " matchingMode: " + matchingMode);
-
- boolean hasMatch = false;
- for (String loa : requiredLoAs) {
- if (verifyQAALevel(qaaAuth, loa, matchingMode))
- hasMatch = true;
-
- }
-
- if (!hasMatch)
- throw new QAANotAllowedException(qaaAuth, StringUtils.join(requiredLoAs, "|"), matchingMode);
-
- else
- log.debug("Requesed LoA fits LoA from authentication. Continue auth process ... ");
-
- }
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java
new file mode 100644
index 00000000..876fa744
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/QaaLevelVerifier.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 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:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * 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.egiz.eaaf.modules.pvp2.impl.utils;
+
+import java.util.List;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.modules.pvp2.exception.QaaNotAllowedException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * EAAF LoA Level verifier checks if requested LoA matchs to LoA of authentication.
+ *
+ *
+ * @author tlenz
+ *
+ */
+public class QaaLevelVerifier {
+
+ private static final Logger log = LoggerFactory.getLogger(QaaLevelVerifier.class);
+
+ private static boolean verifyQaaLevel(final String qaaAuth, final String requiredLoA,
+ final String matchingMode) throws QaaNotAllowedException {
+ // to MINIMUM machting
+ if (EAAFConstants.EIDAS_LOA_MATCHING_MINIMUM.equals(matchingMode)) {
+ log.trace("Perfom LoA matching in 'MINIMUM' mode ... ");
+ if (EAAFConstants.EIDAS_LOA_LOW.equals(requiredLoA)
+ && (EAAFConstants.EIDAS_LOA_LOW.equals(qaaAuth)
+ || EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth)
+ || EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))) {
+ return true;
+ } else if (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(requiredLoA)
+ && (EAAFConstants.EIDAS_LOA_SUBSTANTIAL.equals(qaaAuth)
+ || EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth))) {
+ return true;
+ } else if (EAAFConstants.EIDAS_LOA_HIGH.equals(requiredLoA)
+ && EAAFConstants.EIDAS_LOA_HIGH.equals(qaaAuth)) {
+ return true;
+ }
+
+ } else if (EAAFConstants.EIDAS_LOA_MATCHING_EXACT.equals(matchingMode)) {
+ // to EXACT matching
+ log.trace("Perfom LoA matching in 'EXACT' mode ... ");
+ if (qaaAuth.equals(requiredLoA)) {
+ log.debug("Required LoA fits LoA from authentication. Continue auth process ... ");
+ return true;
+
+ }
+
+ } else {
+ log.warn("LoA matching-mode:" + matchingMode + " is NOT supported by this implementation");
+ throw new QaaNotAllowedException(qaaAuth, requiredLoA, matchingMode);
+
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Check LoA level.
+ *
+ * @param qaaAuth LoA of authentication
+ * @param requiredLoAs List of allowed LoA levels
+ * @param matchingMode LoA matching mode
+ * @throws QaaNotAllowedException If LoA does not match
+ */
+ public static void verifyQaaLevel(final String qaaAuth, final List<String> requiredLoAs,
+ final String matchingMode) throws QaaNotAllowedException {
+ log.trace("Starting LoA verification: authLoA: " + qaaAuth + " requiredLoA: "
+ + StringUtils.join(requiredLoAs, "|") + " matchingMode: " + matchingMode);
+
+ boolean hasMatch = false;
+ for (final String loa : requiredLoAs) {
+ if (verifyQaaLevel(qaaAuth, loa, matchingMode)) {
+ hasMatch = true;
+ }
+
+ }
+
+ if (!hasMatch) {
+ throw new QaaNotAllowedException(qaaAuth, StringUtils.join(requiredLoAs, "|"), matchingMode);
+ } else {
+ log.debug("Requesed LoA fits LoA from authentication. Continue auth process ... ");
+ }
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java
deleted file mode 100644
index d33ee6c6..00000000
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/SAML2Utils.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 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:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * 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.egiz.eaaf.modules.pvp2.impl.utils;
-
-import java.io.IOException;
-import java.security.NoSuchAlgorithmException;
-import java.util.List;
-
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.Validator;
-
-import org.apache.commons.lang3.StringUtils;
-import org.opensaml.Configuration;
-import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
-import org.opensaml.common.xml.SAMLSchemaBuilder;
-import org.opensaml.saml2.core.Attribute;
-import org.opensaml.saml2.core.Status;
-import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.saml2.metadata.AssertionConsumerService;
-import org.opensaml.saml2.metadata.SPSSODescriptor;
-import org.opensaml.ws.soap.soap11.Body;
-import org.opensaml.ws.soap.soap11.Envelope;
-import org.opensaml.xml.XMLObject;
-import org.opensaml.xml.XMLObjectBuilderFactory;
-import org.opensaml.xml.io.Marshaller;
-import org.opensaml.xml.io.MarshallingException;
-import org.opensaml.xml.schema.XSString;
-import org.opensaml.xml.schema.impl.XSStringBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import at.gv.egiz.eaaf.core.impl.utils.Random;
-import at.gv.egiz.eaaf.modules.pvp2.PVPConstants;
-import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EAAFRequestedAttribute;
-
-public class SAML2Utils {
- private static final Logger log = LoggerFactory.getLogger(SAML2Utils.class);
-
- public static <T> T createSAMLObject(final Class<T> clazz) {
- try {
- XMLObjectBuilderFactory builderFactory = Configuration
- .getBuilderFactory();
-
- QName defaultElementName = (QName) clazz.getDeclaredField(
- "DEFAULT_ELEMENT_NAME").get(null);
- @SuppressWarnings("unchecked")
- T object = (T) builderFactory.getBuilder(defaultElementName)
- .buildObject(defaultElementName);
- return object;
- } catch (Throwable e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static String getSecureIdentifier() {
- return "_".concat(Random.nextHexRandom16());
-
- /*Bug-Fix: There are open problems with RandomNumberGenerator via Java SPI and Java JDK 8.121
- * Generation of a 16bit Random identifier FAILES with an Caused by: java.lang.ArrayIndexOutOfBoundsException
- * Caused by: java.lang.ArrayIndexOutOfBoundsException
- at iaik.security.random.o.engineNextBytes(Unknown Source)
- at iaik.security.random.SecRandomSpi.engineNextBytes(Unknown Source)
- at java.security.SecureRandom.nextBytes(SecureRandom.java:468)
- at org.opensaml.common.impl.SecureRandomIdentifierGenerator.generateIdentifier(SecureRandomIdentifierGenerator.java:62)
- at org.opensaml.common.impl.SecureRandomIdentifierGenerator.generateIdentifier(SecureRandomIdentifierGenerator.java:56)
- at at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils.getSecureIdentifier(SAML2Utils.java:69)
- */
- //return idGenerator.generateIdentifier();
- }
-
- private static SecureRandomIdentifierGenerator idGenerator;
-
- private static DocumentBuilder builder;
- static {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- try {
- builder = factory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- idGenerator = new SecureRandomIdentifierGenerator();
- } catch(NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- }
-
- public static Document asDOMDocument(XMLObject object) throws IOException,
- MarshallingException, TransformerException {
- Document document = builder.newDocument();
- Marshaller out = Configuration.getMarshallerFactory().getMarshaller(
- object);
- out.marshall(object, document);
- return document;
- }
-
- public static Status getSuccessStatus() {
- Status status = SAML2Utils.createSAMLObject(Status.class);
- StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class);
- statusCode.setValue(StatusCode.SUCCESS_URI);
- status.setStatusCode(statusCode);
- return status;
- }
-
- public static int getDefaultAssertionConsumerServiceIndex(SPSSODescriptor spSSODescriptor) {
-
- List<AssertionConsumerService> assertionConsumerList = spSSODescriptor.getAssertionConsumerServices();
-
- for (AssertionConsumerService el : assertionConsumerList) {
- if (el.isDefault())
- return el.getIndex();
-
- }
-
- return 0;
- }
-
- public static Envelope buildSOAP11Envelope(XMLObject payload) {
- XMLObjectBuilderFactory bf = Configuration.getBuilderFactory();
- Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME).buildObject(Envelope.DEFAULT_ELEMENT_NAME);
- Body body = (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME);
-
- body.getUnknownXMLObjects().add(payload);
- envelope.setBody(body);
-
- return envelope;
- }
-
- public static EAAFRequestedAttribute generateReqAuthnAttributeSimple(Attribute attr, boolean isRequired, String value) {
- EAAFRequestedAttribute requested = SAML2Utils.createSAMLObject(EAAFRequestedAttribute.class);
- requested.setName(attr.getName());
- requested.setNameFormat(attr.getNameFormat());
- requested.setFriendlyName(attr.getFriendlyName());
- requested.setIsRequired(String.valueOf(isRequired));
- List<XMLObject> attributeValues = requested.getAttributeValues();
- if (StringUtils.isNotEmpty(value)) {
- XMLObject attributeValueForRequest = createAttributeValue(PVPConstants.EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE, value);
- attributeValues.add(attributeValueForRequest);
- }
- return requested;
-
- }
-
- public static void schemeValidation(XMLObject xmlObject) throws Exception {
- try {
- Schema test = SAMLSchemaBuilder.getSAML11Schema();
- Validator val = test.newValidator();
- DOMSource source = new DOMSource(xmlObject.getDOM());
- val.validate(source);
- log.debug("SAML2 Scheme validation successful");
- return;
-
- } catch (Exception e) {
- log.warn("SAML2 scheme validation FAILED.", e);
- throw e;
-
- }
- }
-
- private static XMLObject createAttributeValue(QName attributeValueType, String value) {
- XSStringBuilder stringBuilder = (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME);
- XSString stringValue = stringBuilder.buildObject(attributeValueType, XSString.TYPE_NAME);
- stringValue.setValue(value);
- return stringValue;
-
- }
-}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java
new file mode 100644
index 00000000..1c7a9652
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/Saml2Utils.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 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:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * 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.egiz.eaaf.modules.pvp2.impl.utils;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.Validator;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.modules.pvp2.PvpConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+import org.opensaml.common.xml.SAMLSchemaBuilder;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.ws.soap.soap11.Body;
+import org.opensaml.ws.soap.soap11.Envelope;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.XMLObjectBuilderFactory;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.schema.impl.XSStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+public class Saml2Utils {
+ private static final Logger log = LoggerFactory.getLogger(Saml2Utils.class);
+
+ private static SecureRandomIdentifierGenerator idGenerator;
+
+ private static DocumentBuilder builder;
+
+ static {
+ final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+
+ try {
+ builder = factory.newDocumentBuilder();
+
+ } catch (final ParserConfigurationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ try {
+ idGenerator = new SecureRandomIdentifierGenerator();
+
+ } catch (final NoSuchAlgorithmException e) {
+ e.printStackTrace();
+
+ }
+ }
+
+ /**
+ * Create a SAML2 object.
+ *
+ * @param <T> SAML2 object class
+ * @param clazz object class
+ * @return SAML2 object
+ */
+ public static <T> T createSamlObject(final Class<T> clazz) {
+ try {
+ final XMLObjectBuilderFactory builderFactory =
+ org.opensaml.xml.Configuration.getBuilderFactory();
+
+ final QName defaultElementName =
+ (QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
+ @SuppressWarnings("unchecked")
+ final T object =
+ (T) builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName);
+ return object;
+ } catch (final Throwable e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Get a new SAML2 conform random value.
+ *
+ * @return
+ */
+ public static String getSecureIdentifier() {
+ return "_".concat(Random.nextHexRandom16());
+
+ }
+
+
+ /**
+ * Transform SAML2 Object to Element.
+ *
+ * @param object SAML2 object
+ * @return Element
+ * @throws IOException In case of an transformation error
+ * @throws MarshallingException In case of an transformation error
+ * @throws TransformerException In case of an transformation error
+ */
+ public static Document asDomDocument(final XMLObject object)
+ throws IOException, MarshallingException, TransformerException {
+ final Document document = builder.newDocument();
+ final Marshaller out =
+ org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller(object);
+ out.marshall(object, document);
+ return document;
+ }
+
+ /**
+ * Build success status element.
+ *
+ * @return
+ */
+ public static Status getSuccessStatus() {
+ final Status status = Saml2Utils.createSamlObject(Status.class);
+ final StatusCode statusCode = Saml2Utils.createSamlObject(StatusCode.class);
+ statusCode.setValue(StatusCode.SUCCESS_URI);
+ status.setStatusCode(statusCode);
+ return status;
+ }
+
+ /**
+ * Get AssertionConsumerService Index from metadata element.
+ *
+ * @param spSsoDescriptor metadata element
+ * @return
+ */
+ public static int getDefaultAssertionConsumerServiceIndex(final SPSSODescriptor spSsoDescriptor) {
+
+ final List<AssertionConsumerService> assertionConsumerList =
+ spSsoDescriptor.getAssertionConsumerServices();
+
+ for (final AssertionConsumerService el : assertionConsumerList) {
+ if (el.isDefault()) {
+ return el.getIndex();
+ }
+
+ }
+
+ return 0;
+ }
+
+ /**
+ * Build SOAP11 body from SAML2 object.
+ *
+ * @param payload SAML2 object
+ * @return
+ */
+ public static Envelope buildSoap11Envelope(final XMLObject payload) {
+ final XMLObjectBuilderFactory bf = org.opensaml.xml.Configuration.getBuilderFactory();
+ final Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME)
+ .buildObject(Envelope.DEFAULT_ELEMENT_NAME);
+ final Body body =
+ (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME);
+
+ body.getUnknownXMLObjects().add(payload);
+ envelope.setBody(body);
+
+ return envelope;
+ }
+
+ /**
+ * Generate EAAF specific requested attribute.
+ *
+ * @param attr SAML2 attribute definition
+ * @param isRequired is-mandatory flag
+ * @param value Attribute value
+ * @return
+ */
+ public static EaafRequestedAttribute generateReqAuthnAttributeSimple(final Attribute attr,
+ final boolean isRequired, final String value) {
+ final EaafRequestedAttribute requested =
+ Saml2Utils.createSamlObject(EaafRequestedAttribute.class);
+ requested.setName(attr.getName());
+ requested.setNameFormat(attr.getNameFormat());
+ requested.setFriendlyName(attr.getFriendlyName());
+ requested.setIsRequired(String.valueOf(isRequired));
+ final List<XMLObject> attributeValues = requested.getAttributeValues();
+ if (StringUtils.isNotEmpty(value)) {
+ final XMLObject attributeValueForRequest =
+ createAttributeValue(PvpConstants.EIDAS_REQUESTED_ATTRIBUTE_VALUE_TYPE, value);
+ attributeValues.add(attributeValueForRequest);
+ }
+ return requested;
+
+ }
+
+ /**
+ * Perform XML schema-validation on SAML2 object.
+ *
+ * @param xmlObject SAML2 object
+ * @throws Exception In case of a validation error
+ */
+ public static void schemeValidation(final XMLObject xmlObject) throws Exception {
+ try {
+ final Schema test = SAMLSchemaBuilder.getSAML11Schema();
+ final Validator val = test.newValidator();
+ final DOMSource source = new DOMSource(xmlObject.getDOM());
+ val.validate(source);
+ log.debug("SAML2 Scheme validation successful");
+ return;
+
+ } catch (final Exception e) {
+ log.warn("SAML2 scheme validation FAILED.", e);
+ throw e;
+
+ }
+ }
+
+ private static XMLObject createAttributeValue(final QName attributeValueType,
+ final String value) {
+ final XSStringBuilder stringBuilder = (XSStringBuilder) org.opensaml.xml.Configuration
+ .getBuilderFactory().getBuilder(XSString.TYPE_NAME);
+ final XSString stringValue = stringBuilder.buildObject(attributeValueType, XSString.TYPE_NAME);
+ stringValue.setValue(value);
+ return stringValue;
+
+ }
+}