/*
* 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 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 {
try {
//build signature-verification request
Element domVerifyXMLSignatureRequest = build(signature, trustProfileID);
//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)
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");
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_;
}
}