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