/*
* 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.egiz.eaaf.core.impl.idp.auth.data;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.Base64Utils;
import org.w3c.dom.Element;
import org.w3c.dom.traversal.NodeIterator;
import at.gv.egiz.eaaf.core.api.data.XmlNamespaceConstants;
import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
import at.gv.egiz.eaaf.core.exceptions.EaafParserException;
import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
import at.gv.egiz.eaaf.core.impl.utils.XPathUtils;
/**
* Parses MDS from an identity link. <saml:Assertion>
* This IDL parser extract NO key information!
*
*/
public class SimpleIdentityLinkAssertionParser {
//
// XPath namespace prefix shortcuts
//
/** Xpath prefix for reaching PersonData Namespaces. */
private static final String PDATA = XmlNamespaceConstants.PD_PREFIX + ":";
/** Xpath prefix for reaching SAML Namespaces. */
private static final String SAML = XmlNamespaceConstants.SAML_PREFIX + ":";
/** Xpath prefix for reaching XML-DSIG Namespaces. */
private static final String DSIG = XmlNamespaceConstants.DSIG_PREFIX + ":";
/** Xpath expression to the root element. */
private static final String ROOT = "";
/** Xpath expression to the SAMLSubjectConfirmationData element. */
private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH =
ROOT + SAML + "AttributeStatement/" + SAML + "Subject/" + SAML + "SubjectConfirmation/" + SAML
+ "SubjectConfirmationData";
/** Xpath expression to the PersonData element. */
public static final String PERSON_XPATH =
SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person";
/** Xpath expression to the PersonData GivenName element. */
public static final String PERSON_GIVEN_NAME_XPATH =
PERSON_XPATH + "/" + PDATA + "Name/" + PDATA + "GivenName";
/** Xpath expression to the PersonData FamilyName element. */
public static final String PERSON_FAMILY_NAME_XPATH =
PERSON_XPATH + "/" + PDATA + "Name/" + PDATA + "FamilyName";
/** Xpath expression to the PersonData DateOfBirth element. */
public static final String PERSON_DATE_OF_BIRTH_XPATH =
PERSON_XPATH + "/" + PDATA + "DateOfBirth";
/** Xpath expression to the Identification Value element. */
public static final String PERSON_IDENT_VALUE_XPATH =
PERSON_XPATH + "/" + PDATA + "Identification/" + PDATA + "Value";
/** Xpath expression to the Identification Value element. */
public static final String PERSON_IDENT_TYPE_XPATH =
PERSON_XPATH + "/" + PDATA + "Identification/" + PDATA + "Type";
/** Xpath expression to the DSIG X509Certificate element. */
private static final String DSIG_CERTIFICATES_XPATH = ROOT + DSIG + "Signature/" + DSIG
+ "KeyInfo/" + DSIG + "X509Data/" + DSIG + "X509Certificate";
/** Xpath expression to the DSIG Transforms element. */
private static final String DSIG_REFERENCE_TRANSFORMATION_XPATH =
ROOT + DSIG + "Signature/" + DSIG + "SignedInfo/" + DSIG + "Reference/" + DSIG + "Transforms";
/** The IssueInstant attribute of the SAML assertion. */
private static final String ISSUE_INSTANT_ATTR = "IssueInstant";
public static final String ASSERTIONID = "AssertionID";
/**
* This is the root element of the XML-Document provided by the Security Layer
* Card.
*/
private Element assertionElem;
/**
* Constructor for IdentityLinkAssertionParser
. A
* DOM-representation of the incoming String will be created
*
* @param xmlAssertion <saml:Assertion>
as String
* @throws EaafParserException on any parsing error
*/
public SimpleIdentityLinkAssertionParser(final String xmlAssertion) throws EaafParserException {
try {
final InputStream s = new ByteArrayInputStream(xmlAssertion.getBytes("UTF-8"));
assertionElem = DomUtils.parseXmlValidating(s);
} catch (final Throwable t) {
throw new EaafParserException("parser.01", new Object[] { t.toString() }, t);
}
}
/**
* Sets the <@link assertionElem>.
*
* @param xmlAssertion the assertion element
* @throws EaafParserException on any parsing error
*/
public SimpleIdentityLinkAssertionParser(final Element xmlAssertion) throws EaafParserException {
assertionElem = xmlAssertion;
}
/**
* Constructor for IdentityLinkAssertionParser
. A
* DOM-representation of the incoming Inputstream will be created
*
* @param xmlAssertion <saml:Assertion>
as InputStream
* @throws EaafParserException on any parsing error
*/
public SimpleIdentityLinkAssertionParser(final InputStream xmlAssertion)
throws EaafParserException {
try {
assertionElem = DomUtils.parseXmlValidating(xmlAssertion);
} catch (final Throwable t) {
throw new EaafParserException("parser.01", new Object[] { t.toString() }, t);
}
}
/**
* Parses the identity link from the <saml:Assertion>
.
*
* @return Identity link
* @throws EaafParserException on any parsing error
*/
public IIdentityLink parseIdentityLink() throws EaafParserException {
IIdentityLink identityLink;
try {
identityLink = new IdentityLink();
identityLink.setSamlAssertion(assertionElem);
identityLink.setIssueInstant(assertionElem.getAttribute(ISSUE_INSTANT_ATTR));
identityLink.setPrPerson((Element) XPathUtils.selectSingleNode(assertionElem, PERSON_XPATH));
identityLink.setIdentificationValue(
XPathUtils.getElementValue(assertionElem, PERSON_IDENT_VALUE_XPATH, ""));
identityLink.setIdentificationType(
XPathUtils.getElementValue(assertionElem, PERSON_IDENT_TYPE_XPATH, ""));
final String givenname =
XPathUtils.getElementValue(assertionElem, PERSON_GIVEN_NAME_XPATH, "");
final String familyname =
XPathUtils.getElementValue(assertionElem, PERSON_FAMILY_NAME_XPATH, "");
// replace ' in name with '
// givenname = givenname.replaceAll("'", "'");
// familyname = familyname.replaceAll("'", "'");
identityLink.setGivenName(givenname);
identityLink.setFamilyName(familyname);
identityLink.setDateOfBirth(
XPathUtils.getElementValue(assertionElem, PERSON_DATE_OF_BIRTH_XPATH, ""));
final NodeIterator dsigRefTransforms =
XPathUtils.selectNodeIterator(assertionElem, DSIG_REFERENCE_TRANSFORMATION_XPATH);
final List transElems = new ArrayList();
Element transformsElem;
while ((transformsElem = (Element) dsigRefTransforms.nextNode()) != null) {
transElems.add(transformsElem);
}
final Element[] result = new Element[transElems.size()];
transElems.toArray(result);
identityLink.setDsigReferenceTransforms(result);
// identityLink.setPublicKey(getPublicKeys());
} catch (final Throwable t) {
throw new EaafParserException("parser.01", new Object[] { t.toString() }, t);
}
return identityLink;
}
/**
* Parses a string array of decoded base64 certificates from the
* <InfoboxReadResponse>
found in the dsig-signature.
*
* @return String[] with raw-certificates from the dsig-signature keyinfo
* @throws Exception In case of an error
*/
public String[] getCertificates() throws Exception {
final List certs = new ArrayList();
final NodeIterator rsaIter =
XPathUtils.selectNodeIterator(assertionElem, DSIG_CERTIFICATES_XPATH);
Element certElem;
while ((certElem = (Element) rsaIter.nextNode()) != null) {
final String content = DomUtils.getText(certElem);
certs.add(new String(Base64Utils.decodeFromString(content), "UTF-8"));
}
final String[] result = new String[certs.size()];
certs.toArray(result);
return result;
}
}