diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2021-03-17 22:51:58 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2021-03-17 22:51:58 +0000 |
commit | 2ceb5ff55346ee97c3541c9e7bcd8bc5847be9b4 (patch) | |
tree | 54b5728fae97e9f0d125db9265b8800b1e786b91 /src/java/org/apache | |
parent | 393d3a3ce98b06560b3e6cd0fb4d0ce60f355eaa (diff) | |
download | poi-2ceb5ff55346ee97c3541c9e7bcd8bc5847be9b4.tar.gz poi-2ceb5ff55346ee97c3541c9e7bcd8bc5847be9b4.zip |
#65192 - Allow change of EncryptionMode
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1887764 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r-- | src/java/org/apache/poi/POIDocument.java | 10 | ||||
-rw-r--r-- | src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java | 42 |
2 files changed, 46 insertions, 6 deletions
diff --git a/src/java/org/apache/poi/POIDocument.java b/src/java/org/apache/poi/POIDocument.java index 519da97e3a..e2f613af64 100644 --- a/src/java/org/apache/poi/POIDocument.java +++ b/src/java/org/apache/poi/POIDocument.java @@ -271,7 +271,8 @@ public abstract class POIDocument implements Closeable { */ protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException { final EncryptionInfo ei = getEncryptionInfo(); - final boolean encryptProps = (ei != null && ei.isDocPropsEncrypted()); + Encryptor encGen = (ei == null) ? null : ei.getEncryptor(); + final boolean encryptProps = (ei != null && ei.isDocPropsEncrypted() && encGen instanceof CryptoAPIEncryptor); try (POIFSFileSystem tmpFS = new POIFSFileSystem()) { final POIFSFileSystem fs = (encryptProps) ? tmpFS : outFS; @@ -282,6 +283,8 @@ public abstract class POIDocument implements Closeable { return; } + // Only CryptoAPI encryption supports encrypted property sets + // create empty document summary writePropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME, newDocumentSummaryInformation(), outFS); @@ -289,11 +292,6 @@ public abstract class POIDocument implements Closeable { if (outFS.getRoot().hasEntry(SummaryInformation.DEFAULT_STREAM_NAME)) { outFS.getRoot().getEntry(SummaryInformation.DEFAULT_STREAM_NAME).delete(); } - Encryptor encGen = ei.getEncryptor(); - if (!(encGen instanceof CryptoAPIEncryptor)) { - throw new EncryptedDocumentException( - "Using " + ei.getEncryptionMode() + " encryption. Only CryptoAPI encryption supports encrypted property sets!"); - } CryptoAPIEncryptor enc = (CryptoAPIEncryptor) encGen; try { enc.setSummaryEntries(outFS.getRoot(), getEncryptedPropertyStreamName(), fs); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index d6e5c6329f..bd86c2857f 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -2255,4 +2255,46 @@ public final class HSSFWorkbook extends POIDocument implements Workbook { public HSSFEvaluationWorkbook createEvaluationWorkbook() { return HSSFEvaluationWorkbook.create(this); } + + /** + * Sets the encryption mode - if not set, defaults to {@link EncryptionMode#cryptoAPI}. + * Allowed modes are {@code null} = remove encryption - same as {@code Biff8EncryptionKey.setCurrentUserPassword(null)}, + * {@link EncryptionMode#cryptoAPI}, {@link EncryptionMode#binaryRC4}, {@link EncryptionMode#xor}. + * Use {@link EncryptionMode#binaryRC4} for Libre Office, but better use OOXML format/encryption for real security. + * + * @param mode the encryption mode + */ + public void setEncryptionMode(EncryptionMode mode) { + if (mode == null) { + Biff8EncryptionKey.setCurrentUserPassword(null); + return; + } + if (mode != EncryptionMode.xor && mode != EncryptionMode.binaryRC4 && mode != EncryptionMode.cryptoAPI) { + throw new IllegalArgumentException("Only xor, binaryRC4 and cryptoAPI are supported."); + } + + FilePassRecord oldFPR = (FilePassRecord)getInternalWorkbook().findFirstRecordBySid(FilePassRecord.sid); + EncryptionMode oldMode = (oldFPR == null) ? null : oldFPR.getEncryptionInfo().getEncryptionMode(); + if (mode == oldMode) { + return; + } + + // Properties need to be cached, when we change the encryption mode + readProperties(); + WorkbookRecordList wrl = getInternalWorkbook().getWorkbookRecordList(); + if (oldFPR != null) { + wrl.remove(oldFPR); + } + + FilePassRecord newFPR = new FilePassRecord(mode); + wrl.add(1, newFPR); + } + + /** + * @return the encryption mode or {@code null} if unset + */ + public EncryptionMode getEncryptionMode() { + FilePassRecord r = (FilePassRecord)getInternalWorkbook().findFirstRecordBySid(FilePassRecord.sid); + return (r == null) ? null : r.getEncryptionInfo().getEncryptionMode(); + } } |