Switched to config object

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1625850 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-09-17 23:12:16 +00:00
parent b410e72196
commit c9757d974f
8 changed files with 276 additions and 251 deletions

View File

@ -37,7 +37,6 @@ import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLSignatureFactory;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
@ -51,18 +50,17 @@ public class OOXMLURIDereferencer implements URIDereferencer {
private static final POILogger LOG = POILogFactory.getLogger(OOXMLURIDereferencer.class); private static final POILogger LOG = POILogFactory.getLogger(OOXMLURIDereferencer.class);
private final OPCPackage pkg; private SignatureInfoConfig signatureConfig;
private URIDereferencer baseUriDereferencer;
private final URIDereferencer baseUriDereferencer; public OOXMLURIDereferencer() {
public OOXMLURIDereferencer(OPCPackage pkg) {
if (null == pkg) {
throw new IllegalArgumentException("OPCPackage is null");
}
this.pkg = pkg;
XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory(); XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory();
this.baseUriDereferencer = xmlSignatureFactory.getURIDereferencer(); this.baseUriDereferencer = xmlSignatureFactory.getURIDereferencer();
} }
public void setSignatureConfig(SignatureInfoConfig signatureConfig) {
this.signatureConfig = signatureConfig;
}
public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException { public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
if (null == uriReference) { if (null == uriReference) {
@ -109,6 +107,6 @@ public class OOXMLURIDereferencer implements URIDereferencer {
return null; return null;
} }
return pkg.getPart(ppn); return signatureConfig.getOpcPackage().getPart(ppn);
} }
} }

View File

