\r
package org.apache.poi.poifs.crypt.dsig;\r
\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS;\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XADES_132_NS;\r
+\r
import java.security.PrivateKey;\r
import java.security.cert.X509Certificate;\r
import java.util.ArrayList;\r
import java.util.Date;\r
+import java.util.HashMap;\r
import java.util.List;\r
+import java.util.Map;\r
import java.util.UUID;\r
\r
import javax.xml.crypto.URIDereferencer;\r
*/\r
private SignaturePolicyService signaturePolicyService;\r
private URIDereferencer uriDereferencer = new OOXMLURIDereferencer();\r
- private String signatureNamespacePrefix;\r
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;\r
\r
private boolean includeEntireCertificateChain = true;\r
*/\r
EventListener signCreationListener = null;\r
\r
+ /**\r
+ * Map of namespace uris to prefix\r
+ * If a mapping is specified, the corresponding elements will be prefixed\r
+ */\r
+ Map<String,String> namespacePrefixes = new HashMap<String,String>();\r
+ \r
protected void init(boolean onlyValidation) {\r
if (uriDereferencer == null) {\r
throw new EncryptedDocumentException("uriDereferencer is null");\r
if (uriDereferencer instanceof SignatureConfigurable) {\r
((SignatureConfigurable)uriDereferencer).setSignatureConfig(this);\r
}\r
+ if (namespacePrefixes.isEmpty()) {\r
+ /*\r
+ * OOo doesn't like ds namespaces so per default prefixing is off.\r
+ */\r
+ // namespacePrefixes.put(XML_DIGSIG_NS, "");\r
+ namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");\r
+ namespacePrefixes.put(XADES_132_NS, "xd");\r
+ }\r
+ \r
if (onlyValidation) return;\r
\r
if (signCreationListener == null) {\r
if (signCreationListener instanceof SignatureConfigurable) {\r
((SignatureConfigurable)signCreationListener).setSignatureConfig(this);\r
}\r
-\r
\r
if (tspService != null) {\r
tspService.setSignatureConfig(this);\r
public void setSignatureDescription(String signatureDescription) {\r
this.signatureDescription = signatureDescription;\r
}\r
- public String getSignatureNamespacePrefix() {\r
- return signatureNamespacePrefix;\r
- }\r
- public void setSignatureNamespacePrefix(String signatureNamespacePrefix) {\r
- this.signatureNamespacePrefix = signatureNamespacePrefix;\r
- }\r
public String getCanonicalizationMethod() {\r
return canonicalizationMethod;\r
}\r
public void setSignCreationListener(EventListener signCreationListener) {\r
this.signCreationListener = signCreationListener;\r
}\r
+ public Map<String, String> getNamespacePrefixes() {\r
+ return namespacePrefixes;\r
+ }\r
+ public void setNamespacePrefixes(Map<String, String> namespacePrefixes) {\r
+ this.namespacePrefixes = namespacePrefixes;\r
+ }\r
}\r
\r
package org.apache.poi.poifs.crypt.dsig;\r
\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS;\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_DIGSIG_NS;\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS;\r
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160;\r
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;\r
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256;\r
import org.apache.poi.EncryptedDocumentException;\r
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
import org.apache.poi.openxml4j.opc.OPCPackage;\r
-import org.apache.poi.openxml4j.opc.PackageNamespaces;\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackagePartName;\r
import org.apache.poi.openxml4j.opc.PackageRelationship;\r
\r
public class SignatureInfo implements SignatureConfigurable {\r
\r
- public static final String XmlNS = "http://www.w3.org/2000/xmlns/";\r
- public static final String XmlDSigNS = XMLSignature.XMLNS;\r
- \r
// see https://www.ietf.org/rfc/rfc3110.txt\r
// RSA/SHA1 SIG Resource Records\r
public static final byte[] SHA1_DIGEST_INFO_PREFIX = new byte[]\r
\r
if (packageId.equals(el.getAttribute("Id"))) {\r
target.get().removeEventListener("DOMSubtreeModified", this, false);\r
- el.setAttributeNS(XmlNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);\r
+ el.setAttributeNS(XML_NS, "xmlns:mdssi", OO_DIGSIG_NS);\r
target.get().addEventListener("DOMSubtreeModified", this, false);\r
}\r
}\r
}\r
}\r
}\r
+ \r
public void setSignatureConfig(SignatureConfig signatureConfig) {\r
this.signatureConfig = signatureConfig;\r
}\r
xmlSignContext.setURIDereferencer(uriDereferencer);\r
}\r
\r
- xmlSignContext.putNamespacePrefix(\r
- "http://schemas.openxmlformats.org/package/2006/digital-signature",\r
- "mdssi");\r
- \r
- String sigNsPrefix = signatureConfig.getSignatureNamespacePrefix();\r
- if (sigNsPrefix != null) {\r
- /*\r
- * OOo doesn't like ds namespaces so per default prefixing is off.\r
- */\r
- xmlSignContext.putNamespacePrefix(XmlDSigNS, sigNsPrefix);\r
+ for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet()) {\r
+ xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());\r
}\r
-\r
+ xmlSignContext.setDefaultNamespacePrefix(signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));\r
+ \r
XMLSignatureFactory signatureFactory = SignatureInfo.getSignatureFactory();\r
\r
/*\r
/*\r
* ds:Signature Marshalling.\r
*/\r
- xmlSignContext.setDefaultNamespacePrefix(signatureConfig.getSignatureNamespacePrefix());\r
- // xmlSignContext.putNamespacePrefix(PackageNamespaces.DIGITAL_SIGNATURE, "mdssi");\r
xmlSignature.sign(xmlSignContext);\r
\r
/*\r
* usage.\r
*/\r
\r
- MessageDigest jcaMessageDigest = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());\r
- byte[] digestValue = jcaMessageDigest.digest(octets);\r
+ MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());\r
+ byte[] digestValue = md.digest(octets);\r
\r
\r
String description = signatureConfig.getSignatureDescription();\r
/*\r
* Insert signature value into the ds:SignatureValue element\r
*/\r
- NodeList sigValNl = document.getElementsByTagNameNS(XmlDSigNS, "SignatureValue");\r
+ NodeList sigValNl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "SignatureValue");\r
if (sigValNl.getLength() != 1) {\r
throw new RuntimeException("preSign has to be called before postSign");\r
}\r
protected void writeDocument(Document document) throws IOException, XmlException {\r
XmlOptions xo = new XmlOptions();\r
Map<String,String> namespaceMap = new HashMap<String,String>();\r
- for (SignatureFacet sf : signatureConfig.getSignatureFacets()) {\r
- Map<String,String> sfm = sf.getNamespacePrefixMapping();\r
- if (sfm != null) {\r
- namespaceMap.putAll(sfm);\r
- }\r
- }\r
+ for(Map.Entry<String,String> entry : signatureConfig.getNamespacePrefixes().entrySet()){\r
+ namespaceMap.put(entry.getValue(), entry.getKey());\r
+ } \r
xo.setSaveSuggestedPrefixes(namespaceMap);\r
xo.setUseDefaultNamespace();\r
\r
}\r
\r
@SuppressWarnings("unchecked")\r
- public static <T> List<T> safe(List<T> other) {\r
+ private static <T> List<T> safe(List<T> other) {\r
return other == null ? Collections.EMPTY_LIST : other;\r
}\r
}\r
import java.security.cert.X509Certificate;\r
import java.util.ArrayList;\r
import java.util.List;\r
-import java.util.Map;\r
\r
import javax.xml.crypto.dsig.CanonicalizationMethod;\r
import javax.xml.crypto.dsig.DigestMethod;\r
\r
references.add(reference);\r
}\r
-\r
- @Override\r
- public Map<String,String> getNamespacePrefixMapping() {\r
- return null;\r
- }\r
}\r
\r
package org.apache.poi.poifs.crypt.dsig.facets;\r
\r
-import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;\r
-\r
import java.security.InvalidAlgorithmParameterException;\r
import java.security.Key;\r
import java.security.KeyException;\r
import java.security.NoSuchAlgorithmException;\r
import java.security.cert.X509Certificate;\r
import java.util.ArrayList;\r
-import java.util.HashMap;\r
import java.util.List;\r
-import java.util.Map;\r
\r
import javax.xml.crypto.MarshalException;\r
import javax.xml.crypto.dom.DOMCryptoContext;\r
throws MarshalException {\r
LOG.log(POILogger.DEBUG, "postSign");\r
\r
- NodeList nl = document.getElementsByTagNameNS(XmlDSigNS, "Object");\r
+ NodeList nl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "Object");\r
\r
/*\r
* Make sure we insert right after the ds:SignatureValue element, just\r
Element n = document.getDocumentElement();\r
DOMSignContext domSignContext = new DOMSignContext(key, n, nextSibling);\r
DOMCryptoContext domCryptoContext = domSignContext;\r
- domCryptoContext.putNamespacePrefix(XmlDSigNS, "xd");\r
+ domCryptoContext.putNamespacePrefix(XML_DIGSIG_NS, "xd");\r
DOMStructure domStructure = new DOMStructure(n);\r
// how to set nextSibling??? - marshal is ignoring nextSibling in DOMSignContext\r
domKeyInfo.marshal(domStructure, domCryptoContext);\r
\r
// move keyinfo into the right place\r
if (nextSibling != null) {\r
- NodeList kiNl = document.getElementsByTagNameNS(XmlDSigNS, "KeyInfo");\r
+ NodeList kiNl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "KeyInfo");\r
if (kiNl.getLength() != 1) {\r
throw new RuntimeException("KeyInfo wasn't set");\r
}\r
) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {\r
// empty\r
}\r
-\r
- public Map<String,String> getNamespacePrefixMapping() {\r
- Map<String,String> map = new HashMap<String,String>();\r
- // map.put("xd", XmlDSigNS);\r
- return map;\r
- }\r
-\r
}
\ No newline at end of file
\r
package org.apache.poi.poifs.crypt.dsig.facets;\r
\r
-import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;\r
-import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlNS;\r
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.setPrefix;\r
\r
import java.io.IOException;\r
import java.text.DateFormat;\r
import java.text.SimpleDateFormat;\r
import java.util.ArrayList;\r
-import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.List;\r
-import java.util.Map;\r
import java.util.Set;\r
import java.util.TimeZone;\r
\r
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
import org.apache.poi.openxml4j.opc.ContentTypes;\r
import org.apache.poi.openxml4j.opc.OPCPackage;\r
-import org.apache.poi.openxml4j.opc.PackageNamespaces;\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackagePartName;\r
import org.apache.poi.openxml4j.opc.PackageRelationship;\r
\r
private static final POILogger LOG = POILogFactory.getLogger(OOXMLSignatureFacet.class);\r
\r
- public static final String OOXML_DIGSIG_NS = "http://schemas.openxmlformats.org/package/2006/digital-signature";\r
- public static final String OFFICE_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";\r
-\r
private SignatureConfig signatureConfig;\r
\r
public void setSignatureConfig(SignatureConfig signatureConfig) {\r
\r
DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);\r
Reference reference = signatureFactory.newReference\r
- ("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);\r
+ ("#" + objectId, digestMethod, null, XML_DIGSIG_NS+"Object", null);\r
references.add(reference);\r
}\r
\r
\r
// TODO: find better method to have xmlbeans + export the prefix\r
Element n = (Element)document.importNode(ctTime.getDomNode(),true);\r
- setPrefix(n, PackageNamespaces.DIGITAL_SIGNATURE, "mdssi");\r
+ setPrefix(n, OO_DIGSIG_NS, "mdssi");\r
\r
List<XMLStructure> signatureTimeContent = new ArrayList<XMLStructure>();\r
signatureTimeContent.add(new DOMStructure(n));\r
CTSignatureInfoV1 ctSigV1 = sigV1.addNewSignatureInfoV1();\r
ctSigV1.setManifestHashAlgorithm(signatureConfig.getDigestAlgo().xmlSignUri);\r
Element n = (Element)document.importNode(ctSigV1.getDomNode(), true);\r
- n.setAttributeNS(XmlNS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig");\r
+ n.setAttributeNS(XML_NS, "xmlns", "http://schemas.microsoft.com/office/2006/digsig");\r
\r
List<XMLStructure> signatureInfoContent = new ArrayList<XMLStructure>();\r
signatureInfoContent.add(new DOMStructure(n));\r
\r
DigestMethod digestMethod = signatureFactory.newDigestMethod(signatureConfig.getDigestAlgo().xmlSignUri, null);\r
Reference reference = signatureFactory.newReference\r
- ("#" + objectId, digestMethod, null, XmlDSigNS+"Object", null);\r
+ ("#" + objectId, digestMethod, null, XML_DIGSIG_NS+"Object", null);\r
references.add(reference);\r
}\r
\r
return false;\r
}\r
\r
- public Map<String,String> getNamespacePrefixMapping() {\r
- Map<String,String> m = new HashMap<String,String>();\r
- m.put("mdssi", OOXML_DIGSIG_NS);\r
- m.put("xd", "http://uri.etsi.org/01903/v1.3.2#");\r
- return m;\r
- }\r
-\r
- \r
/**\r
* Office 2010 list of signed types (extensions).\r
*/\r
import java.security.NoSuchAlgorithmException;\r
import java.security.cert.X509Certificate;\r
import java.util.List;\r
-import java.util.Map;\r
\r
import javax.xml.crypto.dsig.Reference;\r
import javax.xml.crypto.dsig.XMLObject;\r
public void postSign(Document document, List<X509Certificate> signingCertificateChain)\r
throws XmlException {\r
// check for XAdES-BES\r
- NodeList nl = document.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "QualifyingProperties");\r
+ NodeList nl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties");\r
if (nl.getLength() != 1) {\r
throw new IllegalArgumentException("no XAdES-BES extension present");\r
}\r
Node n = document.importNode(qualProps.getDomNode().getFirstChild(), true);\r
nl.item(0).getParentNode().replaceChild(n, nl.item(0));\r
}\r
- \r
- public Map<String,String> getNamespacePrefixMapping() {\r
- return null;\r
- }\r
}
\ No newline at end of file
import java.security.NoSuchAlgorithmException;\r
import java.security.cert.X509Certificate;\r
import java.util.List;\r
-import java.util.Map;\r
\r
+import javax.xml.XMLConstants;\r
import javax.xml.crypto.MarshalException;\r
import javax.xml.crypto.dsig.Reference;\r
import javax.xml.crypto.dsig.XMLObject;\r
+import javax.xml.crypto.dsig.XMLSignature;\r
import javax.xml.crypto.dsig.XMLSignatureFactory;\r
\r
+import org.apache.poi.openxml4j.opc.PackageNamespaces;\r
import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable;\r
import org.apache.xmlbeans.XmlException;\r
import org.w3c.dom.Document;\r
*/\r
public interface SignatureFacet extends SignatureConfigurable {\r
\r
+ String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;\r
+ String XML_DIGSIG_NS = XMLSignature.XMLNS;\r
+ String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE;\r
+ String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig";\r
+ String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#";\r
+ String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#";\r
+\r
+\r
/**\r
* This method is being invoked by the XML signature service engine during\r
* pre-sign phase. Via this method a signature facet implementation can add\r
Document document\r
, List<X509Certificate> signingCertificateChain\r
) throws MarshalException, XmlException;\r
- \r
- Map<String,String> getNamespacePrefixMapping();\r
}
\ No newline at end of file
\r
package org.apache.poi.poifs.crypt.dsig.facets;\r
\r
-import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlNS;\r
import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.setPrefix;\r
\r
import java.security.InvalidAlgorithmParameterException;\r
// add XAdES ds:Object\r
List<XMLStructure> xadesObjectContent = new ArrayList<XMLStructure>();\r
Element qualDocEl = (Element)document.importNode(qualifyingProperties.getDomNode(), true);\r
- qualDocEl.setAttributeNS(XmlNS, "xmlns:xd", "http://uri.etsi.org/01903/v1.3.2#");\r
- setPrefix(qualDocEl, "http://uri.etsi.org/01903/v1.3.2#", "xd");\r
+ qualDocEl.setAttributeNS(XML_NS, "xmlns:xd", XADES_132_NS);\r
+ setPrefix(qualDocEl, XADES_132_NS, "xd");\r
xadesObjectContent.add(new DOMStructure(qualDocEl));\r
XMLObject xadesObject = signatureFactory.newXMLObject(xadesObjectContent, null, null, null);\r
objects.add(xadesObject);\r
this.dataObjectFormatMimeTypes.put(dsReferenceUri, mimetype);\r
}\r
\r
- public Map<String,String> getNamespacePrefixMapping() {\r
- Map<String,String> map = new HashMap<String,String>();\r
- map.put("xd", "http://uri.etsi.org/01903/v1.3.2#");\r
- return map;\r
- }\r
-\r
protected static void insertXChild(XmlObject root, XmlObject child) {\r
XmlCursor rootCursor = root.newCursor();\r
rootCursor.toEndToken();\r
\r
package org.apache.poi.poifs.crypt.dsig.facets;\r
\r
-import static org.apache.poi.poifs.crypt.dsig.SignatureInfo.XmlDSigNS;\r
import static org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet.insertXChild;\r
\r
import java.io.ByteArrayInputStream;\r
import java.util.Calendar;\r
import java.util.Collections;\r
import java.util.List;\r
-import java.util.Map;\r
import java.util.UUID;\r
\r
import javax.xml.crypto.dsig.CanonicalizationMethod;\r
\r
private static final POILogger LOG = POILogFactory.getLogger(XAdESXLSignatureFacet.class);\r
\r
- public static final String XADES_NAMESPACE = "http://uri.etsi.org/01903/v1.3.2#";\r
-\r
- public static final String XADES141_NAMESPACE = "http://uri.etsi.org/01903/v1.4.1#";\r
- \r
private SignatureConfig signatureConfig;\r
\r
private String c14nAlgoId = CanonicalizationMethod.EXCLUSIVE;\r
QualifyingPropertiesType qualProps = null;\r
\r
// check for XAdES-BES\r
- NodeList qualNl = document.getElementsByTagNameNS("http://uri.etsi.org/01903/v1.3.2#", "QualifyingProperties");\r
+ NodeList qualNl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties");\r
if (qualNl.getLength() == 1) {\r
qualDoc = QualifyingPropertiesDocument.Factory.parse(qualNl.item(0));\r
qualProps = qualDoc.getQualifyingProperties();\r
\r
\r
// create the XAdES-T time-stamp\r
- NodeList nlSigVal = document.getElementsByTagNameNS(XmlDSigNS, "SignatureValue");\r
+ NodeList nlSigVal = document.getElementsByTagNameNS(XML_DIGSIG_NS, "SignatureValue");\r
if (nlSigVal.getLength() != 1) {\r
throw new IllegalArgumentException("SignatureValue is not set.");\r
}\r
}\r
}\r
}\r
-\r
- public Map<String,String> getNamespacePrefixMapping() {\r
- return null;\r
- }\r
-\r
}\r
\r
package org.apache.poi.poifs.crypt.dsig.services;\r
\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_DIGSIG_NS;\r
+import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS;\r
+\r
import java.io.ByteArrayInputStream;\r
import java.io.ByteArrayOutputStream;\r
import java.io.IOException;\r
LOG.log(POILogger.DEBUG, "marshallParams(parent,context)");\r
DOMStructure domParent = (DOMStructure) parent;\r
Element parentNode = (Element)domParent.getNode();\r
- // parentNode.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", DIGITAL_SIGNATURE);\r
+ // parentNode.setAttributeNS(XML_NS, "xmlns:mdssi", XML_DIGSIG_NS);\r
Document doc = parentNode.getOwnerDocument();\r
\r
for (String sourceId : this.sourceIds) {\r