diff options
| author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-05-30 06:29:29 +0200 | 
|---|---|---|
| committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2018-05-30 06:29:29 +0200 | 
| commit | 52ad604e54cb91073503d708cd0c50ff0121174a (patch) | |
| tree | 3aaaebf8460d79fc99bca243827e4e0987ec4379 /id/server/idserverlib/src/main | |
| parent | dc2fb6695f44e3e01088e8a986ae1ac98b1743b1 (diff) | |
| download | moa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.tar.gz moa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.tar.bz2 moa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.zip | |
add additional validation to SL20 module
Diffstat (limited to 'id/server/idserverlib/src/main')
5 files changed, 1018 insertions, 32 deletions
| diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java index 9ca15c76f..27d983785 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java @@ -22,6 +22,8 @@   */  package at.gv.egovernment.moa.id.auth.builder; +import java.util.List; +  import javax.xml.parsers.DocumentBuilder;  import javax.xml.parsers.DocumentBuilderFactory; @@ -74,10 +76,15 @@ public class SignatureVerificationUtils {  		  }  	  } -	  public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException {		   +	  public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException {	 +		  return verify(signature, trustProfileID, null); +		   +	  } +	   +	  public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID,  List<String> verifyTransformsInfoProfileID) throws MOAIDException {		    		  try {  			  //build signature-verification request -			  Element domVerifyXMLSignatureRequest = build(signature, trustProfileID); +			  Element domVerifyXMLSignatureRequest = build(signature, trustProfileID, verifyTransformsInfoProfileID);  			  //send signature-verification to MOA-SP   			  Element domVerifyXMLSignatureResponse = SignatureVerificationInvoker.getInstance() @@ -112,7 +119,7 @@ public class SignatureVerificationUtils {  	   *   	   * @throws ParseException  	   */ -	  private Element build(byte[] signature, String trustProfileID) +	  private Element build(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID)  	    throws ParseException   	  {   	    try { @@ -153,6 +160,20 @@ public class SignatureVerificationUtils {  	      requestElem_.appendChild(signatureManifestCheckParamsElem);  	      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +	      //verify transformations +	      if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) { +	    	  Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +	    	  signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +	    	  for (String element : verifyTransformsInfoProfileID) { +	    		  Element verifyTransformsInfoProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +	              referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +	              verifyTransformsInfoProfileIDElem.appendChild(requestDoc_.createTextNode(element)); +	             +	    	  } +	      } +	       +	       +	      //hashinput data  	      Element returnHashInputDataElem =   	        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData");  	      requestElem_.appendChild(returnHashInputDataElem); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java new file mode 100644 index 000000000..f3ce6888b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * 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.validator; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * This class is used to validate an {@link IdentityLink}  + * returned by the security layer + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class IdentityLinkValidator implements Constants { + +  // +  // XPath namespace prefix shortcuts +  // +  /** Xpath prefix for reaching PersonData Namespaces */ +  private static final String PDATA = PD_PREFIX + ":"; +  /** Xpath prefix for reaching SAML Namespaces */ +  private static final String SAML = SAML_PREFIX + ":"; +  /** Xpath prefix for reaching XML-DSIG Namespaces */ +  private static final String DSIG = DSIG_PREFIX + ":"; +  /** Xpath prefix for reaching ECDSA Namespaces */ +  private static final String ECDSA = ECDSA_PREFIX + ":"; +  /** Xpath expression to the root element */ +  private static final String ROOT = ""; +  /** Xpath expression to the SAML:SubjectConfirmationData element */ +  private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH = +    ROOT +      + SAML +      + "AttributeStatement/" +      + SAML +      + "Subject/" +      + SAML +      + "SubjectConfirmation/" +      + SAML +      + "SubjectConfirmationData"; +/** Xpath expression to the PersonData:Person element */ +  private static final String PERSON_XPATH = +    SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person"; +  /** Xpath expression to the SAML:Attribute element */ +  private static final String ATTRIBUTE_XPATH = +    ROOT + SAML + "AttributeStatement/" + SAML + "Attribute"; +//  /** Xpath expression to the SAML:AttributeName attribute */ +//  private static final String ATTRIBUTE_NAME_XPATH = +//    ROOT + SAML + "AttributeStatement/" + SAML + "Attribute/@AttributeName"; +//  /** Xpath expression to the SAML:AttributeNamespace attribute */ +//  private static final String ATTRIBUTE_NAMESPACE_XPATH = +//    ROOT +//      + SAML +//      + "AttributeStatement/" +//      + SAML +//      + "Attribute/@AttributeNamespace"; +//  /** Xpath expression to the SAML:AttributeValue element */ +//  private static final String ATTRIBUTE_VALUE_XPATH = +//    ROOT +//      + SAML +//      + "AttributeStatement/" +//      + SAML +//      + "Attribute/" +//      + SAML +//      + "AttributeValue"; + +  /** Singleton instance. <code>null</code>, if none has been created. */ +  private static IdentityLinkValidator instance; + +  /** +   * Constructor for a singleton IdentityLinkValidator. +   * @return a new IdentityLinkValidator instance +   * @throws ValidateException if no instance can be created +   */ +  public static synchronized IdentityLinkValidator getInstance() +    throws ValidateException { +    if (instance == null) { +      instance = new IdentityLinkValidator(); +    } +    return instance; +  } + +  /** +   * Method validate. Validates the {@link IdentityLink}  +   * @param identityLink The identityLink to validate +   * @throws ValidateException on any validation error +   */ +  public void validate(IIdentityLink identityLink) throws ValidateException { + +    Element samlAssertion = identityLink.getSamlAssertion(); +    //Search the SAML:ASSERTION Object (A2.054) +    if (samlAssertion == null) { +      throw new ValidateException("validator.00", null); +    } + +    // Check how many saml:Assertion/saml:AttributeStatement/ +    //      saml:Subject/ saml:SubjectConfirmation/ +    //      saml:SubjectConfirmationData/pr:Person of type +    //      PhysicalPersonType exist (A2.056) +    NodeList nl = XPathUtils.selectNodeList(samlAssertion, PERSON_XPATH); +    // If we have just one Person-Element we don't need to check the attributes +    int counterPhysicalPersonType = 0; +    if (nl.getLength() > 1) +      for (int i = 0; i < nl.getLength(); i++) { +        String xsiType = +          ((Element) nl.item(i)) +            .getAttributeNodeNS( +              "http://www.w3.org/2001/XMLSchema-instance", +              "type") +            .getNodeValue(); +        // We have to check if xsiType contains "PhysicalPersonType" +        // An equal-check will fail because of the Namespace-prefix of the attribute value +        if (xsiType.indexOf("PhysicalPersonType") > -1) +          counterPhysicalPersonType++; +      } +    if (counterPhysicalPersonType > 1) +      throw new ValidateException("validator.01", null); + +    //Check the SAML:ATTRIBUTES +    nl = XPathUtils.selectNodeList(samlAssertion, ATTRIBUTE_XPATH); +    for (int i = 0; i < nl.getLength(); i++) { +      String attributeName = +        XPathUtils.getAttributeValue( +          (Element) nl.item(i), +          "@AttributeName", +          null); +      String attributeNS = +        XPathUtils.getAttributeValue( +          (Element) nl.item(i), +          "@AttributeNamespace", +          null); +      if (attributeName.equals("CitizenPublicKey")) { +                 +        if (attributeNS.equals("http://www.buergerkarte.at/namespaces/personenbindung/20020506#") || +            attributeNS.equals("urn:publicid:gv.at:namespaces:identitylink:1.2")) { +          Element attributeValue =  +              (Element) XPathUtils.selectSingleNode((Element) nl.item(i),nSMap, SAML + "AttributeValue/" + DSIG + "RSAKeyValue");           +           if (attributeValue==null)  +             attributeValue =  +               (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + ECDSA + "ECDSAKeyValue"); +           if (attributeValue==null)  +               attributeValue =  +                 (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + DSIG + "DSAKeyValue"); +           if (attributeValue == null) +            throw new ValidateException("validator.02", null); +                       +        } +        else +          throw new ValidateException("validator.03", new Object [] {attributeNS} ); +      } +      else +        throw new ValidateException("validator.04", new Object [] {attributeName} ); +    } +     +    //Check if dsig:Signature exists +     Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion,ROOT + DSIG + "Signature"); +     if (dsigSignature==null) throw new ValidateException("validator.05", new Object[] {"in der Personenbindung"}); +  } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java new file mode 100644 index 000000000..ae9ff80ae --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * 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.validator; + +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><VerifyXMLSignatureRequestBuilder></code> structure + * used for sending the DSIG-Signature of the Security Layer card for validating to MOA-SP. + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureRequestBuilder { +   +  /** shortcut for XMLNS namespace URI */ +  private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; +  /** shortcut for MOA namespace URI */ +  private static final String MOA_NS_URI = Constants.MOA_NS_URI; +  /** The DSIG-Prefix */ +  private static final String DSIG = Constants.DSIG_PREFIX + ":"; +   +  /** The document containing the <code>VerifyXMLsignatureRequest</code> */ +  private Document requestDoc_; +  /** the <code>VerifyXMLsignatureRequest</code> root element */ +  private Element requestElem_; +   +   +  /** +   * Builds the body for a <code>VerifyXMLsignatureRequest</code> including the root +   * element and namespace declarations. +   *  +   * @throws BuildException If an error occurs on building the document. +   */ +  public VerifyXMLSignatureRequestBuilder() throws BuildException { +    try { +      DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();         +      requestDoc_ = docBuilder.newDocument(); +      requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); +      requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); +      requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); +      requestDoc_.appendChild(requestElem_);        +    } catch (Throwable t) { +      throw new BuildException( +        "builder.00",  +        new Object[] {"VerifyXMLSignatureRequest", t.toString()},  +        t); +    } +  } +   +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from an IdentityLink with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param identityLink - The IdentityLink +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   *  +   * @return Element - The complete request as Dom-Element +   *  +   * @throws ParseException +   */ +  public Element build(IIdentityLink identityLink, String trustProfileID) +    throws ParseException  +  {  +    try { +      // build the request +      Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +      requestElem_.appendChild(dateTimeElem); +      Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +      dateTimeElem.appendChild(dateTime); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); +      verifySignatureEnvironmentElem.appendChild(base64ContentElem); +      // insert the base64 encoded identity link SAML assertion +      String serializedAssertion = identityLink.getSerializedSamlAssertion(); +      String base64EncodedAssertion = Base64Utils.encode(serializedAssertion.getBytes("UTF-8")); +      //replace all '\r' characters by no char. +      StringBuffer replaced = new StringBuffer(); +      for (int i = 0; i < base64EncodedAssertion.length(); i ++) { +        char c = base64EncodedAssertion.charAt(i); +        if (c != '\r') { +          replaced.append(c); +        } +      } +      base64EncodedAssertion = replaced.toString(); +      Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); +      base64ContentElem.appendChild(base64Content);       +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +      // add the transforms +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +      signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +      Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +       +      for (int i = 0; i < dsigTransforms.length; i++) {         +        Element verifyTransformsInfoProfileElem =  +          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +        referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +        verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true));         +      } +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); +    } catch (Throwable t) { +      throw new ParseException("builder.00",  +        new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); +    } + +    return requestElem_; +  } +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from an IdentityLink with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param identityLink - The IdentityLink +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   *  +   * @return Element - The complete request as Dom-Element +   *  +   * @throws ParseException +   */ +  public Element build(byte[]mandate, String trustProfileID) +    throws ParseException  +  {  +    try { +      // build the request +//      Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +//      requestElem_.appendChild(dateTimeElem); +//      Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +//      dateTimeElem.appendChild(dateTime); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); +      verifySignatureEnvironmentElem.appendChild(base64ContentElem); +      // insert the base64 encoded identity link SAML assertion +      //String serializedAssertion = identityLink.getSerializedSamlAssertion(); +      //String base64EncodedAssertion = Base64Utils.encode(mandate.getBytes("UTF-8")); +      String base64EncodedAssertion = Base64Utils.encode(mandate); +      //replace all '\r' characters by no char. +      StringBuffer replaced = new StringBuffer(); +      for (int i = 0; i < base64EncodedAssertion.length(); i ++) { +        char c = base64EncodedAssertion.charAt(i); +        if (c != '\r') { +          replaced.append(c); +        } +      } +      base64EncodedAssertion = replaced.toString(); +      Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); +      base64ContentElem.appendChild(base64Content);       +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +//      // add the transforms +//      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +//      signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +//      Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +//       +//      for (int i = 0; i < dsigTransforms.length; i++) {         +//        Element verifyTransformsInfoProfileElem =  +//          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +//        referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +//        verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true));         +//      } +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); +    } catch (Throwable t) { +      throw new ParseException("builder.00",  +        new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); +    } + +    return requestElem_; +  } +   +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from the signed AUTH-Block with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param csr - signed AUTH-Block +   * @param verifyTransformsInfoProfileID - allowed verifyTransformsInfoProfileID  +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   * @return Element - The complete request as Dom-Element +   * @throws ParseException +   */ +  public Element build( +    CreateXMLSignatureResponse csr, +    List<String> verifyTransformsInfoProfileID, +    String trustProfileID) +    throws BuildException { //samlAssertionObject +     +    try { +      // build the request +//      requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:"  +//        + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); +      verifySignatureEnvironmentElem.appendChild(xmlContentElem); +      xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); +      // insert the SAML assertion +      xmlContentElem.appendChild(requestDoc_.importNode(csr.getSamlAssertion(), true));           +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); +      // add the transform profile IDs +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +        signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +         +//      for (int i = 0; i < verifyTransformsInfoProfileID.length; i++) { +//    	   +//        Element verifyTransformsInfoProfileIDElem =  +//          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +//        referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +//        verifyTransformsInfoProfileIDElem.appendChild( +//          requestDoc_.createTextNode(verifyTransformsInfoProfileID[i]));         +//      } +       +        for (String element : verifyTransformsInfoProfileID) { +      	   +            Element verifyTransformsInfoProfileIDElem =  +              requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +            referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +            verifyTransformsInfoProfileIDElem.appendChild( +              requestDoc_.createTextNode(element));         +          } +         +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); + +    } catch (Throwable t) { +      throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); +    } + +    return requestElem_; +  } +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from the signed data with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param csr - signed AUTH-Block +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   * @return Element - The complete request as Dom-Element +   * @throws ParseException +   */ +  public Element buildDsig( +    CreateXMLSignatureResponse csr, +    String trustProfileID) +    throws BuildException { //samlAssertionObject +     +    try { +      // build the request +//      requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:"  +//        + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); +      +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +       +      Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); +      verifySignatureEnvironmentElem.appendChild(xmlContentElem); +      xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); +       +      // insert the dsig:Signature +      xmlContentElem.appendChild(requestDoc_.importNode(csr.getDsigSignature(), true));           +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode("/"+ DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); +      // add the transform profile IDs +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +        signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +         +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +       +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); + +    } catch (Throwable t) { +      throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); +    } + +    return requestElem_; +  } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java new file mode 100644 index 000000000..832aa58c6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * 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.validator; + +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink; +import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import iaik.asn1.structures.Name; +import iaik.security.ec.common.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +/** + * This class is used to validate an {@link VerifyXMLSignatureResponse}  + * returned by MOA-SPSS + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureResponseValidator { +   +  /** Identification string for checking identity link */ +  public static final String CHECK_IDENTITY_LINK = "IdentityLink"; +  /** Identification string for checking authentication block */ +  public static final String CHECK_AUTH_BLOCK = "AuthBlock"; +   +  /** Singleton instance. <code>null</code>, if none has been created. */ +  private static VerifyXMLSignatureResponseValidator instance; + +  /** +   * Constructor for a singleton VerifyXMLSignatureResponseValidator. +   */ +  public static synchronized VerifyXMLSignatureResponseValidator getInstance() +    throws ValidateException { +    if (instance == null) { +      instance = new VerifyXMLSignatureResponseValidator(); +    } +    return instance; +  } + +  /** +   * Validates a {@link VerifyXMLSignatureResponse} returned by MOA-SPSS.  +   *  +   * @param verifyXMLSignatureResponse the <code><VerifyXMLSignatureResponse></code> +   * @param identityLinkSignersSubjectDNNames subject names configured +   * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated +   * @param oaParam specifies whether the validation result of the  +   *                                       manifest has to be ignored (identityLink validation if +   *                                       the OA is a business service) or not +   * @throws ValidateException on any validation error + * @throws ConfigurationException  +   */ +  public void validate(IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, +                       List<String> identityLinkSignersSubjectDNNames,  +                       String whatToCheck, +                       IOAAuthParameters oaParam) +    throws ValidateException, ConfigurationException { + +    if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) +      throw new ValidateException("validator.06", null); +       +    if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) { +			String checkFailedReason =""; +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 1)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.21", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 2)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.22", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 3)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.23", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 4)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null); + +//     TEST CARDS +      if (whatToCheck.equals(CHECK_IDENTITY_LINK)) +        throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); +      else +        throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); +    } +     +    //check QC  +    if (AuthConfigurationProviderFactory.getInstance().isCertifiacteQCActive() && +    		!whatToCheck.equals(CHECK_IDENTITY_LINK) && +    		!verifyXMLSignatureResponse.isQualifiedCertificate()) { +    	    	 +    	//check if testcards are active and certificate has an extension for test credentials +    	if (oaParam.isTestCredentialEnabled()) { +        	boolean foundTestCredentialOID = false; +        	try { +        		X509Certificate signerCert = verifyXMLSignatureResponse.getX509certificate(); +    		 +        		List<String> validOIDs = new ArrayList<String>(); +        		if (oaParam.getTestCredentialOIDs() != null) +        			validOIDs.addAll(oaParam.getTestCredentialOIDs()); +        		else +        			validOIDs.add(MOAIDAuthConstants.TESTCREDENTIALROOTOID); +    		 +        		Set<String> extentsions = signerCert.getCriticalExtensionOIDs(); +        		extentsions.addAll(signerCert.getNonCriticalExtensionOIDs()); +        		Iterator<String> extit = extentsions.iterator(); +        		while(extit.hasNext()) { +        			String certOID = extit.next(); +        			for (String el : validOIDs) { +        				if (certOID.startsWith(el)) +        					foundTestCredentialOID = true; +        			}    			 +        		} +        		 +        	} catch (Exception e) { +        		Logger.warn("Test credential OID extraction FAILED.", e); +        		 +        	} +        	//throw Exception if not TestCredentialOID is found +        	if (!foundTestCredentialOID) +        		throw new ValidateException("validator.72", null); +    		 +    	} else    	 +    		throw new ValidateException("validator.71", null);         +    } +     +    // if OA is type is business service the manifest validation result has +    // to be ignored +    boolean ignoreManifestValidationResult = false; +    if (whatToCheck.equals(CHECK_IDENTITY_LINK))    	 +    	ignoreManifestValidationResult = (oaParam.hasBaseIdInternalProcessingRestriction()) ? true +            : false; +     +    if (ignoreManifestValidationResult) { +      Logger.debug("OA type is business service, thus ignoring DSIG manifest validation result"); +    } else { +      if (verifyXMLSignatureResponse.isXmlDSIGManigest()) +        if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0) +          throw new ValidateException("validator.08", null); +    } +     +     +    // Check the signature manifest only when verifying the signed AUTHBlock +    if (whatToCheck.equals(CHECK_AUTH_BLOCK)) { +      if (verifyXMLSignatureResponse.getSignatureManifestCheckCode() > 0) { +        throw new ValidateException("validator.50", null); +      } +    } +         +    //Check whether the returned X509 SubjectName is in the MOA-ID configuration or not +    if (identityLinkSignersSubjectDNNames != null) { +      String subjectDN = ""; +      X509Certificate x509Cert = verifyXMLSignatureResponse.getX509certificate(); +      try { +        subjectDN = ((Name) x509Cert.getSubjectDN()).getRFC2253String(); +      } +      catch (RFC2253NameParserException e) { +        throw new ValidateException("validator.17", null); +      } +      //System.out.println("subjectDN: " + subjectDN); +      // check the authorisation to sign the identity link +      if (!identityLinkSignersSubjectDNNames.contains(subjectDN)) { +        // subject DN check failed, try OID check: +        try { +          if (x509Cert.getExtension(MOAIDAuthConstants.IDENTITY_LINK_SIGNER_OID) == null) { +            throw new ValidateException("validator.18", new Object[] { subjectDN }); +          } else { +            Logger.debug("Identity link signer cert accepted for signing identity link: " + +                         "subjectDN check failed, but OID check successfully passed."); +          } +        } catch (X509ExtensionInitException e) { +          throw new ValidateException("validator.49", null); +        } +      } else { +        Logger.debug("Identity link signer cert accepted for signing identity link: " + +                     "subjectDN check successfully passed."); +      } +       +    } +  } +   +  /** +   * Method validateCertificate. +   * @param verifyXMLSignatureResponse The VerifyXMLSignatureResponse +   * @param idl The Identitylink +   * @throws ValidateException +   */ +  public void validateCertificate( +    IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, +    IIdentityLink idl) +    throws ValidateException { + +    X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate(); +    PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey(); + +    PublicKey pubKeySignature = x509Response.getPublicKey(); +    checkIDLAgainstSignatureCertificate(pubKeysIdentityLink, pubKeySignature); +     +  } +   +   +  public void checkIDLAgainstSignatureCertificate( PublicKey[] pubKeysIdentityLink, PublicKey pubKeySignature) throws ValidateException { +    boolean found = false; +    for (int i = 0; i < pubKeysIdentityLink.length; i++) { +      PublicKey idlPubKey = pubKeysIdentityLink[i]; +      //compare RSAPublicKeys +      if ((idlPubKey instanceof java.security.interfaces.RSAPublicKey) &&   +      		(pubKeySignature instanceof java.security.interfaces.RSAPublicKey)) { + +          RSAPublicKey rsaPubKeySignature = (RSAPublicKey) pubKeySignature; +          RSAPublicKey rsakey = (RSAPublicKey) pubKeysIdentityLink[i]; +           +          if (rsakey.getModulus().equals(rsaPubKeySignature.getModulus()) +              && rsakey.getPublicExponent().equals(rsaPubKeySignature.getPublicExponent())) +          found = true;       +      } +       +      //compare ECDSAPublicKeys +      if( ( (idlPubKey instanceof java.security.interfaces.ECPublicKey) ||  +    		  (idlPubKey instanceof ECPublicKey)) &&  +         ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) ||  +        		(pubKeySignature instanceof ECPublicKey) ) ) { + +		try { +			ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded()); +			ECPublicKey ecdsakey = new ECPublicKey(pubKeysIdentityLink[i].getEncoded()); +			 +	        if(ecdsakey.equals(ecdsaPubKeySignature)) +	              found = true; +			 +		} catch (InvalidKeyException e) { +			Logger.warn("ECPublicKey can not parsed into a iaik.ECPublicKey", e); +			throw new ValidateException("validator.09", null); +		} +           +           + +      } +       +//  		Logger.debug("IDL-Pubkey=" + idl.getPublicKey()[i].getClass().getName() +//  				+ "  Resp-Pubkey=" + pubKeySignature.getClass().getName()); +       +    } + +    if (!found) { +       	 +      throw new ValidateException("validator.09", null); +             +    } +  } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java index 9d585bc86..05bb16d0d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java @@ -63,6 +63,7 @@ public class AssertionAttributeExtractor {  			PVPConstants.EID_SOURCE_PIN_NAME,  			PVPConstants.EID_SOURCE_PIN_TYPE_NAME); +  	/**  	 * Parse the SAML2 Response element and extracts included information  	 * <br><br> @@ -81,36 +82,25 @@ public class AssertionAttributeExtractor {  				Logger.warn("Found more then ONE PVP2.1 assertions. Only the First is used.");  			assertion = assertions.get(0); - -			if (assertion.getAttributeStatements() != null && -					assertion.getAttributeStatements().size() > 0) { -				AttributeStatement attrStat = assertion.getAttributeStatements().get(0); -				for (Attribute attr : attrStat.getAttributes()) { -					if (attr.getName().startsWith(PVPConstants.STORK_ATTRIBUTE_PREFIX)) {							 -						List<String> storkAttrValues = new ArrayList<String>(); -						for (XMLObject el : attr.getAttributeValues()) -							storkAttrValues.add(el.getDOM().getTextContent()); -						 -//						PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(),  -//								false, storkAttrValues , "Available"); -//						storkAttributes.put(attr.getName(), storkAttr ); -						 -					} else { -						List<String> attrList = new ArrayList<String>(); -						for (XMLObject el : attr.getAttributeValues()) -							attrList.add(el.getDOM().getTextContent()); - -						attributs.put(attr.getName(), attrList); -												 -					} -			} -				 -			} -						 +			internalInitialize(); +			  		} else  -			throw new AssertionAttributeExtractorExeption();		 +			throw new AssertionAttributeExtractorExeption();  	} - +	 +	/** +	 * Parse the SAML2 Assertion element and extracts included information +	 * <br><br> +	 *  +	 * @param assertion SAML2 Assertion +	 * @throws AssertionAttributeExtractorExeption +	 */ +	public AssertionAttributeExtractor(Assertion assertion) throws AssertionAttributeExtractorExeption {			 +			this.assertion = assertion; +			internalInitialize(); +			 +	} +	  	/**  	 * Get all SAML2 attributes from first SAML2 AttributeStatement element  	 *  @@ -274,7 +264,30 @@ public class AssertionAttributeExtractor {  		}  -		return getFullAssertion().getConditions().getNotOnOrAfter().toDate(); +		try { +			return getFullAssertion().getConditions().getNotOnOrAfter().toDate(); +			 +		} catch (NullPointerException e) { +			return null; +			 +		} +	} +	 +	/** +	 * Get the Assertion validFrom period +	 *  +     * This method returns value of  SAML 'Conditions' element.  +	 *  +	 * @return Date, after this SAML2 assertion is valid, otherwise null +	 */ +	public Date getAssertionNotBefore() { +		try { +			return getFullAssertion().getConditions().getNotBefore().toDate(); +			 +		} catch (NullPointerException e) { +			return null; +			 +		}  	} @@ -288,5 +301,32 @@ public class AssertionAttributeExtractor {  		return authnList.get(0);  	} +	 +	private void internalInitialize() { +		internalInitialize(); +		if (assertion.getAttributeStatements() != null && +				assertion.getAttributeStatements().size() > 0) { +			AttributeStatement attrStat = assertion.getAttributeStatements().get(0); +			for (Attribute attr : attrStat.getAttributes()) { +				if (attr.getName().startsWith(PVPConstants.STORK_ATTRIBUTE_PREFIX)) {							 +					List<String> storkAttrValues = new ArrayList<String>(); +					for (XMLObject el : attr.getAttributeValues()) +						storkAttrValues.add(el.getDOM().getTextContent()); +					 +//					PersonalAttribute storkAttr = new PersonalAttribute(attr.getName(),  +//							false, storkAttrValues , "Available"); +//					storkAttributes.put(attr.getName(), storkAttr ); +					 +				} else { +					List<String> attrList = new ArrayList<String>(); +					for (XMLObject el : attr.getAttributeValues()) +						attrList.add(el.getDOM().getTextContent()); + +					attributs.put(attr.getName(), attrList); +											 +				} +			}	 +		}	 +	}  } | 