@ -32,7 +32,6 @@ import java.security.Provider;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -125,19 +124,24 @@ public class SignatureInfo {
public void confirmSignature(PrivateKey key, X509Certificate x509, HashAlgorithm hashAlgo) public void confirmSignature(PrivateKey key, X509Certificate x509, HashAlgorithm hashAlgo)
throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException { throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException {
XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg); SignatureInfoConfig signatureConfig = new SignatureInfoConfig();
signatureConfig.setOpcPackage(pkg);
signatureConfig.setDigestAlgo(hashAlgo);
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
signatureConfig.setKey(key);
signatureConfig.addDefaultFacets();
XmlSignatureService signatureService = new XmlSignatureService(signatureConfig);
Document document = DocumentHelper.createDocument(); Document document = DocumentHelper.createDocument();
// operate // operate
List<X509Certificate> x509Chain = Collections.singletonList(x509); DigestInfo digestInfo = signatureService.preSign(document, null);
DigestInfo digestInfo = signatureService.preSign(document, null, key, x509Chain, null, null, null);
// setup: key material, signature value // setup: key material, signature value
byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue); byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue);
// operate: postSign // operate: postSign
signatureService.postSign(document, signatureValue, Collections.singletonList(x509)); signatureService.postSign(document, signatureValue);
} }
public static byte[] signDigest(PrivateKey key, HashAlgorithm hashAlgo, byte digest[]) { public static byte[] signDigest(PrivateKey key, HashAlgorithm hashAlgo, byte digest[]) {
@ -156,12 +160,6 @@ public class SignatureInfo {
} }
} }
public XmlSignatureService createSignatureService(HashAlgorithm hashAlgo, OPCPackage pkg) {
XmlSignatureService signatureService = new XmlSignatureService(hashAlgo, pkg);
signatureService.initFacets(new Date());
return signatureService;
}
public List<X509Certificate> getSigners() { public List<X509Certificate> getSigners() {
initXmlProvider(); initXmlProvider();
List<X509Certificate> signers = new ArrayList<X509Certificate>(); List<X509Certificate> signers = new ArrayList<X509Certificate>();
@ -176,19 +174,20 @@ public class SignatureInfo {
LOG.log(POILogger.DEBUG, "no signature resources"); LOG.log(POILogger.DEBUG, "no signature resources");
allValid = false; allValid = false;
} }
SignatureInfoConfig signatureConfig = new SignatureInfoConfig();
signatureConfig.setOpcPackage(pkg);
for (PackagePart signaturePart : signatureParts) { for (PackagePart signaturePart : signatureParts) {
KeyInfoKeySelector keySelector = new KeyInfoKeySelector(); KeyInfoKeySelector keySelector = new KeyInfoKeySelector();
try { try {
Document doc = DocumentHelper.readDocument(signaturePart.getInputStream()); Document doc = DocumentHelper.readDocument(signaturePart.getInputStream());
// dummy call to createSignatureService to tweak document afterwards XmlSignatureService.registerIds(doc);
createSignatureService(HashAlgorithm.sha1, pkg).registerIds(doc);
DOMValidateContext domValidateContext = new DOMValidateContext(keySelector, doc); DOMValidateContext domValidateContext = new DOMValidateContext(keySelector, doc);
domValidateContext.setProperty("org.jcp.xml.dsig.validateManifests", Boolean.TRUE); domValidateContext.setProperty("org.jcp.xml.dsig.validateManifests", Boolean.TRUE);
OOXMLURIDereferencer dereferencer = new OOXMLURIDereferencer(pkg); domValidateContext.setURIDereferencer(signatureConfig.getUriDereferencer());
domValidateContext.setURIDereferencer(dereferencer);
XMLSignatureFactory xmlSignatureFactory = getSignatureFactory(); XMLSignatureFactory xmlSignatureFactory = getSignatureFactory();
XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext); XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);

View File

@ -0,0 +1,163 @@
/* ====================================================================
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.
==================================================================== */
package org.apache.poi.poifs.crypt.dsig;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.crypto.URIDereferencer;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.HashAlgorithm;
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.SignaturePolicyService;
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.IdentityDTO;
public class SignatureInfoConfig {
private List<SignatureFacet> signatureFacets = new ArrayList<SignatureFacet>();
private HashAlgorithm digestAlgo = HashAlgorithm.sha1;
private Date executionTime = new Date();
private OPCPackage opcPackage;
private PrivateKey key;
private List<X509Certificate> signingCertificateChain;
private IdentityDTO identity;
private AddressDTO address;
private byte[] photo;
private SignaturePolicyService signaturePolicyService;
private URIDereferencer uriDereferencer;
public SignatureInfoConfig() {
OOXMLURIDereferencer uriDereferencer = new OOXMLURIDereferencer();
uriDereferencer.setSignatureConfig(this);
this.uriDereferencer = uriDereferencer;
}
public void addSignatureFacet(SignatureFacet sf) {
signatureFacets.add(sf);
}
public void addDefaultFacets() {
addSignatureFacet(new OOXMLSignatureFacet(this));
addSignatureFacet(new KeyInfoSignatureFacet(true, false, false));
XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(this);
xadesSignatureFacet.setIdSignedProperties("idSignedProperties");
xadesSignatureFacet.setSignaturePolicyImplied(true);
/*
* Work-around for Office 2010.
*/
xadesSignatureFacet.setIssuerNameNoReverseOrder(true);
addSignatureFacet(xadesSignatureFacet);
addSignatureFacet(new Office2010SignatureFacet());
}
/**
* Gives back the used XAdES signature facet.
*
* @return
*/
public XAdESSignatureFacet getXAdESSignatureFacet() {
for (SignatureFacet sf : getSignatureFacets()) {
if (sf instanceof XAdESSignatureFacet) {
return (XAdESSignatureFacet)sf;
}
}
return null;
}
public List<SignatureFacet> getSignatureFacets() {
return signatureFacets;
}
public void setSignatureFacets(List<SignatureFacet> signatureFacets) {
this.signatureFacets = signatureFacets;
}
public HashAlgorithm getDigestAlgo() {
return digestAlgo;
}
public void setDigestAlgo(HashAlgorithm digestAlgo) {
this.digestAlgo = digestAlgo;
}
public OPCPackage getOpcPackage() {
return opcPackage;
}
public void setOpcPackage(OPCPackage opcPackage) {
this.opcPackage = opcPackage;
}
public PrivateKey getKey() {
return key;
}
public void setKey(PrivateKey key) {
this.key = key;
}
public List<X509Certificate> getSigningCertificateChain() {
return signingCertificateChain;
}
public void setSigningCertificateChain(
List<X509Certificate> signingCertificateChain) {
this.signingCertificateChain = signingCertificateChain;
}
public IdentityDTO getIdentity() {
return identity;
}
public void setIdentity(IdentityDTO identity) {
this.identity = identity;
}
public AddressDTO getAddress() {
return address;
}
public void setAddress(AddressDTO address) {
this.address = address;
}
public byte[] getPhoto() {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
public Date getExecutionTime() {
return executionTime;
}
public void setExecutionTime(Date executionTime) {
this.executionTime = executionTime;
}
public SignaturePolicyService getSignaturePolicyService() {
return signaturePolicyService;
}
public void setSignaturePolicyService(
SignaturePolicyService signaturePolicyService) {
this.signaturePolicyService = signaturePolicyService;
}
public URIDereferencer getUriDereferencer() {
return uriDereferencer;
}
public void setUriDereferencer(URIDereferencer uriDereferencer) {
this.uriDereferencer = uriDereferencer;
}
}

View File

@ -37,7 +37,6 @@ import java.security.cert.X509Certificate;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -68,10 +67,9 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec; import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec;
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
@ -96,19 +94,13 @@ public class OOXMLSignatureFacet implements SignatureFacet {
public static final String OOXML_DIGSIG_NS = "http://schemas.openxmlformats.org/package/2006/digital-signature"; public static final String OOXML_DIGSIG_NS = "http://schemas.openxmlformats.org/package/2006/digital-signature";
public static final String OFFICE_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig"; public static final String OFFICE_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";
private final XmlSignatureService signatureService; private final SignatureInfoConfig signatureConfig;
private final Date clock;
private final HashAlgorithm hashAlgo;
/** /**
* Main constructor. * Main constructor.
*/ */
public OOXMLSignatureFacet(XmlSignatureService signatureService, Date clock, HashAlgorithm hashAlgo) { public OOXMLSignatureFacet(SignatureInfoConfig signatureConfig) {
this.signatureService = signatureService; this.signatureConfig = signatureConfig;
this.clock = (clock == null ? new Date() : clock);
this.hashAlgo = (hashAlgo == null ? HashAlgorithm.sha1 : hashAlgo);
} }
@Override @Override
@ -142,7 +134,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
XMLObject xo = signatureFactory.newXMLObject(objectContent, objectId, null, null); XMLObject xo = signatureFactory.newXMLObject(objectContent, objectId, null, null);
objects.add(xo); objects.add(xo);
DigestMethod digestMethod = signatureFactory.newDigestMethod(this.hashAlgo.xmlSignUri, null); DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);
Reference reference = signatureFactory.newReference Reference reference = signatureFactory.newReference
("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null); ("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);
references.add(reference); references.add(reference);
@ -152,11 +144,11 @@ public class OOXMLSignatureFacet implements SignatureFacet {
throws IOException, NoSuchAlgorithmException, throws IOException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, URISyntaxException, XmlException { InvalidAlgorithmParameterException, URISyntaxException, XmlException {
OPCPackage ooxml = this.signatureService.getOfficeOpenXMLDocument(); OPCPackage ooxml = this.signatureConfig.getOpcPackage();
List<PackagePart> relsEntryNames = ooxml.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART); List<PackagePart> relsEntryNames = ooxml.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART);
DigestMethod digestMethod = signatureFactory.newDigestMethod(this.hashAlgo.xmlSignUri, null); DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);
Set<String> digestedPartNames = new HashSet<String>(); Set<String> digestedPartNames = new HashSet<String>();
for (PackagePart pp : relsEntryNames) { for (PackagePart pp : relsEntryNames) {
String baseUri = pp.getPartName().getName().replaceFirst("(.*)/_rels/.*", "$1"); String baseUri = pp.getPartName().getName().replaceFirst("(.*)/_rels/.*", "$1");
@ -240,7 +232,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
*/ */
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
fmt.setTimeZone(TimeZone.getTimeZone("UTC")); fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
String nowStr = fmt.format(this.clock); String nowStr = fmt.format(this.signatureConfig.getExecutionTime());
LOG.log(POILogger.DEBUG, "now: " + nowStr); LOG.log(POILogger.DEBUG, "now: " + nowStr);
SignatureTimeDocument sigTime = SignatureTimeDocument.Factory.newInstance(); SignatureTimeDocument sigTime = SignatureTimeDocument.Factory.newInstance();
@ -261,7 +253,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
signaturePropertyContent.add(signatureTimeSignatureProperty); signaturePropertyContent.add(signatureTimeSignatureProperty);
SignatureProperties signatureProperties = signatureFactory SignatureProperties signatureProperties = signatureFactory
.newSignatureProperties(signaturePropertyContent, .newSignatureProperties(signaturePropertyContent,
"id-signature-time-" + this.clock.getTime()); "id-signature-time-" + signatureConfig.getExecutionTime());
objectContent.add(signatureProperties); objectContent.add(signatureProperties);
} }
@ -274,7 +266,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance(); SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance();
CTSignatureInfoV1 ctSigV1 = sigV1.addNewSignatureInfoV1(); CTSignatureInfoV1 ctSigV1 = sigV1.addNewSignatureInfoV1();
ctSigV1.setManifestHashAlgorithm(hashAlgo.xmlSignUri); ctSigV1.setManifestHashAlgorithm(signatureConfig.getDigestAlgo().xmlSignUri);
Element n = (Element)document.importNode(ctSigV1.getDomNode(), true); Element n = (Element)document.importNode(ctSigV1.getDomNode(), true);
n.setAttributeNS(XmlNS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig"); n.setAttributeNS(XmlNS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig");
@ -293,7 +285,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
String objectId = "idOfficeObject"; String objectId = "idOfficeObject";
objects.add(signatureFactory.newXMLObject(objectContent, objectId, null, null)); objects.add(signatureFactory.newXMLObject(objectContent, objectId, null, null));
DigestMethod digestMethod = signatureFactory.newDigestMethod(this.hashAlgo.xmlSignUri, null); DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);
Reference reference = signatureFactory.newReference Reference reference = signatureFactory.newReference
("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null); ("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);
references.add(reference); references.add(reference);

View File

@ -34,7 +34,6 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -53,6 +52,7 @@ import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo; import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService; import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -97,12 +97,8 @@ public class XAdESSignatureFacet implements SignatureFacet {
private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties"; private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties";
private final Date clock; private SignatureInfoConfig signatureConfig;
private final HashAlgorithm hashAlgo;
private final SignaturePolicyService signaturePolicyService;
private String idSignedProperties; private String idSignedProperties;
private boolean signaturePolicyImplied; private boolean signaturePolicyImplied;
@ -111,7 +107,7 @@ public class XAdESSignatureFacet implements SignatureFacet {
private boolean issuerNameNoReverseOrder = false; private boolean issuerNameNoReverseOrder = false;
private Map<String, String> dataObjectFormatMimeTypes; private Map<String, String> dataObjectFormatMimeTypes = new HashMap<String, String>();
/** /**
* Main constructor. * Main constructor.
@ -126,12 +122,8 @@ public class XAdESSignatureFacet implements SignatureFacet {
* @param signaturePolicyService * @param signaturePolicyService
* the optional signature policy service used for XAdES-EPES. * the optional signature policy service used for XAdES-EPES.
*/ */
public XAdESSignatureFacet(Date clock, HashAlgorithm hashAlgo, public XAdESSignatureFacet(SignatureInfoConfig signatureConfig) {
SignaturePolicyService signaturePolicyService) { this.signatureConfig = signatureConfig;
this.clock = (clock == null ? new Date() : clock);
this.hashAlgo = (hashAlgo == null ? HashAlgorithm.sha1 : hashAlgo);
this.signaturePolicyService = signaturePolicyService;
this.dataObjectFormatMimeTypes = new HashMap<String, String>();
} }
@Override @Override
@ -167,7 +159,7 @@ public class XAdESSignatureFacet implements SignatureFacet {
// SigningTime // SigningTime
Calendar xmlGregorianCalendar = Calendar.getInstance(); Calendar xmlGregorianCalendar = Calendar.getInstance();
xmlGregorianCalendar.setTimeZone(TimeZone.getTimeZone("Z")); xmlGregorianCalendar.setTimeZone(TimeZone.getTimeZone("Z"));
xmlGregorianCalendar.setTime(this.clock); xmlGregorianCalendar.setTime(this.signatureConfig.getExecutionTime());
xmlGregorianCalendar.clear(Calendar.MILLISECOND); xmlGregorianCalendar.clear(Calendar.MILLISECOND);
signedSignatureProperties.setSigningTime(xmlGregorianCalendar); signedSignatureProperties.setSigningTime(xmlGregorianCalendar);
@ -179,7 +171,7 @@ public class XAdESSignatureFacet implements SignatureFacet {
CertIDListType signingCertificates = signedSignatureProperties.addNewSigningCertificate(); CertIDListType signingCertificates = signedSignatureProperties.addNewSigningCertificate();
CertIDType certId = signingCertificates.addNewCert(); CertIDType certId = signingCertificates.addNewCert();
X509Certificate signingCertificate = signingCertificateChain.get(0); X509Certificate signingCertificate = signingCertificateChain.get(0);
setCertID(certId, signingCertificate, this.hashAlgo, this.issuerNameNoReverseOrder); setCertID(certId, signingCertificate, this.signatureConfig.getDigestAlgo(), this.issuerNameNoReverseOrder);
// ClaimedRole // ClaimedRole
if (null != this.role && false == this.role.isEmpty()) { if (null != this.role && false == this.role.isEmpty()) {
@ -193,24 +185,24 @@ public class XAdESSignatureFacet implements SignatureFacet {
} }
// XAdES-EPES // XAdES-EPES
if (null != this.signaturePolicyService) { SignaturePolicyService policyService = this.signatureConfig.getSignaturePolicyService();
if (policyService != null) {
SignaturePolicyIdentifierType signaturePolicyIdentifier = SignaturePolicyIdentifierType signaturePolicyIdentifier =
signedSignatureProperties.addNewSignaturePolicyIdentifier(); signedSignatureProperties.addNewSignaturePolicyIdentifier();
SignaturePolicyIdType signaturePolicyId = signaturePolicyIdentifier.addNewSignaturePolicyId(); SignaturePolicyIdType signaturePolicyId = signaturePolicyIdentifier.addNewSignaturePolicyId();
ObjectIdentifierType objectIdentifier = signaturePolicyId.addNewSigPolicyId(); ObjectIdentifierType objectIdentifier = signaturePolicyId.addNewSigPolicyId();
objectIdentifier.setDescription(this.signaturePolicyService.getSignaturePolicyDescription()); objectIdentifier.setDescription(policyService.getSignaturePolicyDescription());
IdentifierType identifier = objectIdentifier.addNewIdentifier(); IdentifierType identifier = objectIdentifier.addNewIdentifier();
identifier.setStringValue(this.signaturePolicyService.getSignaturePolicyIdentifier()); identifier.setStringValue(policyService.getSignaturePolicyIdentifier());
byte[] signaturePolicyDocumentData = this.signaturePolicyService.getSignaturePolicyDocument(); byte[] signaturePolicyDocumentData = policyService.getSignaturePolicyDocument();
DigestAlgAndValueType sigPolicyHash = signaturePolicyId.addNewSigPolicyHash(); DigestAlgAndValueType sigPolicyHash = signaturePolicyId.addNewSigPolicyHash();
setDigestAlgAndValue(sigPolicyHash, signaturePolicyDocumentData, this.hashAlgo); setDigestAlgAndValue(sigPolicyHash, signaturePolicyDocumentData, this.signatureConfig.getDigestAlgo());
String signaturePolicyDownloadUrl = this.signaturePolicyService String signaturePolicyDownloadUrl = policyService.getSignaturePolicyDownloadUrl();
.getSignaturePolicyDownloadUrl();
if (null != signaturePolicyDownloadUrl) { if (null != signaturePolicyDownloadUrl) {
SigPolicyQualifiersListType sigPolicyQualifiers = signaturePolicyId.addNewSigPolicyQualifiers(); SigPolicyQualifiersListType sigPolicyQualifiers = signaturePolicyId.addNewSigPolicyQualifiers();
AnyType sigPolicyQualifier = sigPolicyQualifiers.addNewSigPolicyQualifier(); AnyType sigPolicyQualifier = sigPolicyQualifiers.addNewSigPolicyQualifier();
@ -254,7 +246,7 @@ public class XAdESSignatureFacet implements SignatureFacet {
objects.add(xadesObject); objects.add(xadesObject);
// add XAdES ds:Reference // add XAdES ds:Reference
DigestMethod digestMethod = signatureFactory.newDigestMethod(hashAlgo.xmlSignUri, null); DigestMethod digestMethod = signatureFactory.newDigestMethod(this.signatureConfig.getDigestAlgo().xmlSignUri, null);
List<Transform> transforms = new ArrayList<Transform>(); List<Transform> transforms = new ArrayList<Transform>();
Transform exclusiveTransform = signatureFactory Transform exclusiveTransform = signatureFactory
.newTransform(CanonicalizationMethod.INCLUSIVE, .newTransform(CanonicalizationMethod.INCLUSIVE,

View File

@ -26,16 +26,12 @@ package org.apache.poi.poifs.crypt.dsig.services;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List; import java.util.List;
import javax.xml.crypto.MarshalException; import javax.xml.crypto.MarshalException;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
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.DigestInfo;
import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@ -47,45 +43,17 @@ import org.w3c.dom.Document;
*/ */
public interface SignatureService { 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 * Pre-sign callback method. Depending on the configuration some parameters
* are passed. The returned value will be signed by the eID Applet. * 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 * @param digestInfos
* the optional list of digest infos. * 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. * @return the digest to be signed.
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
DigestInfo preSign(Document document, List<DigestInfo> digestInfos, DigestInfo preSign(Document document, List<DigestInfo> digestInfos)
PrivateKey privateKey, throws NoSuchAlgorithmException;
List<X509Certificate> signingCertificateChain,
IdentityDTO identity, AddressDTO address, byte[] photo)
throws NoSuchAlgorithmException;
/** /**
* Post-sign callback method. Received the signature value. Depending on the * Post-sign callback method. Received the signature value. Depending on the
@ -95,7 +63,6 @@ public interface SignatureService {
* @param signingCertificateChain * @param signingCertificateChain
* the optional chain of signing certificates. * the optional chain of signing certificates.
*/ */
void postSign(Document document, byte[] signatureValue, void postSign(Document document, byte[] signatureValue)
List<X509Certificate> signingCertificateChain) throws IOException, MarshalException, ParserConfigurationException, XmlException;
throws IOException, MarshalException, ParserConfigurationException, XmlException;
} }

View File

@ -37,11 +37,8 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -79,16 +76,10 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.OOXMLURIDereferencer;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo; import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet; import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;
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.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.DigestInfo; 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.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.xml.security.signature.XMLSignature; import org.apache.xml.security.signature.XMLSignature;
@ -112,43 +103,23 @@ import org.xml.sax.SAXException;
public class XmlSignatureService implements SignatureService { public class XmlSignatureService implements SignatureService {
private static final POILogger LOG = POILogFactory.getLogger(XmlSignatureService.class); private static final POILogger LOG = POILogFactory.getLogger(XmlSignatureService.class);
protected final List<SignatureFacet> signatureFacets; protected SignatureInfoConfig signatureConfig;
private String signatureNamespacePrefix; private String signatureNamespacePrefix;
private String signatureId = "idPackageSignature"; private String signatureId = "idPackageSignature";
private final HashAlgorithm hashAlgo;
private final OPCPackage opcPackage;
// private SignatureDocument sigDoc;
private XAdESSignatureFacet xadesSignatureFacet;
/** /**
* Main constructor. * Main constructor.
*/ */
public XmlSignatureService(HashAlgorithm digestAlgo, OPCPackage opcPackage) { public XmlSignatureService(SignatureInfoConfig signatureConfig) {
this.signatureFacets = new ArrayList<SignatureFacet>();
this.signatureNamespacePrefix = null; this.signatureNamespacePrefix = null;
this.hashAlgo = digestAlgo; this.signatureConfig = signatureConfig;
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);
addSignatureFacet(this.xadesSignatureFacet);
addSignatureFacet(new Office2010SignatureFacet());
} }
public SignatureInfoConfig getSignatureConfig() {
return signatureConfig;
}
/** /**
* Sets the signature Id attribute value used to create the XML signature. A * Sets the signature Id attribute value used to create the XML signature. A
* <code>null</code> value will trigger an automatically generated signature * <code>null</code> value will trigger an automatically generated signature
@ -170,39 +141,6 @@ public class XmlSignatureService implements SignatureService {
this.signatureNamespacePrefix = signatureNamespacePrefix; this.signatureNamespacePrefix = signatureNamespacePrefix;
} }
/**
* Adds a signature facet to this XML signature service.
*
* @param signatureFacet
*/
public void addSignatureFacet(SignatureFacet... signatureFacets) {
for (SignatureFacet sf : signatureFacets) {
this.signatureFacets.add(sf);
}
}
/**
* 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 * Gives back the human-readable description of what the citizen will be
* signing. The default value is "XML Document". Override this method to * signing. The default value is "XML Document". Override this method to
@ -214,17 +152,6 @@ public class XmlSignatureService implements SignatureService {
return "Office OpenXML Document"; 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. * Gives back the output stream to which to write the signed XML document.
* *
@ -232,19 +159,16 @@ public class XmlSignatureService implements SignatureService {
*/ */
// protected abstract OutputStream getSignedDocumentOutputStream(); // protected abstract OutputStream getSignedDocumentOutputStream();
@Override @Override
public DigestInfo preSign(Document document, List<DigestInfo> digestInfos, public DigestInfo preSign(Document document, List<DigestInfo> digestInfos)
PrivateKey key,
List<X509Certificate> signingCertificateChain,
IdentityDTO identity, AddressDTO address, byte[] photo)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
SignatureInfo.initXmlProvider(); SignatureInfo.initXmlProvider();
LOG.log(POILogger.DEBUG, "preSign"); LOG.log(POILogger.DEBUG, "preSign");
HashAlgorithm hashAlgo = getSignatureDigestAlgorithm(); HashAlgorithm hashAlgo = this.signatureConfig.getDigestAlgo();
byte[] digestValue; byte[] digestValue;
try { try {
digestValue = getXmlSignatureDigestValue(document, hashAlgo, digestInfos, key, signingCertificateChain); digestValue = getXmlSignatureDigestValue(document, digestInfos);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("XML signature error: " + e.getMessage(), e); throw new RuntimeException("XML signature error: " + e.getMessage(), e);
} }
@ -254,7 +178,7 @@ public class XmlSignatureService implements SignatureService {
} }
@Override @Override
public void postSign(Document document, byte[] signatureValue, List<X509Certificate> signingCertificateChain) public void postSign(Document document, byte[] signatureValue)
throws IOException, MarshalException, ParserConfigurationException, XmlException { throws IOException, MarshalException, ParserConfigurationException, XmlException {
LOG.log(POILogger.DEBUG, "postSign"); LOG.log(POILogger.DEBUG, "postSign");
SignatureInfo.initXmlProvider(); SignatureInfo.initXmlProvider();
@ -278,8 +202,8 @@ public class XmlSignatureService implements SignatureService {
/* /*
* Allow signature facets to inject their own stuff. * Allow signature facets to inject their own stuff.
*/ */
for (SignatureFacet signatureFacet : this.signatureFacets) { for (SignatureFacet signatureFacet : this.signatureConfig.getSignatureFacets()) {
signatureFacet.postSign(document, signingCertificateChain); signatureFacet.postSign(document, this.signatureConfig.getSigningCertificateChain());
} }
registerIds(document); registerIds(document);
@ -287,10 +211,7 @@ public class XmlSignatureService implements SignatureService {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private byte[] getXmlSignatureDigestValue(Document document, HashAlgorithm hashAlgo, private byte[] getXmlSignatureDigestValue(Document document, List<DigestInfo> digestInfos)
List<DigestInfo> digestInfos,
PrivateKey privateKey,
List<X509Certificate> signingCertificateChain)
throws ParserConfigurationException, NoSuchAlgorithmException, throws ParserConfigurationException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MarshalException, InvalidAlgorithmParameterException, MarshalException,
javax.xml.crypto.dsig.XMLSignatureException, javax.xml.crypto.dsig.XMLSignatureException,
@ -321,8 +242,8 @@ public class XmlSignatureService implements SignatureService {
/* /*
* Signature context construction. * Signature context construction.
*/ */
XMLSignContext xmlSignContext = new DOMSignContext(privateKey, document); XMLSignContext xmlSignContext = new DOMSignContext(this.signatureConfig.getKey(), document);
URIDereferencer uriDereferencer = getURIDereferencer(); URIDereferencer uriDereferencer = this.signatureConfig.getUriDereferencer();
if (null != uriDereferencer) { if (null != uriDereferencer) {
xmlSignContext.setURIDereferencer(uriDereferencer); xmlSignContext.setURIDereferencer(uriDereferencer);
} }
@ -354,15 +275,15 @@ public class XmlSignatureService implements SignatureService {
localSignatureId = "xmldsig-" + UUID.randomUUID().toString(); localSignatureId = "xmldsig-" + UUID.randomUUID().toString();
} }
List<XMLObject> objects = new ArrayList<XMLObject>(); List<XMLObject> objects = new ArrayList<XMLObject>();
for (SignatureFacet signatureFacet : this.signatureFacets) { for (SignatureFacet signatureFacet : this.signatureConfig.getSignatureFacets()) {
LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName()); LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
signatureFacet.preSign(document, signatureFactory, localSignatureId, signingCertificateChain, references, objects); signatureFacet.preSign(document, signatureFactory, localSignatureId, this.signatureConfig.getSigningCertificateChain(), references, objects);
} }
/* /*
* ds:SignedInfo * ds:SignedInfo
*/ */
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(getSignatureMethod(hashAlgo), null); SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(getSignatureMethod(this.signatureConfig.getDigestAlgo()), null);
CanonicalizationMethod canonicalizationMethod = signatureFactory CanonicalizationMethod canonicalizationMethod = signatureFactory
.newCanonicalizationMethod(getCanonicalizationMethod(), .newCanonicalizationMethod(getCanonicalizationMethod(),
(C14NMethodParameterSpec) null); (C14NMethodParameterSpec) null);
@ -432,7 +353,7 @@ public class XmlSignatureService implements SignatureService {
* usage. * usage.
*/ */
MessageDigest jcaMessageDigest = CryptoFunctions.getMessageDigest(hashAlgo); MessageDigest jcaMessageDigest = CryptoFunctions.getMessageDigest(this.signatureConfig.getDigestAlgo());
byte[] digestValue = jcaMessageDigest.digest(octets); byte[] digestValue = jcaMessageDigest.digest(octets);
return digestValue; return digestValue;
} }
@ -443,7 +364,7 @@ public class XmlSignatureService implements SignatureService {
* *
* @param doc * @param doc
*/ */
public void registerIds(Document doc) { public static void registerIds(Document doc) {
NodeList nl = doc.getElementsByTagNameNS(XmlDSigNS, "Object"); NodeList nl = doc.getElementsByTagNameNS(XmlDSigNS, "Object");
registerIdAttribute(nl); registerIdAttribute(nl);
nl = doc.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "SignedProperties"); nl = doc.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "SignedProperties");
@ -492,19 +413,6 @@ public class XmlSignatureService implements SignatureService {
throw new RuntimeException("unsupported sign algo: " + hashAlgo); 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() { protected String getCanonicalizationMethod() {
return CanonicalizationMethod.INCLUSIVE; return CanonicalizationMethod.INCLUSIVE;
} }
@ -512,7 +420,7 @@ public class XmlSignatureService implements SignatureService {
protected void writeDocument(Document document) throws IOException, XmlException { protected void writeDocument(Document document) throws IOException, XmlException {
XmlOptions xo = new XmlOptions(); XmlOptions xo = new XmlOptions();
Map<String,String> namespaceMap = new HashMap<String,String>(); Map<String,String> namespaceMap = new HashMap<String,String>();
for (SignatureFacet sf : this.signatureFacets) { for (SignatureFacet sf : this.signatureConfig.getSignatureFacets()) {
Map<String,String> sfm = sf.getNamespacePrefixMapping(); Map<String,String> sfm = sf.getNamespacePrefixMapping();
if (sfm != null) { if (sfm != null) {
namespaceMap.putAll(sfm); namespaceMap.putAll(sfm);
@ -527,7 +435,7 @@ public class XmlSignatureService implements SignatureService {
* Copy the original OOXML content to the signed OOXML package. During * Copy the original OOXML content to the signed OOXML package. During
* copying some files need to changed. * copying some files need to changed.
*/ */
OPCPackage pkg = this.getOfficeOpenXMLDocument(); OPCPackage pkg = this.signatureConfig.getOpcPackage();
PackagePartName sigPartName, sigsPartName; PackagePartName sigPartName, sigsPartName;
try { try {

View File

@ -52,15 +52,14 @@ import javax.xml.crypto.KeySelector;
import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext; import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo; import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.SignatureInfoConfig;
import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.SignaturePolicyService;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet; import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.services.RevocationData; import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
@ -208,13 +207,26 @@ public class TestSignatureInfo {
OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
initKeyPair("Test", "CN=Test"); initKeyPair("Test", "CN=Test");
final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());
// setup // setup
EnvelopedSignatureFacet envelopedSignatureFacet = new EnvelopedSignatureFacet(); SignatureInfoConfig signatureConfig = new SignatureInfoConfig();
KeyInfoSignatureFacet keyInfoSignatureFacet = new KeyInfoSignatureFacet(true, false, false); signatureConfig.setOpcPackage(pkg);
SignaturePolicyService signaturePolicyService = null; signatureConfig.setKey(keyPair.getPrivate());
XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(null, null, signaturePolicyService);
final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate()); /*
* We need at least 2 certificates for the XAdES-C complete certificate
* refs construction.
*/
List<X509Certificate> certificateChain = new ArrayList<X509Certificate>();
certificateChain.add(x509);
certificateChain.add(x509);
signatureConfig.setSigningCertificateChain(certificateChain);
signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet());
signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet(true, false, false));
signatureConfig.addSignatureFacet(new XAdESSignatureFacet(signatureConfig));
// http://timestamping.edelweb.fr/service/tsp // http://timestamping.edelweb.fr/service/tsp
// http://tsa.belgium.be/connect // http://tsa.belgium.be/connect
@ -248,14 +260,6 @@ public class TestSignatureInfo {
timeStampService = tspService; timeStampService = tspService;
} }
List<X509Certificate> certificateChain = new ArrayList<X509Certificate>();
/*
* We need at least 2 certificates for the XAdES-C complete certificate
* refs construction.
*/
certificateChain.add(x509);
certificateChain.add(x509);
final RevocationData revocationData = new RevocationData(); final RevocationData revocationData = new RevocationData();
revocationData.addCRL(crl); revocationData.addCRL(crl);
OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false, OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false,
@ -270,17 +274,12 @@ public class TestSignatureInfo {
XAdESXLSignatureFacet xadesXLSignatureFacet = new XAdESXLSignatureFacet( XAdESXLSignatureFacet xadesXLSignatureFacet = new XAdESXLSignatureFacet(
timeStampService, revocationDataService); timeStampService, revocationDataService);
XmlSignatureService testedInstance = new XmlSignatureService(HashAlgorithm.sha1, pkg); XmlSignatureService testedInstance = new XmlSignatureService(signatureConfig);
testedInstance.addSignatureFacet(envelopedSignatureFacet, keyInfoSignatureFacet,
xadesSignatureFacet, xadesXLSignatureFacet);
Document document = DocumentHelper.createDocument();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document document = dbf.newDocumentBuilder().newDocument();
// operate // operate
DigestInfo digestInfo = testedInstance.preSign(document, null, keyPair.getPrivate(), certificateChain, null, null, null); DigestInfo digestInfo = testedInstance.preSign(document, null);
// verify // verify
assertNotNull(digestInfo); assertNotNull(digestInfo);
@ -301,7 +300,7 @@ public class TestSignatureInfo {
byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue); byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue);
// Operate: postSign // Operate: postSign
testedInstance.postSign(document, signatureValue, certificateChain); testedInstance.postSign(document, signatureValue);
DOMValidateContext domValidateContext = new DOMValidateContext( DOMValidateContext domValidateContext = new DOMValidateContext(
KeySelector.singletonKeySelector(keyPair.getPublic()), KeySelector.singletonKeySelector(keyPair.getPublic()),
@ -332,15 +331,22 @@ public class TestSignatureInfo {
} }
private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception { private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {
XmlSignatureService signatureService = new XmlSignatureService(HashAlgorithm.sha1, pkgCopy);
signatureService.initFacets(cal.getTime());
initKeyPair(alias, signerDn); initKeyPair(alias, signerDn);
SignatureInfoConfig signatureConfig = new SignatureInfoConfig();
signatureConfig.setKey(keyPair.getPrivate());
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
signatureConfig.setExecutionTime(cal.getTime());
signatureConfig.setDigestAlgo(HashAlgorithm.sha1);
signatureConfig.setOpcPackage(pkgCopy);
signatureConfig.addDefaultFacets();
XmlSignatureService signatureService = new XmlSignatureService(signatureConfig);
Document document = DocumentHelper.createDocument(); Document document = DocumentHelper.createDocument();
// operate // operate
List<X509Certificate> x509Chain = Collections.singletonList(x509); DigestInfo digestInfo = signatureService.preSign(document, null);
DigestInfo digestInfo = signatureService.preSign(document, null, keyPair.getPrivate(), x509Chain, null, null, null);
// verify // verify
assertNotNull(digestInfo); assertNotNull(digestInfo);
@ -354,7 +360,7 @@ public class TestSignatureInfo {
byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue); byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue);
// operate: postSign // operate: postSign
signatureService.postSign(document, signatureValue, Collections.singletonList(x509)); signatureService.postSign(document, signatureValue);
// verify: signature // verify: signature
SignatureInfo si = new SignatureInfo(pkgCopy); SignatureInfo si = new SignatureInfo(pkgCopy);