summaryrefslogtreecommitdiff
path: root/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java')
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java229
1 files changed, 229 insertions, 0 deletions
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
new file mode 100644
index 00000000..136fa6f3
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
@@ -0,0 +1,229 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.slcommands.impl;
+
+import java.io.ByteArrayInputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.dsig.XMLSignatureException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
+
+import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureRequestType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
+import at.gv.egiz.bku.slcommands.CreateXMLSignatureCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactory;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactoryImpl;
+import at.gv.egiz.bku.slcommands.impl.xsect.IdValueFactory;
+import at.gv.egiz.bku.slcommands.impl.xsect.IdValueFactoryImpl;
+import at.gv.egiz.bku.slcommands.impl.xsect.Signature;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+import at.gv.egiz.dom.DOMUtils;
+import at.gv.egiz.stal.InfoboxReadRequest;
+import at.gv.egiz.stal.InfoboxReadResponse;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+
+/**
+ * This class implements the security layer command <code>CreateXMLSignatureRequest</code>.
+ *
+ * @author mcentner
+ */
+public class CreateXMLSignatureCommandImpl extends SLCommandImpl<CreateXMLSignatureRequestType> implements
+ CreateXMLSignatureCommand {
+
+ /**
+ * Logging facility.
+ */
+ protected static Log log = LogFactory.getLog(CreateXMLSignatureCommandImpl.class);
+
+ /**
+ * The signing certificate.
+ */
+ protected X509Certificate signingCertificate;
+
+ /**
+ * The keybox identifier of the key used for signing.
+ */
+ protected String keyboxIdentifier;
+
+ /**
+ * The to-be signed signature.
+ */
+ protected Signature signature;
+
+ @Override
+ public void init(SLCommandContext ctx, Object unmarshalledRequest)
+ throws SLCommandException {
+ super.init(ctx, unmarshalledRequest);
+ }
+
+ @Override
+ public void prepareXMLSignature() throws SLCommandException, SLRequestException {
+
+ CreateXMLSignatureRequestType request = getRequestValue();
+
+ // TODO: make configurable?
+ IdValueFactory idValueFactory = new IdValueFactoryImpl();
+
+ // TODO: make configurable?
+ AlgorithmMethodFactory algorithmMethodFactory;
+ try {
+ algorithmMethodFactory = new AlgorithmMethodFactoryImpl(signingCertificate);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ }
+
+ signature = new Signature(getCmdCtx().getURLDereferencerContext(), idValueFactory, algorithmMethodFactory);
+
+ // SigningTime
+ signature.setSigningTime(new Date());
+
+ // SigningCertificate
+ signature.setSignerCeritifcate(signingCertificate);
+
+ // SignatureInfo
+ if (request.getSignatureInfo() != null) {
+ signature.setSignatureInfo(request.getSignatureInfo());
+ }
+
+ // DataObjects
+ for (DataObjectInfoType dataObjectInfo : request.getDataObjectInfo()) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ }
+
+ /**
+ * Gets the signing certificate from STAL.
+ *
+ * @throws SLCommandException
+ * if getting the singing certificate fails
+ */
+ private void getSigningCertificate() throws SLCommandException {
+
+ CreateXMLSignatureRequestType request = getRequestValue();
+ keyboxIdentifier = request.getKeyboxIdentifier();
+
+ InfoboxReadRequest stalRequest = new InfoboxReadRequest();
+ stalRequest.setInfoboxIdentifier(keyboxIdentifier);
+
+ requestSTAL(Collections.singletonList((STALRequest) stalRequest));
+
+ STALResponse stalResponse = stalResponses.next();
+
+ if (stalResponse instanceof InfoboxReadResponse) {
+ byte[] infobox = ((InfoboxReadResponse) stalResponse).getInfoboxValue();
+
+ try {
+ CertificateFactory certFactory = CertificateFactory.getInstance("X509");
+ signingCertificate = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(infobox));
+ } catch (CertificateException e) {
+ log.info("Failed to decode signing certificate.", e);
+ // TODO: issue appropriate error
+ throw new SLCommandException(4000);
+ }
+
+ } else {
+ log.info("Failed to get signing certificate.");
+ // TODO: issue appropriate error
+ throw new SLCommandException(4000);
+ }
+
+ }
+
+ /**
+ * Signs the signature.
+ *
+ * @throws SLCommandException
+ * if signing the signature fails
+ */
+ private void signXMLSignature() throws SLCommandException {
+
+ try {
+ signature.sign(getCmdCtx().getSTAL(), keyboxIdentifier);
+ } catch (MarshalException e) {
+ log.error("Failed to marshall XMLSignature.", e);
+ throw new SLCommandException(4000);
+ } catch (XMLSignatureException e) {
+ if (e.getCause() instanceof URIReferenceException) {
+ URIReferenceException uriReferenceException = (URIReferenceException) e.getCause();
+ if (uriReferenceException.getCause() instanceof SLCommandException) {
+ throw (SLCommandException) uriReferenceException.getCause();
+ }
+ }
+ log.error("Failed to sign XMLSignature.", e);
+ throw new SLCommandException(4000);
+ }
+
+ }
+
+ @Override
+ public SLResult execute() {
+ try {
+
+ // get certificate in order to select appropriate algorithms for hashing and signing
+ getSigningCertificate();
+
+ // prepare the XMLSignature for signing
+ prepareXMLSignature();
+
+ // sign the XMLSignature
+ signXMLSignature();
+
+ if (log.isTraceEnabled()) {
+
+ DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
+ LSSerializer serializer = domImplLS.createLSSerializer();
+ String debugString = serializer.writeToString(signature.getDocument());
+
+ log.trace(debugString);
+
+ }
+
+ return new CreateXMLSignatureResultImpl(signature.getDocument());
+
+ } catch (SLCommandException e) {
+ return new ErrorResultImpl(e);
+ } catch (SLRequestException e) {
+ return new ErrorResultImpl(e);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "CreateXMLSignatureRequest";
+ }
+
+
+}