}
public FilePassRecord(RecordInputStream in) {
- _encryptionType = in.readUShort();
-
- switch (_encryptionType) {
- case ENCRYPTION_XOR:
- _keyData = new XorKeyData();
- break;
- case ENCRYPTION_OTHER:
- _keyData = new Rc4KeyData();
- break;
- default:
- throw new RecordFormatException("Unknown encryption type " + _encryptionType);
- }
-
- _keyData.read(in);
- }
-
- private static byte[] read(RecordInputStream in, int size) {
- byte[] result = new byte[size];
- in.readFully(result);
- return result;
+ encryptionType = in.readUShort();
+
+ EncryptionMode preferredMode;
+ switch (encryptionType) {
+ case ENCRYPTION_XOR:
+ preferredMode = EncryptionMode.xor;
+ break;
+ case ENCRYPTION_OTHER:
+ preferredMode = EncryptionMode.cryptoAPI;
+ break;
+ default:
+ throw new EncryptedDocumentException("invalid encryption type");
+ }
+
+ try {
+ encryptionInfo = new EncryptionInfo(in, preferredMode);
+ } catch (IOException e) {
+ throw new EncryptedDocumentException(e);
+ }
}
- public void serialize(LittleEndianOutput out) {
- out.writeShort(_encryptionType);
- assert(_keyData != null);
- _keyData.serialize(out);
- @Override
++ @SuppressWarnings("resource")
++ @Override
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(encryptionType);
+
+ byte data[] = new byte[1024];
+ LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0);
+
+ switch (encryptionInfo.getEncryptionMode()) {
+ case xor:
+ ((XOREncryptionHeader)encryptionInfo.getHeader()).write(bos);
+ ((XOREncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+ break;
+ case binaryRC4:
+ out.writeShort(encryptionInfo.getVersionMajor());
+ out.writeShort(encryptionInfo.getVersionMinor());
+ ((BinaryRC4EncryptionHeader)encryptionInfo.getHeader()).write(bos);
+ ((BinaryRC4EncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+ break;
+ case cryptoAPI:
+ out.writeShort(encryptionInfo.getVersionMajor());
+ out.writeShort(encryptionInfo.getVersionMinor());
+ out.writeInt(encryptionInfo.getEncryptionFlags());
+ ((CryptoAPIEncryptionHeader)encryptionInfo.getHeader()).write(bos);
+ ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+ break;
+ default:
+ throw new RuntimeException("not supported");
+ }
+
+ out.write(data, 0, bos.getWriteIndex());
}
- protected int getDataSize() {
- assert(_keyData != null);
- return _keyData.getDataSize();
+ @Override
- @SuppressWarnings("resource")
+ protected int getDataSize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ LittleEndianOutputStream leos = new LittleEndianOutputStream(bos);
+ serialize(leos);
+ return bos.size();
}
- public Rc4KeyData getRc4KeyData() {
- return (_keyData instanceof Rc4KeyData)
- ? (Rc4KeyData) _keyData
- : null;
- }
-
- public XorKeyData getXorKeyData() {
- return (_keyData instanceof XorKeyData)
- ? (XorKeyData) _keyData
- : null;
- }
-
- private Rc4KeyData checkRc4() {
- Rc4KeyData rc4 = getRc4KeyData();
- if (rc4 == null) {
- throw new RecordFormatException("file pass record doesn't contain a rc4 key.");
- }
- return rc4;
+ public EncryptionInfo getEncryptionInfo() {
+ return encryptionInfo;
}
- public short getSid() {
+ @Override
+ public short getSid() {
return sid;
}
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.util.Configurator;
import org.apache.poi.util.HexDump;
-import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
+ import org.apache.poi.util.LittleEndianByteArrayInputStream;
+ import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
* The maximum number of cell styles in a .xls workbook.
* The 'official' limit is 4,000, but POI allows a slightly larger number.
* This extra delta takes into account built-in styles that are automatically
-- * created for new workbooks
*
* See http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP005199291.aspx
*/