diff options
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils')
3 files changed, 0 insertions, 556 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java deleted file mode 100644 index c8c5a069..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, 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 "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.modules.auth.eidas.v2.utils; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.gv.egiz.eaaf.core.impl.data.Triple; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.AttributeValue; -import eu.eidas.auth.commons.attribute.AttributeValueMarshaller; -import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException; -import eu.eidas.auth.commons.attribute.AttributeValueTransliterator; -import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; - -public class EidasResponseUtils { - private static final Logger log = LoggerFactory.getLogger(EidasResponseUtils.class); - - public static final String PERSONALIDENIFIER_VALIDATION_PATTERN = "^[A-Z,a-z]{2}/[A-Z,a-z]{2}/.*"; - - /** - * Validate a eIDAS PersonalIdentifier attribute value This validation is done - * according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier - * - * @param uniqueID eIDAS attribute value of a unique identifier - * @return true if the uniqueID matches to eIDAS to Unique Identifier - * specification, otherwise false - */ - public static boolean validateEidasPersonalIdentifier(String uniqueID) { - final Pattern pattern = Pattern.compile(PERSONALIDENIFIER_VALIDATION_PATTERN); - final Matcher matcher = pattern.matcher(uniqueID); - return matcher.matches(); - - } - - /** - * Parse an eIDAS PersonalIdentifier attribute value into it components. This - * processing is done according to eIDAS SAML Attribute Profile - Section 2.2.3 - * Unique Identifier - * - * @param uniqueID eIDAS attribute value of a unique identifier - * @return {@link Trible} that contains: <br> - * First : citizen country <br> - * Second: destination country <br> - * Third : unique identifier <br> - * or null if the attribute value has a wrong format - */ - public static Triple<String, String, String> parseEidasPersonalIdentifier(String uniqueID) { - if (!validateEidasPersonalIdentifier(uniqueID)) { - log.error("eIDAS attribute value for {} looks wrong formated. Value: {}", - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, uniqueID); - return null; - - } - return Triple.newInstance(uniqueID.substring(0, 2), uniqueID.substring(3, 5), uniqueID.substring(6)); - - } - - /** - * Get eIDAS attribute-values from eIDAS Node attributes. - * - * @param attributeDefinition eIDAS attribute definition - * @param attributeValues Attributes from eIDAS response - * @return Set of attribute values. If more then one value than the first value contains the 'Latin' value. - */ - // TODO: check possible problem with nonLatinCharacters - public static List<String> translateStringListAttribute(AttributeDefinition<?> attributeDefinition, - ImmutableSet<? extends AttributeValue<?>> attributeValues) { - final List<String> stringListAttribute = new ArrayList<>(); - if (attributeValues != null) { - final AttributeValueMarshaller<?> attributeValueMarshaller = attributeDefinition - .getAttributeValueMarshaller(); - for (final AttributeValue<?> attributeValue : attributeValues.asList()) { - String valueString = null; - try { - valueString = attributeValueMarshaller.marshal((AttributeValue) attributeValue); - - log.trace("Find attr: {} with value: {} nonLatinFlag: {} needTransliteration: {}", - attributeDefinition.getFriendlyName(), attributeValue.toString(), - attributeValue.isNonLatinScriptAlternateVersion(), - AttributeValueTransliterator.needsTransliteration(valueString)); - - // if (attributeValue.isNonLatinScriptAlternateVersion()) { - if (!AttributeValueTransliterator.needsTransliteration(valueString)) { - stringListAttribute.add(0, valueString); - - } else { - log.trace("Find 'needsTransliteration' flag. Setting this value at last list element ... "); - stringListAttribute.add(valueString); - - } - - } catch (final AttributeValueMarshallingException e) { - throw new IllegalStateException(e); - - } - } - - log.trace("Extract values: {} for attr: {}", - StringUtils.join(stringListAttribute, ","), attributeDefinition.getFriendlyName()); - - } else { - log.info("Can not extract infos from 'null' attribute value"); - - } - - return stringListAttribute; - - } - - /** - * Convert eIDAS DateTime attribute to Java Object. - * - * @param attributeDefinition eIDAS attribute definition. - * @param attributeValues eIDAS attribute value - * @return - */ - @Nullable - public static DateTime translateDateAttribute(AttributeDefinition<?> attributeDefinition, - ImmutableList<? extends AttributeValue<?>> attributeValues) { - if (attributeValues.size() != 0) { - final AttributeValue<?> firstAttributeValue = attributeValues.get(0); - return (DateTime) firstAttributeValue.getValue(); - - } - - return null; - } - - /** - * Concert eIDAS Address attribute to Java object. - * - * @param attributeDefinition eIDAS attribute definition - * @param attributeValues eIDAS attribute value - * @return - */ - @Nullable - public static PostalAddress translateAddressAttribute(AttributeDefinition<?> attributeDefinition, - ImmutableList<? extends AttributeValue<?>> attributeValues) { - final AttributeValue<?> firstAttributeValue = attributeValues.get(0); - return (PostalAddress) firstAttributeValue.getValue(); - - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/JoseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/JoseUtils.java deleted file mode 100644 index e81c4c92..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/JoseUtils.java +++ /dev/null @@ -1,305 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.eidas.v2.utils; - -import at.gv.egiz.eaaf.core.exception.EaafKeyUsageException; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils; -import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.core.impl.utils.X509Utils; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.jose4j.jca.ProviderContext; -import org.jose4j.jwa.AlgorithmConstraints; -import org.jose4j.jws.AlgorithmIdentifiers; -import org.jose4j.jws.JsonWebSignature; -import org.jose4j.jwx.Headers; -import org.jose4j.jwx.JsonWebStructure; -import org.jose4j.keys.resolvers.X509VerificationKeyResolver; -import org.jose4j.lang.JoseException; -import org.springframework.util.Base64Utils; - -import javax.annotation.Nonnull; -import java.io.IOException; -import java.security.Key; -import java.security.KeyStore; -import java.security.Provider; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.RSAPrivateKey; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -/** - * {@link JoseUtils} provides static methods JWS and JWE processing. - * - * @author tlenz - * - */ -@Slf4j -public class JoseUtils { - - /** - * Create a JWS signature. - * - * <p> - * Use {@link AlgorithmIdentifiers.RSA_PSS_USING_SHA256} in case - * of a RSA based key and - * {@link AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256} - * in case of an ECC based key. - * </p> - * - * @param keyStore KeyStore that should be used - * @param keyAlias Alias of the private key - * @param keyPassword Password to access the key - * @param payLoad PayLoad to sign - * @param addFullCertChain If true the full certificate chain will be - * added, otherwise only the - * X509CertSha256Fingerprint is added into JOSE - * header - * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging - * purposes only - * @return Signed PayLoad in serialized form - * @throws EaafException In case of a key-access or key-usage error - * @throws JoseException In case of a JOSE error - */ - public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore, - @Nonnull final String keyAlias, @Nonnull final char[] keyPassword, - @Nonnull final String payLoad, boolean addFullCertChain, - @Nonnull String friendlyNameForLogging) throws EaafException, JoseException { - return createSignature(keyStore, keyAlias, keyPassword, payLoad, addFullCertChain, Collections.emptyMap(), - AlgorithmIdentifiers.RSA_PSS_USING_SHA256, AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256, - friendlyNameForLogging); - - } - - /** - * Create a JWS signature. - * - * <p> - * Use {@link AlgorithmIdentifiers.RSA_PSS_USING_SHA256} in case - * of a RSA based key and - * {@link AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256} - * in case of an ECC based key. - * </p> - * - * @param keyStore KeyStore that should be used - * @param keyAlias Alias of the private key - * @param keyPassword Password to access the key - * @param payLoad PayLoad to sign - * @param addFullCertChain If true the full certificate chain will be - * added, otherwise only the - * X509CertSha256Fingerprint is added into JOSE - * header - * @param joseHeaders HeaderName and HeaderValue that should be set - * into JOSE header - * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging - * purposes only - * @return Signed PayLoad in serialized form - * @throws EaafException In case of a key-access or key-usage error - * @throws JoseException In case of a JOSE error - */ - public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore, - @Nonnull final String keyAlias, @Nonnull final char[] keyPassword, - @Nonnull final String payLoad, boolean addFullCertChain, - @Nonnull final Map<String, String> joseHeaders, - @Nonnull String friendlyNameForLogging) throws EaafException, JoseException { - return createSignature(keyStore, keyAlias, keyPassword, payLoad, addFullCertChain, joseHeaders, - AlgorithmIdentifiers.RSA_PSS_USING_SHA256, AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256, - friendlyNameForLogging); - - } - - /** - * Create a JWS signature. - * - * @param keyStore KeyStore that should be used - * @param keyAlias Alias of the private key - * @param keyPassword Password to access the key - * @param payLoad PayLoad to sign - * @param addFullCertChain If true the full certificate chain will be - * added, otherwise only the - * X509CertSha256Fingerprint is added into JOSE - * header - * @param joseHeaders HeaderName and HeaderValue that should be set - * into JOSE header - * @param rsaAlgToUse Signing algorithm that should be used in case - * of a signing key based on RSA - * @param eccAlgToUse Signing algorithm that should be used in case - * of a signing key based on ECC - * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging - * purposes only - * @return Signed PayLoad in serialized form - * @throws EaafException In case of a key-access or key-usage error - * @throws JoseException In case of a JOSE error - */ - public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore, - @Nonnull final String keyAlias, @Nonnull final char[] keyPassword, - @Nonnull final String payLoad, boolean addFullCertChain, - @Nonnull final Map<String, String> joseHeaders, - @Nonnull final String rsaAlgToUse, @Nonnull final String eccAlgToUse, - @Nonnull String friendlyNameForLogging) throws EaafException, JoseException { - - final JsonWebSignature jws = new JsonWebSignature(); - - // set payload - jws.setPayload(payLoad); - - // set JOSE headers - for (final Entry<String, String> el : joseHeaders.entrySet()) { - log.trace("Set JOSE header: {} with value: {} into JWS", el.getKey(), el.getValue()); - jws.setHeader(el.getKey(), el.getValue()); - - } - - // set signing information - final Pair<Key, X509Certificate[]> signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore.getFirst(), keyAlias, keyPassword, true, friendlyNameForLogging); - jws.setKey(signingCred.getFirst()); - jws.setAlgorithmHeaderValue(getKeyOperationAlgorithmFromCredential( - jws.getKey(), rsaAlgToUse, eccAlgToUse, friendlyNameForLogging)); - - // set special provider if required - if (keyStore.getSecond() != null) { - log.trace("Injecting special Java Security Provider: {}", keyStore.getSecond().getName()); - final ProviderContext providerCtx = new ProviderContext(); - providerCtx.getSuppliedKeyProviderContext().setSignatureProvider( - keyStore.getSecond().getName()); - jws.setProviderContext(providerCtx); - - } - - if (addFullCertChain) { - jws.setCertificateChainHeaderValue(signingCred.getSecond()); - - } - - jws.setX509CertSha256ThumbprintHeaderValue(signingCred.getSecond()[0]); - - return jws.getCompactSerialization(); - - } - - /** - * Verify a JOSE signature. - * - * @param serializedContent Serialized content that should be verified - * @param trustedCerts Trusted certificates that should be used for - * verification - * @param constraints {@link AlgorithmConstraints} for verification - * @return {@link JwsResult} object - * @throws JoseException In case of a signature verification error - * @throws IOException In case of a general error - */ - public static JwsResult validateSignature(@Nonnull final String serializedContent, - @Nonnull final List<X509Certificate> trustedCerts, @Nonnull final AlgorithmConstraints constraints) - throws JoseException, IOException { - final JsonWebSignature jws = new JsonWebSignature(); - // set payload - jws.setCompactSerialization(serializedContent); - - // set security constrains - jws.setAlgorithmConstraints(constraints); - - // load signinc certs - Key selectedKey = null; - final List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue(); - final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue(); - if (x5cCerts != null) { - log.debug("Found x509 certificate in JOSE header ... "); - log.trace("Sorting received X509 certificates ... "); - final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); - - if (trustedCerts.contains(sortedX5cCerts.get(0))) { - selectedKey = sortedX5cCerts.get(0).getPublicKey(); - - } else { - log.info("Can NOT find JOSE certificate in truststore."); - if (log.isDebugEnabled()) { - try { - log.debug("Cert: {}", Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded())); - - } catch (final CertificateEncodingException e) { - log.warn("Can not create DEBUG output", e); - - } - } - } - - } else if (StringUtils.isNotEmpty(x5t256)) { - log.debug("Found x5t256 fingerprint in JOSE header .... "); - final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver( - trustedCerts); - selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList()); - - } else { - throw new JoseException("JWS contains NO signature certificate or NO certificate fingerprint"); - - } - - if (selectedKey == null) { - throw new JoseException("Can NOT select verification key for JWS. Signature verification FAILED"); - - } - - // set verification key - jws.setKey(selectedKey); - - // load payLoad - return new JwsResult( - jws.verifySignature(), - jws.getUnverifiedPayload(), - jws.getHeaders(), - x5cCerts); - - } - - /** - * Select signature algorithm for a given credential. - * - * @param key {@link X509Credential} that will be used for - * key operations - * @param rsaSigAlgorithm RSA based algorithm that should be used in case - * of RSA credential - * @param ecSigAlgorithm EC based algorithm that should be used in case - * of RSA credential - * @param friendlyNameForLogging KeyStore friendlyName for logging purposes - * @return either the RSA based algorithm or the EC based algorithm - * @throws EaafKeyUsageException In case of an unsupported private-key type - */ - private static String getKeyOperationAlgorithmFromCredential(Key key, - String rsaSigAlgorithm, String ecSigAlgorithm, String friendlyNameForLogging) - throws EaafKeyUsageException { - if (key instanceof RSAPrivateKey) { - return rsaSigAlgorithm; - - } else if (key instanceof ECPrivateKey) { - return ecSigAlgorithm; - - } else { - log.warn("Could NOT select the cryptographic algorithm from Private-Key type"); - throw new EaafKeyUsageException(EaafKeyUsageException.ERROR_CODE_01, - friendlyNameForLogging, - "Can not select cryptographic algorithm"); - - } - - } - - private JoseUtils() { - - } - - @Getter - @AllArgsConstructor - public static class JwsResult { - final boolean valid; - final String payLoad; - final Headers fullJoseHeader; - final List<X509Certificate> x5cCerts; - - } -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/LoggingHandler.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/LoggingHandler.java deleted file mode 100644 index 70290cd3..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/LoggingHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, 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 "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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.asitplus.eidas.specific.modules.auth.eidas.v2.utils; - -import java.io.ByteArrayOutputStream; -import java.util.Set; - -import javax.xml.namespace.QName; -import javax.xml.soap.SOAPMessage; -import javax.xml.ws.handler.MessageContext; -import javax.xml.ws.handler.soap.SOAPHandler; -import javax.xml.ws.handler.soap.SOAPMessageContext; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LoggingHandler implements SOAPHandler<SOAPMessageContext> { - - Logger log = LoggerFactory.getLogger(LoggingHandler.class); - - @Override - public boolean handleMessage(SOAPMessageContext context) { - final SOAPMessage msg = context.getMessage(); - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - try { - msg.writeTo(bos); - log.trace(bos.toString("UTF-8")); - log.trace(new String(bos.toByteArray(), "UTF-8")); - - } catch (final Exception e) { - log.trace(e.getMessage(), e); - } - return true; - } - - @Override - public boolean handleFault(SOAPMessageContext context) { - return handleMessage(context); - } - - @Override - public void close(MessageContext context) { - } - - @Override - public Set<QName> getHeaders() { - return null; - } - -} |