/*******************************************************************************
* 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.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.data.CreateXMLSignatureResponse;
import at.gv.egovernment.moa.id.auth.data.IdentityLink;
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(IdentityLink 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_;
}
}