Skip to content
This repository has been archived by the owner on Jun 26, 2022. It is now read-only.

Commit

Permalink
Make it work on Java 11
Browse files Browse the repository at this point in the history
The error was that the XMLSignature.sign invocation was given the
original document, and mutated the document that was signed. For the
signing to work properly it is now given a _new_ empty Document. This
is a much cleaner approach, as the original document instance (which is signed)
is not mutated.

The overly awkward use of misunderstood object-orient'ness in these APIs of the JDK are confusing to say the
least. And don't get me started on the thread safety, or lack thereof, of all the factories and stuff.

Co-authored-by: Øyvind Nerbråten <oyvind@nerbraten.no>
  • Loading branch information
runeflobakk and oyvindn committed Nov 23, 2018
1 parent 6e0f857 commit 6012c72
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>10</maven.compiler.release>
<maven.compiler.release>11</maven.compiler.release>
</properties>

<build>
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/xmlsign/SignTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.List;

import static xmlsign.Utils.newEmptyXmlDocument;
import static xmlsign.Utils.parseXml;
import static xmlsign.Utils.pretty;
import static xmlsign.Utils.sha256;
Expand Down Expand Up @@ -63,10 +64,10 @@ public static void main(String ... args) throws Exception {

System.out.print("*** Document before signing:\n" + pretty(documentToSign));

// ka-boom on JDK 11!
xmlSignature.sign(new DOMSignContext(signKey, documentToSign));
Document signedDocument = newEmptyXmlDocument();
xmlSignature.sign(new DOMSignContext(signKey, signedDocument));

System.out.println("\n*** Document after signing:\n" + pretty(documentToSign));
System.out.println("\n*** Document after signing:\n" + pretty(signedDocument));
}


Expand Down
37 changes: 29 additions & 8 deletions src/main/java/xmlsign/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
Expand All @@ -15,22 +14,44 @@

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static java.nio.charset.StandardCharsets.UTF_8;

final class Utils {
public final class Utils {

/**
* The factory's methods to create documentbuilders are thread safe.
*/
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
static {
DOCUMENT_BUILDER_FACTORY.setNamespaceAware(true);
}

static Document newEmptyXmlDocument() {
return newDocument(DocumentBuilder::newDocument);
}

static Document parseXml(String xml) {
return newDocument(builder -> builder.parse(new ByteArrayInputStream(xml.getBytes(UTF_8))));
}

static Document newDocument(DocumentCreator documentCreator) {
try {
return DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes(UTF_8)));
} catch (SAXException | IOException | ParserConfigurationException e) {
return documentCreator.createDocument(DOCUMENT_BUILDER_FACTORY.newDocumentBuilder());
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

@FunctionalInterface
interface DocumentCreator {
Document createDocument(DocumentBuilder builder) throws Exception;
}

static byte[] sha256(String s) {
return sha256(s.getBytes(UTF_8));
}
Expand All @@ -43,8 +64,6 @@ static byte[] sha256(byte[] bytes) {
}
}

private Utils() {}

static String pretty(Node xml) throws TransformerException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Transformer tr = TransformerFactory.newDefaultInstance().newTransformer();
Expand All @@ -53,4 +72,6 @@ static String pretty(Node xml) throws TransformerException {
tr.transform(new DOMSource(xml), new StreamResult(out));
return out.toString(UTF_8);
}

private Utils() {}
}

0 comments on commit 6012c72

Please sign in to comment.