You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2020/07/22 22:08:36 UTC
svn commit: r1880164 [5/9] - in /poi/trunk: ./
src/examples/src/org/apache/poi/crypt/
src/examples/src/org/apache/poi/examples/
src/examples/src/org/apache/poi/examples/crypt/
src/examples/src/org/apache/poi/examples/hpsf/
src/examples/src/org/apache/p...
Copied: poi/trunk/src/integrationtest/org/apache/poi/stress/POIFileScanner.java (from r1880163, poi/trunk/src/integrationtest/org/apache/poi/POIFileScanner.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/integrationtest/org/apache/poi/stress/POIFileScanner.java?p2=poi/trunk/src/integrationtest/org/apache/poi/stress/POIFileScanner.java&p1=poi/trunk/src/integrationtest/org/apache/poi/POIFileScanner.java&r1=1880163&r2=1880164&rev=1880164&view=diff
==============================================================================
--- poi/trunk/src/integrationtest/org/apache/poi/POIFileScanner.java (original)
+++ poi/trunk/src/integrationtest/org/apache/poi/stress/POIFileScanner.java Wed Jul 22 22:08:33 2020
@@ -17,7 +17,18 @@
* ====================================================================
*/
-package org.apache.poi;
+package org.apache.poi.stress;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
@@ -25,25 +36,12 @@ import org.apache.poi.poifs.filesystem.F
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
-import org.apache.poi.stress.FileHandler;
-import org.apache.poi.stress.XSSFFileHandler;
import org.apache.poi.util.SuppressForbidden;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.tools.ant.DirectoryScanner;
import org.junit.Ignore;
import org.junit.Test;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-
/**
* Helper class to scan a folder for files and return a collection of
* found files together with the matching {@link FileHandler}.
@@ -65,7 +63,7 @@ public class POIFileScanner {
* Scan a folder for files and return a collection of
* found files together with the matching {@link FileHandler}.
*
- * Note: unknown files will be assigned to {@link org.apache.poi.TestAllFiles.NullFileHandler}
+ * Note: unknown files will be assigned to {@link TestAllFiles.NullFileHandler}
*
* @param rootDir The directory to scan
* @return A collection with file-FileHandler pairs which can be used for running tests on that file
@@ -110,7 +108,7 @@ public class POIFileScanner {
*
* @param rootDir The directory where the file resides
* @param file The name of the file without directory
- * @return The matching {@link FileHandler}, A {@link org.apache.poi.TestAllFiles.NullFileHandler}
+ * @return The matching {@link FileHandler}, A {@link TestAllFiles.NullFileHandler}
* is returned if no match is found
* @throws IOException If determining the file-type fails
*/
Copied: poi/trunk/src/integrationtest/org/apache/poi/stress/TestAllFiles.java (from r1880163, poi/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/integrationtest/org/apache/poi/stress/TestAllFiles.java?p2=poi/trunk/src/integrationtest/org/apache/poi/stress/TestAllFiles.java&p1=poi/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java&r1=1880163&r2=1880164&rev=1880164&view=diff
==============================================================================
--- poi/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java (original)
+++ poi/trunk/src/integrationtest/org/apache/poi/stress/TestAllFiles.java Wed Jul 22 22:08:33 2020
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi;
+package org.apache.poi.stress;
import static org.junit.Assert.assertFalse;
@@ -35,25 +35,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import org.apache.poi.OldFileFormatException;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.poifs.crypt.Decryptor;
-import org.apache.poi.stress.AbstractFileHandler;
-import org.apache.poi.stress.FileHandler;
-import org.apache.poi.stress.HDGFFileHandler;
-import org.apache.poi.stress.HMEFFileHandler;
-import org.apache.poi.stress.HPBFFileHandler;
-import org.apache.poi.stress.HPSFFileHandler;
-import org.apache.poi.stress.HSLFFileHandler;
-import org.apache.poi.stress.HSMFFileHandler;
-import org.apache.poi.stress.HSSFFileHandler;
-import org.apache.poi.stress.HWPFFileHandler;
-import org.apache.poi.stress.OPCFileHandler;
-import org.apache.poi.stress.POIFSFileHandler;
-import org.apache.poi.stress.XDGFFileHandler;
-import org.apache.poi.stress.XSLFFileHandler;
-import org.apache.poi.stress.XSSFBFileHandler;
-import org.apache.poi.stress.XSSFFileHandler;
-import org.apache.poi.stress.XWPFFileHandler;
import org.apache.tools.ant.DirectoryScanner;
import org.junit.AssumptionViolatedException;
import org.junit.Before;
Modified: poi/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java (original)
+++ poi/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java Wed Jul 22 22:08:33 2020
@@ -38,8 +38,11 @@ import java.util.Set;
import javax.xml.transform.TransformerException;
import org.apache.poi.EncryptedDocumentException;
-import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.examples.ss.ExcelComparator;
+import org.apache.poi.examples.xssf.eventusermodel.FromHowTo;
+import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
+import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@@ -47,11 +50,8 @@ import org.apache.poi.openxml4j.opc.OPCP
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.ss.examples.ExcelComparator;
import org.apache.poi.util.IOUtils;
-import org.apache.poi.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
-import org.apache.poi.xssf.eventusermodel.examples.FromHowTo;
import org.apache.poi.xssf.extractor.XSSFExportToXml;
import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@@ -99,27 +99,27 @@ public class XSSFFileHandler extends Spr
// use the combined handler for HSSF/XSSF
handleWorkbook(wb);
-
+
// TODO: some documents fail currently...
//XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(wb);
//evaluator.evaluateAll();
// also verify general POIFS-stuff
new POIXMLDocumentHandler().handlePOIXMLDocument(wb);
-
+
// and finally ensure that exporting to XML works
exportToXML(wb);
// this allows to trigger a heap-dump at this point to see which memory is still allocated
//HeapDump.dumpHeap("/tmp/poi.hprof", false);
-
+
wb.close();
}
private void checkXSSFReader(OPCPackage p) throws IOException, OpenXML4JException {
XSSFReader reader = new XSSFReader(p);
-
+
// these can be null...
InputStream sharedStringsData = reader.getSharedStringsData();
if(sharedStringsData != null) {
@@ -132,21 +132,21 @@ public class XSSFFileHandler extends Spr
stylesData.close();
}
reader.getStylesTable();
-
+
InputStream themesData = reader.getThemesData();
if(themesData != null) {
themesData.close();
}
assertNotNull(reader.getWorkbookData());
-
+
Iterator<InputStream> sheetsData = reader.getSheetsData();
while(sheetsData.hasNext()) {
InputStream str = sheetsData.next();
str.close();
}
}
-
+
private void exportToXML(XSSFWorkbook wb) throws SAXException,
TransformerException {
for (XSSFMap map : wb.getCustomXMLMappings()) {
@@ -221,8 +221,8 @@ public class XSSFFileHandler extends Spr
public void testAdditional() throws Exception {
handleAdditional(new File("test-data/spreadsheet/poc-xmlbomb.xlsx"));
}
-
- // need to override all methods to omit calls to UTF-handling methods
+
+ // need to override all methods to omit calls to UTF-handling methods
static class NullPrintStream extends PrintStream {
@SuppressWarnings("resource")
NullPrintStream() {
Modified: poi/trunk/src/java/org/apache/poi/POIDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/POIDocument.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/POIDocument.java (original)
+++ poi/trunk/src/java/org/apache/poi/POIDocument.java Wed Jul 22 22:08:33 2020
@@ -49,7 +49,7 @@ import org.apache.poi.util.POILogger;
/**
* This holds the common functionality for all POI
* Document classes.
- * Currently, this relates to Document Information Properties
+ * Currently, this relates to Document Information Properties
*/
public abstract class POIDocument implements Closeable {
/** Holds metadata on our document */
@@ -76,7 +76,7 @@ public abstract class POIDocument implem
/**
* Constructs from the default POIFS
- *
+ *
* @param fs the filesystem the document is read from
*/
protected POIDocument(POIFSFileSystem fs) {
@@ -85,8 +85,8 @@ public abstract class POIDocument implem
/**
* Fetch the Document Summary Information of the document
- *
- * @return The Document Summary Information or null
+ *
+ * @return The Document Summary Information or null
* if it could not be read for this document.
*/
public DocumentSummaryInformation getDocumentSummaryInformation() {
@@ -96,9 +96,9 @@ public abstract class POIDocument implem
return dsInf;
}
- /**
+ /**
* Fetch the Summary Information of the document
- *
+ *
* @return The Summary information for the document or null
* if it could not be read for this document.
*/
@@ -108,7 +108,7 @@ public abstract class POIDocument implem
}
return sInf;
}
-
+
/**
* Will create whichever of SummaryInformation
* and DocumentSummaryInformation (HPSF) properties
@@ -136,7 +136,8 @@ public abstract class POIDocument implem
* If a given property set is missing or corrupt,
* it will remain null;
*/
- protected void readProperties() {
+ @Internal
+ public void readProperties() {
if (initialized) {
return;
}
@@ -170,11 +171,11 @@ public abstract class POIDocument implem
}
return null;
}
-
- /**
+
+ /**
* For a given named property entry, either return it or null if
* if it wasn't found
- *
+ *
* @param setName The property to read
* @return The value of the given property or null if it wasn't found.
*
@@ -184,11 +185,11 @@ public abstract class POIDocument implem
protected PropertySet getPropertySet(String setName) throws IOException {
return getPropertySet(setName, getEncryptionInfo());
}
-
- /**
+
+ /**
* For a given named property entry, either return it or null if
* if it wasn't found
- *
+ *
* @param setName The property to read
* @param encryptionInfo the encryption descriptor in case of cryptoAPI encryption
* @return The value of the given property or null if it wasn't found.
@@ -198,7 +199,7 @@ public abstract class POIDocument implem
@SuppressWarnings("WeakerAccess")
protected PropertySet getPropertySet(String setName, EncryptionInfo encryptionInfo) throws IOException {
DirectoryNode dirNode = directory;
-
+
POIFSFileSystem encPoifs = null;
String step = "getting";
try {
@@ -212,12 +213,12 @@ public abstract class POIDocument implem
encPoifs = dec.getSummaryEntries(dirNode, encryptedStream);
dirNode = encPoifs.getRoot();
}
-
+
//directory can be null when creating new documents
if (dirNode == null || !dirNode.hasEntry(setName)) {
return null;
}
-
+
// Find the entry, and get an input stream for it
step = "getting";
try (DocumentInputStream dis = dirNode.createDocumentInputStream(dirNode.getEntry(setName))) {
@@ -233,11 +234,11 @@ public abstract class POIDocument implem
IOUtils.closeQuietly(encPoifs);
}
}
-
+
/**
* Writes out the updated standard Document Information Properties (HPSF)
* into the currently open POIFSFileSystem
- *
+ *
* @throws IOException if an error when writing to the open
* {@link POIFSFileSystem} occurs
*/
@@ -249,19 +250,20 @@ public abstract class POIDocument implem
/**
* Writes out the standard Document Information Properties (HPSF)
* @param outFS the POIFSFileSystem to write the properties into
- *
- * @throws IOException if an error when writing to the
+ *
+ * @throws IOException if an error when writing to the
* {@link POIFSFileSystem} occurs
*/
- protected void writeProperties(POIFSFileSystem outFS) throws IOException {
+ @Internal
+ public void writeProperties(POIFSFileSystem outFS) throws IOException {
writeProperties(outFS, null);
}
/**
* Writes out the standard Document Information Properties (HPSF)
* @param outFS the {@link POIFSFileSystem} to write the properties into
* @param writtenEntries a list of POIFS entries to add the property names too
- *
- * @throws IOException if an error when writing to the
+ *
+ * @throws IOException if an error when writing to the
* {@link POIFSFileSystem} occurs
*/
protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
@@ -308,15 +310,15 @@ public abstract class POIDocument implem
writtenEntries.add(name);
}
}
-
+
/**
* Writes out a given PropertySet
*
* @param name the (POIFS Level) name of the property to write
- * @param set the PropertySet to write out
+ * @param set the PropertySet to write out
* @param outFS the {@link POIFSFileSystem} to write the property into
- *
- * @throws IOException if an error when writing to the
+ *
+ * @throws IOException if an error when writing to the
* {@link POIFSFileSystem} occurs
*/
private void writePropertySet(String name, PropertySet set, POIFSFileSystem outFS) throws IOException {
@@ -341,7 +343,7 @@ public abstract class POIDocument implem
* Called during a {@link #write()} to ensure that the Document (and
* associated {@link POIFSFileSystem}) was opened in a way compatible
* with an in-place write.
- *
+ *
* @throws IllegalStateException if the document was opened suitably
*/
protected void validateInPlaceWritePossible() throws IllegalStateException {
@@ -356,32 +358,32 @@ public abstract class POIDocument implem
throw new IllegalStateException("Opened read-only or via an InputStream, a Writeable File is required");
}
}
-
+
/**
* Writes the document out to the currently open {@link File}, via the
* writeable {@link POIFSFileSystem} it was opened from.
- *
+ *
* <p>This will fail (with an {@link IllegalStateException} if the
* document was opened read-only, opened from an {@link InputStream}
- * instead of a File, or if this is not the root document. For those cases,
- * you must use {@link #write(OutputStream)} or {@link #write(File)} to
+ * instead of a File, or if this is not the root document. For those cases,
+ * you must use {@link #write(OutputStream)} or {@link #write(File)} to
* write to a brand new document.
- *
+ *
* @since POI 3.15 beta 3
- *
+ *
* @throws IOException thrown on errors writing to the file
* @throws IllegalStateException if this isn't from a writable File
*/
public abstract void write() throws IOException;
/**
- * Writes the document out to the specified new {@link File}. If the file
+ * Writes the document out to the specified new {@link File}. If the file
* exists, it will be replaced, otherwise a new one will be created
*
* @since POI 3.15 beta 3
- *
+ *
* @param newFile The new File to write to.
- *
+ *
* @throws IOException thrown on errors writing to the file
*/
public abstract void write(File newFile) throws IOException;
@@ -389,20 +391,20 @@ public abstract class POIDocument implem
/**
* Writes the document out to the specified output stream. The
* stream is not closed as part of this operation.
- *
+ *
* Note - if the Document was opened from a {@link File} rather
* than an {@link InputStream}, you <b>must</b> write out using
* {@link #write()} or to a different File. Overwriting the currently
* open file via an OutputStream isn't possible.
- *
+ *
* If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive
* or has a high cost/latency associated with each written byte,
* consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream}
* to improve write performance, or use {@link #write()} / {@link #write(File)}
* if possible.
- *
+ *
* @param out The stream to write to.
- *
+ *
* @throws IOException thrown on errors writing to the stream
*/
public abstract void write(OutputStream out) throws IOException;
@@ -429,7 +431,7 @@ public abstract class POIDocument implem
public DirectoryNode getDirectory() {
return directory;
}
-
+
/**
* Clear/unlink the attached directory entry
*/
@@ -437,11 +439,11 @@ public abstract class POIDocument implem
protected void clearDirectory() {
directory = null;
}
-
+
/**
* check if we were created by POIFS otherwise create a new dummy POIFS
* for storing the package data
- *
+ *
* @return {@code true} if dummy directory was created, {@code false} otherwise
*/
@SuppressWarnings("resource")
@@ -453,7 +455,7 @@ public abstract class POIDocument implem
}
return false;
}
-
+
/**
* Replaces the attached directory, e.g. if this document is written
* to a new POIFSFileSystem
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Wed Jul 22 22:08:33 2020
@@ -1546,7 +1546,8 @@ public final class HSSFWorkbook extends
}
}
- /*package*/ InternalWorkbook getWorkbook() {
+ @Internal
+ public InternalWorkbook getWorkbook() {
return workbook;
}
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java Wed Jul 22 22:08:33 2020
@@ -17,11 +17,17 @@
package org.apache.poi.hssf.usermodel;
+import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.ss.usermodel.WorkbookProvider;
import org.apache.poi.util.Internal;
/**
@@ -30,15 +36,11 @@ import org.apache.poi.util.Internal;
*/
@SuppressWarnings("unused")
@Internal
-public class HSSFWorkbookFactory extends WorkbookFactory {
+public class HSSFWorkbookFactory implements WorkbookProvider {
- static {
- init();
- }
-
- public static void init() {
- WorkbookFactory.createHssfFromScratch = HSSFWorkbookFactory::createWorkbook;
- WorkbookFactory.createHssfByNode = HSSFWorkbookFactory::createWorkbook;
+ @Override
+ public boolean accepts(FileMagic fm) {
+ return FileMagic.OLE2 == fm;
}
/**
@@ -46,7 +48,7 @@ public class HSSFWorkbookFactory extends
*
* @return The created workbook
*/
- public static HSSFWorkbook createWorkbook() {
+ public HSSFWorkbook create() {
return new HSSFWorkbook();
}
@@ -64,7 +66,45 @@ public class HSSFWorkbookFactory extends
* Note that in order to properly release resources the
* Workbook should be closed after use.
*/
- public static HSSFWorkbook createWorkbook(final DirectoryNode root) throws IOException {
- return new HSSFWorkbook(root, true);
+ public HSSFWorkbook create(final DirectoryNode root, String password) throws IOException {
+ boolean passwordSet = false;
+ if (password != null) {
+ Biff8EncryptionKey.setCurrentUserPassword(password);
+ passwordSet = true;
+ }
+ try {
+ return new HSSFWorkbook(root, true);
+ } finally {
+ if (passwordSet) {
+ Biff8EncryptionKey.setCurrentUserPassword(null);
+ }
+ }
+ }
+
+ @Override
+ public Workbook create(InputStream inp) throws IOException {
+ return create(inp, null);
+ }
+
+ @Override
+ public Workbook create(InputStream inp, String password) throws IOException {
+ POIFSFileSystem fs = new POIFSFileSystem(inp);
+ return create(fs.getRoot(), password);
+ }
+
+ @Override
+ public Workbook create(File file, String password, boolean readOnly) throws IOException {
+ boolean passwordSet = false;
+ if (password != null) {
+ Biff8EncryptionKey.setCurrentUserPassword(password);
+ passwordSet = true;
+ }
+ try {
+ return new HSSFWorkbook(new POIFSFileSystem(file, readOnly), true);
+ } finally {
+ if (passwordSet) {
+ Biff8EncryptionKey.setCurrentUserPassword(null);
+ }
+ }
}
}
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java Wed Jul 22 22:08:33 2020
@@ -19,15 +19,27 @@ package org.apache.poi.poifs.crypt;
public enum ChainingMode {
// ecb - only for standard encryption
- ecb("ECB", 1),
- cbc("CBC", 2),
+ ecb("ECB", 1, null),
+ cbc("CBC", 2, "ChainingModeCBC"),
/* Cipher feedback chaining (CFB), with an 8-bit window */
- cfb("CFB8", 3);
+ cfb("CFB8", 3, "ChainingModeCFB");
public final String jceId;
public final int ecmaId;
- ChainingMode(String jceId, int ecmaId) {
+ public final String xmlId;
+
+ ChainingMode(String jceId, int ecmaId, String xmlId) {
this.jceId = jceId;
this.ecmaId = ecmaId;
+ this.xmlId = xmlId;
+ }
+
+ public static ChainingMode fromXmlId(String xmlId) {
+ for (ChainingMode cm : values()) {
+ if (cm.xmlId != null && cm.xmlId.equals(xmlId)) {
+ return cm;
+ }
+ }
+ return null;
}
}
\ No newline at end of file
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java Wed Jul 22 22:08:33 2020
@@ -86,7 +86,7 @@ public abstract class EncryptionHeader i
return flags;
}
- protected void setFlags(int flags) {
+ public void setFlags(int flags) {
this.flags = flags;
}
@@ -94,7 +94,7 @@ public abstract class EncryptionHeader i
return sizeExtra;
}
- protected void setSizeExtra(int sizeExtra) {
+ public void setSizeExtra(int sizeExtra) {
this.sizeExtra = sizeExtra;
}
@@ -102,7 +102,7 @@ public abstract class EncryptionHeader i
return cipherAlgorithm;
}
- protected void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
+ public void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
this.cipherAlgorithm = cipherAlgorithm;
if (cipherAlgorithm.allowedKeySize.length == 1) {
setKeySize(cipherAlgorithm.defaultKeySize);
@@ -113,7 +113,7 @@ public abstract class EncryptionHeader i
return hashAlgorithm;
}
- protected void setHashAlgorithm(HashAlgorithm hashAlgorithm) {
+ public void setHashAlgorithm(HashAlgorithm hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
@@ -128,7 +128,7 @@ public abstract class EncryptionHeader i
*
* @param keyBits
*/
- protected void setKeySize(int keyBits) {
+ public void setKeySize(int keyBits) {
this.keyBits = keyBits;
for (int allowedBits : getCipherAlgorithm().allowedKeySize) {
if (allowedBits == keyBits) {
@@ -142,7 +142,7 @@ public abstract class EncryptionHeader i
return blockSize;
}
- protected void setBlockSize(int blockSize) {
+ public void setBlockSize(int blockSize) {
this.blockSize = blockSize;
}
@@ -150,7 +150,7 @@ public abstract class EncryptionHeader i
return keySalt;
}
- protected void setKeySalt(byte[] salt) {
+ public void setKeySalt(byte[] salt) {
this.keySalt = (salt == null) ? null : salt.clone();
}
@@ -158,7 +158,7 @@ public abstract class EncryptionHeader i
return providerType;
}
- protected void setCipherProvider(CipherProvider providerType) {
+ public void setCipherProvider(CipherProvider providerType) {
this.providerType = providerType;
}
@@ -166,7 +166,7 @@ public abstract class EncryptionHeader i
return cspName;
}
- protected void setCspName(String cspName) {
+ public void setCspName(String cspName) {
this.cspName = cspName;
}
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java Wed Jul 22 22:08:33 2020
@@ -43,6 +43,12 @@ import org.apache.poi.util.LittleEndianI
* @see #getBuilder(EncryptionMode)
*/
public class EncryptionInfo implements GenericRecord {
+
+ /**
+ * Document entry name for encryption info xml descriptor
+ */
+ public static final String ENCRYPTION_INFO_ENTRY = "EncryptionInfo";
+
/**
* A flag that specifies whether CryptoAPI RC4 or ECMA-376 encryption
* ECMA-376 is used. It MUST be 1 unless flagExternal is 1. If flagExternal is 1, it MUST be 0.
@@ -110,25 +116,16 @@ public class EncryptionInfo implements G
versionMinor = dis.readUShort();
}
- if ( versionMajor == xor.versionMajor
- && versionMinor == xor.versionMinor) {
+ if (versionMajor == xor.versionMajor && versionMinor == xor.versionMinor) {
encryptionMode = xor;
encryptionFlags = -1;
- } else if ( versionMajor == binaryRC4.versionMajor
- && versionMinor == binaryRC4.versionMinor) {
+ } else if (versionMajor == binaryRC4.versionMajor && versionMinor == binaryRC4.versionMinor) {
encryptionMode = binaryRC4;
encryptionFlags = -1;
- } else if (
- 2 <= versionMajor && versionMajor <= 4
- && versionMinor == 2) {
+ } else if (2 <= versionMajor && versionMajor <= 4 && versionMinor == 2) {
encryptionFlags = dis.readInt();
- encryptionMode = (
- preferredEncryptionMode == cryptoAPI
- || !flagAES.isSet(encryptionFlags))
- ? cryptoAPI : standard;
- } else if (
- versionMajor == agile.versionMajor
- && versionMinor == agile.versionMinor){
+ encryptionMode = (preferredEncryptionMode == cryptoAPI || !flagAES.isSet(encryptionFlags)) ? cryptoAPI : standard;
+ } else if (versionMajor == agile.versionMajor && versionMinor == agile.versionMinor){
encryptionMode = agile;
encryptionFlags = dis.readInt();
} else {
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java Wed Jul 22 22:08:33 2020
@@ -83,35 +83,35 @@ public abstract class EncryptionVerifier
return chainingMode;
}
- protected void setSalt(byte[] salt) {
+ public void setSalt(byte[] salt) {
this.salt = (salt == null) ? null : salt.clone();
}
- protected void setEncryptedVerifier(byte[] encryptedVerifier) {
+ public void setEncryptedVerifier(byte[] encryptedVerifier) {
this.encryptedVerifier = (encryptedVerifier == null) ? null : encryptedVerifier.clone();
}
- protected void setEncryptedVerifierHash(byte[] encryptedVerifierHash) {
+ public void setEncryptedVerifierHash(byte[] encryptedVerifierHash) {
this.encryptedVerifierHash = (encryptedVerifierHash == null) ? null : encryptedVerifierHash.clone();
}
- protected void setEncryptedKey(byte[] encryptedKey) {
+ public void setEncryptedKey(byte[] encryptedKey) {
this.encryptedKey = (encryptedKey == null) ? null : encryptedKey.clone();
}
- protected void setSpinCount(int spinCount) {
+ public void setSpinCount(int spinCount) {
this.spinCount = spinCount;
}
- protected void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
+ public void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
this.cipherAlgorithm = cipherAlgorithm;
}
- protected void setChainingMode(ChainingMode chainingMode) {
+ public void setChainingMode(ChainingMode chainingMode) {
this.chainingMode = chainingMode;
}
- protected void setHashAlgorithm(HashAlgorithm hashAlgorithm) {
+ public void setHashAlgorithm(HashAlgorithm hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java Wed Jul 22 22:08:33 2020
@@ -19,10 +19,6 @@ package org.apache.poi.poifs.crypt.agile
import java.util.Map;
import java.util.function.Supplier;
-import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity;
-import com.microsoft.schemas.office.x2006.encryption.CTKeyData;
-import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
-import com.microsoft.schemas.office.x2006.encryption.STCipherChaining;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.ChainingMode;
import org.apache.poi.poifs.crypt.CipherAlgorithm;
@@ -45,9 +41,9 @@ public class AgileEncryptionHeader exten
}
protected AgileEncryptionHeader(EncryptionDocument ed) {
- CTKeyData keyData;
+ KeyData keyData;
try {
- keyData = ed.getEncryption().getKeyData();
+ keyData = ed.getKeyData();
if (keyData == null) {
throw new NullPointerException("keyData not set");
}
@@ -55,9 +51,9 @@ public class AgileEncryptionHeader exten
throw new EncryptedDocumentException("Unable to parse keyData");
}
- int keyBits = (int)keyData.getKeyBits();
+ int keyBits = keyData.getKeyBits();
- CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), keyBits);
+ CipherAlgorithm ca = keyData.getCipherAlgorithm();
setCipherAlgorithm(ca);
setCipherProvider(ca.provider);
@@ -67,20 +63,15 @@ public class AgileEncryptionHeader exten
setCspName(null);
setBlockSize(keyData.getBlockSize());
- switch (keyData.getCipherChaining().intValue()) {
- case STCipherChaining.INT_CHAINING_MODE_CBC:
- setChainingMode(ChainingMode.cbc);
- break;
- case STCipherChaining.INT_CHAINING_MODE_CFB:
- setChainingMode(ChainingMode.cfb);
- break;
- default:
+ setChainingMode(keyData.getCipherChaining());
+
+ if (getChainingMode() != ChainingMode.cbc && getChainingMode() != ChainingMode.cfb) {
throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining());
}
int hashSize = keyData.getHashSize();
- HashAlgorithm ha = HashAlgorithm.fromEcmaId(keyData.getHashAlgorithm().toString());
+ HashAlgorithm ha = keyData.getHashAlgorithm();
setHashAlgorithm(ha);
if (getHashAlgorithm().hashSize != hashSize) {
@@ -94,7 +85,7 @@ public class AgileEncryptionHeader exten
throw new EncryptedDocumentException("Invalid salt length");
}
- CTDataIntegrity di = ed.getEncryption().getDataIntegrity();
+ DataIntegrity di = ed.getDataIntegrity();
setEncryptedHmacKey(di.getEncryptedHmacKey());
setEncryptedHmacValue(di.getEncryptedHmacValue());
}
@@ -110,7 +101,7 @@ public class AgileEncryptionHeader exten
// make method visible for this package
@Override
- protected void setKeySalt(byte[] salt) {
+ public void setKeySalt(byte[] salt) {
if (salt == null || salt.length != getBlockSize()) {
throw new EncryptedDocumentException("invalid verifier salt");
}
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java Wed Jul 22 22:08:33 2020
@@ -16,8 +16,6 @@
==================================================================== */
package org.apache.poi.poifs.crypt.agile;
-import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-
import java.io.IOException;
import java.io.InputStream;
@@ -29,12 +27,13 @@ import org.apache.poi.poifs.crypt.Encryp
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.util.LittleEndianInput;
-import org.apache.xmlbeans.XmlException;
-
-import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
+import org.apache.poi.util.XMLHelper;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
public class AgileEncryptionInfoBuilder implements EncryptionInfoBuilder {
-
+
@Override
public void initialize(EncryptionInfo info, LittleEndianInput dis) throws IOException {
EncryptionDocument ed = parseDescriptor((InputStream)dis);
@@ -90,19 +89,22 @@ public class AgileEncryptionInfoBuilder
enc.setEncryptionInfo(info);
info.setEncryptor(enc);
}
-
+
protected static EncryptionDocument parseDescriptor(String descriptor) {
- try {
- return EncryptionDocument.Factory.parse(descriptor, DEFAULT_XML_OPTIONS);
- } catch (XmlException e) {
- throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
- }
+ return parseDescriptor(new InputSource(descriptor));
}
protected static EncryptionDocument parseDescriptor(InputStream descriptor) {
+ return parseDescriptor(new InputSource(descriptor));
+ }
+
+ private static EncryptionDocument parseDescriptor(InputSource descriptor) {
try {
- return EncryptionDocument.Factory.parse(descriptor, DEFAULT_XML_OPTIONS);
- } catch (Exception e) {
+ Document doc = XMLHelper.newDocumentBuilder().parse(descriptor);
+ EncryptionDocument ed = new EncryptionDocument();
+ ed.parse(doc);
+ return ed;
+ } catch (SAXException|IOException e) {
throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
}
}
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java Wed Jul 22 22:08:33 2020
@@ -16,12 +16,6 @@
==================================================================== */
package org.apache.poi.poifs.crypt.agile;
-import java.util.Iterator;
-
-import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor;
-import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
-import com.microsoft.schemas.office.x2006.encryption.STCipherChaining;
-import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.ChainingMode;
import org.apache.poi.poifs.crypt.CipherAlgorithm;
@@ -42,29 +36,27 @@ public class AgileEncryptionVerifier ext
}
protected AgileEncryptionVerifier(EncryptionDocument ed) {
- Iterator<CTKeyEncryptor> encList = ed.getEncryption().getKeyEncryptors().getKeyEncryptorList().iterator();
- CTPasswordKeyEncryptor keyData;
- try {
- keyData = encList.next().getEncryptedPasswordKey();
- if (keyData == null) {
- throw new NullPointerException("encryptedKey not set");
+ PasswordKeyEncryptor keyData = null;
+ for (KeyEncryptor ke : ed.getKeyEncryptors()) {
+ keyData = ke.getPasswordKeyEncryptor();
+ if (keyData != null) {
+ break;
}
- } catch (Exception e) {
- throw new EncryptedDocumentException("Unable to parse keyData", e);
}
- int kb = (int)keyData.getKeyBits();
- CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), kb);
- setCipherAlgorithm(ca);
+ if (keyData == null) {
+ throw new NullPointerException("encryptedKey not set");
+ }
- setKeySize(kb);
+ setCipherAlgorithm(keyData.getCipherAlgorithm());
+ setKeySize(keyData.getKeyBits());
int blockSize = keyData.getBlockSize();
setBlockSize(blockSize);
int hashSize = keyData.getHashSize();
- HashAlgorithm ha = HashAlgorithm.fromEcmaId(keyData.getHashAlgorithm().toString());
+ HashAlgorithm ha = keyData.getHashAlgorithm();
setHashAlgorithm(ha);
if (getHashAlgorithm().hashSize != hashSize) {
@@ -83,15 +75,9 @@ public class AgileEncryptionVerifier ext
throw new EncryptedDocumentException("Invalid salt size");
}
- switch (keyData.getCipherChaining().intValue()) {
- case STCipherChaining.INT_CHAINING_MODE_CBC:
- setChainingMode(ChainingMode.cbc);
- break;
- case STCipherChaining.INT_CHAINING_MODE_CFB:
- setChainingMode(ChainingMode.cfb);
- break;
- default:
- throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining());
+ setChainingMode(keyData.getCipherChaining());
+ if (keyData.getCipherChaining() != ChainingMode.cbc && keyData.getCipherChaining() != ChainingMode.cfb) {
+ throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining());
}
}
@@ -111,7 +97,7 @@ public class AgileEncryptionVerifier ext
}
@Override
- protected void setSalt(byte[] salt) {
+ public void setSalt(byte[] salt) {
if (salt == null || salt.length != getCipherAlgorithm().blockSize) {
throw new EncryptedDocumentException("invalid verifier salt");
}
@@ -120,19 +106,19 @@ public class AgileEncryptionVerifier ext
// make method visible for this package
@Override
- protected void setEncryptedVerifier(byte[] encryptedVerifier) {
+ public void setEncryptedVerifier(byte[] encryptedVerifier) {
super.setEncryptedVerifier(encryptedVerifier);
}
// make method visible for this package
@Override
- protected void setEncryptedVerifierHash(byte[] encryptedVerifierHash) {
+ public void setEncryptedVerifierHash(byte[] encryptedVerifierHash) {
super.setEncryptedVerifierHash(encryptedVerifierHash);
}
// make method visible for this package
@Override
- protected void setEncryptedKey(byte[] encryptedKey) {
+ public void setEncryptedKey(byte[] encryptedKey) {
super.setEncryptedKey(encryptedKey);
}
@@ -169,7 +155,7 @@ public class AgileEncryptionVerifier ext
*
* @param keyBits the keysize (in bits)
*/
- protected void setKeySize(int keyBits) {
+ public void setKeySize(int keyBits) {
this.keyBits = keyBits;
for (int allowedBits : getCipherAlgorithm().allowedKeySize) {
if (allowedBits == keyBits) {
@@ -185,12 +171,12 @@ public class AgileEncryptionVerifier ext
*
* @param blockSize the blockSize (in bytes)
*/
- protected void setBlockSize(int blockSize) {
+ public void setBlockSize(int blockSize) {
this.blockSize = blockSize;
}
@Override
- protected final void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
+ public final void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
super.setCipherAlgorithm(cipherAlgorithm);
if (cipherAlgorithm.allowedKeySize.length == 1) {
setKeySize(cipherAlgorithm.defaultKeySize);
Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java?rev=1880164&r1=1880163&r2=1880164&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java Wed Jul 22 22:08:33 2020
@@ -21,6 +21,7 @@ import static org.apache.poi.poifs.crypt
import static org.apache.poi.poifs.crypt.CryptoFunctions.getMessageDigest;
import static org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword;
import static org.apache.poi.poifs.crypt.DataSpaceMapUtils.createEncryptionEntry;
+import static org.apache.poi.poifs.crypt.EncryptionInfo.ENCRYPTION_INFO_ENTRY;
import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.getNextBlockSize;
import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.hashInput;
import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kCryptoKeyBlock;
@@ -29,35 +30,26 @@ import static org.apache.poi.poifs.crypt
import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kIntegrityValueBlock;
import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kVerifierInputBlock;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
-import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity;
-import com.microsoft.schemas.office.x2006.encryption.CTEncryption;
-import com.microsoft.schemas.office.x2006.encryption.CTKeyData;
-import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor;
-import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptors;
-import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
-import com.microsoft.schemas.office.x2006.encryption.STCipherAlgorithm;
-import com.microsoft.schemas.office.x2006.encryption.STCipherChaining;
-import com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm;
-import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream;
import org.apache.poi.poifs.crypt.CryptoFunctions;
@@ -70,7 +62,8 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianConsts;
-import org.apache.xmlbeans.XmlOptions;
+import org.apache.poi.util.XMLHelper;
+import org.w3c.dom.Document;
public class AgileEncryptor extends Encryptor {
@@ -261,21 +254,19 @@ public class AgileEncryptor extends Encr
header.setEncryptedHmacValue(encryptedHmacValue);
}
- private final CTKeyEncryptor.Uri.Enum passwordUri =
- CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_PASSWORD;
-
protected EncryptionDocument createEncryptionDocument() {
AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier();
AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader();
- EncryptionDocument ed = EncryptionDocument.Factory.newInstance();
- CTEncryption edRoot = ed.addNewEncryption();
+ EncryptionDocument ed = new EncryptionDocument();
+ KeyData keyData = new KeyData();
+ ed.setKeyData(keyData);
+
+ KeyEncryptor keyEnc = new KeyEncryptor();
+ ed.getKeyEncryptors().add(keyEnc);
- CTKeyData keyData = edRoot.addNewKeyData();
- CTKeyEncryptors keyEncList = edRoot.addNewKeyEncryptors();
- CTKeyEncryptor keyEnc = keyEncList.addNewKeyEncryptor();
- keyEnc.setUri(passwordUri);
- CTPasswordKeyEncryptor keyPass = keyEnc.addNewEncryptedPasswordKey();
+ PasswordKeyEncryptor keyPass = new PasswordKeyEncryptor();
+ keyEnc.setPasswordKeyEncryptor(keyPass);
keyPass.setSpinCount(ver.getSpinCount());
@@ -295,28 +286,15 @@ public class AgileEncryptor extends Encr
if (!header.getCipherAlgorithm().xmlId.equals(ver.getCipherAlgorithm().xmlId)) {
throw new EncryptedDocumentException("Cipher algorithm of header and verifier have to match");
}
- STCipherAlgorithm.Enum xmlCipherAlgo = STCipherAlgorithm.Enum.forString(header.getCipherAlgorithm().xmlId);
- if (xmlCipherAlgo == null) {
- throw new EncryptedDocumentException("CipherAlgorithm "+header.getCipherAlgorithm()+" not supported.");
- }
- keyData.setCipherAlgorithm(xmlCipherAlgo);
- keyPass.setCipherAlgorithm(xmlCipherAlgo);
- switch (header.getChainingMode()) {
- case cbc:
- keyData.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC);
- keyPass.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC);
- break;
- case cfb:
- keyData.setCipherChaining(STCipherChaining.CHAINING_MODE_CFB);
- keyPass.setCipherChaining(STCipherChaining.CHAINING_MODE_CFB);
- break;
- default:
- throw new EncryptedDocumentException("ChainingMode "+header.getChainingMode()+" not supported.");
- }
+ keyData.setCipherAlgorithm(header.getCipherAlgorithm());
+ keyPass.setCipherAlgorithm(header.getCipherAlgorithm());
+
+ keyData.setCipherChaining(header.getChainingMode());
+ keyPass.setCipherChaining(header.getChainingMode());
- keyData.setHashAlgorithm(mapHashAlgorithm(header.getHashAlgorithm()));
- keyPass.setHashAlgorithm(mapHashAlgorithm(ver.getHashAlgorithm()));
+ keyData.setHashAlgorithm(header.getHashAlgorithm());
+ keyPass.setHashAlgorithm(ver.getHashAlgorithm());
keyData.setSaltValue(header.getKeySalt());
keyPass.setSaltValue(ver.getSalt());
@@ -324,40 +302,26 @@ public class AgileEncryptor extends Encr
keyPass.setEncryptedVerifierHashValue(ver.getEncryptedVerifierHash());
keyPass.setEncryptedKeyValue(ver.getEncryptedKey());
- CTDataIntegrity hmacData = edRoot.addNewDataIntegrity();
+ DataIntegrity hmacData = new DataIntegrity();
+ ed.setDataIntegrity(hmacData);
hmacData.setEncryptedHmacKey(header.getEncryptedHmacKey());
hmacData.setEncryptedHmacValue(header.getEncryptedHmacValue());
return ed;
}
- private static STHashAlgorithm.Enum mapHashAlgorithm(HashAlgorithm hashAlgo) {
- STHashAlgorithm.Enum xmlHashAlgo = STHashAlgorithm.Enum.forString(hashAlgo.ecmaString);
- if (xmlHashAlgo == null) {
- throw new EncryptedDocumentException("HashAlgorithm "+hashAlgo+" not supported.");
- }
- return xmlHashAlgo;
- }
-
protected void marshallEncryptionDocument(EncryptionDocument ed, LittleEndianByteArrayOutputStream os) {
- XmlOptions xo = new XmlOptions();
- xo.setCharacterEncoding("UTF-8");
- Map<String,String> nsMap = new HashMap<>();
- nsMap.put(passwordUri.toString(),"p");
- xo.setUseDefaultNamespace();
- xo.setSaveSuggestedPrefixes(nsMap);
- xo.setSaveNamespacesFirst();
- xo.setSaveAggressiveNamespaces();
-
- // setting standalone doesn't work with xmlbeans-2.3 & 2.6
- // ed.documentProperties().setStandalone(true);
- xo.setSaveNoXmlDecl();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ Document doc = XMLHelper.newDocumentBuilder().newDocument();
+ ed.write(doc);
+
try {
- bos.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n".getBytes(StandardCharsets.UTF_8));
- ed.save(bos, xo);
- bos.writeTo(os);
- } catch (IOException e) {
+ Transformer trans = XMLHelper.newTransformer();
+ trans.setOutputProperty(OutputKeys.METHOD, "xml");
+ trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ trans.setOutputProperty(OutputKeys.INDENT, "no");
+ trans.setOutputProperty(OutputKeys.STANDALONE, "yes");
+ trans.transform(new DOMSource(doc), new StreamResult(os));
+ } catch (TransformerException e) {
throw new EncryptedDocumentException("error marshalling encryption info document", e);
}
}
@@ -399,7 +363,7 @@ public class AgileEncryptor extends Encr
protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile)
throws IOException {
DataSpaceMapUtils.addDefaultDataSpace(dir);
- createEncryptionEntry(dir, "EncryptionInfo", this::marshallEncryptionRecord);
+ createEncryptionEntry(dir, ENCRYPTION_INFO_ENTRY, this::marshallEncryptionRecord);
}
private void marshallEncryptionRecord(LittleEndianByteArrayOutputStream bos) {
Added: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/CertificateKeyEncryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/CertificateKeyEncryptor.java?rev=1880164&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/CertificateKeyEncryptor.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/CertificateKeyEncryptor.java Wed Jul 22 22:08:33 2020
@@ -0,0 +1,95 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.crypt.agile;
+
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getBinAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.setBinAttr;
+
+import org.apache.poi.EncryptedDocumentException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class CertificateKeyEncryptor {
+
+ /**
+ * A base64-encoded value that specifies the encrypted form of the intermediate key,
+ * which is encrypted with the public key contained within the X509Certificate attribute.
+ */
+ private byte[] encryptedKeyValue;
+
+ /**
+ * A base64-encoded value that specifies a DER-encoded X.509 certificate (1) used to encrypt the intermediate key.
+ * The certificate (1) MUST contain only the public portion of the public-private key pair.
+ */
+ private byte[] x509Certificate;
+
+ /**
+ * A base64-encoded value that specifies the HMAC of the binary data obtained by base64-decoding the X509Certificate
+ * attribute. The hashing algorithm used to derive the HMAC MUST be the hashing algorithm specified for the
+ * Encryption.keyData element. The secret key used to derive the HMAC MUST be the intermediate key. If the
+ * intermediate key is reset, any CertificateKeyEncryptor elements are also reset to contain the new intermediate
+ * key, except that the certVerifier attribute MUST match the value calculated using the current intermediate key,
+ * to verify that the CertificateKeyEncryptor element actually encrypted the current intermediate key. If a
+ * CertificateKeyEncryptor element does not have a correct certVerifier attribute, it MUST be discarded.
+ */
+ private byte[] certVerifier;
+
+ public CertificateKeyEncryptor(Element certificateKey) {
+ if (certificateKey == null) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ encryptedKeyValue = getBinAttr(certificateKey, "encryptedKeyValue");
+ x509Certificate = getBinAttr(certificateKey, "X509Certificate");
+ certVerifier = getBinAttr(certificateKey, "certVerifier");
+ }
+
+ void write(Element encryption) {
+ Document doc = encryption.getOwnerDocument();
+ Element keyEncryptor = (Element) encryption.appendChild(doc.createElement("keyEncryptor"));
+ keyEncryptor.setAttribute("uri", KeyEncryptor.CERT_NS);
+ Element encryptedKey = (Element) keyEncryptor.appendChild(doc.createElement("c:encryptedKey"));
+
+ setBinAttr(encryptedKey, "encryptedKeyValue", encryptedKeyValue);
+ setBinAttr(encryptedKey, "x509Certificate", x509Certificate);
+ setBinAttr(encryptedKey, "certVerifier", certVerifier);
+ }
+
+ public byte[] getEncryptedKeyValue() {
+ return encryptedKeyValue;
+ }
+
+ public void setEncryptedKeyValue(byte[] encryptedKeyValue) {
+ this.encryptedKeyValue = encryptedKeyValue;
+ }
+
+ public byte[] getX509Certificate() {
+ return x509Certificate;
+ }
+
+ public void setX509Certificate(byte[] x509Certificate) {
+ this.x509Certificate = x509Certificate;
+ }
+
+ public byte[] getCertVerifier() {
+ return certVerifier;
+ }
+
+ public void setCertVerifier(byte[] certVerifier) {
+ this.certVerifier = certVerifier;
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/CertificateKeyEncryptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/DataIntegrity.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/DataIntegrity.java?rev=1880164&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/DataIntegrity.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/DataIntegrity.java Wed Jul 22 22:08:33 2020
@@ -0,0 +1,82 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.crypt.agile;
+
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.ENC_NS;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getBinAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getTag;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.setBinAttr;
+
+import org.apache.poi.EncryptedDocumentException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * A complex type that specifies data used to verify whether the encrypted data passes an integrity check.
+ * It MUST be generated using the method specified in section 2.3.4.14
+ *
+ * @see <a href="http://msdn.microsoft.com/en-us/library/dd924068(v=office.12).aspx">DataIntegrity Generation</a>
+ */
+public class DataIntegrity {
+ /**
+ * A base64-encoded value that specifies an encrypted key used in calculating the encryptedHmacValue.
+ */
+ private byte[] encryptedHmacKey;
+
+ /**
+ * A base64-encoded value that specifies an HMAC derived from encryptedHmacKey and the encrypted data.
+ */
+ private byte[] encryptedHmacValue;
+
+ public DataIntegrity() {
+
+ }
+
+ public DataIntegrity(Element parent) {
+ Element dataIntegrity = getTag(parent, ENC_NS, "dataIntegrity");
+ if (dataIntegrity == null) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ encryptedHmacKey = getBinAttr(dataIntegrity, "encryptedHmacKey");
+ encryptedHmacValue = getBinAttr(dataIntegrity, "encryptedHmacValue");
+ }
+
+ void write(Element encryption) {
+ Document doc = encryption.getOwnerDocument();
+ Element dataIntegrity = (Element)encryption.appendChild(doc.createElement("dataIntegrity"));
+ setBinAttr(dataIntegrity, "encryptedHmacKey", encryptedHmacKey);
+ setBinAttr(dataIntegrity, "encryptedHmacValue", encryptedHmacValue);
+ }
+
+ public byte[] getEncryptedHmacKey() {
+ return encryptedHmacKey;
+ }
+
+ public void setEncryptedHmacKey(byte[] encryptedHmacKey) {
+ this.encryptedHmacKey = encryptedHmacKey;
+ }
+
+ public byte[] getEncryptedHmacValue() {
+ return encryptedHmacValue;
+ }
+
+ public void setEncryptedHmacValue(byte[] encryptedHmacValue) {
+ this.encryptedHmacValue = encryptedHmacValue;
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/DataIntegrity.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/EncryptionDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/EncryptionDocument.java?rev=1880164&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/EncryptionDocument.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/EncryptionDocument.java Wed Jul 22 22:08:33 2020
@@ -0,0 +1,150 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.crypt.agile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.XMLConstants;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.poi.EncryptedDocumentException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class EncryptionDocument {
+ static final String ENC_NS = "http://schemas.microsoft.com/office/2006/encryption";
+
+ private KeyData keyData;
+
+ /**
+ * All ECMA-376 documents [ECMA-376] encrypted by Microsoft Office using agile encryption will have a DataIntegrity
+ * element present. The schema allows for a DataIntegrity element to not be present because the encryption schema
+ * can be used by applications that do not create ECMA-376 documents [ECMA-376].
+ */
+ private DataIntegrity dataIntegrity;
+
+ private final List<KeyEncryptor> keyEncryptors = new ArrayList<>();
+
+ public EncryptionDocument() {
+
+ }
+
+ public void parse(Document doc) {
+ Element encryption = doc.getDocumentElement();
+ if (!ENC_NS.equals(encryption.getNamespaceURI()) || !"encryption".equals(encryption.getLocalName())) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ keyData = new KeyData(encryption);
+ dataIntegrity = new DataIntegrity(encryption);
+
+ // The KeyEncryptor element, which MUST be used when encrypting password-protected agile encryption documents,
+ // is either a PasswordKeyEncryptor or a CertificateKeyEncryptor. Exactly one PasswordKeyEncryptor MUST be
+ // present. Zero or more CertificateKeyEncryptor elements are contained within the KeyEncryptors element.
+ Element keyEncryptors = getTag(encryption, ENC_NS, "keyEncryptors");
+ if (keyEncryptors == null) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ NodeList ke = keyEncryptors.getElementsByTagNameNS(ENC_NS, "keyEncryptor");
+ for (int i=0; i<ke.getLength(); i++) {
+ this.keyEncryptors.add(new KeyEncryptor((Element)ke.item(i)));
+ }
+ }
+
+ public void write(Document doc) {
+ doc.setXmlStandalone(true);
+ Element encryption = (Element)doc.appendChild(doc.createElementNS(ENC_NS, "encryption"));
+ if (keyData != null) {
+ keyData.write(encryption);
+ }
+ if (dataIntegrity != null) {
+ dataIntegrity.write(encryption);
+ }
+ Element keyEncryptors = (Element)encryption.appendChild(doc.createElement("keyEncryptors"));
+ boolean hasPass = false;
+ boolean hasCert = false;
+ for (KeyEncryptor ke : this.keyEncryptors) {
+ ke.write(keyEncryptors);
+ hasPass |= ke.getPasswordKeyEncryptor() != null;
+ hasCert |= ke.getCertificateKeyEncryptor() != null;
+ }
+ if (hasPass) {
+ encryption.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:p", KeyEncryptor.PASS_NS);
+ }
+ if (hasCert) {
+ encryption.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:c", KeyEncryptor.CERT_NS);
+ }
+
+ }
+
+
+ public KeyData getKeyData() {
+ return keyData;
+ }
+
+ public void setKeyData(KeyData keyData) {
+ this.keyData = keyData;
+ }
+
+ public DataIntegrity getDataIntegrity() {
+ return dataIntegrity;
+ }
+
+ public void setDataIntegrity(DataIntegrity dataIntegrity) {
+ this.dataIntegrity = dataIntegrity;
+ }
+
+ public List<KeyEncryptor> getKeyEncryptors() {
+ return keyEncryptors;
+ }
+
+ static Element getTag(Element el, String ns, String name) {
+ if (el == null) {
+ return null;
+ }
+ NodeList nl = el.getElementsByTagNameNS(ns, name);
+ return (nl.getLength() > 0) ? (Element)nl.item(0) : null;
+ }
+
+ static Integer getIntAttr(Element el, String name) {
+ String at = el.getAttribute(name);
+ return (at.isEmpty()) ? null : Integer.valueOf(at);
+ }
+
+ static byte[] getBinAttr(Element el, String name) {
+ String at = el.getAttribute(name);
+ return (at.isEmpty()) ? null : Base64.decodeBase64(at);
+ }
+
+ static void setIntAttr(Element el, String name, Integer val) {
+ setAttr(el, name, val == null ? null : val.toString());
+ }
+
+ static void setAttr(Element el, String name, String val) {
+ if (val != null) {
+ el.setAttribute(name, val);
+ }
+ }
+
+ static void setBinAttr(Element el, String name, byte[] val) {
+ if (val != null) {
+ setAttr(el, name, Base64.encodeBase64String(val));
+ }
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/EncryptionDocument.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyData.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyData.java?rev=1880164&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyData.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyData.java Wed Jul 22 22:08:33 2020
@@ -0,0 +1,148 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.crypt.agile;
+
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.ENC_NS;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getBinAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getIntAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.getTag;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.setAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.setBinAttr;
+import static org.apache.poi.poifs.crypt.agile.EncryptionDocument.setIntAttr;
+
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.poifs.crypt.ChainingMode;
+import org.apache.poi.poifs.crypt.CipherAlgorithm;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * A complex type that specifies the encryption used within this element. The saltValue attribute is a base64-encoded
+ * binary value that is randomly generated. The number of bytes required to decode the saltValue attribute MUST be equal
+ * to the value of the saltSize attribute.
+ */
+public class KeyData {
+ private Integer saltSize;
+ private Integer blockSize;
+ private Integer keyBits;
+ private Integer hashSize;
+ private CipherAlgorithm cipherAlgorithm;
+ private ChainingMode cipherChaining;
+ private HashAlgorithm hashAlgorithm;
+ private byte[] saltValue;
+
+ public KeyData() {
+
+ }
+
+ public KeyData(Element parent) {
+ Element keyData = getTag(parent, ENC_NS, "keyData");
+ if (keyData == null) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ saltSize = getIntAttr(keyData, "saltSize");
+ blockSize = getIntAttr(keyData, "blockSize");
+ keyBits = getIntAttr(keyData, "keyBits");
+ hashSize = getIntAttr(keyData, "hashSize");
+ cipherAlgorithm = CipherAlgorithm.fromXmlId(keyData.getAttribute("cipherAlgorithm"), keyBits);
+ cipherChaining = ChainingMode.fromXmlId(keyData.getAttribute("cipherChaining"));
+ hashAlgorithm = HashAlgorithm.fromEcmaId(keyData.getAttribute("hashAlgorithm"));
+ if (cipherAlgorithm == null || cipherChaining == null || hashAlgorithm == null) {
+ throw new EncryptedDocumentException("Cipher algorithm, chaining mode or hash algorithm was null");
+ }
+ saltValue = getBinAttr(keyData, "saltValue");
+ }
+
+ void write(Element encryption) {
+ Document doc = encryption.getOwnerDocument();
+ Element keyData = (Element)encryption.appendChild(doc.createElement("keyData"));
+ setIntAttr(keyData, "saltSize", saltSize);
+ setIntAttr(keyData, "blockSize", blockSize);
+ setIntAttr(keyData, "keyBits", keyBits);
+ setIntAttr(keyData, "hashSize", hashSize);
+ setAttr(keyData, "cipherAlgorithm", cipherAlgorithm == null ? null : cipherAlgorithm.xmlId);
+ setAttr(keyData, "cipherChaining", cipherChaining == null ? null : cipherChaining.xmlId);
+ setAttr(keyData, "hashAlgorithm", hashAlgorithm == null ? null : hashAlgorithm.ecmaString);
+ setBinAttr(keyData, "saltValue", saltValue);
+ }
+
+ public Integer getSaltSize() {
+ return saltSize;
+ }
+
+ public void setSaltSize(Integer saltSize) {
+ this.saltSize = saltSize;
+ }
+
+ public Integer getBlockSize() {
+ return blockSize;
+ }
+
+ public void setBlockSize(Integer blockSize) {
+ this.blockSize = blockSize;
+ }
+
+ public Integer getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(Integer keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public Integer getHashSize() {
+ return hashSize;
+ }
+
+ public void setHashSize(Integer hashSize) {
+ this.hashSize = hashSize;
+ }
+
+ public CipherAlgorithm getCipherAlgorithm() {
+ return cipherAlgorithm;
+ }
+
+ public void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
+ this.cipherAlgorithm = cipherAlgorithm;
+ }
+
+ public ChainingMode getCipherChaining() {
+ return cipherChaining;
+ }
+
+ public void setCipherChaining(ChainingMode cipherChaining) {
+ this.cipherChaining = cipherChaining;
+ }
+
+ public HashAlgorithm getHashAlgorithm() {
+ return hashAlgorithm;
+ }
+
+ public void setHashAlgorithm(HashAlgorithm hashAlgorithm) {
+ this.hashAlgorithm = hashAlgorithm;
+ }
+
+ public byte[] getSaltValue() {
+ return saltValue;
+ }
+
+ public void setSaltValue(byte[] saltValue) {
+ this.saltValue = (saltValue == null) ? null : saltValue.clone();
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyData.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyEncryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyEncryptor.java?rev=1880164&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyEncryptor.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyEncryptor.java Wed Jul 22 22:08:33 2020
@@ -0,0 +1,81 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.crypt.agile;
+
+import org.apache.poi.EncryptedDocumentException;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * A sequence of KeyEncryptor elements. Exactly one KeyEncryptors element MUST be present, and the KeyEncryptors element
+ * MUST contain at least one KeyEncryptor.
+ */
+public class KeyEncryptor {
+ static final String PASS_NS = "http://schemas.microsoft.com/office/2006/keyEncryptor/password";
+ static final String CERT_NS = "http://schemas.microsoft.com/office/2006/keyEncryptor/certificate";
+
+ private PasswordKeyEncryptor passwordKeyEncryptor;
+ private CertificateKeyEncryptor certificateKeyEncryptor;
+
+ public KeyEncryptor() {
+
+ }
+
+ public KeyEncryptor(Element keyEncryptor) {
+ if (keyEncryptor == null) {
+ throw new EncryptedDocumentException("Unable to parse encryption descriptor");
+ }
+ NodeList nl = keyEncryptor.getElementsByTagNameNS("*", "encryptedKey");
+ // usually only one encryptor is set, so iterate and overwrite the encryptor members
+ for (int i=0; i<nl.getLength(); i++) {
+ Element el = (Element)nl.item(i);
+ String nsUri = el.getNamespaceURI();
+ if (PASS_NS.equals(nsUri)) {
+ passwordKeyEncryptor = new PasswordKeyEncryptor(el);
+ } else if (CERT_NS.equals(nsUri)) {
+ certificateKeyEncryptor = new CertificateKeyEncryptor(el);
+ }
+ }
+ }
+
+ void write(Element keyEncryptors) {
+ if (passwordKeyEncryptor != null) {
+ passwordKeyEncryptor.write(keyEncryptors);
+ } else if (certificateKeyEncryptor != null) {
+ certificateKeyEncryptor.write(keyEncryptors);
+ }
+ }
+
+
+
+ public PasswordKeyEncryptor getPasswordKeyEncryptor() {
+ return passwordKeyEncryptor;
+ }
+
+ public void setPasswordKeyEncryptor(PasswordKeyEncryptor passwordKeyEncryptor) {
+ this.passwordKeyEncryptor = passwordKeyEncryptor;
+ }
+
+ public CertificateKeyEncryptor getCertificateKeyEncryptor() {
+ return certificateKeyEncryptor;
+ }
+
+ public void setCertificateKeyEncryptor(CertificateKeyEncryptor certificateKeyEncryptor) {
+ this.certificateKeyEncryptor = certificateKeyEncryptor;
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/poifs/crypt/agile/KeyEncryptor.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org