From 93dffcb366c327b6a7b6c5e6989d26449016cee3 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 5 Dec 2014 20:20:23 +0000 Subject: [PATCH] XML signatures - ignore line breaks in Office 2007 .rels files git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1643415 13f79535-47bb-0310-9956-ffa450edef68 --- .../crypt/dsig/OOXMLURIDereferencer.java | 23 ++++++++++++++-- .../poi/poifs/crypt/TestSignatureInfo.java | 25 +++++++++++------- .../xmldsign/office2007prettyPrintedRels.docx | Bin 0 -> 15390 bytes 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 test-data/xmldsign/office2007prettyPrintedRels.docx diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java index dad12d2e8..64eb53d6f 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java @@ -24,7 +24,10 @@ package org.apache.poi.poifs.crypt.dsig; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; @@ -81,12 +84,28 @@ public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigura LOG.log(POILogger.DEBUG, "cannot resolve, delegating to base DOM URI dereferencer", uri); return this.baseUriDereferencer.dereference(uriReference, context); } - + + InputStream dataStream; try { - return new OctetStreamData(part.getInputStream(), uri.toString(), null); + dataStream = part.getInputStream(); + + // workaround for office 2007 pretty-printed .rels files + if (part.getPartName().toString().endsWith(".rels")) { + // although xmlsec has an option to ignore line breaks, currently this + // only affects .rels files, so we only modify these + // http://stackoverflow.com/questions/4728300 + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + for (int ch; (ch = dataStream.read()) != -1; ) { + if (ch == 10 || ch == 13) continue; + bos.write(ch); + } + dataStream = new ByteArrayInputStream(bos.toByteArray()); + } } catch (IOException e) { throw new URIReferenceException("I/O error: " + e.getMessage(), e); } + + return new OctetStreamData(dataStream, uri.toString(), null); } private PackagePart findPart(URI uri) { diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java index 609a26d6b..fe7a91bc0 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java @@ -23,7 +23,10 @@ ================================================================= */ package org.apache.poi.poifs.crypt; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; @@ -108,6 +111,17 @@ public class TestSignatureInfo { additionalJar == null || additionalJar.trim().length() == 0); } + @Test + public void office2007prettyPrintedRels() throws Exception { + OPCPackage pkg = OPCPackage.open(testdata.getFile("office2007prettyPrintedRels.docx"), PackageAccess.READ); + SignatureConfig sic = new SignatureConfig(); + sic.setOpcPackage(pkg); + SignatureInfo si = new SignatureInfo(); + si.setSignatureConfig(sic); + boolean isValid = si.verifySignature(); + assertTrue(isValid); + } + @Test public void getSignerUnsigned() throws Exception { String testFiles[] = { @@ -222,7 +236,6 @@ public class TestSignatureInfo { public void testManipulation() throws Exception { // sign & validate String testFile = "hello-world-unsigned.xlsx"; - @SuppressWarnings("resource") // closed via XSSFWorkbook.close() below ?! OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); sign(pkg, "Test", "CN=Test", 1); @@ -523,14 +536,6 @@ public class TestSignatureInfo { si.confirmSignature(); boolean b = si.verifySignature(); assertTrue("Signature not correctly calculated for " + ha, b); -// } catch (EncryptedDocumentException e) { -// // see http://apache-poi.1045710.n5.nabble.com/org-apache-poi-poifs-crypt-TestSignatureInfo-failing-on-trunk-on-Java-6-tp5717032.html -// Throwable cause = e.getCause(); -// if (cause instanceof ArrayIndexOutOfBoundsException) { -// LOG.log(POILogger.ERROR, "ignoring AIOOBE - hopefully a SHA2 bug ...", e); -// } else { -// throw e; -// } } finally { if (pkg != null) pkg.close(); } diff --git a/test-data/xmldsign/office2007prettyPrintedRels.docx b/test-data/xmldsign/office2007prettyPrintedRels.docx new file mode 100644 index 0000000000000000000000000000000000000000..ce8b940944a3b8c94976233e903ecc14423abfbb GIT binary patch literal 15390 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 B*2@3@ literal 0 HcmV?d00001