From 76bae60e9bda1acb7ee0e3d45ab187749d16bf82 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 14 Sep 2015 13:29:32 +0200 Subject: move citizen-card authentication and validation (Security-layer communication) to discrete module --- .../moa/id/auth/builder/SAMLArtifactBuilder.java | 167 +++++++++++++++++++++ .../moa/id/auth/parser/SAMLArtifactParser.java | 104 +++++++++++++ .../moa/id/protocols/saml1/GetArtifactAction.java | 3 +- .../protocols/saml1/SAML1AuthenticationServer.java | 43 ++++++ 4 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java create mode 100644 id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java (limited to 'id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa') diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java new file mode 100644 index 000000000..eeca78e60 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +/* + * Copyright 2003 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.auth.builder; + +import java.io.ByteArrayOutputStream; +import java.security.MessageDigest; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; + +/** + * Builder for the SAML artifact, as defined in the + * Browser/Artifact profile of SAML. + * + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactBuilder { + + /** + * The generic configuration parameter for an alternative SourceID. + */ +// private static final String GENERIC_CONFIG_PARAM_SOURCEID = "AuthenticationServer.SourceID"; + + /** + * Constructor for SAMLArtifactBuilder. + */ + public SAMLArtifactBuilder() { + super(); + } + + /** + * Builds the SAML artifact, encoded BASE64. + * + * @param authURL URL auf the MOA-ID Auth component to be used for construction + * of SourceID + * @param sessionID MOASessionID to be used for construction + * of AssertionHandle + * @return the 42-byte SAML artifact, encoded BASE64 + */ + public String build(String authURL, String sessionID, String sourceIdParam) throws BuildException { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] sourceID; + // alternative sourceId + String alternativeSourceID = AuthConfigurationProviderFactory.getInstance().getAlternativeSourceID(); + + // if sourceID is given in GET/POST param - use this as source id + if (!ParepUtils.isEmpty(sourceIdParam)) { + // if GET/POST parameter sourceID is set, use that sourceID instead of authURL; + //sourceID = md.digest(sourceIdParam.getBytes()); + + // if sourceIdParam is too short (must have 20 characters) - add " " + int length = sourceIdParam.length(); + if (length < 20) { + int l = 20 - length; + for (int i = 0; i < l; i++) { + sourceIdParam += " "; + } + } + + sourceID = sourceIdParam.getBytes(); + Logger.info("Building SAMArtifact from sourceID \"" + sourceIdParam + "\" instead of authURL \"" + authURL + "\"."); + + byte[] assertionHandle = md.digest(sessionID.getBytes()); + ByteArrayOutputStream out = new ByteArrayOutputStream(42); + out.write(0); + out.write(1); + out.write(sourceID, 0, 20); + out.write(assertionHandle, 0, 20); + byte[] samlArtifact = out.toByteArray(); + String samlArtifactBase64 = Base64Utils.encode(samlArtifact); + return samlArtifactBase64; + } + + // if generic config parameter "AuthenticationServer.SourceID" is given, use that sourceID instead of authURL; + if (!ParepUtils.isEmpty(alternativeSourceID)) { + sourceID = md.digest(alternativeSourceID.getBytes()); + Logger.info("Building SAMArtifact from sourceID \"" + alternativeSourceID + "\" instead of authURL \"" + authURL + "\"."); + + byte[] assertionHandle = md.digest(sessionID.getBytes()); + ByteArrayOutputStream out = new ByteArrayOutputStream(42); + out.write(0); + out.write(1); + out.write(sourceID, 0, 20); + out.write(assertionHandle, 0, 20); + byte[] samlArtifact = out.toByteArray(); + String samlArtifactBase64 = Base64Utils.encode(samlArtifact); + return samlArtifactBase64; + } + + // default: sourecID from authURL + sourceID = md.digest(authURL.getBytes()); + byte[] assertionHandle = md.digest(sessionID.getBytes()); + ByteArrayOutputStream out = new ByteArrayOutputStream(42); + out.write(0); + out.write(1); + out.write(sourceID, 0, 20); + out.write(assertionHandle, 0, 20); + byte[] samlArtifact = out.toByteArray(); + String samlArtifactBase64 = Base64Utils.encode(samlArtifact); + return samlArtifactBase64; + + //System.out.println("sourceID: " + new String(sourceID)); + + + } + catch (Throwable ex) { + throw new BuildException( + "builder.00", + new Object[] {"SAML Artifact, MOASessionID=" + sessionID, ex.toString()}, + ex); + } + } + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java new file mode 100644 index 000000000..0e0b42cde --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +/* + * Copyright 2003 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.auth.parser; + +import java.io.IOException; + +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Base64Utils; + +/** + * Parser for a SAML artifact. + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactParser { + /** byte array containing the SamlArtifact bytes */ + private byte[] samlArtifactBytes; + + /** + * Constructor + * @param samlArtifact as String + * @throws ParseException on any parsing error + */ + public SAMLArtifactParser(String samlArtifact) throws ParseException { + try { + samlArtifactBytes = Base64Utils.decode(samlArtifact, false); + } + catch (IOException ex) { + throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); + } + } + /** + * Parses the type code. + * @return type code + * @throws ParseException when SAML artifact is invalid + */ + public byte[] parseTypeCode() throws ParseException { + try { + byte[] typeCode = new byte[] {samlArtifactBytes[0], samlArtifactBytes[1]}; + return typeCode; + } + catch (Throwable ex) { + throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); + } + } + /** + * Parses the assertion handle. + * @return assertion handle + * @throws ParseException when SAML artifact is invalid + */ + public String parseAssertionHandle() throws ParseException { + try { + return new String(samlArtifactBytes, 22, 20); + } + catch (Throwable ex) { + throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); + } + } + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index 2019b0d20..b94348856 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -31,7 +31,6 @@ import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; -import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; @@ -73,7 +72,7 @@ public class GetArtifactAction implements IAction { // add other stork attributes to MOA assertion if available if(null != authData.getStorkAttributes()) { - List moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(authData.getStorkAttributes()); + List moaExtendedSAMLAttibutes = SAML1AuthenticationServer.addAdditionalSTORKAttributes(authData.getStorkAttributes()); authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes); Logger.info("MOA assertion assembled and SAML Artifact generated."); } diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java index e70e71d49..eb869756e 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.saml1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; +import java.util.Vector; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -33,9 +34,13 @@ import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; +import org.apache.commons.lang3.StringEscapeUtils; import org.w3c.dom.Element; import org.xml.sax.SAXException; +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; + import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; @@ -43,6 +48,7 @@ import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder; import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; +import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.BuildException; @@ -119,6 +125,43 @@ public class SAML1AuthenticationServer extends AuthenticationServer { return error; } + /** + * Transforms additional STORK attributes to MOA Extended attributes + * @param iPersonalAttributeList STORK attribute list + * @return + */ + public static List addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { + List moaExtendedSAMLAttributeList = new Vector(); + + if(null == iPersonalAttributeList) + return moaExtendedSAMLAttributeList; + + Logger.trace("Adding the following attributes to MOA assertion: "); + int count = 0; + + for (PersonalAttribute attribute : iPersonalAttributeList) { + Object attributeValue = attribute.getValue(); + if (null == attributeValue) + attributeValue = attribute.getComplexValue(); + + // escape attributeValue + attributeValue = StringEscapeUtils.escapeXml10(attributeValue.toString()); + // and remove trailing and tailing brackets. Might break something but we never saw an array with more than one entry! + attributeValue = ((String) attributeValue).substring(1, ((String) attributeValue).length() - 1); + + ExtendedSAMLAttribute extendedSAMLAttribute = + new ExtendedSAMLAttributeImpl(attribute.getName(), attributeValue, Constants.STORK_NS_URI, 0); + moaExtendedSAMLAttributeList.add(extendedSAMLAttribute); + count++; + Logger.trace("Additional attribute: " + attribute.getName()); + } + + Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion."); + + return moaExtendedSAMLAttributeList; + } + + /** * Retrieves AuthenticationData indexed by the SAML artifact. * The AuthenticationData is deleted from the store upon end of -- cgit v1.2.3