/* * 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.egovernment.moa.id.auth.builder; 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.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.auth.exception.ServiceException; import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.Constants; /** * @author tlenz * */ public class SignatureVerificationUtils { /** 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_; public SignatureVerificationUtils() 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); } } public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException { return verify(signature, trustProfileID, null); } public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID, List verifyTransformsInfoProfileID) throws MOAIDException { try { //build signature-verification request Element domVerifyXMLSignatureRequest = build(signature, trustProfileID, verifyTransformsInfoProfileID); //send signature-verification to MOA-SP Element domVerifyXMLSignatureResponse = SignatureVerificationInvoker.getInstance() .verifyXMLSignature(domVerifyXMLSignatureRequest); // parses the IVerifiyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( domVerifyXMLSignatureResponse).parseData(); return verifyXMLSignatureResponse; } catch (ParseException e) { //Logger.error("Build signature-verification request FAILED." ,e); throw e; } catch (ServiceException e) { //Logger.error("MOA-SP signature verification FAILED." ,e); throw e; } } /** * Builds a <VerifyXMLSignatureRequest> * from an IdentityLink with a known trustProfileID which * has to exist in MOA-SP * @param signature - The XML signature as byte[] * @param trustProfileID - a preconfigured TrustProfile at MOA-SP * * @return Element - The complete request as Dom-Element * * @throws ParseException */ private Element build(byte[] signature, String trustProfileID, List verifyTransformsInfoProfileID) throws ParseException { try { // build the request 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 signature String base64EncodedAssertion = Base64Utils.encode(signature); //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"); //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); //add trustProfileID 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_; } }