Patch from Andreas Beeker from bug #53475 - CSPName may not always be present on OOXML encrypted documents, plus test

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1539828 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2013-11-07 21:29:14 +00:00
parent 224b66e8d4
commit f7b44f5e9f
4 changed files with 75 additions and 15 deletions

View File

@ -16,15 +16,16 @@
==================================================================== */
package org.apache.poi.poifs.crypt;
import org.apache.commons.codec.binary.Base64;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.w3c.dom.NamedNodeMap;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.util.LittleEndianConsts;
import org.w3c.dom.NamedNodeMap;
/**
* Reads and processes OOXML Encryption Headers
@ -69,18 +70,24 @@ public class EncryptionHeader {
is.readLong(); // skip reserved
StringBuilder builder = new StringBuilder();
while (true) {
char c = (char) is.readShort();
if (c == 0) {
break;
// CSPName may not always be specified
// In some cases, the sale value of the EncryptionVerifier has the details
is.mark(LittleEndianConsts.INT_SIZE+1);
int checkForSalt = is.readInt();
is.reset();
if (checkForSalt == 16) {
cspName = "";
} else {
StringBuilder builder = new StringBuilder();
while (true) {
char c = (char) is.readShort();
if (c == 0) break;
builder.append(c);
}
builder.append(c);
cspName = builder.toString();
}
cspName = builder.toString();
cipherMode = MODE_ECB;
keySalt = null;
}

View File

@ -41,6 +41,7 @@ public final class AllXWPFTests {
public static Test suite() {
TestSuite result = new TestSuite(AllXWPFTests.class.getName());
result.addTestSuite(TestXWPFBugs.class);
result.addTestSuite(TestXWPFDocument.class);
result.addTestSuite(TestXWPFWordExtractor.class);
result.addTestSuite(TestXWPFHeaderFooterPolicy.class);

View File

@ -0,0 +1,52 @@
package org.apache.poi.xwpf;
import java.io.File;
import java.io.InputStream;
import junit.framework.TestCase;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionHeader;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
public class TestXWPFBugs extends TestCase {
/**
* A word document that's encrypted with non-standard
* Encryption options, and no cspname section. See bug 53475
*/
public void test53475() throws Exception {
try {
Biff8EncryptionKey.setCurrentUserPassword("solrcell");
File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx");
NPOIFSFileSystem filesystem = new NPOIFSFileSystem(file, true);
// Check the encryption details
EncryptionInfo info = new EncryptionInfo(filesystem);
assertEquals(128, info.getHeader().getKeySize());
assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm());
assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm());
// Check it can be decoded
Decryptor d = Decryptor.getInstance(info);
assertTrue("Unable to process: document is encrypted", d.verifyPassword("solrcell"));
// Check we can read the word document in that
InputStream dataStream = d.getDataStream(filesystem);
OPCPackage opc = OPCPackage.open(dataStream);
XWPFDocument doc = new XWPFDocument(opc);
XWPFWordExtractor ex = new XWPFWordExtractor(doc);
String text = ex.getText();
assertNotNull(text);
assertEquals("This is password protected Word document.", text.trim());
ex.close();
} finally {
Biff8EncryptionKey.setCurrentUserPassword(null);
}
}
}

Binary file not shown.