You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ug...@apache.org on 2009/10/13 18:31:30 UTC
svn commit: r824836 [1/3] - in /poi/trunk: ./ legal/ ooxml-lib/
src/ooxml/java/org/apache/poi/ooxml/
src/ooxml/java/org/apache/poi/ooxml/signature/
src/ooxml/java/org/apache/poi/ooxml/signature/service/
src/ooxml/java/org/apache/poi/ooxml/signature/ser...
Author: ugo
Date: Tue Oct 13 16:31:28 2009
New Revision: 824836
URL: http://svn.apache.org/viewvc?rev=824836&view=rev
Log:
Added implementation of Digital Signature support using code initially developed for the eId Applet project <http://code.google.com/p/eid-applet/> and re-released under Apache License.
Added:
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLSignatureAspect.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLSignatureVerifier.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLURIDereferencer.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/RelationshipComparator.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/RelationshipTransformParameterSpec.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/RelationshipTransformService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/package-info.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/package-info.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/AuthenticationService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/DigestInfo.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/InsecureClientEnvironmentException.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/SecureClientEnvironmentService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/SignatureService.java (with props)
poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/spi/package-info.java (with props)
poi/trunk/src/ooxml/testcases/hello-world-office-2010-technical-preview-unsigned.docx (with props)
poi/trunk/src/ooxml/testcases/hello-world-office-2010-technical-preview.docx (with props)
poi/trunk/src/ooxml/testcases/hello-world-signed-twice.docx (with props)
poi/trunk/src/ooxml/testcases/hello-world-signed.docx (with props)
poi/trunk/src/ooxml/testcases/hello-world-signed.pptx (with props)
poi/trunk/src/ooxml/testcases/hello-world-signed.xlsx (with props)
poi/trunk/src/ooxml/testcases/hello-world-unsigned.docx (with props)
poi/trunk/src/ooxml/testcases/hello-world-unsigned.pptx (with props)
poi/trunk/src/ooxml/testcases/hello-world-unsigned.xlsx (with props)
poi/trunk/src/ooxml/testcases/invalidsig.docx (with props)
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/PkiTestUtils.java (with props)
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/TemporaryTestDataStorage.java (with props)
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/TestAbstractOOXMLSignatureService.java (with props)
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/TestAbstractXmlSignatureService.java (with props)
poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/signature/service/signer/TestOOXMLSignatureVerifier.java (with props)
Modified:
poi/trunk/build.xml
poi/trunk/legal/NOTICE
poi/trunk/ooxml-lib/ (props changed)
Modified: poi/trunk/build.xml
URL: http://svn.apache.org/viewvc/poi/trunk/build.xml?rev=824836&r1=824835&r2=824836&view=diff
==============================================================================
--- poi/trunk/build.xml (original)
+++ poi/trunk/build.xml Tue Oct 13 16:31:28 2009
@@ -132,6 +132,21 @@
<property name="ooxml.jsr173.url" value="${repository.m2}/maven2/org/apache/geronimo/specs/geronimo-stax-api_1.0_spec/1.0/geronimo-stax-api_1.0_spec-1.0.jar"/>
<property name="ooxml.schemas.jar" location="${ooxml.lib}/ooxml-schemas-1.0.jar"/>
<property name="ooxml.schemas.url" value="${repository.m2}/maven2/org/apache/poi/ooxml-schemas/1.0/ooxml-schemas-1.0.jar"/>
+ <property name="ooxml.commons-lang.jar" location="${ooxml.lib}/commons-lang-2.4.jar"/>
+ <property name="ooxml.commons-lang.url" value="${repository.m2}/maven2/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/>
+ <property name="ooxml.commons-io.jar" location="${ooxml.lib}/commons-io-1.4.jar"/>
+ <property name="ooxml.commons-io.url" value="${repository.m2}/maven2/commons-io/commons-io/1.4/commons-io-1.4.jar"/>
+ <property name="ooxml.xmlsec.jar" location="${ooxml.lib}/xmlsec-1.4.3.jar"/>
+ <property name="ooxml.xmlsec.url" value="${repository.m2}/maven2/org/apache/santuario/xmlsec/1.4.3/xmlsec-1.4.3.jar"/>
+ <property name="ooxml.xalan.jar" location="${ooxml.lib}/xalan-2.7.1.jar"/>
+ <property name="ooxml.xalan.url" value="${repository.m2}/maven2/xalan/xalan/2.7.1/xalan-2.7.1.jar"/>
+ <property name="ooxml.xalan-serializer.jar" location="${ooxml.lib}/serializer-2.7.1.jar"/>
+ <property name="ooxml.xalan-serializer.url" value="${repository.m2}/maven2/xalan/serializer/2.7.1/serializer-2.7.1.jar"/>
+ <property name="ooxml.joda-time.jar" location="${ooxml.lib}/joda-time-1.6.jar"/>
+ <property name="ooxml.joda-time.url" value="${repository.m2}/maven2/joda-time/joda-time/1.6/joda-time-1.6.jar"/>
+ <!-- BouncyCastle is used only for OOXML Digital Signature tests -->
+ <property name="ooxml.bcprov.jar" location="${ooxml.lib}/bcprov-jdk15-140.jar"/>
+ <property name="ooxml.bcprov.url" value="${repository.m2}/maven2/bouncycastle/bcprov-jdk15/140/bcprov-jdk15-140.jar"/>
<!-- See http://www.ecma-international.org/publications/standards/Ecma-376.htm -->
<!-- "Copy these file(s), free of charge" -->
@@ -183,6 +198,9 @@
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${contrib.output.dir}"/>
<pathelement location="${contrib.output.test.dir}"/>
+ <fileset dir="${ooxml.lib}">
+ <include name="*.jar" />
+ </fileset>
</path>
<path id="ooxml.classpath">
@@ -208,6 +226,7 @@
<pathelement location="${main.output.test.dir}"/> <!-- ooxml tests use some utilities from main tests -->
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
+ <pathelement location="${ooxml.src.test}"/>
</path>
@@ -351,6 +370,13 @@
<available file="${ooxml.xmlbeans.jar}"/>
<available file="${ooxml.jsr173.jar}"/>
<available file="${ooxml.schemas.jar}"/>
+ <available file="${ooxml.commons-lang.jar}"/>
+ <available file="${ooxml.commons-io.jar}"/>
+ <available file="${ooxml.xmlsec.jar}"/>
+ <available file="${ooxml.xalan.jar}"/>
+ <available file="${ooxml.xalan-serializer.jar}"/>
+ <available file="${ooxml.joda-time.jar}"/>
+ <available file="${ooxml.bcprov.jar}"/>
</and>
<isset property="disconnected"/>
</or>
@@ -373,6 +399,34 @@
<param name="sourcefile" value="${ooxml.schemas.url}"/>
<param name="destfile" value="${ooxml.schemas.jar}"/>
</antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.commons-lang.url}"/>
+ <param name="destfile" value="${ooxml.commons-lang.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.commons-io.url}"/>
+ <param name="destfile" value="${ooxml.commons-io.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.xmlsec.url}"/>
+ <param name="destfile" value="${ooxml.xmlsec.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.xalan.url}"/>
+ <param name="destfile" value="${ooxml.xalan.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.xalan-serializer.url}"/>
+ <param name="destfile" value="${ooxml.xalan-serializer.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.joda-time.url}"/>
+ <param name="destfile" value="${ooxml.joda-time.jar}"/>
+ </antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.bcprov.url}"/>
+ <param name="destfile" value="${ooxml.bcprov.jar}"/>
+ </antcall>
</target>
<target name="check-ooxml-xsds">
Modified: poi/trunk/legal/NOTICE
URL: http://svn.apache.org/viewvc/poi/trunk/legal/NOTICE?rev=824836&r1=824835&r2=824836&view=diff
==============================================================================
--- poi/trunk/legal/NOTICE (original)
+++ poi/trunk/legal/NOTICE Tue Oct 13 16:31:28 2009
@@ -19,3 +19,6 @@
This product contains the chunks_parse_cmds.tbl file from the vsdump program.
Copyright (C) 2006-2007 Valek Filippov (frob@df.ru)
+
+This product contains parts that were originally based on the eID Applet project
+(http://code.google.com/p/eid-applet/). Copyright (C) 2008-2009 FedICT.
\ No newline at end of file
Propchange: poi/trunk/ooxml-lib/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 13 16:31:28 2009
@@ -1,4 +1 @@
-dom4j*.jar
-xmlbeans*.jar
-geronimo-stax-api*.jar
-ooxml-schemas*.jar
+*.jar
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,610 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.poi.ooxml.signature.service.spi.DigestInfo;
+import org.apache.poi.ooxml.signature.service.spi.SignatureService;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.utils.Base64;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xpath.XPathAPI;
+import org.jcp.xml.dsig.internal.dom.DOMReference;
+import org.jcp.xml.dsig.internal.dom.DOMSignedInfo;
+import org.jcp.xml.dsig.internal.dom.DOMXMLSignature;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+
+/**
+ * Abstract base class for an XML Signature Service implementation.
+ */
+public abstract class AbstractXmlSignatureService implements SignatureService {
+
+ static final Log LOG = LogFactory.getLog(AbstractXmlSignatureService.class);
+
+ private static final String SIGNATURE_ID_ATTRIBUTE = "signature-id";
+
+ // TODO refactor everything using the signature aspect design pattern
+ private final List<SignatureAspect> signatureAspects;
+
+ /**
+ * Main constructor.
+ */
+ public AbstractXmlSignatureService() {
+ this.signatureAspects = new LinkedList<SignatureAspect>();
+ }
+
+ /**
+ * Adds a signature aspect to this XML signature service.
+ *
+ * @param signatureAspect
+ */
+ protected void addSignatureAspect(SignatureAspect signatureAspect) {
+ this.signatureAspects.add(signatureAspect);
+ }
+
+ /**
+ * Gives back the signature digest algorithm. Allowed values are SHA-1,
+ * SHA-256, SHA-384, SHA-512, RIPEND160. The default algorithm is SHA-1.
+ * Override this method to select another signature digest algorithm.
+ *
+ * @return
+ */
+ protected String getSignatureDigestAlgorithm() {
+ return "SHA-1";
+ }
+
+ /**
+ * Gives back a list of service digest infos. Override this method to
+ * provide digest infos of files located in the service itself.
+ *
+ * @return
+ */
+ protected List<DigestInfo> getServiceDigestInfos() {
+ return new LinkedList<DigestInfo>();
+ }
+
+ /**
+ * Gives back the enveloping document. Return <code>null</code> in case
+ * ds:Signature should be the top-level element. Implementations can
+ * override this method to provide a custom enveloping document.
+ *
+ * @return
+ * @throws SAXException
+ * @throws IOException
+ */
+ protected Document getEnvelopingDocument() throws ParserConfigurationException, IOException, SAXException {
+ return null;
+ }
+
+ /**
+ * Gives back a list of reference URIs that need to be signed. These URIs
+ * can refer to elements inside the enveloping document or to external
+ * resources. Override this method to feed in other ds:Reference URIs.
+ *
+ * @return
+ */
+ protected List<String> getReferenceUris() {
+ return new LinkedList<String>();
+ }
+
+ public static class ReferenceInfo {
+ private final String uri;
+ private final String transform;
+
+ public ReferenceInfo(String uri, String transform) {
+ this.uri = uri;
+ this.transform = transform;
+ }
+
+ public ReferenceInfo(String uri) {
+ this(uri, null);
+ }
+
+ public String getUri() {
+ return this.uri;
+ }
+
+ public String getTransform() {
+ return this.transform;
+ }
+ }
+
+ /**
+ * Gives back a list of references that need to be signed. Implementation
+ * can override this method.
+ *
+ * @return
+ */
+ protected List<ReferenceInfo> getReferences() {
+ return new LinkedList<ReferenceInfo>();
+ }
+
+ /**
+ * Override this method to change the URI dereferener used by the signing
+ * engine.
+ *
+ * @return
+ */
+ protected URIDereferencer getURIDereferencer() {
+ return null;
+ }
+
+ /**
+ * Gives back the human-readable description of what the citizen will be
+ * signing. The default value is "XML Signature". Override this method to
+ * provide the citizen with another description.
+ *
+ * @return
+ */
+ protected String getSignatureDescription() {
+ return "XML Signature";
+ }
+
+ /**
+ * Gives back a temporary data storage component. This component is used for
+ * temporary storage of the XML signature documents.
+ *
+ * @return
+ */
+ protected abstract TemporaryDataStorage getTemporaryDataStorage();
+
+ /**
+ * Gives back the output stream to which to write the signed XML document.
+ *
+ * @return
+ */
+ protected abstract OutputStream getSignedDocumentOutputStream();
+
+ public DigestInfo preSign(List<DigestInfo> digestInfos, List<X509Certificate> signingCertificateChain) throws NoSuchAlgorithmException {
+ LOG.debug("preSign");
+ String digestAlgo = getSignatureDigestAlgorithm();
+
+ byte[] digestValue;
+ try {
+ digestValue = getXmlSignatureDigestValue(digestAlgo, digestInfos);
+ } catch (Exception e) {
+ throw new RuntimeException("XML signature error: " + e.getMessage(), e);
+ }
+
+ String description = getSignatureDescription();
+ return new DigestInfo(digestValue, digestAlgo, description);
+ }
+
+ /**
+ * Can be overridden by XML signature service implementation to further
+ * process the signed XML document.
+ *
+ * @param sinatureElement
+ * @param signingCertificateChain
+ */
+ protected void postSign(Element sinatureElement, List<X509Certificate> signingCertificateChain) {
+ // empty
+ }
+
+ public void postSign(byte[] signatureValue, List<X509Certificate> signingCertificateChain) {
+ LOG.debug("postSign");
+
+ /*
+ * Retrieve the intermediate XML signature document from the temporary
+ * data storage.
+ */
+ TemporaryDataStorage temporaryDataStorage = getTemporaryDataStorage();
+ InputStream documentInputStream = temporaryDataStorage.getTempInputStream();
+ String signatureId = (String) temporaryDataStorage.getAttribute(SIGNATURE_ID_ATTRIBUTE);
+ LOG.debug("signature Id: " + signatureId);
+
+ /*
+ * Load the signature DOM document.
+ */
+ Document document;
+ try {
+ document = loadDocument(documentInputStream);
+ } catch (Exception e) {
+ throw new RuntimeException("DOM error: " + e.getMessage(), e);
+ }
+
+ /*
+ * Locate the correct ds:Signature node.
+ */
+ Element nsElement = document.createElement("ns");
+ nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
+ Element signatureElement;
+ try {
+ signatureElement = (Element) XPathAPI.selectSingleNode(document, "//ds:Signature[@Id='" + signatureId + "']", nsElement);
+ } catch (TransformerException e) {
+ throw new RuntimeException("XPATH error: " + e.getMessage(), e);
+ }
+ if (null == signatureElement) {
+ throw new RuntimeException("ds:Signature not found for @Id: " + signatureId);
+ }
+
+ /*
+ * Insert signature value into the ds:SignatureValue element
+ */
+ NodeList signatureValueNodeList = signatureElement.getElementsByTagNameNS(javax.xml.crypto.dsig.XMLSignature.XMLNS, "SignatureValue");
+ Element signatureValueElement = (Element) signatureValueNodeList.item(0);
+ signatureValueElement.setTextContent(Base64.encode(signatureValue));
+
+ /*
+ * Allow implementation classes to inject their own stuff.
+ */
+ postSign(signatureElement, signingCertificateChain);
+
+ OutputStream signedDocumentOutputStream = getSignedDocumentOutputStream();
+ if (null == signedDocumentOutputStream) {
+ throw new IllegalArgumentException("signed document output stream is null");
+ }
+ try {
+ writeDocument(document, signedDocumentOutputStream);
+ } catch (Exception e) {
+ LOG.debug("error writing the signed XML document: " + e.getMessage(), e);
+ throw new RuntimeException("error writing the signed XML document: " + e.getMessage(), e);
+ }
+ }
+
+ protected String getCanonicalizationMethod() {
+ // CanonicalizationMethod.INCLUSIVE fails for OOo
+ return CanonicalizationMethod.EXCLUSIVE;
+ }
+
+ private byte[] getXmlSignatureDigestValue(String digestAlgo, List<DigestInfo> digestInfos) throws ParserConfigurationException, NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException, MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ TransformerFactoryConfigurationError, TransformerException, IOException, SAXException {
+ /*
+ * DOM Document construction.
+ */
+ Document document = getEnvelopingDocument();
+ if (null == document) {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ document = documentBuilder.newDocument();
+ }
+
+ /*
+ * Signature context construction.
+ */
+ Key key = new Key() {
+ private static final long serialVersionUID = 1L;
+
+ public String getAlgorithm() {
+ return null;
+ }
+
+ public byte[] getEncoded() {
+ return null;
+ }
+
+ public String getFormat() {
+ return null;
+ }
+ };
+ XMLSignContext xmlSignContext = new DOMSignContext(key, document);
+ URIDereferencer uriDereferencer = getURIDereferencer();
+ if (null != uriDereferencer) {
+ xmlSignContext.setURIDereferencer(uriDereferencer);
+ }
+
+ // OOo doesn't like ds namespaces.
+ // xmlSignContext.putNamespacePrefix(
+ // javax.xml.crypto.dsig.XMLSignature.XMLNS, "ds");
+
+ XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
+
+ /*
+ * ds:Reference
+ */
+ List<Reference> references = new LinkedList<Reference>();
+ addDigestInfosAsReferences(digestInfos, signatureFactory, references);
+ List<DigestInfo> serviceDigestInfos = getServiceDigestInfos();
+ addDigestInfosAsReferences(serviceDigestInfos, signatureFactory, references);
+ addReferenceIds(signatureFactory, xmlSignContext, references);
+ addReferences(signatureFactory, references);
+
+ /*
+ * Invoke the signature aspects.
+ */
+ String signatureId = "xmldsig-" + UUID.randomUUID().toString();
+ List<XMLObject> objects = new LinkedList<XMLObject>();
+ for (SignatureAspect signatureAspect : this.signatureAspects) {
+ LOG.debug("invoking signature aspect: " + signatureAspect.getClass().getSimpleName());
+ signatureAspect.preSign(signatureFactory, document, signatureId, references, objects);
+ }
+
+ /*
+ * ds:SignedInfo
+ */
+ SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(getSignatureMethod(digestAlgo), null);
+ CanonicalizationMethod canonicalizationMethod = signatureFactory.newCanonicalizationMethod(getCanonicalizationMethod(), (C14NMethodParameterSpec) null);
+ SignedInfo signedInfo = signatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, references);
+
+ /*
+ * JSR105 ds:Signature creation
+ */
+ String signatureValueId = signatureId + "-signature-value";
+ javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory.newXMLSignature(signedInfo, null, objects, signatureId, signatureValueId);
+
+ /*
+ * ds:Signature Marshalling.
+ */
+ DOMXMLSignature domXmlSignature = (DOMXMLSignature) xmlSignature;
+ Node documentNode = document.getDocumentElement();
+ if (null == documentNode) {
+ /*
+ * In case of an empty DOM document.
+ */
+ documentNode = document;
+ }
+ String dsPrefix = null;
+ // String dsPrefix = "ds";
+ domXmlSignature.marshal(documentNode, dsPrefix, (DOMCryptoContext) xmlSignContext);
+
+ /*
+ * Completion of undigested ds:References in the ds:Manifests.
+ */
+ for (XMLObject object : objects) {
+ LOG.debug("object java type: " + object.getClass().getName());
+ List<XMLStructure> objectContentList = object.getContent();
+ for (XMLStructure objectContent : objectContentList) {
+ LOG.debug("object content java type: " + objectContent.getClass().getName());
+ if (false == objectContent instanceof Manifest) {
+ continue;
+ }
+ Manifest manifest = (Manifest) objectContent;
+ List<Reference> manifestReferences = manifest.getReferences();
+ for (Reference manifestReference : manifestReferences) {
+ if (null != manifestReference.getDigestValue()) {
+ continue;
+ }
+ DOMReference manifestDOMReference = (DOMReference) manifestReference;
+ manifestDOMReference.digest(xmlSignContext);
+ }
+ }
+ }
+
+ /*
+ * Completion of undigested ds:References.
+ */
+ List<Reference> signedInfoReferences = signedInfo.getReferences();
+ for (Reference signedInfoReference : signedInfoReferences) {
+ DOMReference domReference = (DOMReference) signedInfoReference;
+ if (null != domReference.getDigestValue()) {
+ // ds:Reference with external digest value
+ continue;
+ }
+ domReference.digest(xmlSignContext);
+ }
+
+ /*
+ * Store the intermediate XML signature document.
+ */
+ TemporaryDataStorage temporaryDataStorage = getTemporaryDataStorage();
+ OutputStream tempDocumentOutputStream = temporaryDataStorage.getTempOutputStream();
+ writeDocument(document, tempDocumentOutputStream);
+ temporaryDataStorage.setAttribute(SIGNATURE_ID_ATTRIBUTE, signatureId);
+
+ /*
+ * Calculation of XML signature digest value.
+ */
+ DOMSignedInfo domSignedInfo = (DOMSignedInfo) signedInfo;
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ domSignedInfo.canonicalize(xmlSignContext, dataStream);
+ byte[] octets = dataStream.toByteArray();
+
+ /*
+ * TODO: we could be using DigestOutputStream here to optimize memory
+ * usage.
+ */
+
+ MessageDigest jcaMessageDigest = MessageDigest.getInstance(digestAlgo);
+ byte[] digestValue = jcaMessageDigest.digest(octets);
+ return digestValue;
+ }
+
+ private void addReferenceIds(XMLSignatureFactory signatureFactory, XMLSignContext xmlSignContext, List<Reference> references)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, XMLSignatureException {
+ List<String> referenceUris = getReferenceUris();
+ if (null == referenceUris) {
+ return;
+ }
+ DigestMethod digestMethod = signatureFactory.newDigestMethod(DigestMethod.SHA1, null);
+ for (String referenceUri : referenceUris) {
+ Reference reference = signatureFactory.newReference(referenceUri, digestMethod);
+ references.add(reference);
+ }
+ }
+
+ private void addReferences(XMLSignatureFactory xmlSignatureFactory, List<Reference> references) throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException {
+ List<ReferenceInfo> referenceInfos = getReferences();
+ if (null == referenceInfos) {
+ return;
+ }
+ if (referenceInfos.isEmpty()) {
+ return;
+ }
+ DigestMethod digestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1, null);
+ for (ReferenceInfo referenceInfo : referenceInfos) {
+ List<Transform> transforms = new LinkedList<Transform>();
+ if (null != referenceInfo.getTransform()) {
+ Transform transform = xmlSignatureFactory.newTransform(referenceInfo.getTransform(), (TransformParameterSpec) null);
+ transforms.add(transform);
+ }
+ LOG.debug("adding ds:Reference " + referenceInfo.getUri());
+ Reference reference = xmlSignatureFactory.newReference(referenceInfo.getUri(), digestMethod, transforms, null, null);
+ references.add(reference);
+ }
+ }
+
+ private void addDigestInfosAsReferences(List<DigestInfo> digestInfos, XMLSignatureFactory signatureFactory, List<Reference> references)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MalformedURLException {
+ if (null == digestInfos) {
+ return;
+ }
+ for (DigestInfo digestInfo : digestInfos) {
+ byte[] documentDigestValue = digestInfo.digestValue;
+
+ DigestMethod digestMethod = signatureFactory.newDigestMethod(getXmlDigestAlgo(digestInfo.digestAlgo), null);
+
+ String uri = FilenameUtils.getName(new File(digestInfo.description).toURI().toURL().getFile());
+
+ Reference reference = signatureFactory.newReference(uri, digestMethod, null, null, null, documentDigestValue);
+ references.add(reference);
+ }
+ }
+
+ private String getXmlDigestAlgo(String digestAlgo) {
+ if ("SHA-1".equals(digestAlgo)) {
+ return DigestMethod.SHA1;
+ }
+ if ("SHA-256".equals(digestAlgo)) {
+ return DigestMethod.SHA256;
+ }
+ if ("SHA-512".equals(digestAlgo)) {
+ return DigestMethod.SHA512;
+ }
+ throw new RuntimeException("unsupported digest algo: " + digestAlgo);
+ }
+
+ private String getSignatureMethod(String digestAlgo) {
+ if (null == digestAlgo) {
+ throw new RuntimeException("digest algo is null");
+ }
+ if ("SHA-1".equals(digestAlgo)) {
+ return SignatureMethod.RSA_SHA1;
+ }
+ if ("SHA-256".equals(digestAlgo)) {
+ return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256;
+ }
+ if ("SHA-512".equals(digestAlgo)) {
+ return XMLSignature.ALGO_ID_MAC_HMAC_SHA512;
+ }
+ if ("SHA-384".equals(digestAlgo)) {
+ return XMLSignature.ALGO_ID_MAC_HMAC_SHA384;
+ }
+ if ("RIPEMD160".equals(digestAlgo)) {
+ return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160;
+ }
+ throw new RuntimeException("unsupported sign algo: " + digestAlgo);
+ }
+
+ protected void writeDocument(Document document, OutputStream documentOutputStream) throws TransformerConfigurationException,
+ TransformerFactoryConfigurationError, TransformerException, IOException {
+ writeDocumentNoClosing(document, documentOutputStream);
+ documentOutputStream.close();
+ }
+
+ protected void writeDocumentNoClosing(Document document, OutputStream documentOutputStream) throws TransformerConfigurationException,
+ TransformerFactoryConfigurationError, TransformerException, IOException {
+ // we need the XML processing initial line for OOXML
+ writeDocumentNoClosing(document, documentOutputStream, false);
+ }
+
+ protected void writeDocumentNoClosing(Document document, OutputStream documentOutputStream, boolean omitXmlDeclaration)
+ throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException, IOException {
+ NoCloseOutputStream outputStream = new NoCloseOutputStream(documentOutputStream);
+ Result result = new StreamResult(outputStream);
+ Transformer xformer = TransformerFactory.newInstance().newTransformer();
+ if (omitXmlDeclaration) {
+ xformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ }
+ Source source = new DOMSource(document);
+ xformer.transform(source, result);
+ }
+
+ protected Document loadDocument(InputStream documentInputStream) throws ParserConfigurationException, SAXException, IOException {
+ InputSource inputSource = new InputSource(documentInputStream);
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document document = documentBuilder.parse(inputSource);
+ return document;
+ }
+
+ protected Document loadDocumentNoClose(InputStream documentInputStream) throws ParserConfigurationException, SAXException, IOException {
+ NoCloseInputStream noCloseInputStream = new NoCloseInputStream(documentInputStream);
+ InputSource inputSource = new InputSource(noCloseInputStream);
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document document = documentBuilder.parse(inputSource);
+ return document;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/AbstractXmlSignatureService.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,99 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.security.Key;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.KeySelectorResult;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * JSR105 key selector implementation using the ds:KeyInfo data of the signature
+ * itself.
+ */
+public class KeyInfoKeySelector extends KeySelector implements KeySelectorResult {
+
+ private static final Log LOG = LogFactory.getLog(KeyInfoKeySelector.class);
+
+ private X509Certificate certificate;
+
+ @Override
+ public KeySelectorResult select(KeyInfo keyInfo, Purpose purpose, AlgorithmMethod method, XMLCryptoContext context) throws KeySelectorException {
+ LOG.debug("select key");
+ if (null == keyInfo) {
+ throw new KeySelectorException("no ds:KeyInfo present");
+ }
+ List<XMLStructure> keyInfoContent = keyInfo.getContent();
+ this.certificate = null;
+ for (XMLStructure keyInfoStructure : keyInfoContent) {
+ if (false == (keyInfoStructure instanceof X509Data)) {
+ continue;
+ }
+ X509Data x509Data = (X509Data) keyInfoStructure;
+ List<Object> x509DataList = x509Data.getContent();
+ for (Object x509DataObject : x509DataList) {
+ if (false == (x509DataObject instanceof X509Certificate)) {
+ continue;
+ }
+ X509Certificate certificate = (X509Certificate) x509DataObject;
+ LOG.debug("certificate: " + certificate.getSubjectX500Principal());
+ if (null == this.certificate) {
+ /*
+ * The first certificate is presumably the signer.
+ */
+ this.certificate = certificate;
+ }
+ }
+ if (null != this.certificate) {
+ return this;
+ }
+ }
+ throw new KeySelectorException("No key found!");
+ }
+
+ public Key getKey() {
+ return this.certificate.getPublicKey();
+ }
+
+ /**
+ * Gives back the X509 certificate used during the last signature
+ * verification operation.
+ *
+ * @return
+ */
+ public X509Certificate getCertificate() {
+ return this.certificate;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/KeyInfoKeySelector.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,53 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Input Stream proxy that doesn't close the underlying input stream.
+ */
+public class NoCloseInputStream extends ProxyInputStream {
+
+ private static final Log LOG = LogFactory.getLog(NoCloseInputStream.class);
+
+ /**
+ * Main constructor.
+ *
+ * @param proxy
+ */
+ public NoCloseInputStream(InputStream proxy) {
+ super(proxy);
+ }
+
+ @Override
+ public void close() throws IOException {
+ LOG.debug("close");
+ }
+}
\ No newline at end of file
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseInputStream.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,54 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Output Stream proxy that doesn't close the underlying stream.
+ */
+public class NoCloseOutputStream extends ProxyOutputStream {
+
+ private static final Log LOG = LogFactory.getLog(NoCloseOutputStream.class);
+
+ /**
+ * Main constructor.
+ *
+ * @param proxy
+ */
+ public NoCloseOutputStream(OutputStream proxy) {
+ super(proxy);
+ }
+
+ @Override
+ public void close() throws IOException {
+ LOG.debug("close");
+ // empty
+ }
+}
\ No newline at end of file
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/NoCloseOutputStream.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,56 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+
+import org.w3c.dom.Document;
+
+/**
+ * JSR105 Signature Aspect interface.
+ */
+public interface SignatureAspect {
+
+ /**
+ * This method is being invoked by the XML signature service engine during
+ * pre-sign phase. Via this method a signature aspect implementation can add
+ * signature aspects to an XML signature.
+ *
+ * @param signatureFactory
+ * @param document
+ * @param signatureId
+ * @param references
+ * @param objects
+ * @throws InvalidAlgorithmParameterException
+ * @throws NoSuchAlgorithmException
+ */
+ void preSign(XMLSignatureFactory signatureFactory, Document document, String signatureId, List<Reference> references, List<XMLObject> objects)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/SignatureAspect.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,65 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * Interface for temporary data storage.
+ */
+public interface TemporaryDataStorage {
+
+ /**
+ * Gives back the temporary output stream that can be used for data storage.
+ *
+ * @return
+ */
+ OutputStream getTempOutputStream();
+
+ /**
+ * Gives back the temporary input stream for retrieval of the previously
+ * stored data.
+ *
+ * @return
+ */
+ InputStream getTempInputStream();
+
+ /**
+ * Stores an attribute to the temporary data storage.
+ *
+ * @param attributeName
+ * @param attributeValue
+ */
+ void setAttribute(String attributeName, Serializable attributeValue);
+
+ /**
+ * Retrieves an attribute from the temporary data storage.
+ *
+ * @param attributeName
+ * @return
+ */
+ Serializable getAttribute(String attributeName);
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/TemporaryDataStorage.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,348 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer.ooxml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.security.Key;
+import java.security.KeyException;
+import java.security.cert.X509Certificate;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.poi.ooxml.signature.service.signer.AbstractXmlSignatureService;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xpath.XPathAPI;
+import org.jcp.xml.dsig.internal.dom.DOMKeyInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+
+
+/**
+ * Signature Service implementation for Office OpenXML document format XML
+ * signatures.
+ */
+public abstract class AbstractOOXMLSignatureService extends AbstractXmlSignatureService {
+
+ static final Log LOG = LogFactory.getLog(AbstractOOXMLSignatureService.class);
+
+ protected AbstractOOXMLSignatureService() {
+ addSignatureAspect(new OOXMLSignatureAspect(this));
+ }
+
+ @Override
+ protected String getSignatureDescription() {
+ return "Office OpenXML Document";
+ }
+
+ public String getFilesDigestAlgorithm() {
+ return null;
+ }
+
+ @Override
+ protected final URIDereferencer getURIDereferencer() {
+ URL ooxmlUrl = getOfficeOpenXMLDocumentURL();
+ return new OOXMLURIDereferencer(ooxmlUrl);
+ }
+
+ @Override
+ protected String getCanonicalizationMethod() {
+ return CanonicalizationMethod.INCLUSIVE;
+ }
+
+ @Override
+ protected void postSign(Element signatureElement, List<X509Certificate> signingCertificateChain) {
+ // TODO: implement as SignatureAspect
+ LOG.debug("postSign: adding ds:KeyInfo");
+ /*
+ * Make sure we insert right after the ds:SignatureValue element.
+ */
+ Node nextSibling;
+ NodeList objectNodeList = signatureElement.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Object");
+ if (0 == objectNodeList.getLength()) {
+ nextSibling = null;
+ } else {
+ nextSibling = objectNodeList.item(0);
+ }
+ /*
+ * Add a ds:KeyInfo entry.
+ */
+ KeyInfoFactory keyInfoFactory = KeyInfoFactory.getInstance();
+ List<Object> x509DataObjects = new LinkedList<Object>();
+
+ X509Certificate signingCertificate = signingCertificateChain.get(0);
+ KeyValue keyValue;
+ try {
+ keyValue = keyInfoFactory.newKeyValue(signingCertificate.getPublicKey());
+ } catch (KeyException e) {
+ throw new RuntimeException("key exception: " + e.getMessage(), e);
+ }
+
+ for (X509Certificate certificate : signingCertificateChain) {
+ x509DataObjects.add(certificate);
+ }
+ X509Data x509Data = keyInfoFactory.newX509Data(x509DataObjects);
+ List<Object> keyInfoContent = new LinkedList<Object>();
+ keyInfoContent.add(keyValue);
+ keyInfoContent.add(x509Data);
+ KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoContent);
+ DOMKeyInfo domKeyInfo = (DOMKeyInfo) keyInfo;
+ Key key = new Key() {
+ private static final long serialVersionUID = 1L;
+
+ public String getAlgorithm() {
+ return null;
+ }
+
+ public byte[] getEncoded() {
+ return null;
+ }
+
+ public String getFormat() {
+ return null;
+ }
+ };
+ XMLSignContext xmlSignContext = new DOMSignContext(key, signatureElement);
+ DOMCryptoContext domCryptoContext = (DOMCryptoContext) xmlSignContext;
+ String dsPrefix = null;
+ // String dsPrefix = "ds";
+ try {
+ domKeyInfo.marshal(signatureElement, nextSibling, dsPrefix, domCryptoContext);
+ } catch (MarshalException e) {
+ throw new RuntimeException("marshall error: " + e.getMessage(), e);
+ }
+ }
+
+ private class OOXMLSignedDocumentOutputStream extends ByteArrayOutputStream {
+
+ @Override
+ public void close() throws IOException {
+ LOG.debug("close OOXML signed document output stream");
+ super.close();
+ try {
+ outputSignedOfficeOpenXMLDocument(this.toByteArray());
+ } catch (Exception e) {
+ throw new IOException("generic error: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * The output stream to which to write the signed Office OpenXML file.
+ *
+ * @return
+ */
+ abstract protected OutputStream getSignedOfficeOpenXMLDocumentOutputStream();
+
+ /**
+ * Gives back the URL of the OOXML to be signed.
+ *
+ * @return
+ */
+ abstract protected URL getOfficeOpenXMLDocumentURL();
+
+ private void outputSignedOfficeOpenXMLDocument(byte[] signatureData) throws IOException, ParserConfigurationException, SAXException, TransformerException {
+ LOG.debug("output signed Office OpenXML document");
+ OutputStream signedOOXMLOutputStream = getSignedOfficeOpenXMLDocumentOutputStream();
+ if (null == signedOOXMLOutputStream) {
+ throw new NullPointerException("signedOOXMLOutputStream is null");
+ }
+
+ String signatureZipEntryName = "_xmlsignatures/sig-" + UUID.randomUUID().toString() + ".xml";
+ LOG.debug("signature ZIP entry name: " + signatureZipEntryName);
+ /*
+ * Copy the original OOXML content to the signed OOXML package. During
+ * copying some files need to changed.
+ */
+ ZipOutputStream zipOutputStream = copyOOXMLContent(signatureZipEntryName, signedOOXMLOutputStream);
+
+ /*
+ * Add the OOXML XML signature file to the OOXML package.
+ */
+ ZipEntry zipEntry = new ZipEntry(signatureZipEntryName);
+ zipOutputStream.putNextEntry(zipEntry);
+ IOUtils.write(signatureData, zipOutputStream);
+ zipOutputStream.close();
+ }
+
+ private ZipOutputStream copyOOXMLContent(String signatureZipEntryName, OutputStream signedOOXMLOutputStream) throws IOException,
+ ParserConfigurationException, SAXException, TransformerConfigurationException, TransformerFactoryConfigurationError,
+ TransformerException {
+ ZipOutputStream zipOutputStream = new ZipOutputStream(signedOOXMLOutputStream);
+ ZipInputStream zipInputStream = new ZipInputStream(this.getOfficeOpenXMLDocumentURL().openStream());
+ ZipEntry zipEntry;
+ boolean hasOriginSigsRels = false;
+ while (null != (zipEntry = zipInputStream.getNextEntry())) {
+ LOG.debug("copy ZIP entry: " + zipEntry.getName());
+ ZipEntry newZipEntry = new ZipEntry(zipEntry.getName());
+ zipOutputStream.putNextEntry(newZipEntry);
+ if ("[Content_Types].xml".equals(zipEntry.getName())) {
+ Document contentTypesDocument = loadDocumentNoClose(zipInputStream);
+ Element typesElement = contentTypesDocument.getDocumentElement();
+
+ /*
+ * We need to add an Override element.
+ */
+ Element overrideElement = contentTypesDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/content-types", "Override");
+ overrideElement.setAttribute("PartName", "/" + signatureZipEntryName);
+ overrideElement.setAttribute("ContentType", "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml");
+ typesElement.appendChild(overrideElement);
+
+ Element nsElement = contentTypesDocument.createElement("ns");
+ nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:tns", "http://schemas.openxmlformats.org/package/2006/content-types");
+ NodeList nodeList = XPathAPI.selectNodeList(contentTypesDocument, "/tns:Types/tns:Default[@Extension='sigs']", nsElement);
+ if (0 == nodeList.getLength()) {
+ /*
+ * Add Default element for 'sigs' extension.
+ */
+ Element defaultElement = contentTypesDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/content-types", "Default");
+ defaultElement.setAttribute("Extension", "sigs");
+ defaultElement.setAttribute("ContentType", "application/vnd.openxmlformats-package.digital-signature-origin");
+ typesElement.appendChild(defaultElement);
+ }
+
+ writeDocumentNoClosing(contentTypesDocument, zipOutputStream, false);
+ } else if ("_rels/.rels".equals(zipEntry.getName())) {
+ Document relsDocument = loadDocumentNoClose(zipInputStream);
+
+ Element nsElement = relsDocument.createElement("ns");
+ nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:tns", "http://schemas.openxmlformats.org/package/2006/relationships");
+ NodeList nodeList = XPathAPI.selectNodeList(relsDocument, "/tns:Relationships/tns:Relationship[@Target='_xmlsignatures/origin.sigs']",
+ nsElement);
+ if (0 == nodeList.getLength()) {
+ Element relationshipElement = relsDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/relationships", "Relationship");
+ relationshipElement.setAttribute("Id", "rel-id-" + UUID.randomUUID().toString());
+ relationshipElement.setAttribute("Type", "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin");
+ relationshipElement.setAttribute("Target", "_xmlsignatures/origin.sigs");
+
+ relsDocument.getDocumentElement().appendChild(relationshipElement);
+ }
+
+ writeDocumentNoClosing(relsDocument, zipOutputStream, false);
+ } else if ("_xmlsignatures/_rels/origin.sigs.rels".equals(zipEntry.getName())) {
+ hasOriginSigsRels = true;
+ Document originSignRelsDocument = loadDocumentNoClose(zipInputStream);
+
+ Element relationshipElement = originSignRelsDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/relationships",
+ "Relationship");
+ String relationshipId = "rel-" + UUID.randomUUID().toString();
+ relationshipElement.setAttribute("Id", relationshipId);
+ relationshipElement.setAttribute("Type", "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature");
+ String target = FilenameUtils.getName(signatureZipEntryName);
+ LOG.debug("target: " + target);
+ relationshipElement.setAttribute("Target", target);
+ originSignRelsDocument.getDocumentElement().appendChild(relationshipElement);
+
+ writeDocumentNoClosing(originSignRelsDocument, zipOutputStream, false);
+ } else {
+ IOUtils.copy(zipInputStream, zipOutputStream);
+ }
+ }
+
+ if (false == hasOriginSigsRels) {
+ /*
+ * Add signature relationships document.
+ */
+ addOriginSigsRels(signatureZipEntryName, zipOutputStream);
+ addOriginSigs(zipOutputStream);
+ }
+
+ /*
+ * Return.
+ */
+ zipInputStream.close();
+ return zipOutputStream;
+ }
+
+ private void addOriginSigs(ZipOutputStream zipOutputStream) throws IOException {
+ zipOutputStream.putNextEntry(new ZipEntry("_xmlsignatures/origin.sigs"));
+ }
+
+ private void addOriginSigsRels(String signatureZipEntryName, ZipOutputStream zipOutputStream) throws ParserConfigurationException, IOException,
+ TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document originSignRelsDocument = documentBuilder.newDocument();
+
+ Element relationshipsElement = originSignRelsDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/relationships", "Relationships");
+ relationshipsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
+ originSignRelsDocument.appendChild(relationshipsElement);
+
+ Element relationshipElement = originSignRelsDocument.createElementNS("http://schemas.openxmlformats.org/package/2006/relationships", "Relationship");
+ String relationshipId = "rel-" + UUID.randomUUID().toString();
+ relationshipElement.setAttribute("Id", relationshipId);
+ relationshipElement.setAttribute("Type", "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature");
+ String target = FilenameUtils.getName(signatureZipEntryName);
+ LOG.debug("target: " + target);
+ relationshipElement.setAttribute("Target", target);
+ relationshipsElement.appendChild(relationshipElement);
+
+ zipOutputStream.putNextEntry(new ZipEntry("_xmlsignatures/_rels/origin.sigs.rels"));
+ writeDocumentNoClosing(originSignRelsDocument, zipOutputStream, false);
+ }
+
+ @Override
+ protected OutputStream getSignedDocumentOutputStream() {
+ LOG.debug("get signed document output stream");
+ /*
+ * Create each time a new object; we want an empty output stream to
+ * start with.
+ */
+ OutputStream signedDocumentOutputStream = new OOXMLSignedDocumentOutputStream();
+ return signedDocumentOutputStream;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/AbstractOOXMLSignatureService.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java?rev=824836&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java Tue Oct 13 16:31:28 2009
@@ -0,0 +1,54 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+==================================================================== */
+
+
+/*
+ * Based on the eID Applet Project code.
+ * Original Copyright (C) 2008-2009 FedICT.
+ */
+
+package org.apache.poi.ooxml.signature.service.signer.ooxml;
+
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * Security Provider for Office OpenXML.
+ */
+public class OOXMLProvider extends Provider {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String NAME = "OOXMLProvider";
+
+ private OOXMLProvider() {
+ super(NAME, 1.0, "OOXML Security Provider");
+ put("TransformService." + RelationshipTransformService.TRANSFORM_URI, RelationshipTransformService.class.getName());
+ put("TransformService." + RelationshipTransformService.TRANSFORM_URI + " MechanismType", "DOM");
+ }
+
+ /**
+ * Installs this security provider.
+ */
+ public static void install() {
+ Provider provider = Security.getProvider(NAME);
+ if (null == provider) {
+ Security.addProvider(new OOXMLProvider());
+ }
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/signature/service/signer/ooxml/OOXMLProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org