use of javax.xml.crypto.dsig.XMLSignContext in project poi by apache.
the class SignatureInfo method preSign.
/**
* Helper method for adding informations before the signing.
* Normally {@link #confirmSignature()} is sufficient to be used.
*/
@SuppressWarnings("unchecked")
public DigestInfo preSign(Document document, List<DigestInfo> digestInfos) throws XMLSignatureException, MarshalException {
signatureConfig.init(false);
// 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 ...
EventTarget target = (EventTarget) document;
EventListener creationListener = signatureConfig.getSignatureMarshalListener();
if (creationListener != null) {
if (creationListener instanceof SignatureMarshalListener) {
((SignatureMarshalListener) creationListener).setEventTarget(target);
}
SignatureMarshalListener.setListener(target, creationListener, true);
}
/*
* Signature context construction.
*/
XMLSignContext xmlSignContext = new DOMSignContext(signatureConfig.getKey(), document);
URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer();
if (null != uriDereferencer) {
xmlSignContext.setURIDereferencer(uriDereferencer);
}
for (Map.Entry<String, String> me : signatureConfig.getNamespacePrefixes().entrySet()) {
xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());
}
xmlSignContext.setDefaultNamespacePrefix("");
// signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
brokenJvmWorkaround(xmlSignContext);
XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
/*
* Add ds:References that come from signing client local files.
*/
List<Reference> references = new ArrayList<Reference>();
for (DigestInfo digestInfo : safe(digestInfos)) {
byte[] documentDigestValue = digestInfo.digestValue;
String uri = new File(digestInfo.description).getName();
Reference reference = SignatureFacet.newReference(uri, null, null, null, documentDigestValue, signatureConfig);
references.add(reference);
}
/*
* Invoke the signature facets.
*/
List<XMLObject> objects = new ArrayList<XMLObject>();
for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
signatureFacet.preSign(document, references, objects);
}
/*
* ds:SignedInfo
*/
SignedInfo signedInfo;
try {
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(signatureConfig.getSignatureMethodUri(), 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
*/
String signatureValueId = signatureConfig.getPackageSignatureId() + "-signature-value";
javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory.newXMLSignature(signedInfo, null, objects, signatureConfig.getPackageSignatureId(), signatureValueId);
/*
* ds:Signature Marshalling.
*/
xmlSignature.sign(xmlSignContext);
/*
* Completion of undigested ds:References in the ds:Manifests.
*/
for (XMLObject object : objects) {
LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName());
List<XMLStructure> objectContentList = object.getContent();
for (XMLStructure objectContent : objectContentList) {
LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName());
if (!(objectContent instanceof Manifest))
continue;
Manifest manifest = (Manifest) objectContent;
List<Reference> manifestReferences = manifest.getReferences();
for (Reference manifestReference : manifestReferences) {
if (manifestReference.getDigestValue() != null)
continue;
DOMReference manifestDOMReference = (DOMReference) manifestReference;
manifestDOMReference.digest(xmlSignContext);
}
}
}
/*
* Completion of undigested ds:References.
*/
List<Reference> signedInfoReferences = signedInfo.getReferences();
for (Reference signedInfoReference : signedInfoReferences) {
DOMReference domReference = (DOMReference) signedInfoReference;
// ds:Reference with external digest value
if (domReference.getDigestValue() != null)
continue;
domReference.digest(xmlSignContext);
}
/*
* Calculation of XML signature digest value.
*/
DOMSignedInfo domSignedInfo = (DOMSignedInfo) signedInfo;
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
domSignedInfo.canonicalize(xmlSignContext, dataStream);
byte[] octets = dataStream.toByteArray();
/*
* TODO: we could be using DigestOutputStream here to optimize memory
* usage.
*/
MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());
byte[] digestValue = md.digest(octets);
String description = signatureConfig.getSignatureDescription();
return new DigestInfo(digestValue, signatureConfig.getDigestAlgo(), description);
}
use of javax.xml.crypto.dsig.XMLSignContext in project testcases by coheigea.
the class SignatureJSR105EnvelopedTest method testSignatureUsingJSR105.
// Sign + Verify an XML Document using the JSR-105 API
@org.junit.Test
public void testSignatureUsingJSR105() throws Exception {
// Read in plaintext document
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("plaintext.xml");
DocumentBuilder builder = XMLUtils.createDocumentBuilder(false);
Document document = builder.parse(sourceDocument);
// Set up the Key
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(this.getClass().getClassLoader().getResource("clientstore.jks").openStream(), "cspass".toCharArray());
Key key = keyStore.getKey("myclientkey", "ckpass".toCharArray());
X509Certificate cert = (X509Certificate) keyStore.getCertificate("myclientkey");
String signatureId = "_" + UUID.randomUUID().toString();
String signaturePropertyId = "_" + UUID.randomUUID().toString();
// Sign using DOM
XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
CanonicalizationMethod c14nMethod = signatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec) null);
KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
X509Data x509Data = keyInfoFactory.newX509Data(Collections.singletonList(cert));
javax.xml.crypto.dsig.keyinfo.KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod("http://www.w3.org/2000/09/xmldsig#rsa-sha1", null);
Transform transform = signatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
DigestMethod digestMethod = signatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null);
Reference reference = signatureFactory.newReference("", digestMethod, Collections.singletonList(transform), null, null);
Transform objectTransform = signatureFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);
Reference objectReference = signatureFactory.newReference("#" + signaturePropertyId, digestMethod, Collections.singletonList(objectTransform), "http://www.w3.org/2000/09/xmldsig#SignatureProperties", null);
List<Reference> references = new ArrayList<>();
references.add(reference);
references.add(objectReference);
SignedInfo signedInfo = signatureFactory.newSignedInfo(c14nMethod, signatureMethod, references);
// Add a SignatureProperty containing a Timestamp
Element timestamp = document.createElementNS(null, "Timestamp");
timestamp.setTextContent(new Date().toString());
XMLStructure content = new DOMStructure(timestamp);
SignatureProperty signatureProperty = signatureFactory.newSignatureProperty(Collections.singletonList(content), "#" + signatureId, signaturePropertyId);
SignatureProperties signatureProperties = signatureFactory.newSignatureProperties(Collections.singletonList(signatureProperty), null);
XMLObject object = signatureFactory.newXMLObject(Collections.singletonList(signatureProperties), null, null, null);
XMLSignature sig = signatureFactory.newXMLSignature(signedInfo, keyInfo, Collections.singletonList(object), signatureId, null);
XMLSignContext signContext = new DOMSignContext(key, document.getDocumentElement());
sig.sign(signContext);
// XMLUtils.outputDOM(document, System.out);
// Verify using JSR-105
// Find the Signature Element
Element sigElement = SignatureUtils.getSignatureElement(document);
Assert.assertNotNull(sigElement);
XMLValidateContext context = new DOMValidateContext(cert.getPublicKey(), sigElement);
context.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
signatureFactory = XMLSignatureFactory.getInstance("DOM");
XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
// Check the Signature value
Assert.assertTrue(xmlSignature.validate(context));
// First find the Timestamp
SignatureProperty timestampSignatureProperty = getTimestampSignatureProperty(xmlSignature);
assertNotNull(timestampSignatureProperty);
// Check that what was signed is what we expected to be signed.
boolean foundEnvelopedSig = false;
boolean foundSignedTimestamp = false;
for (Object refObject : signedInfo.getReferences()) {
Reference ref = (Reference) refObject;
if ("".equals(ref.getURI())) {
List<Transform> transforms = (List<Transform>) ref.getTransforms();
if (transforms != null && transforms.stream().anyMatch(t -> t.getAlgorithm().equals(Transform.ENVELOPED))) {
foundEnvelopedSig = true;
}
} else if ("http://www.w3.org/2000/09/xmldsig#SignatureProperties".equals(ref.getType()) && ref.getURI().equals("#" + timestampSignatureProperty.getId())) {
// Found matching SignatureProperties Object
// Now validate Timestamp
validateTimestamp(signatureProperty, cert);
foundSignedTimestamp = true;
}
}
assertEquals(sigElement.getParentNode(), document.getDocumentElement());
assertTrue(foundEnvelopedSig);
assertTrue(foundSignedTimestamp);
}
use of javax.xml.crypto.dsig.XMLSignContext in project testcases by coheigea.
the class SignatureUtils method signUsingJSR105.
/**
* Sign the document using the JSR-105 API, which is included in the JDK
* It signs a list of QNames that it finds in the Document via XPath.
*/
public static void signUsingJSR105(Document document, List<QName> namesToSign, String algorithm, Key signingKey, X509Certificate signingCert) throws Exception {
XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
CanonicalizationMethod c14nMethod = signatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec) null);
KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
X509Data x509Data = keyInfoFactory.newX509Data(Collections.singletonList(signingCert));
javax.xml.crypto.dsig.keyinfo.KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
xpath.setNamespaceContext(new DSNamespaceContext());
List<javax.xml.crypto.dsig.Reference> referenceList = new ArrayList<>();
for (QName nameToSign : namesToSign) {
String expression = "//*[local-name()='" + nameToSign.getLocalPart() + "']";
NodeList elementsToSign = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
for (int i = 0; i < elementsToSign.getLength(); i++) {
Element elementToSign = (Element) elementsToSign.item(i);
Assert.assertNotNull(elementToSign);
String id = UUID.randomUUID().toString();
elementToSign.setAttributeNS(null, "Id", id);
elementToSign.setIdAttributeNS(null, "Id", true);
javax.xml.crypto.dsig.Transform transform = signatureFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);
DigestMethod digestMethod = signatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null);
javax.xml.crypto.dsig.Reference reference = signatureFactory.newReference("#" + id, digestMethod, Collections.singletonList(transform), null, null);
referenceList.add(reference);
}
}
SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(algorithm, null);
SignedInfo signedInfo = signatureFactory.newSignedInfo(c14nMethod, signatureMethod, referenceList);
javax.xml.crypto.dsig.XMLSignature sig = signatureFactory.newXMLSignature(signedInfo, keyInfo, null, null, null);
XMLSignContext signContext = new DOMSignContext(signingKey, document.getDocumentElement());
sig.sign(signContext);
// Find the Signature Element
Element sigElement = getSignatureElement(document);
Assert.assertNotNull(sigElement);
}
Aggregations