another round of refactoring, limited exception declarations, more javadocs
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1629332 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ab84e448ca
commit
30d72983d1
@ -34,7 +34,6 @@ import javax.xml.crypto.URIDereferencer;
|
||||
import javax.xml.crypto.URIReference;
|
||||
import javax.xml.crypto.URIReferenceException;
|
||||
import javax.xml.crypto.XMLCryptoContext;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
@ -54,16 +53,15 @@ public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigura
|
||||
private SignatureConfig signatureConfig;
|
||||
private URIDereferencer baseUriDereferencer;
|
||||
|
||||
public OOXMLURIDereferencer() {
|
||||
XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory();
|
||||
this.baseUriDereferencer = xmlSignatureFactory.getURIDereferencer();
|
||||
}
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
|
||||
if (baseUriDereferencer == null) {
|
||||
baseUriDereferencer = signatureConfig.getSignatureFactory().getURIDereferencer();
|
||||
}
|
||||
|
||||
if (null == uriReference) {
|
||||
throw new NullPointerException("URIReference cannot be null");
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS
|
||||
import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XADES_132_NS;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@ -32,6 +33,8 @@ import java.util.UUID;
|
||||
import javax.xml.crypto.URIDereferencer;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
||||
|
||||
import org.apache.poi.EncryptedDocumentException;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
@ -46,21 +49,28 @@ import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.TSPTimeStampService;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.w3c.dom.events.EventListener;
|
||||
|
||||
/**
|
||||
* This class bundles the configuration options used for the existing
|
||||
* signature facets.
|
||||
* Apart of the opc-package (thread local) most values will probably be constant, so
|
||||
* Apart of the thread local members (e.g. opc-package) most values will probably be constant, so
|
||||
* it might be configured centrally (e.g. by spring)
|
||||
*/
|
||||
public class SignatureConfig {
|
||||
|
||||
private static final POILogger LOG = POILogFactory.getLogger(SignatureConfig.class);
|
||||
|
||||
public static interface SignatureConfigurable {
|
||||
void setSignatureConfig(SignatureConfig signatureConfig);
|
||||
}
|
||||
|
||||
private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<OPCPackage>();
|
||||
private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<XMLSignatureFactory>();
|
||||
private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<KeyInfoFactory>();
|
||||
private ThreadLocal<Provider> provider = new ThreadLocal<Provider>();
|
||||
|
||||
private List<SignatureFacet> signatureFacets = new ArrayList<SignatureFacet>();
|
||||
private HashAlgorithm digestAlgo = HashAlgorithm.sha1;
|
||||
@ -72,7 +82,7 @@ public class SignatureConfig {
|
||||
* the optional signature policy service used for XAdES-EPES.
|
||||
*/
|
||||
private SignaturePolicyService signaturePolicyService;
|
||||
private URIDereferencer uriDereferencer = new OOXMLURIDereferencer();
|
||||
private URIDereferencer uriDereferencer = null;
|
||||
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;
|
||||
|
||||
private boolean includeEntireCertificateChain = true;
|
||||
@ -146,13 +156,22 @@ public class SignatureConfig {
|
||||
*/
|
||||
Map<String,String> namespacePrefixes = new HashMap<String,String>();
|
||||
|
||||
/**
|
||||
* Inits and checks the config object.
|
||||
* If not set previously, complex configuration properties also get
|
||||
* created/initialized via this initialization call.
|
||||
*
|
||||
* @param onlyValidation if true, only a subset of the properties
|
||||
* is initialized, which are necessary for validation. If false,
|
||||
* also the other properties needed for signing are been taken care of
|
||||
*/
|
||||
protected void init(boolean onlyValidation) {
|
||||
if (uriDereferencer == null) {
|
||||
throw new EncryptedDocumentException("uriDereferencer is null");
|
||||
}
|
||||
if (opcPackage == null) {
|
||||
throw new EncryptedDocumentException("opcPackage is null");
|
||||
}
|
||||
if (uriDereferencer == null) {
|
||||
uriDereferencer = new OOXMLURIDereferencer();
|
||||
}
|
||||
if (uriDereferencer instanceof SignatureConfigurable) {
|
||||
((SignatureConfigurable)uriDereferencer).setSignatureConfig(this);
|
||||
}
|
||||
@ -195,68 +214,155 @@ public class SignatureConfig {
|
||||
}
|
||||
}
|
||||
|
||||
public void addSignatureFacet(SignatureFacet sf) {
|
||||
signatureFacets.add(sf);
|
||||
/**
|
||||
* @param signatureFacet the signature facet is appended to facet list
|
||||
*/
|
||||
public void addSignatureFacet(SignatureFacet signatureFacet) {
|
||||
signatureFacets.add(signatureFacet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of facets, may be empty when the config object is not initialized
|
||||
*/
|
||||
public List<SignatureFacet> getSignatureFacets() {
|
||||
return signatureFacets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signatureFacets the new list of facets
|
||||
*/
|
||||
public void setSignatureFacets(List<SignatureFacet> signatureFacets) {
|
||||
this.signatureFacets = signatureFacets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the main digest algorithm, defaults to sha-1
|
||||
*/
|
||||
public HashAlgorithm getDigestAlgo() {
|
||||
return digestAlgo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param digestAlgo the main digest algorithm
|
||||
*/
|
||||
public void setDigestAlgo(HashAlgorithm digestAlgo) {
|
||||
this.digestAlgo = digestAlgo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the opc package to be used by this thread, stored as thread-local
|
||||
*/
|
||||
public OPCPackage getOpcPackage() {
|
||||
return opcPackage.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opcPackage the opc package to be handled by this thread, stored as thread-local
|
||||
*/
|
||||
public void setOpcPackage(OPCPackage opcPackage) {
|
||||
this.opcPackage.set(opcPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the private key
|
||||
*/
|
||||
public PrivateKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the private key
|
||||
*/
|
||||
public void setKey(PrivateKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the certificate chain, index 0 is usually the certificate matching
|
||||
* the private key
|
||||
*/
|
||||
public List<X509Certificate> getSigningCertificateChain() {
|
||||
return signingCertificateChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signingCertificateChain the certificate chain, index 0 should be
|
||||
* the certificate matching the private key
|
||||
*/
|
||||
public void setSigningCertificateChain(
|
||||
List<X509Certificate> signingCertificateChain) {
|
||||
this.signingCertificateChain = signingCertificateChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time at which the document is signed, also used for the timestamp service.
|
||||
* defaults to now
|
||||
*/
|
||||
public Date getExecutionTime() {
|
||||
return executionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param executionTime sets the time at which the document ought to be signed
|
||||
*/
|
||||
public void setExecutionTime(Date executionTime) {
|
||||
this.executionTime = executionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the service to be used for XAdES-EPES properties. There's no default implementation
|
||||
*/
|
||||
public SignaturePolicyService getSignaturePolicyService() {
|
||||
return signaturePolicyService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signaturePolicyService the service to be used for XAdES-EPES properties
|
||||
*/
|
||||
public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) {
|
||||
this.signaturePolicyService = signaturePolicyService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dereferencer used for Reference/@URI attributes, defaults to {@link OOXMLURIDereferencer}
|
||||
*/
|
||||
public URIDereferencer getUriDereferencer() {
|
||||
return uriDereferencer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uriDereferencer the dereferencer used for Reference/@URI attributes
|
||||
*/
|
||||
public void setUriDereferencer(URIDereferencer uriDereferencer) {
|
||||
this.uriDereferencer = uriDereferencer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gives back the human-readable description of what the citizen
|
||||
* will be signing. The default value is "Office OpenXML Document".
|
||||
*/
|
||||
public String getSignatureDescription() {
|
||||
return signatureDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signatureDescription the human-readable description of
|
||||
* what the citizen will be signing.
|
||||
*/
|
||||
public void setSignatureDescription(String signatureDescription) {
|
||||
this.signatureDescription = signatureDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default canonicalization method, defaults to INCLUSIVE
|
||||
*/
|
||||
public String getCanonicalizationMethod() {
|
||||
return canonicalizationMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canonicalizationMethod the default canonicalization method
|
||||
*/
|
||||
public void setCanonicalizationMethod(String canonicalizationMethod) {
|
||||
this.canonicalizationMethod = canonicalizationMethod;
|
||||
}
|
||||
@ -469,4 +575,59 @@ public class SignatureConfig {
|
||||
}
|
||||
}
|
||||
|
||||
public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
|
||||
this.signatureFactory.set(signatureFactory);
|
||||
}
|
||||
|
||||
public XMLSignatureFactory getSignatureFactory() {
|
||||
XMLSignatureFactory sigFac = signatureFactory.get();
|
||||
if (sigFac == null) {
|
||||
sigFac = XMLSignatureFactory.getInstance("DOM", getProvider());
|
||||
setSignatureFactory(sigFac);
|
||||
}
|
||||
return sigFac;
|
||||
}
|
||||
|
||||
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
|
||||
this.keyInfoFactory.set(keyInfoFactory);
|
||||
}
|
||||
|
||||
public KeyInfoFactory getKeyInfoFactory() {
|
||||
KeyInfoFactory keyFac = keyInfoFactory.get();
|
||||
if (keyFac == null) {
|
||||
keyFac = KeyInfoFactory.getInstance("DOM", getProvider());
|
||||
setKeyInfoFactory(keyFac);
|
||||
}
|
||||
return keyFac;
|
||||
}
|
||||
|
||||
// currently classes are linked to Apache Santuario, so this might be superfluous
|
||||
public Provider getProvider() {
|
||||
Provider prov = provider.get();
|
||||
if (prov == null) {
|
||||
String dsigProviderNames[] = {
|
||||
System.getProperty("jsr105Provider"),
|
||||
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", // Santuario xmlsec
|
||||
"org.jcp.xml.dsig.internal.dom.XMLDSigRI" // JDK xmlsec
|
||||
};
|
||||
for (String pn : dsigProviderNames) {
|
||||
if (pn == null) continue;
|
||||
try {
|
||||
prov = (Provider)Class.forName(pn).newInstance();
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+pn+"' can't be found - trying next.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prov == null) {
|
||||
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
|
||||
}
|
||||
|
||||
return prov;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -30,12 +30,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Provider;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -50,7 +46,6 @@ import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.URIDereferencer;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
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;
|
||||
@ -62,11 +57,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactoryConfigurationError;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
@ -103,7 +94,6 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.events.EventListener;
|
||||
import org.w3c.dom.events.EventTarget;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
/**
|
||||
@ -144,7 +134,7 @@ import org.xml.sax.SAXException;
|
||||
* SignatureConfig signatureConfig = new SignatureConfig();
|
||||
* signatureConfig.setKey(keyPair.getPrivate());
|
||||
* signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
|
||||
* OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ);
|
||||
* OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ_WRITE);
|
||||
* signatureConfig.setOpcPackage(pkg);
|
||||
*
|
||||
* // adding the signature document to the package
|
||||
@ -220,7 +210,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
domValidateContext.setProperty("org.jcp.xml.dsig.validateManifests", Boolean.TRUE);
|
||||
domValidateContext.setURIDereferencer(signatureConfig.getUriDereferencer());
|
||||
|
||||
XMLSignatureFactory xmlSignatureFactory = getSignatureFactory();
|
||||
XMLSignatureFactory xmlSignatureFactory = signatureConfig.getSignatureFactory();
|
||||
XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
|
||||
boolean valid = xmlSignature.validate(domValidateContext);
|
||||
|
||||
@ -258,8 +248,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void confirmSignature()
|
||||
throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException, InvalidAlgorithmParameterException, NoSuchProviderException, XMLSignatureException, TransformerFactoryConfigurationError, TransformerException, SAXException, URISyntaxException {
|
||||
public void confirmSignature() throws XMLSignatureException, MarshalException {
|
||||
Document document = DocumentHelper.createDocument();
|
||||
|
||||
// operate
|
||||
@ -335,33 +324,6 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
};
|
||||
}
|
||||
|
||||
public static XMLSignatureFactory getSignatureFactory() {
|
||||
return XMLSignatureFactory.getInstance("DOM", getProvider());
|
||||
}
|
||||
|
||||
public static KeyInfoFactory getKeyInfoFactory() {
|
||||
return KeyInfoFactory.getInstance("DOM", getProvider());
|
||||
}
|
||||
|
||||
// currently classes are linked to Apache Santuario, so this might be superfluous
|
||||
public static Provider getProvider() {
|
||||
String dsigProviderNames[] = {
|
||||
System.getProperty("jsr105Provider"),
|
||||
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", // Santuario xmlsec
|
||||
"org.jcp.xml.dsig.internal.dom.XMLDSigRI" // JDK xmlsec
|
||||
};
|
||||
for (String pn : dsigProviderNames) {
|
||||
if (pn == null) continue;
|
||||
try {
|
||||
return (Provider)Class.forName(pn).newInstance();
|
||||
} catch (Exception e) {
|
||||
LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+pn+"' can't be found - trying next.");
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
|
||||
}
|
||||
|
||||
protected static synchronized void initXmlProvider() {
|
||||
if (isInitialized) return;
|
||||
isInitialized = true;
|
||||
@ -381,11 +343,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public DigestInfo preSign(Document document, List<DigestInfo> digestInfos)
|
||||
throws ParserConfigurationException, NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, MarshalException,
|
||||
javax.xml.crypto.dsig.XMLSignatureException,
|
||||
TransformerFactoryConfigurationError, TransformerException,
|
||||
IOException, SAXException, NoSuchProviderException, XmlException, URISyntaxException {
|
||||
throws XMLSignatureException, MarshalException {
|
||||
signatureConfig.init(false);
|
||||
|
||||
// it's necessary to explicitly set the mdssi namespace, but the sign() method has no
|
||||
@ -413,7 +371,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
}
|
||||
xmlSignContext.setDefaultNamespacePrefix(""); // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
|
||||
|
||||
XMLSignatureFactory signatureFactory = SignatureInfo.getSignatureFactory();
|
||||
XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
|
||||
|
||||
/*
|
||||
* Add ds:References that come from signing client local files.
|
||||
@ -422,13 +380,9 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
for (DigestInfo digestInfo : safe(digestInfos)) {
|
||||
byte[] documentDigestValue = digestInfo.digestValue;
|
||||
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod
|
||||
(signatureConfig.getDigestMethodUri(), null);
|
||||
|
||||
String uri = new File(digestInfo.description).getName();
|
||||
|
||||
Reference reference = signatureFactory.newReference
|
||||
(uri, digestMethod, null, null, null, documentDigestValue);
|
||||
Reference reference = SignatureFacet.newReference
|
||||
(uri, null, null, null, documentDigestValue, signatureConfig);
|
||||
references.add(reference);
|
||||
}
|
||||
|
||||
@ -438,19 +392,24 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
List<XMLObject> objects = new ArrayList<XMLObject>();
|
||||
for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
|
||||
LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
|
||||
signatureFacet.preSign(document, signatureFactory, references, objects);
|
||||
signatureFacet.preSign(document, references, objects);
|
||||
}
|
||||
|
||||
/*
|
||||
* ds:SignedInfo
|
||||
*/
|
||||
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod
|
||||
(signatureConfig.getSignatureMethod(), null);
|
||||
CanonicalizationMethod canonicalizationMethod = signatureFactory
|
||||
.newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(),
|
||||
(C14NMethodParameterSpec) null);
|
||||
SignedInfo signedInfo = signatureFactory.newSignedInfo(
|
||||
canonicalizationMethod, signatureMethod, references);
|
||||
SignedInfo signedInfo;
|
||||
try {
|
||||
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod
|
||||
(signatureConfig.getSignatureMethod(), null);
|
||||
CanonicalizationMethod canonicalizationMethod = signatureFactory
|
||||
.newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(),
|
||||
(C14NMethodParameterSpec) null);
|
||||
signedInfo = signatureFactory.newSignedInfo(
|
||||
canonicalizationMethod, signatureMethod, references);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* JSR105 ds:Signature creation
|
||||
@ -524,7 +483,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
* Normally {@link #confirmSignature()} is sufficient to be used.
|
||||
*/
|
||||
public void postSign(Document document, byte[] signatureValue)
|
||||
throws IOException, MarshalException, ParserConfigurationException, XmlException {
|
||||
throws MarshalException {
|
||||
LOG.log(POILogger.DEBUG, "postSign");
|
||||
|
||||
/*
|
||||
@ -554,7 +513,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
writeDocument(document);
|
||||
}
|
||||
|
||||
protected void writeDocument(Document document) throws IOException, XmlException {
|
||||
protected void writeDocument(Document document) throws MarshalException {
|
||||
XmlOptions xo = new XmlOptions();
|
||||
Map<String,String> namespaceMap = new HashMap<String,String>();
|
||||
for(Map.Entry<String,String> entry : signatureConfig.getNamespacePrefixes().entrySet()){
|
||||
@ -578,7 +537,7 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
// <Default Extension="sigs" ContentType="application/vnd.openxmlformats-package.digital-signature-origin"/>
|
||||
sigsPartName = PackagingURIHelper.createPartName("/_xmlsignatures/origin.sigs");
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new IOException(e);
|
||||
throw new MarshalException(e);
|
||||
}
|
||||
|
||||
PackagePart sigPart = pkg.getPart(sigPartName);
|
||||
@ -586,10 +545,14 @@ public class SignatureInfo implements SignatureConfigurable {
|
||||
sigPart = pkg.createPart(sigPartName, ContentTypes.DIGITAL_SIGNATURE_XML_SIGNATURE_PART);
|
||||
}
|
||||
|
||||
OutputStream os = sigPart.getOutputStream();
|
||||
SignatureDocument sigDoc = SignatureDocument.Factory.parse(document);
|
||||
sigDoc.save(os, xo);
|
||||
os.close();
|
||||
try {
|
||||
OutputStream os = sigPart.getOutputStream();
|
||||
SignatureDocument sigDoc = SignatureDocument.Factory.parse(document);
|
||||
sigDoc.save(os, xo);
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
throw new MarshalException("Unable to write signature document", e);
|
||||
}
|
||||
|
||||
PackagePart sigsPart = pkg.getPart(sigsPartName);
|
||||
if (sigsPart == null) {
|
||||
|
@ -24,20 +24,15 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
@ -46,39 +41,20 @@ import org.w3c.dom.Document;
|
||||
* @author Frank Cornelis
|
||||
*
|
||||
*/
|
||||
public class EnvelopedSignatureFacet implements SignatureFacet {
|
||||
|
||||
private SignatureConfig signatureConfig;
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postSign(Document document) {
|
||||
// empty
|
||||
}
|
||||
public class EnvelopedSignatureFacet extends SignatureFacet {
|
||||
|
||||
@Override
|
||||
public void preSign(Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod
|
||||
(signatureConfig.getDigestMethodUri(), null);
|
||||
|
||||
throws XMLSignatureException {
|
||||
List<Transform> transforms = new ArrayList<Transform>();
|
||||
Transform envelopedTransform = signatureFactory.newTransform
|
||||
(CanonicalizationMethod.ENVELOPED, (TransformParameterSpec) null);
|
||||
Transform envelopedTransform = newTransform(CanonicalizationMethod.ENVELOPED);
|
||||
transforms.add(envelopedTransform);
|
||||
Transform exclusiveTransform = signatureFactory.newTransform
|
||||
(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
|
||||
Transform exclusiveTransform = newTransform(CanonicalizationMethod.EXCLUSIVE);
|
||||
transforms.add(exclusiveTransform);
|
||||
|
||||
Reference reference = signatureFactory.newReference("", digestMethod,
|
||||
transforms, null, null);
|
||||
|
||||
Reference reference = newReference("", transforms, null, null, null);
|
||||
references.add(reference);
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,8 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -35,9 +33,6 @@ import java.util.Map;
|
||||
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.dom.DOMStructure;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
||||
@ -45,8 +40,6 @@ import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
|
||||
import org.apache.jcp.xml.dsig.internal.dom.DOMKeyInfo;
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.w3c.dom.Document;
|
||||
@ -60,16 +53,10 @@ import org.w3c.dom.NodeList;
|
||||
* @author Frank Cornelis
|
||||
*
|
||||
*/
|
||||
public class KeyInfoSignatureFacet implements SignatureFacet {
|
||||
public class KeyInfoSignatureFacet extends SignatureFacet {
|
||||
|
||||
private static final POILogger LOG = POILogFactory.getLogger(KeyInfoSignatureFacet.class);
|
||||
|
||||
SignatureConfig signatureConfig;
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postSign(Document document)
|
||||
throws MarshalException {
|
||||
@ -86,7 +73,7 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
|
||||
/*
|
||||
* Construct the ds:KeyInfo element using JSR 105.
|
||||
*/
|
||||
KeyInfoFactory keyInfoFactory = SignatureInfo.getKeyInfoFactory();
|
||||
KeyInfoFactory keyInfoFactory = signatureConfig.getKeyInfoFactory();
|
||||
List<Object> x509DataObjects = new ArrayList<Object>();
|
||||
X509Certificate signingCertificate = signatureConfig.getSigningCertificateChain().get(0);
|
||||
|
||||
@ -104,8 +91,8 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
|
||||
|
||||
if (signatureConfig.isIncludeIssuerSerial()) {
|
||||
x509DataObjects.add(keyInfoFactory.newX509IssuerSerial(
|
||||
signingCertificate.getIssuerX500Principal().toString(),
|
||||
signingCertificate.getSerialNumber()));
|
||||
signingCertificate.getIssuerX500Principal().toString(),
|
||||
signingCertificate.getSerialNumber()));
|
||||
}
|
||||
|
||||
if (signatureConfig.isIncludeEntireCertificateChain()) {
|
||||
@ -155,14 +142,4 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
|
||||
nextSibling.getParentNode().insertBefore(kiNl.item(0), nextSibling);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSign(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects
|
||||
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
// empty
|
||||
}
|
||||
}
|
@ -24,11 +24,8 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
@ -41,15 +38,13 @@ import javax.xml.XMLConstants;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dom.DOMStructure;
|
||||
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.SignatureProperties;
|
||||
import javax.xml.crypto.dsig.SignatureProperty;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.ContentTypes;
|
||||
@ -60,12 +55,10 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.CTSignatureTime;
|
||||
import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.SignatureTimeDocument;
|
||||
import org.w3c.dom.Document;
|
||||
@ -80,64 +73,50 @@ import com.microsoft.schemas.office.x2006.digsig.SignatureInfoV1Document;
|
||||
* @author fcorneli
|
||||
* @see <a href="http://msdn.microsoft.com/en-us/library/cc313071.aspx">[MS-OFFCRYPTO]: Office Document Cryptography Structure</a>
|
||||
*/
|
||||
public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
public class OOXMLSignatureFacet extends SignatureFacet {
|
||||
|
||||
private static final POILogger LOG = POILogFactory.getLogger(OOXMLSignatureFacet.class);
|
||||
|
||||
private SignatureConfig signatureConfig;
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSign(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException {
|
||||
throws XMLSignatureException {
|
||||
LOG.log(POILogger.DEBUG, "pre sign");
|
||||
addManifestObject(document, signatureFactory, references, objects);
|
||||
addSignatureInfo(document, signatureFactory, references, objects);
|
||||
addManifestObject(document, references, objects);
|
||||
addSignatureInfo(document, references, objects);
|
||||
}
|
||||
|
||||
protected void addManifestObject(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException {
|
||||
throws XMLSignatureException {
|
||||
|
||||
List<Reference> manifestReferences = new ArrayList<Reference>();
|
||||
addManifestReferences(signatureFactory, manifestReferences);
|
||||
Manifest manifest = signatureFactory.newManifest(manifestReferences);
|
||||
addManifestReferences(manifestReferences);
|
||||
Manifest manifest = getSignatureFactory().newManifest(manifestReferences);
|
||||
|
||||
String objectId = "idPackageObject"; // really has to be this value.
|
||||
List<XMLStructure> objectContent = new ArrayList<XMLStructure>();
|
||||
objectContent.add(manifest);
|
||||
|
||||
addSignatureTime(document, signatureFactory, objectContent);
|
||||
addSignatureTime(document, objectContent);
|
||||
|
||||
XMLObject xo = signatureFactory.newXMLObject(objectContent, objectId, null, null);
|
||||
XMLObject xo = getSignatureFactory().newXMLObject(objectContent, objectId, null, null);
|
||||
objects.add(xo);
|
||||
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod
|
||||
(signatureConfig.getDigestMethodUri(), null);
|
||||
Reference reference = signatureFactory.newReference
|
||||
("#" + objectId, digestMethod, null, XML_DIGSIG_NS+"Object", null);
|
||||
Reference reference = newReference("#" + objectId, null, XML_DIGSIG_NS+"Object", null, null);
|
||||
references.add(reference);
|
||||
}
|
||||
|
||||
protected void addManifestReferences
|
||||
(XMLSignatureFactory signatureFactory, List<Reference> manifestReferences)
|
||||
throws IOException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, URISyntaxException, XmlException {
|
||||
protected void addManifestReferences(List<Reference> manifestReferences)
|
||||
throws XMLSignatureException {
|
||||
|
||||
OPCPackage ooxml = signatureConfig.getOpcPackage();
|
||||
List<PackagePart> relsEntryNames = ooxml.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART);
|
||||
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod
|
||||
(signatureConfig.getDigestMethodUri(), null);
|
||||
Set<String> digestedPartNames = new HashSet<String>();
|
||||
for (PackagePart pp : relsEntryNames) {
|
||||
String baseUri = pp.getPartName().getName().replaceFirst("(.*)/_rels/.*", "$1");
|
||||
@ -147,7 +126,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
prc = new PackageRelationshipCollection(ooxml);
|
||||
prc.parseRelationshipsPart(pp);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new IOException("Invalid relationship descriptor: "+pp.getPartName().getName(), e);
|
||||
throw new XMLSignatureException("Invalid relationship descriptor: "+pp.getPartName().getName(), e);
|
||||
}
|
||||
|
||||
RelationshipTransformParameterSpec parameterSpec = new RelationshipTransformParameterSpec();
|
||||
@ -169,8 +148,12 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
|
||||
// TODO: find a better way ...
|
||||
String partName = baseUri + relationship.getTargetURI().toString();
|
||||
partName = new URI(partName).normalize().getPath().replace('\\', '/');
|
||||
LOG.log(POILogger.DEBUG, "part name: " + partName);
|
||||
try {
|
||||
partName = new URI(partName).normalize().getPath().replace('\\', '/');
|
||||
LOG.log(POILogger.DEBUG, "part name: " + partName);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
}
|
||||
|
||||
String contentType;
|
||||
try {
|
||||
@ -178,7 +161,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
PackagePart pp2 = ooxml.getPart(relName);
|
||||
contentType = pp2.getContentType();
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new IOException(e);
|
||||
throw new XMLSignatureException(e);
|
||||
}
|
||||
|
||||
if (relationshipType.endsWith("customXml")
|
||||
@ -190,7 +173,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
if (!digestedPartNames.contains(partName)) {
|
||||
// We only digest a part once.
|
||||
String uri = partName + "?ContentType=" + contentType;
|
||||
Reference reference = signatureFactory.newReference(uri, digestMethod);
|
||||
Reference reference = newReference(uri, null, null, null, null);
|
||||
manifestReferences.add(reference);
|
||||
digestedPartNames.add(partName);
|
||||
}
|
||||
@ -198,25 +181,18 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
|
||||
if (parameterSpec.hasSourceIds()) {
|
||||
List<Transform> transforms = new ArrayList<Transform>();
|
||||
transforms.add(signatureFactory.newTransform(
|
||||
RelationshipTransformService.TRANSFORM_URI,
|
||||
parameterSpec));
|
||||
transforms.add(signatureFactory.newTransform(
|
||||
CanonicalizationMethod.INCLUSIVE,
|
||||
(TransformParameterSpec) null));
|
||||
transforms.add(newTransform(RelationshipTransformService.TRANSFORM_URI, parameterSpec));
|
||||
transforms.add(newTransform(CanonicalizationMethod.INCLUSIVE));
|
||||
String uri = pp.getPartName().getName()
|
||||
+ "?ContentType=application/vnd.openxmlformats-package.relationships+xml";
|
||||
Reference reference = signatureFactory.newReference(uri, digestMethod, transforms, null, null);
|
||||
Reference reference = newReference(uri, transforms, null, null, null);
|
||||
manifestReferences.add(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void addSignatureTime(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<XMLStructure> objectContent) {
|
||||
protected void addSignatureTime(Document document, List<XMLStructure> objectContent) {
|
||||
/*
|
||||
* SignatureTime
|
||||
*/
|
||||
@ -233,22 +209,21 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
Element n = (Element)document.importNode(ctTime.getDomNode(),true);
|
||||
List<XMLStructure> signatureTimeContent = new ArrayList<XMLStructure>();
|
||||
signatureTimeContent.add(new DOMStructure(n));
|
||||
SignatureProperty signatureTimeSignatureProperty = signatureFactory
|
||||
SignatureProperty signatureTimeSignatureProperty = getSignatureFactory()
|
||||
.newSignatureProperty(signatureTimeContent, "#" + signatureConfig.getPackageSignatureId(),
|
||||
"idSignatureTime");
|
||||
List<SignatureProperty> signaturePropertyContent = new ArrayList<SignatureProperty>();
|
||||
signaturePropertyContent.add(signatureTimeSignatureProperty);
|
||||
SignatureProperties signatureProperties = signatureFactory
|
||||
SignatureProperties signatureProperties = getSignatureFactory()
|
||||
.newSignatureProperties(signaturePropertyContent,
|
||||
"id-signature-time-" + signatureConfig.getExecutionTime());
|
||||
objectContent.add(signatureProperties);
|
||||
}
|
||||
|
||||
protected void addSignatureInfo(Document document,
|
||||
XMLSignatureFactory signatureFactory,
|
||||
List<Reference> references,
|
||||
List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
throws XMLSignatureException {
|
||||
List<XMLStructure> objectContent = new ArrayList<XMLStructure>();
|
||||
|
||||
SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance();
|
||||
@ -259,31 +234,23 @@ public class OOXMLSignatureFacet implements SignatureFacet {
|
||||
|
||||
List<XMLStructure> signatureInfoContent = new ArrayList<XMLStructure>();
|
||||
signatureInfoContent.add(new DOMStructure(n));
|
||||
SignatureProperty signatureInfoSignatureProperty = signatureFactory
|
||||
SignatureProperty signatureInfoSignatureProperty = getSignatureFactory()
|
||||
.newSignatureProperty(signatureInfoContent, "#" + signatureConfig.getPackageSignatureId(),
|
||||
"idOfficeV1Details");
|
||||
|
||||
List<SignatureProperty> signaturePropertyContent = new ArrayList<SignatureProperty>();
|
||||
signaturePropertyContent.add(signatureInfoSignatureProperty);
|
||||
SignatureProperties signatureProperties = signatureFactory
|
||||
SignatureProperties signatureProperties = getSignatureFactory()
|
||||
.newSignatureProperties(signaturePropertyContent, null);
|
||||
objectContent.add(signatureProperties);
|
||||
|
||||
String objectId = "idOfficeObject";
|
||||
objects.add(signatureFactory.newXMLObject(objectContent, objectId, null, null));
|
||||
objects.add(getSignatureFactory().newXMLObject(objectContent, objectId, null, null));
|
||||
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod
|
||||
(signatureConfig.getDigestMethodUri(), null);
|
||||
Reference reference = signatureFactory.newReference
|
||||
("#" + objectId, digestMethod, null, XML_DIGSIG_NS+"Object", null);
|
||||
Reference reference = newReference("#" + objectId, null, XML_DIGSIG_NS+"Object", null, null);
|
||||
references.add(reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postSign(Document document) {
|
||||
// empty
|
||||
}
|
||||
|
||||
protected static String getRelationshipReferenceURI(String zipEntryName) {
|
||||
return "/"
|
||||
+ zipEntryName
|
||||
|
@ -24,15 +24,8 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
|
||||
import org.etsi.uri.x01903.v13.UnsignedPropertiesType;
|
||||
@ -50,32 +43,23 @@ import org.w3c.dom.NodeList;
|
||||
* @author Frank Cornelis
|
||||
*
|
||||
*/
|
||||
public class Office2010SignatureFacet implements SignatureFacet {
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
// this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSign(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects
|
||||
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
}
|
||||
public class Office2010SignatureFacet extends SignatureFacet {
|
||||
|
||||
@Override
|
||||
public void postSign(Document document)
|
||||
throws XmlException {
|
||||
throws MarshalException {
|
||||
// check for XAdES-BES
|
||||
NodeList nl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties");
|
||||
if (nl.getLength() != 1) {
|
||||
throw new IllegalArgumentException("no XAdES-BES extension present");
|
||||
throw new MarshalException("no XAdES-BES extension present");
|
||||
}
|
||||
|
||||
QualifyingPropertiesType qualProps =
|
||||
QualifyingPropertiesType.Factory.parse(nl.item(0));
|
||||
QualifyingPropertiesType qualProps;
|
||||
try {
|
||||
qualProps = QualifyingPropertiesType.Factory.parse(nl.item(0));
|
||||
} catch (XmlException e) {
|
||||
throw new MarshalException(e);
|
||||
}
|
||||
|
||||
// create basic XML container structure
|
||||
UnsignedPropertiesType unsignedProps = qualProps.getUnsignedProperties();
|
||||
|
@ -24,39 +24,43 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* JSR105 Signature Facet interface.
|
||||
*
|
||||
* @author Frank Cornelis
|
||||
*
|
||||
* JSR105 Signature Facet base class.
|
||||
*/
|
||||
public interface SignatureFacet extends SignatureConfigurable {
|
||||
public abstract class SignatureFacet implements SignatureConfigurable {
|
||||
|
||||
String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
|
||||
String XML_DIGSIG_NS = XMLSignature.XMLNS;
|
||||
String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE;
|
||||
String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";
|
||||
String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#";
|
||||
String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#";
|
||||
public static final String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
|
||||
public static final String XML_DIGSIG_NS = XMLSignature.XMLNS;
|
||||
public static final String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE;
|
||||
public static final String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";
|
||||
public static final String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#";
|
||||
public static final String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#";
|
||||
|
||||
protected SignatureConfig signatureConfig;
|
||||
protected ThreadLocal<XMLSignatureFactory> signatureFactory;
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is being invoked by the XML signature service engine during
|
||||
@ -64,21 +68,17 @@ public interface SignatureFacet extends SignatureConfigurable {
|
||||
* signature facets to an XML signature.
|
||||
*
|
||||
* @param document the signature document to be used for imports
|
||||
* @param signatureFactory the signature factory
|
||||
* @param references list of reference definitions
|
||||
* @param objects objects to be signed/included in the signature document
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* @throws IOException
|
||||
* @throws URISyntaxException
|
||||
* @throws XmlException
|
||||
* @throws XMLSignatureException
|
||||
*/
|
||||
void preSign(
|
||||
public void preSign(
|
||||
Document document
|
||||
, XMLSignatureFactory signatureFactory
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects
|
||||
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException;
|
||||
) throws XMLSignatureException {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is being invoked by the XML signature service engine during
|
||||
@ -87,9 +87,59 @@ public interface SignatureFacet extends SignatureConfigurable {
|
||||
*
|
||||
* @param document the signature document to be modified
|
||||
* @throws MarshalException
|
||||
* @throws XmlException
|
||||
*/
|
||||
void postSign(
|
||||
Document document
|
||||
) throws MarshalException, XmlException;
|
||||
public void postSign(Document document) throws MarshalException {
|
||||
// empty
|
||||
}
|
||||
|
||||
protected XMLSignatureFactory getSignatureFactory() {
|
||||
return signatureConfig.getSignatureFactory();
|
||||
}
|
||||
|
||||
protected Transform newTransform(String canonicalizationMethod) throws XMLSignatureException {
|
||||
return newTransform(canonicalizationMethod, null);
|
||||
}
|
||||
|
||||
protected Transform newTransform(String canonicalizationMethod, TransformParameterSpec paramSpec)
|
||||
throws XMLSignatureException {
|
||||
try {
|
||||
return getSignatureFactory().newTransform(canonicalizationMethod, paramSpec);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new XMLSignatureException("unknown canonicalization method: "+canonicalizationMethod, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Reference newReference(String uri, List<Transform> transforms, String type, String id, byte digestValue[])
|
||||
throws XMLSignatureException {
|
||||
return newReference(uri, transforms, type, id, digestValue, signatureConfig);
|
||||
}
|
||||
|
||||
public static Reference newReference(
|
||||
String uri
|
||||
, List<Transform> transforms
|
||||
, String type
|
||||
, String id
|
||||
, byte digestValue[]
|
||||
, SignatureConfig signatureConfig)
|
||||
throws XMLSignatureException {
|
||||
// the references appear in the package signature or the package object
|
||||
// so we can use the default digest algorithm
|
||||
String digestMethodUri = signatureConfig.getDigestMethodUri();
|
||||
XMLSignatureFactory sigFac = signatureConfig.getSignatureFactory();
|
||||
DigestMethod digestMethod;
|
||||
try {
|
||||
digestMethod = sigFac.newDigestMethod(digestMethodUri, null);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new XMLSignatureException("unknown digest method uri: "+digestMethodUri, e);
|
||||
}
|
||||
|
||||
Reference reference;
|
||||
if (digestValue == null) {
|
||||
reference = sigFac.newReference(uri, digestMethod, transforms, type, id);
|
||||
} else {
|
||||
reference = sigFac.newReference(uri, digestMethod, transforms, type, id, digestValue);
|
||||
}
|
||||
|
||||
return reference;
|
||||
}
|
||||
}
|
@ -24,9 +24,7 @@
|
||||
|
||||
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
@ -39,12 +37,10 @@ import java.util.TimeZone;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dom.DOMStructure;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
|
||||
import org.apache.poi.poifs.crypt.CryptoFunctions;
|
||||
import org.apache.poi.poifs.crypt.HashAlgorithm;
|
||||
@ -89,30 +85,21 @@ import org.w3c.dom.Element;
|
||||
* @see <a href="http://en.wikipedia.org/wiki/XAdES">XAdES</a>
|
||||
*
|
||||
*/
|
||||
public class XAdESSignatureFacet implements SignatureFacet {
|
||||
public class XAdESSignatureFacet extends SignatureFacet {
|
||||
|
||||
private static final POILogger LOG = POILogFactory.getLogger(XAdESSignatureFacet.class);
|
||||
|
||||
private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties";
|
||||
|
||||
private SignatureConfig signatureConfig;
|
||||
|
||||
private Map<String, String> dataObjectFormatMimeTypes = new HashMap<String, String>();
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postSign(Document document) {
|
||||
LOG.log(POILogger.DEBUG, "postSign");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSign(Document document,
|
||||
XMLSignatureFactory signatureFactory,
|
||||
List<Reference> references, List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
public void preSign(
|
||||
Document document
|
||||
, List<Reference> references
|
||||
, List<XMLObject> objects)
|
||||
throws XMLSignatureException {
|
||||
LOG.log(POILogger.DEBUG, "preSign");
|
||||
|
||||
// QualifyingProperties
|
||||
@ -209,18 +196,15 @@ public class XAdESSignatureFacet implements SignatureFacet {
|
||||
Element qualDocElSrc = (Element)qualifyingProperties.getDomNode();
|
||||
Element qualDocEl = (Element)document.importNode(qualDocElSrc, true);
|
||||
xadesObjectContent.add(new DOMStructure(qualDocEl));
|
||||
XMLObject xadesObject = signatureFactory.newXMLObject(xadesObjectContent, null, null, null);
|
||||
XMLObject xadesObject = getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null);
|
||||
objects.add(xadesObject);
|
||||
|
||||
// add XAdES ds:Reference
|
||||
DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestMethodUri(), null);
|
||||
List<Transform> transforms = new ArrayList<Transform>();
|
||||
Transform exclusiveTransform = signatureFactory
|
||||
.newTransform(CanonicalizationMethod.INCLUSIVE,
|
||||
(TransformParameterSpec) null);
|
||||
Transform exclusiveTransform = newTransform(CanonicalizationMethod.INCLUSIVE);
|
||||
transforms.add(exclusiveTransform);
|
||||
Reference reference = signatureFactory.newReference
|
||||
("#"+signatureConfig.getXadesSignatureId(), digestMethod, transforms, XADES_TYPE, null);
|
||||
Reference reference = newReference
|
||||
("#"+signatureConfig.getXadesSignatureId(), transforms, XADES_TYPE, null, null);
|
||||
references.add(reference);
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,6 @@ import static org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet.insertX
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
@ -43,12 +41,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.XMLObject;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
|
||||
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
|
||||
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
@ -106,20 +101,14 @@ import org.w3c.dom.NodeList;
|
||||
* @author Frank Cornelis
|
||||
* @see XAdESSignatureFacet
|
||||
*/
|
||||
public class XAdESXLSignatureFacet implements SignatureFacet {
|
||||
public class XAdESXLSignatureFacet extends SignatureFacet {
|
||||
|
||||
private static final POILogger LOG = POILogFactory.getLogger(XAdESXLSignatureFacet.class);
|
||||
|
||||
private SignatureConfig signatureConfig;
|
||||
|
||||
private String c14nAlgoId = CanonicalizationMethod.EXCLUSIVE;
|
||||
|
||||
private final CertificateFactory certificateFactory;
|
||||
|
||||
public void setSignatureConfig(SignatureConfig signatureConfig) {
|
||||
this.signatureConfig = signatureConfig;
|
||||
}
|
||||
|
||||
public XAdESXLSignatureFacet() {
|
||||
try {
|
||||
this.certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
@ -133,7 +122,7 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postSign(Document document) throws XmlException {
|
||||
public void postSign(Document document) throws MarshalException {
|
||||
LOG.log(POILogger.DEBUG, "XAdES-X-L post sign phase");
|
||||
|
||||
QualifyingPropertiesDocument qualDoc = null;
|
||||
@ -142,10 +131,14 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
|
||||
// check for XAdES-BES
|
||||
NodeList qualNl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties");
|
||||
if (qualNl.getLength() == 1) {
|
||||
qualDoc = QualifyingPropertiesDocument.Factory.parse(qualNl.item(0));
|
||||
try {
|
||||
qualDoc = QualifyingPropertiesDocument.Factory.parse(qualNl.item(0));
|
||||
} catch (XmlException e) {
|
||||
throw new MarshalException(e);
|
||||
}
|
||||
qualProps = qualDoc.getQualifyingProperties();
|
||||
} else {
|
||||
throw new IllegalArgumentException("no XAdES-BES extension present");
|
||||
throw new MarshalException("no XAdES-BES extension present");
|
||||
}
|
||||
|
||||
// create basic XML container structure
|
||||
@ -335,14 +328,6 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
|
||||
return c14nValue.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSign(Document document,
|
||||
XMLSignatureFactory signatureFactory,
|
||||
List<Reference> references, List<XMLObject> objects)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
private BigInteger getCrlNumber(X509CRL crl) {
|
||||
try {
|
||||
byte[] crlNumberExtensionValue = crl.getExtensionValue(Extension.cRLNumber.getId());
|
||||
|
Loading…
Reference in New Issue
Block a user