You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2014/08/10 20:25:12 UTC
svn commit: r1617141 [3/5] - in /poi/branches/xml_signature: ./
src/java/org/apache/poi/poifs/crypt/
src/ooxml/java/org/apache/poi/openxml4j/opc/
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/ src/...
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,249 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.TransformService;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.XmlSort;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.RelationshipReferenceDocument;
+import org.openxmlformats.schemas.xpackage.x2006.relationships.CTRelationship;
+import org.openxmlformats.schemas.xpackage.x2006.relationships.CTRelationships;
+import org.openxmlformats.schemas.xpackage.x2006.relationships.RelationshipsDocument;
+import org.openxmlformats.schemas.xpackage.x2006.relationships.STTargetMode;
+import org.w3.x2000.x09.xmldsig.TransformDocument;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * JSR105 implementation of the RelationshipTransform transformation.
+ *
+ * <p>
+ * Specs: http://openiso.org/Ecma/376/Part2/12.2.4#26
+ * </p>
+ */
+public class RelationshipTransformService extends TransformService {
+
+ public static final String TRANSFORM_URI = "http://schemas.openxmlformats.org/package/2006/RelationshipTransform";
+
+ private final List<String> sourceIds;
+
+ private static final POILogger LOG = POILogFactory.getLogger(RelationshipTransformService.class);
+
+ /**
+ * Relationship Transform parameter specification class.
+ */
+ public static class RelationshipTransformParameterSpec implements TransformParameterSpec {
+ List<String> sourceIds = new LinkedList<String>();
+ public void addRelationshipReference(String relationshipId) {
+ sourceIds.add(relationshipId);
+ }
+ public boolean hasSourceIds() {
+ return !sourceIds.isEmpty();
+ }
+ }
+
+
+ public RelationshipTransformService() {
+ super();
+ LOG.log(POILogger.DEBUG, "constructor");
+ this.sourceIds = new LinkedList<String>();
+ }
+
+ /**
+ * Register the provider for this TransformService
+ *
+ * @see javax.xml.crypto.dsig.TransformService
+ */
+ public static synchronized void registerDsigProvider() {
+ // the xml signature classes will try to find a special TransformerService,
+ // which is ofcourse unknown to JCE before ...
+ final String dsigProvider = "POIXmlDsigProvider";
+ if (Security.getProperty(dsigProvider) == null) {
+ Provider p = new Provider(dsigProvider, 1.0, dsigProvider){
+ static final long serialVersionUID = 1L;
+ };
+ p.put("TransformService." + TRANSFORM_URI, RelationshipTransformService.class.getName());
+ p.put("TransformService." + TRANSFORM_URI + " MechanismType", "DOM");
+ Security.addProvider(p);
+ }
+ }
+
+
+ @Override
+ public void init(TransformParameterSpec params) throws InvalidAlgorithmParameterException {
+ LOG.log(POILogger.DEBUG, "init(params)");
+ if (!(params instanceof RelationshipTransformParameterSpec)) {
+ throw new InvalidAlgorithmParameterException();
+ }
+ RelationshipTransformParameterSpec relParams = (RelationshipTransformParameterSpec) params;
+ for (String sourceId : relParams.sourceIds) {
+ this.sourceIds.add(sourceId);
+ }
+ }
+
+ @Override
+ public void init(XMLStructure parent, XMLCryptoContext context) throws InvalidAlgorithmParameterException {
+ LOG.log(POILogger.DEBUG, "init(parent,context)");
+ LOG.log(POILogger.DEBUG, "parent java type: " + parent.getClass().getName());
+ DOMStructure domParent = (DOMStructure) parent;
+ Node parentNode = domParent.getNode();
+
+ try {
+ TransformDocument transDoc = TransformDocument.Factory.parse(parentNode);
+ XmlObject xoList[] = transDoc.getTransform().selectChildren(RelationshipReferenceDocument.type.getDocumentElementName());
+ if (xoList.length == 0) {
+ LOG.log(POILogger.WARN, "no RelationshipReference/@SourceId parameters present");
+ }
+ for (XmlObject xo : xoList) {
+ RelationshipReferenceDocument refDoc =
+ RelationshipReferenceDocument.Factory.parse(xo.getDomNode());
+ String sourceId = refDoc.getRelationshipReference().getSourceId();
+ LOG.log(POILogger.DEBUG, "sourceId: ", sourceId);
+ this.sourceIds.add(sourceId);
+ }
+ } catch (XmlException e) {
+ throw new InvalidAlgorithmParameterException(e);
+ }
+ }
+
+ @Override
+ public void marshalParams(XMLStructure parent, XMLCryptoContext context) throws MarshalException {
+ LOG.log(POILogger.DEBUG, "marshallParams(parent,context)");
+ DOMStructure domParent = (DOMStructure) parent;
+ Element parentNode = (Element)domParent.getNode();
+ // parentNode.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", DIGITAL_SIGNATURE);
+ Document doc = parentNode.getOwnerDocument();
+
+ for (String sourceId : this.sourceIds) {
+ RelationshipReferenceDocument relRef = RelationshipReferenceDocument.Factory.newInstance();
+ relRef.addNewRelationshipReference().setSourceId(sourceId);
+ Node n = relRef.getRelationshipReference().getDomNode();
+ // TODO: is there a more elegant way to do this?
+ n.setPrefix("mdssi");
+ n = doc.importNode(n, true);
+ parentNode.appendChild(n);
+ }
+ }
+
+ public AlgorithmParameterSpec getParameterSpec() {
+ LOG.log(POILogger.DEBUG, "getParameterSpec");
+ return null;
+ }
+
+ public Data transform(Data data, XMLCryptoContext context) throws TransformException {
+ LOG.log(POILogger.DEBUG, "transform(data,context)");
+ LOG.log(POILogger.DEBUG, "data java type: " + data.getClass().getName());
+ OctetStreamData octetStreamData = (OctetStreamData) data;
+ LOG.log(POILogger.DEBUG, "URI: " + octetStreamData.getURI());
+ InputStream octetStream = octetStreamData.getOctetStream();
+
+ RelationshipsDocument relDoc;
+ try {
+ relDoc = RelationshipsDocument.Factory.parse(octetStream);
+ } catch (Exception e) {
+ throw new TransformException(e.getMessage(), e);
+ }
+ LOG.log(POILogger.DEBUG, "relationships document", relDoc);
+
+ CTRelationships rels = relDoc.getRelationships();
+ List<CTRelationship> relList = rels.getRelationshipList();
+ Iterator<CTRelationship> relIter = rels.getRelationshipList().iterator();
+ while (relIter.hasNext()) {
+ CTRelationship rel = relIter.next();
+ /*
+ * See: ISO/IEC 29500-2:2008(E) - 13.2.4.24 Relationships Transform
+ * Algorithm.
+ */
+ if (!this.sourceIds.contains(rel.getId())) {
+ LOG.log(POILogger.DEBUG, "removing element: " + rel.getId());
+ relIter.remove();
+ } else {
+ if (!rel.isSetTargetMode()) {
+ rel.setTargetMode(STTargetMode.INTERNAL);
+ }
+ }
+ }
+
+ // TODO: remove non element nodes ???
+ LOG.log(POILogger.DEBUG, "# Relationship elements", relList.size());
+
+ XmlSort.sort(rels, new Comparator<XmlCursor>(){
+ public int compare(XmlCursor c1, XmlCursor c2) {
+ String id1 = ((CTRelationship)c1.getObject()).getId();
+ String id2 = ((CTRelationship)c2.getObject()).getId();
+ return id1.compareTo(id2);
+ }
+ });
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XmlOptions xo = new XmlOptions();
+ xo.setSaveNoXmlDecl();
+ relDoc.save(bos, xo);
+ return new OctetStreamData(new ByteArrayInputStream(bos.toByteArray()));
+ } catch (IOException e) {
+ throw new TransformException(e.getMessage(), e);
+ }
+ }
+
+ public Data transform(Data data, XMLCryptoContext context, OutputStream os) throws TransformException {
+ LOG.log(POILogger.DEBUG, "transform(data,context,os)");
+ return null;
+ }
+
+ public boolean isFeatureSupported(String feature) {
+ LOG.log(POILogger.DEBUG, "isFeatureSupported(feature)");
+ return false;
+ }
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,131 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Container class for PKI revocation data.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public class RevocationData {
+
+ private final List<byte[]> crls;
+
+ private final List<byte[]> ocsps;
+
+ /**
+ * Default constructor.
+ */
+ public RevocationData() {
+ this.crls = new LinkedList<byte[]>();
+ this.ocsps = new LinkedList<byte[]>();
+ }
+
+ /**
+ * Adds a CRL to this revocation data set.
+ *
+ * @param encodedCrl
+ */
+ public void addCRL(byte[] encodedCrl) {
+ this.crls.add(encodedCrl);
+ }
+
+ /**
+ * Adds a CRL to this revocation data set.
+ *
+ * @param crl
+ */
+ public void addCRL(X509CRL crl) {
+ byte[] encodedCrl;
+ try {
+ encodedCrl = crl.getEncoded();
+ } catch (CRLException e) {
+ throw new IllegalArgumentException("CRL coding error: "
+ + e.getMessage(), e);
+ }
+ addCRL(encodedCrl);
+ }
+
+ /**
+ * Adds an OCSP response to this revocation data set.
+ *
+ * @param encodedOcsp
+ */
+ public void addOCSP(byte[] encodedOcsp) {
+ this.ocsps.add(encodedOcsp);
+ }
+
+ /**
+ * Gives back a list of all CRLs.
+ *
+ * @return
+ */
+ public List<byte[]> getCRLs() {
+ return this.crls;
+ }
+
+ /**
+ * Gives back a list of all OCSP responses.
+ *
+ * @return
+ */
+ public List<byte[]> getOCSPs() {
+ return this.ocsps;
+ }
+
+ /**
+ * Returns <code>true</code> if this revocation data set holds OCSP
+ * responses.
+ *
+ * @return
+ */
+ public boolean hasOCSPs() {
+ return false == this.ocsps.isEmpty();
+ }
+
+ /**
+ * Returns <code>true</code> if this revocation data set holds CRLs.
+ *
+ * @return
+ */
+ public boolean hasCRLs() {
+ return false == this.crls.isEmpty();
+ }
+
+ /**
+ * Returns <code>true</code> if this revocation data is not empty.
+ *
+ * @return
+ */
+ public boolean hasRevocationDataEntries() {
+ return hasOCSPs() || hasCRLs();
+ }
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,47 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+/**
+ * Interface for a service that retrieves revocation data about some given
+ * certificate chain.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public interface RevocationDataService {
+
+ /**
+ * Gives back the revocation data corresponding with the given certificate
+ * chain.
+ *
+ * @param certificateChain
+ * @return
+ */
+ RevocationData getRevocationData(List<X509Certificate> certificateChain);
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignatureService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignatureService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignatureService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignatureService.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,101 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import org.apache.poi.poifs.crypt.dsig.CertificateSecurityException;
+import org.apache.poi.poifs.crypt.dsig.ExpiredCertificateSecurityException;
+import org.apache.poi.poifs.crypt.dsig.RevokedCertificateSecurityException;
+import org.apache.poi.poifs.crypt.dsig.TrustCertificateSecurityException;
+import org.apache.poi.poifs.crypt.dsig.spi.AddressDTO;
+import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
+import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;
+
+/**
+ * Interface for signature service component.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public interface SignatureService {
+
+ /**
+ * Gives back the digest algorithm to be used for construction of the digest
+ * infos of the preSign method. Return a digest algorithm here if you want
+ * to let the client sign some locally stored files. Return
+ * <code>null</code> if no pre-sign digest infos are required.
+ *
+ * @return the digest algorithm to be used when digesting local files.
+ * @see #preSign(List, List)
+ */
+ String getFilesDigestAlgorithm();
+
+ /**
+ * Pre-sign callback method. Depending on the configuration some parameters
+ * are passed. The returned value will be signed by the eID Applet.
+ *
+ * <p>
+ * TODO: service must be able to throw some exception on failure.
+ * </p>
+ *
+ * @param digestInfos
+ * the optional list of digest infos.
+ * @param signingCertificateChain
+ * the optional list of certificates.
+ * @param identity
+ * the optional identity.
+ * @param address
+ * the optional identity address.
+ * @param photo
+ * the optional identity photo.
+ * @param timestamp
+ * the optional timestamp, defaults to now
+ * @return the digest to be signed.
+ * @throws NoSuchAlgorithmException
+ */
+ DigestInfo preSign(List<DigestInfo> digestInfos,
+ List<X509Certificate> signingCertificateChain,
+ IdentityDTO identity, AddressDTO address, byte[] photo)
+ throws NoSuchAlgorithmException;
+
+ /**
+ * Post-sign callback method. Received the signature value. Depending on the
+ * configuration the signing certificate chain is also obtained.
+ *
+ * @param signatureValue
+ * @param signingCertificateChain
+ * the optional chain of signing certificates.
+ */
+ void postSign(byte[] signatureValue,
+ List<X509Certificate> signingCertificateChain)
+ throws ExpiredCertificateSecurityException,
+ RevokedCertificateSecurityException,
+ TrustCertificateSecurityException, CertificateSecurityException,
+ SecurityException, IOException;
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,392 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.x500.X500Principal;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1OctetStringIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityKeyIdentifierIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BcDigestCalculatorProviderIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BcRSASignerInfoVerifierBuilderIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DEROctetStringIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DefaultDigestAlgorithmIdentifierFinderIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.PKIFailureInfoIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SignerIdIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SignerInformationVerifierIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectKeyIdentifierIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampRequestGeneratorIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampRequestIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampResponseIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampTokenIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509CertificateHolderIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * A TSP time-stamp service implementation.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public class TSPTimeStampService implements TimeStampService {
+
+ private static final POILogger LOG = POILogFactory.getLogger(TSPTimeStampService.class);
+
+ static {
+ CryptoFunctions.registerBouncyCastle();
+ }
+
+ public static final String DEFAULT_USER_AGENT = "eID Applet Service TSP Client";
+
+ private final String tspServiceUrl;
+
+ private String requestPolicy;
+
+ private final String userAgent;
+
+ private final TimeStampServiceValidator validator;
+
+ private String username;
+
+ private String password;
+
+ private String proxyHost;
+
+ private int proxyPort;
+
+ private String digestAlgo;
+
+ private String digestAlgoOid;
+
+ public TSPTimeStampService(String tspServiceUrl,
+ TimeStampServiceValidator validator) {
+ this(tspServiceUrl, validator, null, null);
+ }
+
+ /**
+ * Main constructor.
+ *
+ * @param tspServiceUrl
+ * the URL of the TSP service.
+ * @param validator
+ * the trust validator used to validate incoming TSP response
+ * signatures.
+ * @param requestPolicy
+ * the optional TSP request policy.
+ * @param userAgent
+ * the optional User-Agent TSP request header value.
+ */
+ public TSPTimeStampService(String tspServiceUrl,
+ TimeStampServiceValidator validator, String requestPolicy,
+ String userAgent) {
+ if (null == tspServiceUrl) {
+ throw new IllegalArgumentException("TSP service URL required");
+ }
+ this.tspServiceUrl = tspServiceUrl;
+
+ if (null == validator) {
+ throw new IllegalArgumentException("TSP validator required");
+ }
+ this.validator = validator;
+
+ this.requestPolicy = requestPolicy;
+
+ if (null != userAgent) {
+ this.userAgent = userAgent;
+ } else {
+ this.userAgent = DEFAULT_USER_AGENT;
+ }
+
+ this.digestAlgo = "SHA-1";
+ this.digestAlgoOid = "1.3.14.3.2.26";
+ }
+
+ /**
+ * Sets the request policy OID.
+ *
+ * @param policyOid
+ */
+ public void setRequestPolicy(String policyOid) {
+ this.requestPolicy = policyOid;
+ }
+
+ /**
+ * Sets the credentials used in case the TSP service requires
+ * authentication.
+ *
+ * @param username
+ * @param password
+ */
+ public void setAuthenticationCredentials(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ /**
+ * Resets the authentication credentials.
+ */
+ public void resetAuthenticationCredentials() {
+ this.username = null;
+ this.password = null;
+ }
+
+ /**
+ * Sets the digest algorithm used for time-stamping data. Example value:
+ * "SHA-1".
+ *
+ * @param digestAlgo
+ */
+ public void setDigestAlgo(String digestAlgo) {
+ if ("SHA-1".equals(digestAlgo)) {
+ this.digestAlgoOid = "1.3.14.3.2.26";
+ } else if ("SHA-256".equals(digestAlgo)) {
+ this.digestAlgoOid = "2.16.840.1.101.3.4.2.1";
+ } else if ("SHA-384".equals(digestAlgo)) {
+ this.digestAlgoOid = "2.16.840.1.101.3.4.2.2";
+ } else if ("SHA-512".equals(digestAlgo)) {
+ this.digestAlgoOid = "2.16.840.1.101.3.4.2.3";
+ } else {
+ throw new IllegalArgumentException("unsupported digest algo: " + digestAlgo);
+ }
+
+ this.digestAlgo = digestAlgo;
+ }
+
+ /**
+ * Configures the HTTP proxy settings to be used to connect to the TSP
+ * service.
+ *
+ * @param proxyHost
+ * @param proxyPort
+ */
+ public void setProxy(String proxyHost, int proxyPort) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ /**
+ * Resets the HTTP proxy settings.
+ */
+ public void resetProxy() {
+ this.proxyHost = null;
+ this.proxyPort = 0;
+ }
+
+ public byte[] timeStamp(byte[] data, RevocationData revocationData)
+ throws Exception {
+ // digest the message
+ MessageDigest messageDigest = MessageDigest
+ .getInstance(this.digestAlgo);
+ byte[] digest = messageDigest.digest(data);
+
+ // generate the TSP request
+ BigInteger nonce = new BigInteger(128, new SecureRandom());
+ TimeStampRequestGeneratorIf requestGenerator = HorribleProxy.newProxy(TimeStampRequestGeneratorIf.class);
+ requestGenerator.setCertReq(true);
+ if (null != this.requestPolicy) {
+ requestGenerator.setReqPolicy(this.requestPolicy);
+ }
+ TimeStampRequestIf request = requestGenerator.generate(this.digestAlgoOid, digest, nonce);
+ byte[] encodedRequest = request.getEncoded();
+
+ // create the HTTP POST request
+ Proxy proxy = (this.proxyHost != null)
+ ? new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.proxyHost, this.proxyPort))
+ : Proxy.NO_PROXY;
+ HttpURLConnection huc = (HttpURLConnection)new URL(this.tspServiceUrl).openConnection(proxy);
+
+ if (null != this.username) {
+ String userPassword = this.username + ":" + this.password;
+ String encoding = DatatypeConverter.printBase64Binary(userPassword.getBytes(Charset.forName("iso-8859-1")));
+ huc.setRequestProperty("Authorization", "Basic " + encoding);
+ }
+
+ huc.setDoOutput(true); // also sets method to POST.
+ huc.setRequestProperty("User-Agent", this.userAgent);
+ huc.setRequestProperty("Content-Type", "application/timestamp-query;charset=ISO-8859-1");
+
+ OutputStream hucOut = huc.getOutputStream();
+ hucOut.write(encodedRequest);
+
+ // invoke TSP service
+ huc.connect();
+
+ int statusCode = huc.getResponseCode();
+ if (statusCode != 200) {
+ LOG.log(POILogger.ERROR, "Error contacting TSP server ", this.tspServiceUrl);
+ throw new Exception("Error contacting TSP server " + this.tspServiceUrl);
+ }
+
+ // HTTP input validation
+ String contentType = huc.getHeaderField("Content-Type");
+ if (null == contentType) {
+ throw new RuntimeException("missing Content-Type header");
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(huc.getInputStream(), bos);
+ LOG.log(POILogger.DEBUG, "response content: ", bos.toString());
+
+ if (!contentType.startsWith("application/timestamp-reply")) {
+ throw new RuntimeException("invalid Content-Type: " + contentType);
+ }
+
+ if (bos.size() == 0) {
+ throw new RuntimeException("Content-Length is zero");
+ }
+
+ // TSP response parsing and validation
+ TimeStampResponseIf timeStampResponse = HorribleProxy.newProxy(TimeStampResponseIf.class, bos.toByteArray());
+ timeStampResponse.validate(request);
+
+ if (0 != timeStampResponse.getStatus()) {
+ LOG.log(POILogger.DEBUG, "status: " + timeStampResponse.getStatus());
+ LOG.log(POILogger.DEBUG, "status string: " + timeStampResponse.getStatusString());
+ PKIFailureInfoIf failInfo = timeStampResponse.getFailInfo();
+ if (null != failInfo) {
+ LOG.log(POILogger.DEBUG, "fail info int value: " + failInfo.intValue());
+ if (/*PKIFailureInfo.unacceptedPolicy*/(1 << 8) == failInfo.intValue()) {
+ LOG.log(POILogger.DEBUG, "unaccepted policy");
+ }
+ }
+ throw new RuntimeException("timestamp response status != 0: "
+ + timeStampResponse.getStatus());
+ }
+ TimeStampTokenIf timeStampToken = timeStampResponse.getTimeStampToken();
+ SignerIdIf signerId = timeStampToken.getSID();
+ BigInteger signerCertSerialNumber = signerId.getSerialNumber();
+ X500Principal signerCertIssuer = signerId.getIssuer();
+ LOG.log(POILogger.DEBUG, "signer cert serial number: " + signerCertSerialNumber);
+ LOG.log(POILogger.DEBUG, "signer cert issuer: " + signerCertIssuer);
+
+ // TSP signer certificates retrieval
+ Collection<Certificate> certificates = timeStampToken.getCertificates().getMatches(null);
+
+ X509Certificate signerCert = null;
+ Map<String, X509Certificate> certificateMap = new HashMap<String, X509Certificate>();
+ for (Certificate certificate : certificates) {
+ X509Certificate x509Certificate = (X509Certificate) certificate;
+ if (signerCertIssuer.equals(x509Certificate
+ .getIssuerX500Principal())
+ && signerCertSerialNumber.equals(x509Certificate
+ .getSerialNumber())) {
+ signerCert = x509Certificate;
+ }
+ String ski = Hex.encodeHexString(getSubjectKeyId(x509Certificate));
+ certificateMap.put(ski, x509Certificate);
+ LOG.log(POILogger.DEBUG, "embedded certificate: "
+ + x509Certificate.getSubjectX500Principal() + "; SKI="
+ + ski);
+ }
+
+ // TSP signer cert path building
+ if (null == signerCert) {
+ throw new RuntimeException(
+ "TSP response token has no signer certificate");
+ }
+ List<X509Certificate> tspCertificateChain = new LinkedList<X509Certificate>();
+ X509Certificate certificate = signerCert;
+ do {
+ LOG.log(POILogger.DEBUG, "adding to certificate chain: "
+ + certificate.getSubjectX500Principal());
+ tspCertificateChain.add(certificate);
+ if (certificate.getSubjectX500Principal().equals(
+ certificate.getIssuerX500Principal())) {
+ break;
+ }
+ String aki = Hex.encodeHexString(getAuthorityKeyId(certificate));
+ certificate = certificateMap.get(aki);
+ } while (null != certificate);
+
+ // verify TSP signer signature
+ X509CertificateHolderIf holder = HorribleProxy.newProxy(X509CertificateHolderIf.class, tspCertificateChain.get(0).getEncoded());
+ DefaultDigestAlgorithmIdentifierFinderIf finder = HorribleProxy.newProxy(DefaultDigestAlgorithmIdentifierFinderIf.class);
+ BcDigestCalculatorProviderIf calculator = HorribleProxy.newProxy(BcDigestCalculatorProviderIf.class);
+ BcRSASignerInfoVerifierBuilderIf verifierBuilder = HorribleProxy.newProxy(BcRSASignerInfoVerifierBuilderIf.class, finder, calculator);
+ SignerInformationVerifierIf verifier = verifierBuilder.build(holder);
+
+ timeStampToken.validate(verifier);
+
+ // verify TSP signer certificate
+ this.validator.validate(tspCertificateChain, revocationData);
+
+ LOG.log(POILogger.DEBUG, "time-stamp token time: "
+ + timeStampToken.getTimeStampInfo().getGenTime());
+
+ byte[] timestamp = timeStampToken.getEncoded();
+ return timestamp;
+ }
+
+ private byte[] getSubjectKeyId(X509Certificate cert) throws Exception {
+ // X509Extensions.SubjectKeyIdentifier.getId()
+ byte[] extvalue = cert.getExtensionValue("2.5.29.14");
+ if (extvalue == null) return null;
+
+ ASN1InputStreamIf keyCntStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(extvalue));
+ ASN1OctetStringIf cntStr = HorribleProxy.createProxy(ASN1OctetStringIf.class, "getInstance", keyCntStream.readObject$Object());
+ ASN1InputStreamIf keyIdStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(cntStr.getOctets()));
+ SubjectKeyIdentifierIf keyId = HorribleProxy.createProxy(SubjectKeyIdentifierIf.class, "getInstance", keyIdStream.readObject$Object());
+
+ return keyId.getKeyIdentifier();
+ }
+
+ private byte[] getAuthorityKeyId(X509Certificate cert) throws Exception {
+ // X509Extensions.AuthorityKeyIdentifier.getId()
+ byte[] extvalue = cert.getExtensionValue("2.5.29.35");
+ if (extvalue == null) return null;
+
+ ASN1InputStreamIf keyCntStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(extvalue));
+ DEROctetStringIf cntStr = keyCntStream.readObject$DERString();
+ ASN1InputStreamIf keyIdStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(cntStr.getOctets()));
+ AuthorityKeyIdentifierIf keyId = HorribleProxy.newProxy(AuthorityKeyIdentifierIf.class, keyIdStream.readObject$Sequence());
+
+ return keyId.getKeyIdentifier();
+ }
+}
\ No newline at end of file
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,52 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+
+/**
+ * Interface for a time-stamp service.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public interface TimeStampService {
+
+ /**
+ * Gives back the encoded time-stamp token for the given array of data
+ * bytes. We assume that the time-stamp token itself contains its full
+ * certificate chain required for proper validation.
+ *
+ * @param data
+ * the data to be time-stamped.
+ * @param revocationData
+ * the optional container that needs to be filled up with the
+ * revocation data used to validate the TSA certificate chain.
+ * @return the DER encoded time-stamp token.
+ * @throws Exception
+ * in case something went wrong.
+ */
+ byte[] timeStamp(byte[] data, RevocationData revocationData)
+ throws Exception;
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,51 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+/**
+ * Interface for trust validator of a TSP.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public interface TimeStampServiceValidator {
+
+ /**
+ * Validates the given certificate chain.
+ *
+ * @param certificateChain
+ * @param revocationData
+ * the optional data container that should be filled with
+ * revocation data that was used to validate the given
+ * certificate chain.
+ * @throws Exception
+ * in case the certificate chain is invalid.
+ */
+ void validate(List<X509Certificate> certificateChain,
+ RevocationData revocationData) throws Exception;
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/XmlSignatureService.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/XmlSignatureService.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/XmlSignatureService.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/XmlSignatureService.java Sun Aug 10 18:25:10 2014
@@ -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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.services;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+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.NoSuchProviderException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+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.XMLObject;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageNamespaces;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMReferenceIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMSignedInfoIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMXMLSignatureIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxies.XMLSignatureIf;
+import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
+import org.apache.poi.poifs.crypt.dsig.OOXMLURIDereferencer;
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
+import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
+import org.apache.poi.poifs.crypt.dsig.facets.OOXMLSignatureFacet;
+import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;
+import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;
+import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
+import org.apache.poi.poifs.crypt.dsig.spi.AddressDTO;
+import org.apache.poi.poifs.crypt.dsig.spi.Constants;
+import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
+import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.w3.x2000.x09.xmldsig.SignatureDocument;
+import org.w3.x2000.x09.xmldsig.SignatureType;
+import org.w3.x2000.x09.xmldsig.SignatureValueType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Abstract base class for an XML Signature Service implementation.
+ */
+public class XmlSignatureService implements SignatureService {
+ private static final POILogger LOG = POILogFactory.getLogger(XmlSignatureService.class);
+
+ protected final List<SignatureFacet> signatureFacets;
+
+ private String signatureNamespacePrefix;
+ private String signatureId;
+ private final HashAlgorithm hashAlgo;
+ private final OPCPackage opcPackage;
+ private SignatureDocument sigDoc;
+ private XAdESSignatureFacet xadesSignatureFacet;
+
+ /**
+ * Main constructor.
+ */
+ public XmlSignatureService(HashAlgorithm digestAlgo, OPCPackage opcPackage) {
+ this.signatureFacets = new LinkedList<SignatureFacet>();
+ this.signatureNamespacePrefix = null;
+ this.signatureId = null;
+ this.hashAlgo = digestAlgo;
+ this.opcPackage = opcPackage;
+ this.sigDoc = null;
+ }
+
+ public void initFacets(Date clock) {
+ if (clock == null) clock = new Date();
+ addSignatureFacet(new OOXMLSignatureFacet(this, clock, hashAlgo));
+ addSignatureFacet(new KeyInfoSignatureFacet(true, false, false));
+
+ this.xadesSignatureFacet = new XAdESSignatureFacet(clock, hashAlgo, null);
+ this.xadesSignatureFacet.setIdSignedProperties("idSignedProperties");
+ this.xadesSignatureFacet.setSignaturePolicyImplied(true);
+ /*
+ * Work-around for Office 2010.
+ */
+ this.xadesSignatureFacet.setIssuerNameNoReverseOrder(true);
+ setSignatureId("idPackageSignature");
+ addSignatureFacet(this.xadesSignatureFacet);
+ addSignatureFacet(new Office2010SignatureFacet());
+ }
+
+
+ /**
+ * Sets the signature Id attribute value used to create the XML signature. A
+ * <code>null</code> value will trigger an automatically generated signature
+ * Id.
+ *
+ * @param signatureId
+ */
+ protected void setSignatureId(String signatureId) {
+ this.signatureId = signatureId;
+ }
+
+ /**
+ * Sets the XML Signature namespace prefix to be used for signature
+ * creation. A <code>null</code> value will omit the prefixing.
+ *
+ * @param signatureNamespacePrefix
+ */
+ protected void setSignatureNamespacePrefix(String signatureNamespacePrefix) {
+ this.signatureNamespacePrefix = signatureNamespacePrefix;
+ }
+
+ /**
+ * Adds a signature facet to this XML signature service.
+ *
+ * @param signatureFacet
+ */
+ protected void addSignatureFacet(SignatureFacet signatureFacet) {
+ this.signatureFacets.add(signatureFacet);
+ }
+
+ /**
+ * 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 HashAlgorithm getSignatureDigestAlgorithm() {
+ return null != this.hashAlgo ? this.hashAlgo : HashAlgorithm.sha1;
+ }
+
+ /**
+ * Override this method to change the URI dereferener used by the signing
+ * engine.
+ *
+ * @return
+ */
+ protected URIDereferencer getURIDereferencer() {
+ OPCPackage ooxmlDocument = getOfficeOpenXMLDocument();
+ return new OOXMLURIDereferencer(ooxmlDocument);
+ }
+
+ /**
+ * Gives back the human-readable description of what the citizen will be
+ * signing. The default value is "XML Document". Override this method to
+ * provide the citizen with another description.
+ *
+ * @return
+ */
+ protected String getSignatureDescription() {
+ return "Office OpenXML Document";
+ }
+
+ /**
+ * Gives back the URL of the OOXML to be signed.
+ *
+ * @return
+ */
+ public OPCPackage getOfficeOpenXMLDocument() {
+ return opcPackage;
+ }
+
+
+
+ /**
+ * 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,
+ IdentityDTO identity, AddressDTO address, byte[] photo)
+ throws NoSuchAlgorithmException {
+ SignatureInfo.initXmlProvider();
+
+ LOG.log(POILogger.DEBUG, "preSign");
+ HashAlgorithm hashAlgo = getSignatureDigestAlgorithm();
+
+ byte[] digestValue;
+ try {
+ digestValue = getXmlSignatureDigestValue(hashAlgo, digestInfos, signingCertificateChain);
+ } catch (Exception e) {
+ throw new RuntimeException("XML signature error: " + e.getMessage(), e);
+ }
+
+ String description = getSignatureDescription();
+ return new DigestInfo(digestValue, hashAlgo, description);
+ }
+
+ public void postSign(byte[] signatureValue, List<X509Certificate> signingCertificateChain)
+ throws IOException {
+ LOG.log(POILogger.DEBUG, "postSign");
+ SignatureInfo.initXmlProvider();
+
+ /*
+ * Retrieve the intermediate XML signature document from the temporary
+ * data storage.
+ */
+ SignatureType sigType = sigDoc.getSignature();
+
+ /*
+ * Check ds:Signature node.
+ */
+ if (!signatureId.equals(sigType.getId())) {
+ throw new RuntimeException("ds:Signature not found for @Id: " + signatureId);
+ }
+
+ /*
+ * Insert signature value into the ds:SignatureValue element
+ */
+ SignatureValueType sigVal = sigType.getSignatureValue();
+ sigVal.setByteArrayValue(signatureValue);
+
+ /*
+ * Allow signature facets to inject their own stuff.
+ */
+ for (SignatureFacet signatureFacet : this.signatureFacets) {
+ signatureFacet.postSign(sigType, signingCertificateChain);
+ }
+
+ writeDocument();
+ }
+
+ @SuppressWarnings("unchecked")
+ private byte[] getXmlSignatureDigestValue(HashAlgorithm hashAlgo,
+ List<DigestInfo> digestInfos,
+ List<X509Certificate> signingCertificateChain)
+ throws ParserConfigurationException, NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException, MarshalException,
+ javax.xml.crypto.dsig.XMLSignatureException,
+ TransformerFactoryConfigurationError, TransformerException,
+ IOException, SAXException, NoSuchProviderException, XmlException {
+ /*
+ * DOM Document construction.
+ */
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ Document doc = dbf.newDocumentBuilder().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;
+ }
+ };
+
+ // As of JDK 7, can't use sigDoc here directly, because the
+ // setAttributeID will be called and it's not implemented in xmlbeans
+ XMLSignContext xmlSignContext = new DOMSignContext(key, doc);
+ URIDereferencer uriDereferencer = getURIDereferencer();
+ if (null != uriDereferencer) {
+ xmlSignContext.setURIDereferencer(uriDereferencer);
+ }
+
+ xmlSignContext.putNamespacePrefix(
+ "http://schemas.openxmlformats.org/package/2006/digital-signature",
+ "mdssi");
+
+ if (this.signatureNamespacePrefix != null) {
+ /*
+ * OOo doesn't like ds namespaces so per default prefixing is off.
+ */
+ xmlSignContext.putNamespacePrefix(
+ javax.xml.crypto.dsig.XMLSignature.XMLNS,
+ this.signatureNamespacePrefix);
+ }
+
+ XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM", "XMLDSig");
+
+ /*
+ * Add ds:References that come from signing client local files.
+ */
+ List<Reference> references = new LinkedList<Reference>();
+ addDigestInfosAsReferences(digestInfos, signatureFactory, references);
+
+ /*
+ * Invoke the signature facets.
+ */
+ String localSignatureId;
+ if (null == this.signatureId) {
+ localSignatureId = "xmldsig-" + UUID.randomUUID().toString();
+ } else {
+ localSignatureId = this.signatureId;
+ }
+ List<XMLObject> objects = new LinkedList<XMLObject>();
+ for (SignatureFacet signatureFacet : this.signatureFacets) {
+ LOG.log(POILogger.DEBUG, "invoking signature facet: "
+ + signatureFacet.getClass().getSimpleName());
+ signatureFacet.preSign(signatureFactory, localSignatureId, signingCertificateChain, references, objects);
+ }
+
+ /*
+ * ds:SignedInfo
+ */
+ SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(
+ getSignatureMethod(hashAlgo), null);
+ CanonicalizationMethod canonicalizationMethod = signatureFactory
+ .newCanonicalizationMethod(getCanonicalizationMethod(),
+ (C14NMethodParameterSpec) null);
+ SignedInfo signedInfo = signatureFactory.newSignedInfo(
+ canonicalizationMethod, signatureMethod, references);
+
+ /*
+ * JSR105 ds:Signature creation
+ */
+ String signatureValueId = localSignatureId + "-signature-value";
+ javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory
+ .newXMLSignature(signedInfo, null, objects, localSignatureId,
+ signatureValueId);
+
+ /*
+ * ds:Signature Marshalling.
+ */
+ DOMXMLSignatureIf domXmlSignature;
+ try {
+ domXmlSignature = HorribleProxy.newProxy(DOMXMLSignatureIf.class, xmlSignature);
+ } catch (Exception e) {
+ throw new RuntimeException("DomXmlSignature instance error: " + e.getMessage(), e);
+ }
+
+ domXmlSignature.marshal(doc, this.signatureNamespacePrefix, (DOMCryptoContext) xmlSignContext);
+
+ registerIds(doc);
+ Element el = doc.getElementById("idPackageObject");
+ assert (el != null);
+ el.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);
+
+
+ /*
+ * Completion of undigested ds:References in the ds:Manifests.
+ */
+ for (XMLObject object : objects) {
+ LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName());
+ List<XMLStructure> objectContentList = object.getContent();
+ for (XMLStructure objectContent : objectContentList) {
+ LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName());
+ if (!(objectContent instanceof Manifest)) continue;
+ Manifest manifest = (Manifest) objectContent;
+ List<Reference> manifestReferences = manifest.getReferences();
+ for (Reference manifestReference : manifestReferences) {
+ if (manifestReference.getDigestValue() != null) continue;
+
+ DOMReferenceIf manifestDOMReference;
+ try {
+ manifestDOMReference = HorribleProxy.newProxy(DOMReferenceIf.class, manifestReference);
+ } catch (Exception e) {
+ throw new RuntimeException("DOMReference instance error: " + e.getMessage(), e);
+ }
+ manifestDOMReference.digest(xmlSignContext);
+ }
+ }
+ }
+
+ /*
+ * Completion of undigested ds:References.
+ */
+ List<Reference> signedInfoReferences = signedInfo.getReferences();
+ for (Reference signedInfoReference : signedInfoReferences) {
+ DOMReferenceIf domReference;
+ try {
+ domReference = HorribleProxy.newProxy(DOMReferenceIf.class, signedInfoReference);
+ } catch (Exception e) {
+ throw new RuntimeException("DOMReference instance error: " + e.getMessage(), e);
+ }
+
+ // ds:Reference with external digest value
+ if (domReference.getDigestValue() != null) continue;
+
+ domReference.digest(xmlSignContext);
+ }
+
+ /*
+ * Calculation of XML signature digest value.
+ */
+ DOMSignedInfoIf domSignedInfo;
+ try {
+ domSignedInfo = HorribleProxy.newProxy(DOMSignedInfoIf.class, signedInfo);
+ } catch (Exception e) {
+ throw new RuntimeException("DOMSignedInfo instance error: " + e.getMessage(), e);
+ }
+
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ domSignedInfo.canonicalize(xmlSignContext, dataStream);
+ byte[] octets = dataStream.toByteArray();
+
+ sigDoc = SignatureDocument.Factory.parse(doc.getDocumentElement());
+
+
+ /*
+ * TODO: we could be using DigestOutputStream here to optimize memory
+ * usage.
+ */
+
+ MessageDigest jcaMessageDigest = CryptoFunctions.getMessageDigest(hashAlgo);
+ byte[] digestValue = jcaMessageDigest.digest(octets);
+ return digestValue;
+ }
+
+ /**
+ * the resulting document needs to be tweaked before it can be digested -
+ * this applies to the verification and signing step
+ *
+ * @param doc
+ */
+ public void registerIds(Document doc) {
+ NodeList nl = doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Object");
+ registerIdAttribute(nl);
+ nl = doc.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "SignedProperties");
+ registerIdAttribute(nl);
+ }
+
+ protected void registerIdAttribute(NodeList nl) {
+ for (int i=0; i<nl.getLength(); i++) {
+ Element el = (Element)nl.item(i);
+ if (el.hasAttribute("Id")) {
+ el.setIdAttribute("Id", true);
+ }
+ }
+ }
+
+ private void addDigestInfosAsReferences(List<DigestInfo> digestInfos,
+ XMLSignatureFactory signatureFactory, List<Reference> references)
+ throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException, MalformedURLException {
+ if (digestInfos == null) return;
+ for (DigestInfo digestInfo : digestInfos) {
+ byte[] documentDigestValue = digestInfo.digestValue;
+
+ DigestMethod digestMethod = signatureFactory.newDigestMethod(
+ digestInfo.hashAlgo.xmlSignUri, null);
+
+ String uri = new File(digestInfo.description).getName();
+
+ Reference reference = signatureFactory.newReference(uri,
+ digestMethod, null, null, null, documentDigestValue);
+ references.add(reference);
+ }
+ }
+
+ private String getSignatureMethod(HashAlgorithm hashAlgo) {
+ if (null == hashAlgo) {
+ throw new RuntimeException("digest algo is null");
+ }
+
+ XMLSignatureIf XmlSignature;
+ try {
+ XmlSignature = HorribleProxy.newProxy(XMLSignatureIf.class);
+ } catch (Exception e) {
+ throw new RuntimeException("JDK doesn't support XmlSignature", e);
+ }
+
+ switch (hashAlgo) {
+ case sha1: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA1();
+ case sha256: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA256();
+ case sha384: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA384();
+ case sha512: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA512();
+ case ripemd160: return XmlSignature.ALGO_ID_MAC_HMAC_RIPEMD160();
+ default: break;
+ }
+
+ throw new RuntimeException("unsupported sign algo: " + hashAlgo);
+ }
+
+ /**
+ * Gives back the used XAdES signature facet.
+ *
+ * @return
+ */
+ protected XAdESSignatureFacet getXAdESSignatureFacet() {
+ return this.xadesSignatureFacet;
+ }
+
+ public String getFilesDigestAlgorithm() {
+ return null;
+ }
+
+ protected String getCanonicalizationMethod() {
+ return CanonicalizationMethod.INCLUSIVE;
+ }
+
+ protected void writeDocument() throws IOException {
+ XmlOptions xo = new XmlOptions();
+ Map<String,String> namespaceMap = new HashMap<String,String>();
+ for (SignatureFacet sf : this.signatureFacets) {
+ Map<String,String> sfm = sf.getNamespacePrefixMapping();
+ if (sfm != null) {
+ namespaceMap.putAll(sfm);
+ }
+ }
+ xo.setSaveSuggestedPrefixes(namespaceMap);
+ xo.setUseDefaultNamespace();
+
+ LOG.log(POILogger.DEBUG, "output signed Office OpenXML document");
+
+ /*
+ * Copy the original OOXML content to the signed OOXML package. During
+ * copying some files need to changed.
+ */
+ OPCPackage pkg = this.getOfficeOpenXMLDocument();
+
+ PackagePartName sigPartName, sigsPartName;
+ try {
+ // <Override PartName="/_xmlsignatures/sig1.xml" ContentType="application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"/>
+ sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig1.xml");
+ // <Default Extension="sigs" ContentType="application/vnd.openxmlformats-package.digital-signature-origin"/>
+ sigsPartName = PackagingURIHelper.createPartName("/_xmlsignatures/origin.sigs");
+ } catch (InvalidFormatException e) {
+ throw new IOException(e);
+ }
+
+ String sigContentType = "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml";
+ PackagePart sigPart = pkg.getPart(sigPartName);
+ if (sigPart == null) {
+ sigPart = pkg.createPart(sigPartName, sigContentType);
+ }
+
+ OutputStream os = sigPart.getOutputStream();
+ sigDoc.save(os, xo);
+ os.close();
+
+ String sigsContentType = "application/vnd.openxmlformats-package.digital-signature-origin";
+ PackagePart sigsPart = pkg.getPart(sigsPartName);
+ if (sigsPart == null) {
+ // touch empty marker file
+ sigsPart = pkg.createPart(sigsPartName, sigsContentType);
+ }
+
+ PackageRelationshipCollection relCol = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
+ for (PackageRelationship pr : relCol) {
+ pkg.removeRelationship(pr.getId());
+ }
+ pkg.addRelationship(sigsPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
+
+ sigsPart.addRelationship(sigPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE);
+ }
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/AddressDTO.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/AddressDTO.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/AddressDTO.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/AddressDTO.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,51 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.spi;
+
+import java.io.Serializable;
+import java.security.Identity;
+
+/**
+ * Address Data Transfer Object.
+ *
+ * @author Frank Cornelis
+ * @see Identity
+ *
+ */
+public class AddressDTO implements Serializable {
+
+ /*
+ * We implement serializable to allow this class to be used in distributed
+ * containers as defined in the Servlet v2.4 specification.
+ */
+
+ private static final long serialVersionUID = 1L;
+
+ public String streetAndNumber;
+
+ public String zip;
+
+ public String city;
+}
\ No newline at end of file
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/Constants.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/Constants.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/Constants.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/Constants.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,30 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.spi;
+
+public interface Constants {
+ String NamespaceSpecNS = "http://www.w3.org/2000/xmlns/";
+ String SignatureSpecNS = "http://www.w3.org/2000/09/xmldsig#";
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/DigestInfo.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/DigestInfo.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/DigestInfo.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/DigestInfo.java Sun Aug 10 18:25:10 2014
@@ -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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.spi;
+
+import java.io.Serializable;
+
+import org.apache.poi.poifs.crypt.HashAlgorithm;
+
+/**
+ * Digest Information data transfer class.
+ */
+public class DigestInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Main constructor.
+ *
+ * @param digestValue
+ * @param hashAlgo
+ * @param description
+ */
+ public DigestInfo(byte[] digestValue, HashAlgorithm hashAlgo, String description) {
+ this.digestValue = digestValue;
+ this.hashAlgo = hashAlgo;
+ this.description = description;
+ }
+
+ public final byte[] digestValue;
+
+ public final String description;
+
+ public final HashAlgorithm hashAlgo;
+}
Added: poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/IdentityDTO.java
URL: http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/IdentityDTO.java?rev=1617141&view=auto
==============================================================================
--- poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/IdentityDTO.java (added)
+++ poi/branches/xml_signature/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/spi/IdentityDTO.java Sun Aug 10 18:25:10 2014
@@ -0,0 +1,75 @@
+/* ====================================================================
+ 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.
+==================================================================== */
+
+/* ====================================================================
+ This product contains an ASLv2 licensed version of the OOXML signer
+ package from the eID Applet project
+ http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
+ Copyright (C) 2008-2014 FedICT.
+ ================================================================= */
+
+package org.apache.poi.poifs.crypt.dsig.spi;
+
+import java.io.Serializable;
+import java.util.GregorianCalendar;
+
+/**
+ * Identity Data Transfer Object.
+ *
+ * @author Frank Cornelis
+ *
+ */
+public class IdentityDTO implements Serializable {
+
+ /*
+ * We implement serializable to allow this class to be used in distributed
+ * containers as defined in the Servlet v2.4 specification.
+ */
+ private static final long serialVersionUID = 1L;
+
+ public String cardNumber;
+
+ public String chipNumber;
+
+ public GregorianCalendar cardValidityDateBegin;
+
+ public GregorianCalendar cardValidityDateEnd;
+
+ public String cardDeliveryMunicipality;
+
+ public String nationalNumber;
+
+ public String name;
+
+ public String firstName;
+
+ public String middleName;
+
+ public String nationality;
+
+ public String placeOfBirth;
+
+ public GregorianCalendar dateOfBirth;
+
+ public boolean male;
+
+ public boolean female;
+
+ public String nobleCondition;
+
+ public String duplicate;
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org