/******************************************************************************* * 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.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; 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.util.Base64Utils; import at.gv.egovernment.moa.util.Constants; /** * Builder for the <VerifyXMLSignatureRequestBuilder> 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 VerifyXMLsignatureRequest */ private Document requestDoc_; /** the VerifyXMLsignatureRequest root element */ private Element requestElem_; /** * Builds the body for a VerifyXMLsignatureRequest 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 <VerifyXMLSignatureRequest> * 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 <VerifyXMLSignatureRequest> * 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 <VerifyXMLSignatureRequest> * 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 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 <VerifyXMLSignatureRequest> * 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_; } }