removed HorribleProxy

added current version of BouncyCastle and xmlsec (using xmlsec instead of jdk internal classes, because of interoperabiltiy with e.g. IBM JDK)
heaps of changes because of above

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1620230 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-08-24 23:06:05 +00:00
parent d0cc2e4267
commit 687194fd91
13 changed files with 365 additions and 458 deletions

View File

@ -3,7 +3,7 @@ package org.apache.poi.poifs.crypt.dsig.facets;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -16,7 +16,7 @@ import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3c.dom.Document;
/**
* Signature Facet implementation to create enveloped signatures.
@ -47,13 +47,13 @@ public class EnvelopedSignatureFacet implements SignatureFacet {
}
@Override
public void postSign(SignatureType signatureElement
, List<X509Certificate> signingCertificateChain) {
public void postSign(Document document, List<X509Certificate> signingCertificateChain) {
// empty
}
@Override
public void preSign(XMLSignatureFactory signatureFactory,
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references, List<XMLObject> objects)
@ -61,7 +61,7 @@ public class EnvelopedSignatureFacet implements SignatureFacet {
DigestMethod digestMethod = signatureFactory.newDigestMethod(
this.hashAlgo.xmlSignUri, null);
List<Transform> transforms = new LinkedList<Transform>();
List<Transform> transforms = new ArrayList<Transform>();
Transform envelopedTransform = signatureFactory
.newTransform(CanonicalizationMethod.ENVELOPED,
(TransformParameterSpec) null);

View File

@ -24,19 +24,21 @@
package org.apache.poi.poifs.crypt.dsig.facets;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureFactory;
@ -46,13 +48,14 @@ import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMKeyInfoIf;
import org.apache.jcp.xml.dsig.internal.dom.DOMKeyInfo;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.w3.x2000.x09.xmldsig.ObjectType;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Signature Facet implementation that adds ds:KeyInfo to the XML signature.
@ -84,34 +87,27 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
this.includeKeyValue = includeKeyValue;
}
public void postSign(SignatureType signatureElement,
List<X509Certificate> signingCertificateChain) {
@Override
public void postSign(Document document, List<X509Certificate> signingCertificateChain)
throws MarshalException {
LOG.log(POILogger.DEBUG, "postSign");
List<ObjectType> objList = signatureElement.getObjectList();
NodeList nl = document.getElementsByTagNameNS(XmlDSigNS, "Object");
/*
* Make sure we insert right after the ds:SignatureValue element, just
* before the first ds:Object element.
*/
Node nextSibling = (objList.isEmpty()) ? null : objList.get(0).getDomNode();
Node nextSibling = (nl.getLength() == 0) ? null : nl.item(0);
/*
* Construct the ds:KeyInfo element using JSR 105.
*/
String providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
Provider xmlDSigProv;
try {
xmlDSigProv = (Provider) Class.forName(providerName).newInstance();
} catch (Exception e) {
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!", e);
}
KeyInfoFactory keyInfoFactory = KeyInfoFactory.getInstance("DOM", xmlDSigProv);
List<Object> x509DataObjects = new LinkedList<Object>();
KeyInfoFactory keyInfoFactory = SignatureInfo.getKeyInfoFactory();
List<Object> x509DataObjects = new ArrayList<Object>();
X509Certificate signingCertificate = signingCertificateChain.get(0);
List<Object> keyInfoContent = new LinkedList<Object>();
List<Object> keyInfoContent = new ArrayList<Object>();
if (this.includeKeyValue) {
KeyValue keyValue;
@ -130,24 +126,17 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
}
if (this.includeEntireCertificateChain) {
for (X509Certificate certificate : signingCertificateChain) {
x509DataObjects.add(certificate);
}
x509DataObjects.addAll(signingCertificateChain);
} else {
x509DataObjects.add(signingCertificate);
}
if (false == x509DataObjects.isEmpty()) {
if (!x509DataObjects.isEmpty()) {
X509Data x509Data = keyInfoFactory.newX509Data(x509DataObjects);
keyInfoContent.add(x509Data);
}
KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoContent);
DOMKeyInfoIf domKeyInfo;
try {
domKeyInfo = HorribleProxy.newProxy(DOMKeyInfoIf.class, keyInfo);
} catch (Exception e) {
throw new RuntimeException("DOMKeyInfo instance error: " + e.getMessage(), e);
}
DOMKeyInfo domKeyInfo = (DOMKeyInfo)keyInfo;
Key key = new Key() {
private static final long serialVersionUID = 1L;
@ -165,18 +154,27 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
}
};
DOMSignContext domSignContext = new DOMSignContext(key, signatureElement.getDomNode());
Element n = document.getDocumentElement();
DOMSignContext domSignContext = new DOMSignContext(key, n, nextSibling);
DOMCryptoContext domCryptoContext = domSignContext;
String signatureNamespacePrefix = "xd";
try {
domKeyInfo.marshal(signatureElement.getDomNode(), nextSibling,
signatureNamespacePrefix, domCryptoContext);
} catch (MarshalException e) {
throw new RuntimeException("marshall error: " + e.getMessage(), e);
domCryptoContext.putNamespacePrefix(XmlDSigNS, "xd");
DOMStructure domStructure = new DOMStructure(n);
// how to set nextSibling??? - marshal is ignoring nextSibling in DOMSignContext
domKeyInfo.marshal(domStructure, domCryptoContext);
// move keyinfo into the right place
if (nextSibling != null) {
NodeList kiNl = document.getElementsByTagNameNS(XmlDSigNS, "KeyInfo");
if (kiNl.getLength() != 1) {
throw new RuntimeException("KeyInfo wasn't set");
}
nextSibling.getParentNode().insertBefore(kiNl.item(0), nextSibling);
}
}
public void preSign(XMLSignatureFactory signatureFactory,
@Override
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references,
@ -187,7 +185,7 @@ public class KeyInfoSignatureFacet implements SignatureFacet {
public Map<String,String> getNamespacePrefixMapping() {
Map<String,String> map = new HashMap<String,String>();
// map.put("xd", "http://www.w3.org/2000/09/xmldsig#");
// map.put("xd", XmlDSigNS);
return map;
}

View File

@ -24,6 +24,8 @@
package org.apache.poi.poifs.crypt.dsig.facets;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlNS;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.setPrefix;
import java.io.IOException;
@ -38,7 +40,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -71,15 +72,13 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
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.XmlSignatureService;
import org.apache.poi.poifs.crypt.dsig.spi.Constants;
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.w3.x2000.x09.xmldsig.SignatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.microsoft.schemas.office.x2006.digsig.CTSignatureInfoV1;
import com.microsoft.schemas.office.x2006.digsig.SignatureInfoV1Document;
@ -112,50 +111,43 @@ public class OOXMLSignatureFacet implements SignatureFacet {
this.hashAlgo = (hashAlgo == null ? HashAlgorithm.sha1 : hashAlgo);
}
public void preSign(XMLSignatureFactory signatureFactory,
@Override
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references, List<XMLObject> objects)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException {
LOG.log(POILogger.DEBUG, "pre sign");
addManifestObject(signatureFactory, signatureId, references, objects);
addSignatureInfo(signatureFactory, signatureId, references, objects);
addManifestObject(document, signatureFactory, signatureId, references, objects);
addSignatureInfo(document, signatureFactory, signatureId, references, objects);
}
private void addManifestObject(XMLSignatureFactory signatureFactory,
private void addManifestObject(Document document,
XMLSignatureFactory signatureFactory,
String signatureId, List<Reference> references,
List<XMLObject> objects) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
Manifest manifest = constructManifest(signatureFactory);
InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException {
List<Reference> manifestReferences = new ArrayList<Reference>();
addManifestReferences(signatureFactory, manifestReferences);
Manifest manifest = signatureFactory.newManifest(manifestReferences);
String objectId = "idPackageObject"; // really has to be this value.
List<XMLStructure> objectContent = new LinkedList<XMLStructure>();
List<XMLStructure> objectContent = new ArrayList<XMLStructure>();
objectContent.add(manifest);
addSignatureTime(signatureFactory, signatureId, objectContent);
addSignatureTime(document, signatureFactory, signatureId, objectContent);
objects.add(signatureFactory.newXMLObject(objectContent, objectId,
null, null));
XMLObject xo = signatureFactory.newXMLObject(objectContent, objectId, null, null);
objects.add(xo);
DigestMethod digestMethod = signatureFactory.newDigestMethod(this.hashAlgo.xmlSignUri, null);
Reference reference = signatureFactory.newReference("#" + objectId,
digestMethod, null, "http://www.w3.org/2000/09/xmldsig#Object",
null);
Reference reference = signatureFactory.newReference
("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);
references.add(reference);
}
private Manifest constructManifest(XMLSignatureFactory signatureFactory)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
List<Reference> manifestReferences = new ArrayList<Reference>();
try {
addManifestReferences(signatureFactory, manifestReferences);
} catch (Exception e) {
throw new RuntimeException("error: " + e.getMessage(), e);
}
return signatureFactory.newManifest(manifestReferences);
}
private void addManifestReferences(XMLSignatureFactory signatureFactory, List<Reference> manifestReferences)
throws IOException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, URISyntaxException, XmlException {
@ -223,7 +215,7 @@ public class OOXMLSignatureFacet implements SignatureFacet {
}
if (parameterSpec.hasSourceIds()) {
List<Transform> transforms = new LinkedList<Transform>();
List<Transform> transforms = new ArrayList<Transform>();
transforms.add(signatureFactory.newTransform(
RelationshipTransformService.TRANSFORM_URI,
parameterSpec));
@ -239,7 +231,8 @@ public class OOXMLSignatureFacet implements SignatureFacet {
}
private void addSignatureTime(XMLSignatureFactory signatureFactory,
private void addSignatureTime(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<XMLStructure> objectContent) {
/*
@ -256,15 +249,15 @@ public class OOXMLSignatureFacet implements SignatureFacet {
ctTime.setValue(nowStr);
// TODO: find better method to have xmlbeans + export the prefix
Node n = ctTime.getDomNode();
setPrefix(ctTime, PackageNamespaces.DIGITAL_SIGNATURE, "mdssi");
Element n = (Element)document.importNode(ctTime.getDomNode(),true);
setPrefix(n, PackageNamespaces.DIGITAL_SIGNATURE, "mdssi");
List<XMLStructure> signatureTimeContent = new LinkedList<XMLStructure>();
List<XMLStructure> signatureTimeContent = new ArrayList<XMLStructure>();
signatureTimeContent.add(new DOMStructure(n));
SignatureProperty signatureTimeSignatureProperty = signatureFactory
.newSignatureProperty(signatureTimeContent, "#" + signatureId,
"idSignatureTime");
List<SignatureProperty> signaturePropertyContent = new LinkedList<SignatureProperty>();
List<SignatureProperty> signaturePropertyContent = new ArrayList<SignatureProperty>();
signaturePropertyContent.add(signatureTimeSignatureProperty);
SignatureProperties signatureProperties = signatureFactory
.newSignatureProperties(signaturePropertyContent,
@ -272,43 +265,42 @@ public class OOXMLSignatureFacet implements SignatureFacet {
objectContent.add(signatureProperties);
}
private void addSignatureInfo(XMLSignatureFactory signatureFactory,
private void addSignatureInfo(Document document,
XMLSignatureFactory signatureFactory,
String signatureId, List<Reference> references,
List<XMLObject> objects) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
List<XMLStructure> objectContent = new LinkedList<XMLStructure>();
List<XMLStructure> objectContent = new ArrayList<XMLStructure>();
SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance();
CTSignatureInfoV1 ctSigV1 = sigV1.addNewSignatureInfoV1();
ctSigV1.setManifestHashAlgorithm(hashAlgo.xmlSignUri);
Node n = ctSigV1.getDomNode();
((Element)n).setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig");
Element n = (Element)document.importNode(ctSigV1.getDomNode(), true);
n.setAttributeNS(XmlNS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig");
List<XMLStructure> signatureInfoContent = new LinkedList<XMLStructure>();
List<XMLStructure> signatureInfoContent = new ArrayList<XMLStructure>();
signatureInfoContent.add(new DOMStructure(n));
SignatureProperty signatureInfoSignatureProperty = signatureFactory
.newSignatureProperty(signatureInfoContent, "#" + signatureId,
"idOfficeV1Details");
List<SignatureProperty> signaturePropertyContent = new LinkedList<SignatureProperty>();
List<SignatureProperty> signaturePropertyContent = new ArrayList<SignatureProperty>();
signaturePropertyContent.add(signatureInfoSignatureProperty);
SignatureProperties signatureProperties = signatureFactory
.newSignatureProperties(signaturePropertyContent, null);
objectContent.add(signatureProperties);
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);
Reference reference = signatureFactory.newReference("#" + objectId,
digestMethod, null, "http://www.w3.org/2000/09/xmldsig#Object",
null);
Reference reference = signatureFactory.newReference
("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);
references.add(reference);
}
public void postSign(SignatureType signatureElement,
List<X509Certificate> signingCertificateChain) {
@Override
public void postSign(Document document, List<X509Certificate> signingCertificateChain) {
// empty
}

View File

@ -34,11 +34,13 @@ import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlException;
import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
import org.etsi.uri.x01903.v13.UnsignedPropertiesType;
import org.etsi.uri.x01903.v13.UnsignedSignaturePropertiesType;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Work-around for Office2010 to accept the XAdES-BES/EPES signature.
@ -51,7 +53,9 @@ import org.w3.x2000.x09.xmldsig.SignatureType;
*/
public class Office2010SignatureFacet implements SignatureFacet {
public void preSign(XMLSignatureFactory signatureFactory,
@Override
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references,
@ -59,23 +63,18 @@ public class Office2010SignatureFacet implements SignatureFacet {
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
}
public void postSign(SignatureType signatureElement, List<X509Certificate> signingCertificateChain) {
QualifyingPropertiesType qualProps = null;
@Override
public void postSign(Document document, List<X509Certificate> signingCertificateChain)
throws XmlException {
// check for XAdES-BES
String qualPropXQuery =
"declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "
+ "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "
+ "$this/ds:Object/xades:QualifyingProperties";
XmlObject xoList[] = signatureElement.selectPath(qualPropXQuery);
if (xoList.length == 1) {
qualProps = (QualifyingPropertiesType)xoList[0];
}
if (qualProps == null) {
NodeList nl = document.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "QualifyingProperties");
if (nl.getLength() != 1) {
throw new IllegalArgumentException("no XAdES-BES extension present");
}
QualifyingPropertiesType qualProps =
QualifyingPropertiesType.Factory.parse(nl.item(0));
// create basic XML container structure
UnsignedPropertiesType unsignedProps = qualProps.getUnsignedProperties();
if (unsignedProps == null) {
@ -85,6 +84,9 @@ public class Office2010SignatureFacet implements SignatureFacet {
if (unsignedSigProps == null) {
unsignedSigProps = unsignedProps.addNewUnsignedSignatureProperties();
}
Node n = document.importNode(qualProps.getDomNode().getFirstChild(), true);
nl.item(0).getParentNode().replaceChild(n, nl.item(0));
}
public Map<String,String> getNamespacePrefixMapping() {

View File

@ -24,17 +24,21 @@
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.cert.X509Certificate;
import java.util.List;
import java.util.Map;
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.w3.x2000.x09.xmldsig.SignatureType;
import org.apache.xmlbeans.XmlException;
import org.w3c.dom.Document;
/**
* JSR105 Signature Facet interface.
@ -60,12 +64,13 @@ public interface SignatureFacet {
* @throws NoSuchAlgorithmException
*/
void preSign(
XMLSignatureFactory signatureFactory
Document document
, XMLSignatureFactory signatureFactory
, String signatureId
, List<X509Certificate> signingCertificateChain
, List<Reference> references
, List<XMLObject> objects
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, URISyntaxException, XmlException;
/**
* This method is being invoked by the XML signature service engine during
@ -76,8 +81,9 @@ public interface SignatureFacet {
* @param signingCertificateChain
*/
void postSign(
SignatureType signatureElement
, List<X509Certificate> signingCertificateChain);
Document document
, List<X509Certificate> signingCertificateChain
) throws MarshalException, XmlException;
Map<String,String> getNamespacePrefixMapping();
}

View File

@ -24,6 +24,7 @@
package org.apache.poi.poifs.crypt.dsig.facets;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlNS;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.setPrefix;
import java.security.InvalidAlgorithmParameterException;
@ -31,10 +32,10 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
@ -52,7 +53,7 @@ import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.spi.Constants;
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlString;
@ -74,8 +75,8 @@ import org.etsi.uri.x01903.v13.SignedPropertiesType;
import org.etsi.uri.x01903.v13.SignedSignaturePropertiesType;
import org.etsi.uri.x01903.v13.SignerRoleType;
import org.w3.x2000.x09.xmldsig.DigestMethodType;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3.x2000.x09.xmldsig.X509IssuerSerialType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
@ -133,12 +134,14 @@ public class XAdESSignatureFacet implements SignatureFacet {
this.dataObjectFormatMimeTypes = new HashMap<String, String>();
}
public void postSign(SignatureType signatureElement,
List<X509Certificate> signingCertificateChain) {
@Override
public void postSign(Document document, List<X509Certificate> signingCertificateChain) {
LOG.log(POILogger.DEBUG, "postSign");
}
public void preSign(XMLSignatureFactory signatureFactory,
@Override
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references, List<XMLObject> objects)
@ -152,10 +155,8 @@ public class XAdESSignatureFacet implements SignatureFacet {
// SignedProperties
SignedPropertiesType signedProperties = qualifyingProperties.addNewSignedProperties();
String signedPropertiesId;
if (null != this.idSignedProperties) {
signedPropertiesId = this.idSignedProperties;
} else {
String signedPropertiesId = this.idSignedProperties;
if (this.idSignedProperties == null) {
signedPropertiesId = signatureId + "-xades";
}
signedProperties.setId(signedPropertiesId);
@ -243,17 +244,18 @@ public class XAdESSignatureFacet implements SignatureFacet {
// ((Element)qualifyingProperties.getSignedProperties().getDomNode()).setIdAttribute("Id", true);
// add XAdES ds:Object
List<XMLStructure> xadesObjectContent = new LinkedList<XMLStructure>();
Element qualDocEl = (Element)qualifyingProperties.getDomNode();
qualDocEl.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:xd", "http://uri.etsi.org/01903/v1.3.2#");
setPrefix(qualifyingProperties, "http://uri.etsi.org/01903/v1.3.2#", "xd");
List<XMLStructure> xadesObjectContent = new ArrayList<XMLStructure>();
Element qualDocEl = (Element)document.importNode(qualifyingProperties.getDomNode(), true);
XmlSignatureService.registerIdAttribute(qualDocEl.getElementsByTagName("SignedProperties"));
qualDocEl.setAttributeNS(XmlNS, "xmlns:xd", "http://uri.etsi.org/01903/v1.3.2#");
setPrefix(qualDocEl, "http://uri.etsi.org/01903/v1.3.2#", "xd");
xadesObjectContent.add(new DOMStructure(qualDocEl));
XMLObject xadesObject = signatureFactory.newXMLObject(xadesObjectContent, null, null, null);
objects.add(xadesObject);
// add XAdES ds:Reference
DigestMethod digestMethod = signatureFactory.newDigestMethod(hashAlgo.xmlSignUri, null);
List<Transform> transforms = new LinkedList<Transform>();
List<Transform> transforms = new ArrayList<Transform>();
Transform exclusiveTransform = signatureFactory
.newTransform(CanonicalizationMethod.INCLUSIVE,
(TransformParameterSpec) null);

View File

@ -24,7 +24,7 @@
package org.apache.poi.poifs.crypt.dsig.facets;
import static org.apache.poi.poifs.crypt.dsig.HorribleProxy.newProxy;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -37,9 +37,9 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -50,26 +50,24 @@ import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1IntegerIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1OctetStringIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.CanonicalizerIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DERTaggedObjectIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.InitIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.RespIDIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ResponderIDIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509ExtensionsIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509NameIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlObject;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xmlbeans.XmlException;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.ocsp.ResponderID;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.bouncycastle.cert.ocsp.RespID;
import org.etsi.uri.x01903.v13.CRLIdentifierType;
import org.etsi.uri.x01903.v13.CRLRefType;
import org.etsi.uri.x01903.v13.CRLRefsType;
@ -93,9 +91,9 @@ import org.etsi.uri.x01903.v13.UnsignedSignaturePropertiesType;
import org.etsi.uri.x01903.v13.XAdESTimeStampType;
import org.etsi.uri.x01903.v14.ValidationDataType;
import org.w3.x2000.x09.xmldsig.CanonicalizationMethodType;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3.x2000.x09.xmldsig.SignatureValueType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* XAdES-X-L v1.4.1 signature facet. This signature facet implementation will
@ -129,14 +127,6 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
private final HashAlgorithm hashAlgo;
static {
try {
HorribleProxy.createProxy(InitIf.class, "init");
} catch (Exception e) {
throw new RuntimeException("Can't initialize JDK xml signature classes - feature unsupported by the this JDK?!", e);
}
}
/**
* Convenience constructor.
*
@ -184,21 +174,19 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
this.c14nAlgoId = c14nAlgoId;
}
public void postSign(SignatureType signatureElement,
List<X509Certificate> signingCertificateChain) {
@Override
public void postSign(Document document,
List<X509Certificate> signingCertificateChain
) throws XmlException {
LOG.log(POILogger.DEBUG, "XAdES-X-L post sign phase");
QualifyingPropertiesType qualProps = null;
String qualPropXQuery =
"declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "
+ "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "
+ "$this/ds:Object/xades:QualifyingProperties";
XmlObject xoList[] = signatureElement.selectPath(qualPropXQuery);
if (xoList.length == 1) {
qualProps = (QualifyingPropertiesType)xoList[0];
}
if (qualProps == null) {
// check for XAdES-BES
NodeList qualNl = document.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "QualifyingProperties");
if (qualNl.getLength() == 1) {
qualProps = QualifyingPropertiesType.Factory.parse(qualNl.item(0));
} else {
throw new IllegalArgumentException("no XAdES-BES extension present");
}
@ -214,14 +202,15 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
// create the XAdES-T time-stamp
SignatureValueType svt = signatureElement.getSignatureValue();
NodeList nlSigVal = document.getElementsByTagNameNS(XmlDSigNS, "SignatureValue");
if (nlSigVal.getLength() != 1) {
throw new IllegalArgumentException("SignatureValue is not set.");
}
RevocationData tsaRevocationDataXadesT = new RevocationData();
LOG.log(POILogger.DEBUG, "creating XAdES-T time-stamp");
XAdESTimeStampType signatureTimeStamp = createXAdESTimeStamp(
Collections.singletonList(svt.getDomNode()),
tsaRevocationDataXadesT, this.c14nAlgoId,
this.timeStampService);
Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT, this.c14nAlgoId, this.timeStampService);
// marshal the XAdES-T extension
unsignedSigProps.addNewSignatureTimeStamp().set(signatureTimeStamp);
@ -298,9 +287,9 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
OCSPIdentifierType ocspIdentifier = ocspRef.addNewOCSPIdentifier();
OCSPRespIf ocspResp = HorribleProxy.newProxy(OCSPRespIf.class, ocsp);
OCSPResp ocspResp = new OCSPResp(ocsp);
BasicOCSPRespIf basicOcspResp = ocspResp.getResponseObject();
BasicOCSPResp basicOcspResp = (BasicOCSPResp)ocspResp.getResponseObject();
Calendar cal = Calendar.getInstance();
cal.setTime(basicOcspResp.getProducedAt());
@ -308,16 +297,16 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
ResponderIDType responderId = ocspIdentifier.addNewResponderID();
RespIDIf respId = basicOcspResp.getResponderId();
ResponderIDIf ocspResponderId = respId.toASN1Object();
DERTaggedObjectIf derTaggedObject = ocspResponderId.toASN1Object();
RespID respId = basicOcspResp.getResponderId();
ResponderID ocspResponderId = respId.toASN1Object();
DERTaggedObject derTaggedObject = (DERTaggedObject)ocspResponderId.toASN1Primitive();
if (2 == derTaggedObject.getTagNo()) {
ASN1OctetStringIf keyHashOctetString = derTaggedObject.getObject$String();
ASN1OctetString keyHashOctetString = (ASN1OctetString)derTaggedObject.getObject();
byte key[] = keyHashOctetString.getOctets();
responderId.setByKey(key);
} else {
X509NameIf name = HorribleProxy.createProxy(X509NameIf.class, "getInstance", derTaggedObject.getObject$Object());
String nameStr = name.toString$delegate();
X500Name name = X500Name.getInstance(derTaggedObject.getObject());
String nameStr = name.toString();
responderId.setByName(nameStr);
}
} catch (Exception e) {
@ -327,13 +316,10 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
}
// marshal XAdES-C
// XAdES-X Type 1 timestamp
List<Node> timeStampNodesXadesX1 = new LinkedList<Node>();
timeStampNodesXadesX1.add(signatureElement.getDomNode());
List<Node> timeStampNodesXadesX1 = new ArrayList<Node>();
timeStampNodesXadesX1.add(nlSigVal.item(0));
timeStampNodesXadesX1.add(signatureTimeStamp.getDomNode());
timeStampNodesXadesX1.add(completeCertificateRefs.getDomNode());
timeStampNodesXadesX1.add(completeRevocationRefs.getDomNode());
@ -365,6 +351,8 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
createRevocationValues(revocationValues, revocationData);
// marshal XAdES-X-L
Node n = document.importNode(qualProps.getDomNode().getFirstChild(), true);
qualNl.item(0).getParentNode().replaceChild(n, qualNl.item(0));
}
public static byte[] getC14nValue(List<Node> nodeList, String c14nAlgoId) {
@ -375,7 +363,7 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
* Re-initialize the c14n else the namespaces will get cached
* and will be missing from the c14n resulting nodes.
*/
CanonicalizerIf c14n = HorribleProxy.createProxy(CanonicalizerIf.class, "getInstance", c14nAlgoId);
Canonicalizer c14n = Canonicalizer.getInstance(c14nAlgoId);
c14nValue.write(c14n.canonicalizeSubtree(node));
}
} catch (RuntimeException e) {
@ -386,7 +374,9 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
return c14nValue.toByteArray();
}
public void preSign(XMLSignatureFactory signatureFactory,
@Override
public void preSign(Document document,
XMLSignatureFactory signatureFactory,
String signatureId,
List<X509Certificate> signingCertificateChain,
List<Reference> references, List<XMLObject> objects)
@ -396,17 +386,17 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
private BigInteger getCrlNumber(X509CRL crl) {
try {
X509ExtensionsIf x509ext = newProxy(X509ExtensionsIf.class);
byte[] crlNumberExtensionValue = crl.getExtensionValue(x509ext.CRLNumber().getId());
byte[] crlNumberExtensionValue = crl.getExtensionValue(Extension.cRLNumber.getId());
if (null == crlNumberExtensionValue) {
return null;
}
ASN1InputStreamIf asn1InputStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, crlNumberExtensionValue);
ASN1OctetStringIf octetString = asn1InputStream.readObject$ASNString();
@SuppressWarnings("resource")
ASN1InputStream asn1InputStream = new ASN1InputStream(crlNumberExtensionValue);
ASN1OctetString octetString = (ASN1OctetString)asn1InputStream.readObject();
byte[] octets = octetString.getOctets();
asn1InputStream = HorribleProxy.newProxy(ASN1InputStreamIf.class, octets);
ASN1IntegerIf integer = asn1InputStream.readObject$Integer();
asn1InputStream = new ASN1InputStream(octets);
ASN1Integer integer = (ASN1Integer)asn1InputStream.readObject();
BigInteger crlNumber = integer.getPositiveValue();
return crlNumber;
} catch (Exception e) {

View File

@ -33,9 +33,9 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.Provider;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.xml.crypto.Data;
@ -85,7 +85,7 @@ public class RelationshipTransformService extends TransformService {
* Relationship Transform parameter specification class.
*/
public static class RelationshipTransformParameterSpec implements TransformParameterSpec {
List<String> sourceIds = new LinkedList<String>();
List<String> sourceIds = new ArrayList<String>();
public void addRelationshipReference(String relationshipId) {
sourceIds.add(relationshipId);
}
@ -98,7 +98,7 @@ public class RelationshipTransformService extends TransformService {
public RelationshipTransformService() {
super();
LOG.log(POILogger.DEBUG, "constructor");
this.sourceIds = new LinkedList<String>();
this.sourceIds = new ArrayList<String>();
}
/**

View File

@ -26,7 +26,7 @@ package org.apache.poi.poifs.crypt.dsig.services;
import java.security.cert.CRLException;
import java.security.cert.X509CRL;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
/**
@ -45,8 +45,8 @@ public class RevocationData {
* Default constructor.
*/
public RevocationData() {
this.crls = new LinkedList<byte[]>();
this.ocsps = new LinkedList<byte[]>();
this.crls = new ArrayList<byte[]>();
this.ocsps = new ArrayList<byte[]>();
}
/**

View File

@ -26,16 +26,18 @@ package org.apache.poi.poifs.crypt.dsig.services;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
import org.apache.poi.poifs.crypt.dsig.CertificateSecurityException;
import org.apache.poi.poifs.crypt.dsig.ExpiredCertificateSecurityException;
import org.apache.poi.poifs.crypt.dsig.RevokedCertificateSecurityException;
import org.apache.poi.poifs.crypt.dsig.TrustCertificateSecurityException;
import javax.xml.crypto.MarshalException;
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.IdentityDTO;
import org.apache.xmlbeans.XmlException;
import org.w3c.dom.Document;
/**
* Interface for signature service component.
@ -79,7 +81,8 @@ public interface SignatureService {
* @return the digest to be signed.
* @throws NoSuchAlgorithmException
*/
DigestInfo preSign(List<DigestInfo> digestInfos,
DigestInfo preSign(Document document, List<DigestInfo> digestInfos,
PrivateKey privateKey,
List<X509Certificate> signingCertificateChain,
IdentityDTO identity, AddressDTO address, byte[] photo)
throws NoSuchAlgorithmException;
@ -92,10 +95,7 @@ public interface SignatureService {
* @param signingCertificateChain
* the optional chain of signing certificates.
*/
void postSign(byte[] signatureValue,
void postSign(Document document, byte[] signatureValue,
List<X509Certificate> signingCertificateChain)
throws ExpiredCertificateSecurityException,
RevokedCertificateSecurityException,
TrustCertificateSecurityException, CertificateSecurityException,
SecurityException, IOException;
throws IOException, MarshalException, ParserConfigurationException, XmlException;
}

View File

@ -24,10 +24,6 @@
package org.apache.poi.poifs.crypt.dsig.services;
import static org.apache.poi.poifs.crypt.dsig.HorribleProxy.createProxy;
import static org.apache.poi.poifs.crypt.dsig.HorribleProxy.newProxy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.math.BigInteger;
@ -38,39 +34,37 @@ import java.net.URL;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Hex;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1OctetStringIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.AuthorityKeyIdentifierIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BcDigestCalculatorProviderIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BcRSASignerInfoVerifierBuilderIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DEROctetStringIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DefaultDigestAlgorithmIdentifierFinderIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.PKIFailureInfoIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SignerIdIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SignerInformationVerifierIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.SubjectKeyIdentifierIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampRequestGeneratorIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampRequestIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampResponseIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.TimeStampTokenIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509CertificateHolderIf;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.bouncycastle.asn1.cmp.PKIFailureInfo;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.tsp.TimeStampRequest;
import org.bouncycastle.tsp.TimeStampRequestGenerator;
import org.bouncycastle.tsp.TimeStampResponse;
import org.bouncycastle.tsp.TimeStampToken;
/**
* A TSP time-stamp service implementation.
@ -108,6 +102,10 @@ public class TSPTimeStampService implements TimeStampService {
private String digestAlgoOid;
private String requestContentType = "application/timestamp-query;charset=ISO-8859-1";
private String responseContentType = "application/timestamp-reply";
public TSPTimeStampService(String tspServiceUrl,
TimeStampServiceValidator validator) {
this(tspServiceUrl, validator, null, null);
@ -234,12 +232,12 @@ public class TSPTimeStampService implements TimeStampService {
// generate the TSP request
BigInteger nonce = new BigInteger(128, new SecureRandom());
TimeStampRequestGeneratorIf requestGenerator = newProxy(TimeStampRequestGeneratorIf.class);
TimeStampRequestGenerator requestGenerator = new TimeStampRequestGenerator();
requestGenerator.setCertReq(true);
if (null != this.requestPolicy) {
requestGenerator.setReqPolicy(this.requestPolicy);
}
TimeStampRequestIf request = requestGenerator.generate(this.digestAlgoOid, digest, nonce);
TimeStampRequest request = requestGenerator.generate(this.digestAlgoOid, digest, nonce);
byte[] encodedRequest = request.getEncoded();
// create the HTTP POST request
@ -256,8 +254,7 @@ public class TSPTimeStampService implements TimeStampService {
huc.setDoOutput(true); // also sets method to POST.
huc.setRequestProperty("User-Agent", this.userAgent);
// "application/timestamp-query;charset=ISO-8859-1"
huc.setRequestProperty("Content-Type", "application/timestamp-request");
huc.setRequestProperty("Content-Type", requestContentType);
OutputStream hucOut = huc.getOutputStream();
hucOut.write(encodedRequest);
@ -281,8 +278,7 @@ public class TSPTimeStampService implements TimeStampService {
IOUtils.copy(huc.getInputStream(), bos);
LOG.log(POILogger.DEBUG, "response content: ", bos.toString());
// "application/timestamp-reply"
if (!contentType.startsWith("application/timestamp-response")) {
if (!contentType.startsWith(responseContentType)) {
throw new RuntimeException("invalid Content-Type: " + contentType);
}
@ -291,13 +287,13 @@ public class TSPTimeStampService implements TimeStampService {
}
// TSP response parsing and validation
TimeStampResponseIf timeStampResponse = newProxy(TimeStampResponseIf.class, bos.toByteArray());
TimeStampResponse timeStampResponse = new TimeStampResponse(bos.toByteArray());
timeStampResponse.validate(request);
if (0 != timeStampResponse.getStatus()) {
LOG.log(POILogger.DEBUG, "status: " + timeStampResponse.getStatus());
LOG.log(POILogger.DEBUG, "status string: " + timeStampResponse.getStatusString());
PKIFailureInfoIf failInfo = timeStampResponse.getFailInfo();
PKIFailureInfo failInfo = timeStampResponse.getFailInfo();
if (null != failInfo) {
LOG.log(POILogger.DEBUG, "fail info int value: " + failInfo.intValue());
if (/*PKIFailureInfo.unacceptedPolicy*/(1 << 8) == failInfo.intValue()) {
@ -307,30 +303,29 @@ public class TSPTimeStampService implements TimeStampService {
throw new RuntimeException("timestamp response status != 0: "
+ timeStampResponse.getStatus());
}
TimeStampTokenIf timeStampToken = timeStampResponse.getTimeStampToken();
SignerIdIf signerId = timeStampToken.getSID();
TimeStampToken timeStampToken = timeStampResponse.getTimeStampToken();
SignerId signerId = timeStampToken.getSID();
BigInteger signerCertSerialNumber = signerId.getSerialNumber();
X500Principal signerCertIssuer = signerId.getIssuer();
X500Name signerCertIssuer = signerId.getIssuer();
LOG.log(POILogger.DEBUG, "signer cert serial number: " + signerCertSerialNumber);
LOG.log(POILogger.DEBUG, "signer cert issuer: " + signerCertIssuer);
// TSP signer certificates retrieval
Collection<Certificate> certificates = timeStampToken.getCertificates().getMatches(null);
Collection<X509CertificateHolder> certificates = timeStampToken.getCertificates().getMatches(null);
JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils();
X509Certificate signerCert = null;
Map<String, X509Certificate> certificateMap = new HashMap<String, X509Certificate>();
for (Certificate certificate : certificates) {
X509Certificate x509Certificate = (X509Certificate) certificate;
if (signerCertIssuer.equals(x509Certificate
.getIssuerX500Principal())
&& signerCertSerialNumber.equals(x509Certificate
.getSerialNumber())) {
signerCert = x509Certificate;
X509CertificateHolder signerCert = null;
Map<String, X509CertificateHolder> certificateMap = new HashMap<String, X509CertificateHolder>();
for (X509CertificateHolder certificate : certificates) {
if (signerCertIssuer.equals(certificate.getIssuer())
&& signerCertSerialNumber.equals(certificate.getSerialNumber())) {
signerCert = certificate;
}
String ski = Hex.encodeHexString(getSubjectKeyId(x509Certificate));
certificateMap.put(ski, x509Certificate);
byte skiBytes[] = utils.createSubjectKeyIdentifier(certificate.getSubjectPublicKeyInfo()).getKeyIdentifier();
String ski = Hex.encodeHexString(skiBytes);
certificateMap.put(ski, certificate);
LOG.log(POILogger.DEBUG, "embedded certificate: "
+ x509Certificate.getSubjectX500Principal() + "; SKI="
+ certificate.getSubject() + "; SKI="
+ ski);
}
@ -339,26 +334,29 @@ public class TSPTimeStampService implements TimeStampService {
throw new RuntimeException(
"TSP response token has no signer certificate");
}
List<X509Certificate> tspCertificateChain = new LinkedList<X509Certificate>();
X509Certificate certificate = signerCert;
List<X509Certificate> tspCertificateChain = new ArrayList<X509Certificate>();
JcaX509CertificateConverter x509converter = new JcaX509CertificateConverter();
x509converter.setProvider("BC");
X509CertificateHolder certificate = signerCert;
do {
LOG.log(POILogger.DEBUG, "adding to certificate chain: "
+ certificate.getSubjectX500Principal());
tspCertificateChain.add(certificate);
if (certificate.getSubjectX500Principal().equals(
certificate.getIssuerX500Principal())) {
LOG.log(POILogger.DEBUG, "adding to certificate chain: " + certificate.getSubject());
tspCertificateChain.add(x509converter.getCertificate(certificate));
if (certificate.getSubject().equals(certificate.getIssuer())) {
break;
}
String aki = Hex.encodeHexString(getAuthorityKeyId(certificate));
byte akiBytes[] = utils.createAuthorityKeyIdentifier(certificate.getSubjectPublicKeyInfo()).getKeyIdentifier();
String aki = Hex.encodeHexString(akiBytes);
certificate = certificateMap.get(aki);
} while (null != certificate);
// verify TSP signer signature
X509CertificateHolderIf holder = newProxy(X509CertificateHolderIf.class, tspCertificateChain.get(0).getEncoded());
DefaultDigestAlgorithmIdentifierFinderIf finder = newProxy(DefaultDigestAlgorithmIdentifierFinderIf.class);
BcDigestCalculatorProviderIf calculator = newProxy(BcDigestCalculatorProviderIf.class);
BcRSASignerInfoVerifierBuilderIf verifierBuilder = newProxy(BcRSASignerInfoVerifierBuilderIf.class, finder, calculator);
SignerInformationVerifierIf verifier = verifierBuilder.build(holder);
X509CertificateHolder holder = new X509CertificateHolder(tspCertificateChain.get(0).getEncoded());
DefaultCMSSignatureAlgorithmNameGenerator nameGen = new DefaultCMSSignatureAlgorithmNameGenerator();
DefaultSignatureAlgorithmIdentifierFinder sigAlgoFinder = new DefaultSignatureAlgorithmIdentifierFinder();
DefaultDigestAlgorithmIdentifierFinder hashAlgoFinder = new DefaultDigestAlgorithmIdentifierFinder();
BcDigestCalculatorProvider calculator = new BcDigestCalculatorProvider();
BcRSASignerInfoVerifierBuilder verifierBuilder = new BcRSASignerInfoVerifierBuilder(nameGen, sigAlgoFinder, hashAlgoFinder, calculator);
SignerInformationVerifier verifier = verifierBuilder.build(holder);
timeStampToken.validate(verifier);
@ -372,29 +370,19 @@ public class TSPTimeStampService implements TimeStampService {
return timestamp;
}
private byte[] getSubjectKeyId(X509Certificate cert) throws Exception {
// X509Extensions.SubjectKeyIdentifier.getId()
byte[] extvalue = cert.getExtensionValue("2.5.29.14");
if (extvalue == null) return null;
ASN1InputStreamIf keyCntStream = newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(extvalue));
ASN1OctetStringIf cntStr = createProxy(ASN1OctetStringIf.class, "getInstance", keyCntStream.readObject$Object());
ASN1InputStreamIf keyIdStream = newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(cntStr.getOctets()));
SubjectKeyIdentifierIf keyId = createProxy(SubjectKeyIdentifierIf.class, "getInstance", keyIdStream.readObject$Object());
return keyId.getKeyIdentifier();
/**
* usually the request content type is "application/timestamp-query;charset=ISO-8859-1",
* but some timestamp server use a different content type
*/
public void setRequestContentType(String requestContentType) {
this.requestContentType = requestContentType;
}
private byte[] getAuthorityKeyId(X509Certificate cert) throws Exception {
// X509Extensions.AuthorityKeyIdentifier.getId()
byte[] extvalue = cert.getExtensionValue("2.5.29.35");
if (extvalue == null) return null;
ASN1InputStreamIf keyCntStream = newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(extvalue));
DEROctetStringIf cntStr = keyCntStream.readObject$DERString();
ASN1InputStreamIf keyIdStream = newProxy(ASN1InputStreamIf.class, new ByteArrayInputStream(cntStr.getOctets()));
AuthorityKeyIdentifierIf keyId = newProxy(AuthorityKeyIdentifierIf.class, keyIdStream.readObject$Sequence());
return keyId.getKeyIdentifier();
/**
* usually the response content type is "application/timestamp-reply",
* but some timestamp server use a different content type
*/
public void setResponseContentType(String responseContentType) {
this.responseContentType = responseContentType;
}
}

View File

@ -24,20 +24,25 @@
package org.apache.poi.poifs.crypt.dsig.services;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlNS;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -45,7 +50,6 @@ import java.util.UUID;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Manifest;
@ -57,11 +61,12 @@ import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import org.apache.jcp.xml.dsig.internal.dom.DOMReference;
import org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
@ -74,11 +79,6 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMReferenceIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMSignedInfoIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.DOMXMLSignatureIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.XMLSignatureIf;
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
import org.apache.poi.poifs.crypt.dsig.OOXMLURIDereferencer;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
@ -87,19 +87,22 @@ import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet;
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
import org.apache.poi.poifs.crypt.dsig.spi.AddressDTO;
import org.apache.poi.poifs.crypt.dsig.spi.Constants;
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
import org.apache.poi.poifs.crypt.dsig.spi.IdentityDTO;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.utils.Base64;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.w3.x2000.x09.xmldsig.SignatureDocument;
import org.w3.x2000.x09.xmldsig.SignatureType;
import org.w3.x2000.x09.xmldsig.SignatureValueType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;
import org.xml.sax.SAXException;
@ -115,18 +118,18 @@ public class XmlSignatureService implements SignatureService {
private String signatureId = "idPackageSignature";
private final HashAlgorithm hashAlgo;
private final OPCPackage opcPackage;
private SignatureDocument sigDoc;
// private SignatureDocument sigDoc;
private XAdESSignatureFacet xadesSignatureFacet;
/**
* Main constructor.
*/
public XmlSignatureService(HashAlgorithm digestAlgo, OPCPackage opcPackage) {
this.signatureFacets = new LinkedList<SignatureFacet>();
this.signatureFacets = new ArrayList<SignatureFacet>();
this.signatureNamespacePrefix = null;
this.hashAlgo = digestAlgo;
this.opcPackage = opcPackage;
this.sigDoc = null;
// this.sigDoc = null;
}
public void initFacets(Date clock) {
@ -228,19 +231,20 @@ public class XmlSignatureService implements SignatureService {
* @return
*/
// protected abstract OutputStream getSignedDocumentOutputStream();
public DigestInfo preSign(List<DigestInfo> digestInfos,
@Override
public DigestInfo preSign(Document document, List<DigestInfo> digestInfos,
PrivateKey key,
List<X509Certificate> signingCertificateChain,
IdentityDTO identity, AddressDTO address, byte[] photo)
throws NoSuchAlgorithmException {
SignatureInfo.initXmlProvider();
LOG.log(POILogger.DEBUG, "preSign");
HashAlgorithm hashAlgo = getSignatureDigestAlgorithm();
byte[] digestValue;
try {
digestValue = getXmlSignatureDigestValue(hashAlgo, digestInfos, signingCertificateChain);
digestValue = getXmlSignatureDigestValue(document, hashAlgo, digestInfos, key, signingCertificateChain);
} catch (Exception e) {
throw new RuntimeException("XML signature error: " + e.getMessage(), e);
}
@ -249,78 +253,74 @@ public class XmlSignatureService implements SignatureService {
return new DigestInfo(digestValue, hashAlgo, description);
}
public void postSign(byte[] signatureValue, List<X509Certificate> signingCertificateChain)
throws IOException {
@Override
public void postSign(Document document, byte[] signatureValue, List<X509Certificate> signingCertificateChain)
throws IOException, MarshalException, ParserConfigurationException, XmlException {
LOG.log(POILogger.DEBUG, "postSign");
SignatureInfo.initXmlProvider();
/*
* Retrieve the intermediate XML signature document from the temporary
* data storage.
*/
SignatureType sigType = sigDoc.getSignature();
/*
* Check ds:Signature node.
*/
if (!signatureId.equals(sigType.getId())) {
if (!signatureId.equals(document.getDocumentElement().getAttribute("Id"))) {
throw new RuntimeException("ds:Signature not found for @Id: " + signatureId);
}
/*
* Insert signature value into the ds:SignatureValue element
*/
SignatureValueType sigVal = sigType.getSignatureValue();
sigVal.setByteArrayValue(signatureValue);
NodeList sigValNl = document.getElementsByTagNameNS(XmlDSigNS, "SignatureValue");
if (sigValNl.getLength() != 1) {
throw new RuntimeException("preSign has to be called before postSign");
}
sigValNl.item(0).setTextContent(Base64.encode(signatureValue));
/*
* Allow signature facets to inject their own stuff.
*/
for (SignatureFacet signatureFacet : this.signatureFacets) {
signatureFacet.postSign(sigType, signingCertificateChain);
signatureFacet.postSign(document, signingCertificateChain);
}
writeDocument();
writeDocument(document);
}
@SuppressWarnings("unchecked")
private byte[] getXmlSignatureDigestValue(HashAlgorithm hashAlgo,
private byte[] getXmlSignatureDigestValue(Document document, HashAlgorithm hashAlgo,
List<DigestInfo> digestInfos,
PrivateKey privateKey,
List<X509Certificate> signingCertificateChain)
throws ParserConfigurationException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MarshalException,
javax.xml.crypto.dsig.XMLSignatureException,
TransformerFactoryConfigurationError, TransformerException,
IOException, SAXException, NoSuchProviderException, XmlException {
/*
* DOM Document construction.
*/
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();
IOException, SAXException, NoSuchProviderException, XmlException, URISyntaxException {
/*
* Signature context construction.
*/
Key key = new Key() {
private static final long serialVersionUID = 1L;
public String getAlgorithm() {
return null;
}
public byte[] getEncoded() {
return null;
}
public String getFormat() {
return null;
// it's necessary to explicitly set the mdssi namespace, but the sign() method has no
// normal way to interfere with, so we need to add the namespace under the hand ...
final EventTarget et = (EventTarget)document;
EventListener myModificationListener = new EventListener() {
@Override
public void handleEvent(Event e) {
if (e instanceof MutationEvent) {
MutationEvent mutEvt = (MutationEvent)e;
if (mutEvt.getTarget() instanceof Element) {
Element el = (Element)mutEvt.getTarget();
if ("idPackageObject".equals(el.getAttribute("Id"))) {
et.removeEventListener("DOMSubtreeModified", this, false);
el.setAttributeNS(XmlNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);
}
}
}
}
};
// As of JDK 7, can't use sigDoc here directly, because the
// setAttributeID will be called and it's not implemented in xmlbeans
XMLSignContext xmlSignContext = new DOMSignContext(key, doc);
et.addEventListener("DOMSubtreeModified", myModificationListener, false);
/*
* Signature context construction.
*/
XMLSignContext xmlSignContext = new DOMSignContext(privateKey, document);
URIDereferencer uriDereferencer = getURIDereferencer();
if (null != uriDereferencer) {
xmlSignContext.setURIDereferencer(uriDereferencer);
@ -334,40 +334,34 @@ public class XmlSignatureService implements SignatureService {
/*
* OOo doesn't like ds namespaces so per default prefixing is off.
*/
xmlSignContext.putNamespacePrefix(
javax.xml.crypto.dsig.XMLSignature.XMLNS,
this.signatureNamespacePrefix);
xmlSignContext.putNamespacePrefix(XmlDSigNS, this.signatureNamespacePrefix);
}
XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM", "XMLDSig");
XMLSignatureFactory signatureFactory = SignatureInfo.getSignatureFactory();
/*
* Add ds:References that come from signing client local files.
*/
List<Reference> references = new LinkedList<Reference>();
List<Reference> references = new ArrayList<Reference>();
addDigestInfosAsReferences(digestInfos, signatureFactory, references);
/*
* Invoke the signature facets.
*/
String localSignatureId;
if (null == this.signatureId) {
String localSignatureId = this.signatureId;
if (localSignatureId == null) {
localSignatureId = "xmldsig-" + UUID.randomUUID().toString();
} else {
localSignatureId = this.signatureId;
}
List<XMLObject> objects = new LinkedList<XMLObject>();
List<XMLObject> objects = new ArrayList<XMLObject>();
for (SignatureFacet signatureFacet : this.signatureFacets) {
LOG.log(POILogger.DEBUG, "invoking signature facet: "
+ signatureFacet.getClass().getSimpleName());
signatureFacet.preSign(signatureFactory, localSignatureId, signingCertificateChain, references, objects);
LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
signatureFacet.preSign(document, signatureFactory, localSignatureId, signingCertificateChain, references, objects);
}
/*
* ds:SignedInfo
*/
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(
getSignatureMethod(hashAlgo), null);
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(getSignatureMethod(hashAlgo), null);
CanonicalizationMethod canonicalizationMethod = signatureFactory
.newCanonicalizationMethod(getCanonicalizationMethod(),
(C14NMethodParameterSpec) null);
@ -385,20 +379,12 @@ public class XmlSignatureService implements SignatureService {
/*
* ds:Signature Marshalling.
*/
DOMXMLSignatureIf domXmlSignature;
try {
domXmlSignature = HorribleProxy.newProxy(DOMXMLSignatureIf.class, xmlSignature);
} catch (Exception e) {
throw new RuntimeException("DomXmlSignature instance error: " + e.getMessage(), e);
}
domXmlSignature.marshal(doc, this.signatureNamespacePrefix, (DOMCryptoContext) xmlSignContext);
xmlSignContext.setDefaultNamespacePrefix(this.signatureNamespacePrefix);
// xmlSignContext.putNamespacePrefix(PackageNamespaces.DIGITAL_SIGNATURE, "mdssi");
xmlSignature.sign(xmlSignContext);
registerIds(doc);
Element el = doc.getElementById("idPackageObject");
if (el != null) {
el.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);
}
registerIds(document);
// document.getElementById("idPackageObject").setAttributeNS(XmlNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);
/*
@ -415,12 +401,7 @@ public class XmlSignatureService implements SignatureService {
for (Reference manifestReference : manifestReferences) {
if (manifestReference.getDigestValue() != null) continue;
DOMReferenceIf manifestDOMReference;
try {
manifestDOMReference = HorribleProxy.newProxy(DOMReferenceIf.class, manifestReference);
} catch (Exception e) {
throw new RuntimeException("DOMReference instance error: " + e.getMessage(), e);
}
DOMReference manifestDOMReference = (DOMReference)manifestReference;
manifestDOMReference.digest(xmlSignContext);
}
}
@ -431,12 +412,7 @@ public class XmlSignatureService implements SignatureService {
*/
List<Reference> signedInfoReferences = signedInfo.getReferences();
for (Reference signedInfoReference : signedInfoReferences) {
DOMReferenceIf domReference;
try {
domReference = HorribleProxy.newProxy(DOMReferenceIf.class, signedInfoReference);
} catch (Exception e) {
throw new RuntimeException("DOMReference instance error: " + e.getMessage(), e);
}
DOMReference domReference = (DOMReference)signedInfoReference;
// ds:Reference with external digest value
if (domReference.getDigestValue() != null) continue;
@ -447,20 +423,11 @@ public class XmlSignatureService implements SignatureService {
/*
* Calculation of XML signature digest value.
*/
DOMSignedInfoIf domSignedInfo;
try {
domSignedInfo = HorribleProxy.newProxy(DOMSignedInfoIf.class, signedInfo);
} catch (Exception e) {
throw new RuntimeException("DOMSignedInfo instance error: " + e.getMessage(), e);
}
DOMSignedInfo domSignedInfo = (DOMSignedInfo)signedInfo;
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
domSignedInfo.canonicalize(xmlSignContext, dataStream);
byte[] octets = dataStream.toByteArray();
sigDoc = SignatureDocument.Factory.parse(doc.getDocumentElement());
/*
* TODO: we could be using DigestOutputStream here to optimize memory
* usage.
@ -478,13 +445,13 @@ public class XmlSignatureService implements SignatureService {
* @param doc
*/
public void registerIds(Document doc) {
NodeList nl = doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Object");
NodeList nl = doc.getElementsByTagNameNS(XmlDSigNS, "Object");
registerIdAttribute(nl);
nl = doc.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "SignedProperties");
registerIdAttribute(nl);
}
protected void registerIdAttribute(NodeList nl) {
public static void registerIdAttribute(NodeList nl) {
for (int i=0; i<nl.getLength(); i++) {
Element el = (Element)nl.item(i);
if (el.hasAttribute("Id")) {
@ -493,12 +460,9 @@ public class XmlSignatureService implements SignatureService {
}
}
private void addDigestInfosAsReferences(List<DigestInfo> digestInfos,
XMLSignatureFactory signatureFactory, List<Reference> references)
throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MalformedURLException {
if (digestInfos == null) return;
for (DigestInfo digestInfo : digestInfos) {
private void addDigestInfosAsReferences(List<DigestInfo> digestInfos, XMLSignatureFactory signatureFactory, List<Reference> references)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MalformedURLException {
for (DigestInfo digestInfo : safe(digestInfos)) {
byte[] documentDigestValue = digestInfo.digestValue;
DigestMethod digestMethod = signatureFactory.newDigestMethod(
@ -517,19 +481,12 @@ public class XmlSignatureService implements SignatureService {
throw new RuntimeException("digest algo is null");
}
XMLSignatureIf XmlSignature;
try {
XmlSignature = HorribleProxy.newProxy(XMLSignatureIf.class);
} catch (Exception e) {
throw new RuntimeException("JDK doesn't support XmlSignature", e);
}
switch (hashAlgo) {
case sha1: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA1();
case sha256: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA256();
case sha384: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA384();
case sha512: return XmlSignature.ALGO_ID_SIGNATURE_RSA_SHA512();
case ripemd160: return XmlSignature.ALGO_ID_MAC_HMAC_RIPEMD160();
case sha1: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;
case sha256: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256;
case sha384: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384;
case sha512: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512;
case ripemd160: return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160;
default: break;
}
@ -549,15 +506,11 @@ public class XmlSignatureService implements SignatureService {
return null;
}
public SignatureDocument getSignatureDocument() {
return sigDoc;
}
protected String getCanonicalizationMethod() {
return CanonicalizationMethod.INCLUSIVE;
}
protected void writeDocument() throws IOException {
protected void writeDocument(Document document) throws IOException, XmlException {
XmlOptions xo = new XmlOptions();
Map<String,String> namespaceMap = new HashMap<String,String>();
for (SignatureFacet sf : this.signatureFacets) {
@ -594,6 +547,7 @@ public class XmlSignatureService implements SignatureService {
}
OutputStream os = sigPart.getOutputStream();
SignatureDocument sigDoc = SignatureDocument.Factory.parse(document);
sigDoc.save(os, xo);
os.close();
@ -612,4 +566,9 @@ public class XmlSignatureService implements SignatureService {
sigsPart.addRelationship(sigPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE);
}
@SuppressWarnings("unchecked")
public static <T> List<T> safe(List<T> other) {
return other == null ? Collections.EMPTY_LIST : other;
}
}

View File

@ -1,30 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
/* ====================================================================
This product contains an ASLv2 licensed version of the OOXML signer
package from the eID Applet project
http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
Copyright (C) 2008-2014 FedICT.
================================================================= */
package org.apache.poi.poifs.crypt.dsig.spi;
public interface Constants {
String NamespaceSpecNS = "http://www.w3.org/2000/xmlns/";
String SignatureSpecNS = "http://www.w3.org/2000/09/xmldsig#";
}