Java Code Examples for org.apache.poi.EncryptedDocumentException

The following examples show how to use org.apache.poi.EncryptedDocumentException. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: lams   Source File: BinaryRC4Encryptor.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public void confirmPassword(String password, byte keySpec[],
        byte keySalt[], byte verifier[], byte verifierSalt[],
        byte integritySalt[]) {
    BinaryRC4EncryptionVerifier ver = (BinaryRC4EncryptionVerifier)getEncryptionInfo().getVerifier();
    ver.setSalt(verifierSalt);
    SecretKey skey = BinaryRC4Decryptor.generateSecretKey(password, ver);
    setSecretKey(skey);
    try {
        Cipher cipher = BinaryRC4Decryptor.initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.ENCRYPT_MODE);
        byte encryptedVerifier[] = new byte[16];
        cipher.update(verifier, 0, 16, encryptedVerifier);
        ver.setEncryptedVerifier(encryptedVerifier);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash);
        ver.setEncryptedVerifierHash(encryptedVerifierHash);
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("Password confirmation failed", e);
    }
}
 
Example 2
Source Project: lams   Source File: BinaryRC4Decryptor.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean verifyPassword(String password) {
    EncryptionVerifier ver = getEncryptionInfo().getVerifier();
    SecretKey skey = generateSecretKey(password, ver);
    try {
        Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE);
        byte encryptedVerifier[] = ver.getEncryptedVerifier();
        byte verifier[] = new byte[encryptedVerifier.length];
        cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier);
        setVerifier(verifier);
        byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash();
        byte verifierHash[] = cipher.doFinal(encryptedVerifierHash);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        if (Arrays.equals(calcVerifierHash, verifierHash)) {
            setSecretKey(skey);
            return true;
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
    return false;
}
 
Example 3
Source Project: lams   Source File: EncryptionInfo.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * Constructs an EncryptionInfo from scratch
 *
 * @param encryptionMode see {@link EncryptionMode} for values, {@link EncryptionMode#cryptoAPI} is for
 *   internal use only, as it's record based
 * @param cipherAlgorithm
 * @param hashAlgorithm
 * @param keyBits
 * @param blockSize
 * @param chainingMode
 * 
 * @throws EncryptedDocumentException if the given parameters mismatch, e.g. only certain combinations
 *   of keyBits, blockSize are allowed for a given {@link CipherAlgorithm}
 */
public EncryptionInfo(
        EncryptionMode encryptionMode
      , CipherAlgorithm cipherAlgorithm
      , HashAlgorithm hashAlgorithm
      , int keyBits
      , int blockSize
      , ChainingMode chainingMode
  ) {
    this.encryptionMode = encryptionMode; 
    versionMajor = encryptionMode.versionMajor;
    versionMinor = encryptionMode.versionMinor;
    encryptionFlags = encryptionMode.encryptionFlags;

    EncryptionInfoBuilder eib;
    try {
        eib = getBuilder(encryptionMode);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
    
    eib.initialize(this, cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode);
}
 
Example 4
Source Project: lams   Source File: StandardEncryptor.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public void processPOIFSWriterEvent(POIFSWriterEvent event) {
    try {
        LittleEndianOutputStream leos = new LittleEndianOutputStream(event.getStream());

        // StreamSize (8 bytes): An unsigned integer that specifies the number of bytes used by data 
        // encrypted within the EncryptedData field, not including the size of the StreamSize field. 
        // Note that the actual size of the \EncryptedPackage stream (1) can be larger than this 
        // value, depending on the block size of the chosen encryption algorithm
        leos.writeLong(countBytes);

        FileInputStream fis = new FileInputStream(fileOut);
        try {
            IOUtils.copy(fis, leos);
        } finally {
            fis.close();
        }
        if (!fileOut.delete()) {
            logger.log(POILogger.ERROR, "Can't delete temporary encryption file: "+fileOut);
        }

        leos.close();
    } catch (IOException e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example 5
@Override
public void setKeySize(int keyBits) {
    // Microsoft Base Cryptographic Provider is limited up to 40 bits
    // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375599(v=vs.85).aspx
    boolean found = false;
    for (int size : getCipherAlgorithm().allowedKeySize) {
        if (size == keyBits) {
            found = true;
            break;
        }
    }
    if (!found) {
        throw new EncryptedDocumentException("invalid keysize "+keyBits+" for cipher algorithm "+getCipherAlgorithm());
    }
    super.setKeySize(keyBits);
    if (keyBits > 40) {
        setCspName("Microsoft Enhanced Cryptographic Provider v1.0");
    } else {
        setCspName(CipherProvider.rc4.cipherProviderName);
    }
}
 
Example 6
Source Project: lams   Source File: CryptoAPIEncryptor.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public void confirmPassword(String password, byte keySpec[],
        byte keySalt[], byte verifier[], byte verifierSalt[],
        byte integritySalt[]) {
    assert(verifier != null && verifierSalt != null);
    CryptoAPIEncryptionVerifier ver = (CryptoAPIEncryptionVerifier)getEncryptionInfo().getVerifier();
    ver.setSalt(verifierSalt);
    SecretKey skey = CryptoAPIDecryptor.generateSecretKey(password, ver);
    setSecretKey(skey);
    try {
        Cipher cipher = initCipherForBlock(null, 0);
        byte encryptedVerifier[] = new byte[verifier.length];
        cipher.update(verifier, 0, verifier.length, encryptedVerifier);
        ver.setEncryptedVerifier(encryptedVerifier);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash);
        ver.setEncryptedVerifierHash(encryptedVerifierHash);
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("Password confirmation failed", e);
    }
}
 
Example 7
Source Project: lams   Source File: CryptoAPIDecryptor.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean verifyPassword(String password) {
    EncryptionVerifier ver = getEncryptionInfo().getVerifier();
    SecretKey skey = generateSecretKey(password, ver);
    try {
        Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE);
        byte encryptedVerifier[] = ver.getEncryptedVerifier();
        byte verifier[] = new byte[encryptedVerifier.length];
        cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier);
        setVerifier(verifier);
        byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash();
        byte verifierHash[] = cipher.doFinal(encryptedVerifierHash);
        HashAlgorithm hashAlgo = ver.getHashAlgorithm();
        MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo);
        byte calcVerifierHash[] = hashAlg.digest(verifier);
        if (Arrays.equals(calcVerifierHash, verifierHash)) {
            setSecretKey(skey);
            return true;
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
    return false;
}
 
Example 8
Source Project: lams   Source File: DataSpaceMapUtils.java    License: GNU General Public License v2.0 6 votes vote down vote up
public static String readUnicodeLPP4(LittleEndianInput is) {
    int length = is.readInt();
    if (length%2 != 0) {
        throw new EncryptedDocumentException(
            "UNICODE-LP-P4 structure is a multiple of 4 bytes. "
            + "If Padding is present, it MUST be exactly 2 bytes long");
    }
    
    String result = StringUtil.readUnicodeLE(is, length/2);
    if (length%4==2) {
        // Padding (variable): A set of bytes that MUST be of the correct size such that the size of the 
        // UNICODE-LP-P4 structure is a multiple of 4 bytes. If Padding is present, it MUST be exactly 
        // 2 bytes long, and each byte MUST be 0x00.            
        is.readShort();
    }
    
    return result;
}
 
Example 9
Source Project: lams   Source File: FilePassRecord.java    License: GNU General Public License v2.0 6 votes vote down vote up
public FilePassRecord(RecordInputStream in) {
	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);
       }
}
 
Example 10
public RecordInputStream createDecryptingStream(InputStream original) {
	FilePassRecord fpr = _filePassRec;
	String userPassword = Biff8EncryptionKey.getCurrentUserPassword();
	if (userPassword == null) {
	    userPassword = Decryptor.DEFAULT_PASSWORD;
	}

	EncryptionInfo info = fpr.getEncryptionInfo();
          try {
              if (!info.getDecryptor().verifyPassword(userPassword)) {
                  throw new EncryptedDocumentException(
                          (Decryptor.DEFAULT_PASSWORD.equals(userPassword) ? "Default" : "Supplied")
                          + " password is invalid for salt/verifier/verifierHash");
              }
          } catch (GeneralSecurityException e) {
              throw new EncryptedDocumentException(e);
          }

	return new RecordInputStream(original, info, _initialRecordsSize);
}
 
Example 11
@Override
public List<Sheet> buildExcelSheetsFromFile(File file) throws EmptySheetException {
  List<Sheet> sheets = newArrayList();
  try (Workbook workbook = WorkbookFactory.create(file)) {
    int numberOfSheets = workbook.getNumberOfSheets();

    for (int index = 0; index < numberOfSheets; index++) {
      Sheet sheet = workbook.getSheetAt(index);
      if (sheet.getPhysicalNumberOfRows() == 0) {
        throw new EmptySheetException("Sheet [" + sheet.getSheetName() + "] is empty");
      } else if (sheet.getPhysicalNumberOfRows() == 1) {
        throw new MolgenisDataException(
            "Header was found, but no data is present in sheet [" + sheet.getSheetName() + "]");
      } else {
        sheets.add(sheet);
      }
    }

  } catch (IOException | EncryptedDocumentException ex) {
    LOG.error(ex.getLocalizedMessage());
    throw new MolgenisDataException("Could not create excel workbook from file");
  }
  return sheets;
}
 
Example 12
Source Project: vividus   Source File: ExcelSheetsExtractor.java    License: Apache License 2.0 5 votes vote down vote up
public ExcelSheetsExtractor(byte[] bytes) throws WorkbookParsingException
{
    try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
    {
        sheets = getAllSheetsFromWorkbook(wb);
    }
    catch (EncryptedDocumentException | IOException e)
    {
        throw new WorkbookParsingException(e);
    }
}
 
Example 13
Source Project: vividus   Source File: ExcelSheetsExtractor.java    License: Apache License 2.0 5 votes vote down vote up
public ExcelSheetsExtractor(String path) throws WorkbookParsingException
{
    try (Workbook wb = WorkbookFactory
            .create(ResourceUtils.loadFile(this.getClass(), StringUtils.prependIfMissing(path, "/"))))
    {
        sheets = getAllSheetsFromWorkbook(wb);
    }
    catch (EncryptedDocumentException | IOException e)
    {
        throw new WorkbookParsingException(e);
    }
}
 
Example 14
Source Project: vividus   Source File: ExcelSheetsExtractorTests.java    License: Apache License 2.0 5 votes vote down vote up
@DataProvider
public static Object[][] exceptionDataProvider()
{
    // @formatter:off
    return new Object[][] {
        { EncryptedDocumentException.class },
        { IOException.class }};
    // @formatter:on
}
 
Example 15
Source Project: Exam-Online   Source File: ExcelToQuestionUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static List<Question> readQuestions(File file) 
		throws EncryptedDocumentException, InvalidFormatException, IOException {
	
	Workbook workbook = WorkbookFactory.create(file);
	List<Question> questions = readQuestions(workbook.getSheetAt(0)); 
	workbook.close();
	return questions;
}
 
Example 16
Source Project: Exam-Online   Source File: ExcelToQuestionUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static List<Question> readQuestions(InputStream inputStream) 
		throws EncryptedDocumentException, InvalidFormatException, IOException {
	
	Workbook workbook = WorkbookFactory.create(inputStream);
	List<Question> questions = readQuestions(workbook.getSheetAt(0)); 
	workbook.close();
	return questions;
}
 
Example 17
Source Project: Exam-Online   Source File: ExcelToQuestionUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) throws EncryptedDocumentException, InvalidFormatException, IOException {
	File file = new File("e://test.xls");
	List<Question> questions = readQuestions(file);
	questions.forEach(q -> {
		System.out.println(q);
	});
}
 
Example 18
Source Project: lams   Source File: DocumentFactoryHelper.java    License: GNU General Public License v2.0 5 votes vote down vote up
/**
 * Wrap the OLE2 data in the NPOIFSFileSystem into a decrypted stream by using
 * the given password.
 *
 * @param fs The OLE2 stream for the document
 * @param password The password, null if the default password should be used
 * @return A stream for reading the decrypted data
 * @throws IOException If an error occurs while decrypting or if the password does not match
 */
public static InputStream getDecryptedStream(final NPOIFSFileSystem fs, String password)
        throws IOException {
    EncryptionInfo info = new EncryptionInfo(fs);
    Decryptor d = Decryptor.getInstance(info);

    try {
        boolean passwordCorrect = false;
        if (password != null && d.verifyPassword(password)) {
            passwordCorrect = true;
        }
        if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
            passwordCorrect = true;
        }

        if (passwordCorrect) {
            // wrap the stream in a FilterInputStream to close the NPOIFSFileSystem
            // as well when the resulting OPCPackage is closed
            return new FilterInputStream(d.getDataStream(fs.getRoot())) {
                @Override
                public void close() throws IOException {
                    fs.close();

                    super.close();
                }
            };
        } else {
            if (password != null)
                throw new EncryptedDocumentException("Password incorrect");
            else
                throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied");
        }
    } catch (GeneralSecurityException e) {
        throw new IOException(e);
    }
}
 
Example 19
@Override
protected void setSalt(byte salt[]) {
    if (salt == null || salt.length != 16) {
        throw new EncryptedDocumentException("invalid verifier salt");
    }
    
    super.setSalt(salt);
}
 
Example 20
@Override
public void processPOIFSWriterEvent(POIFSWriterEvent event) {
    try {
        OutputStream os = event.getStream();

        // StreamSize (8 bytes): An unsigned integer that specifies the number of bytes used by data
        // encrypted within the EncryptedData field, not including the size of the StreamSize field.
        // Note that the actual size of the \EncryptedPackage stream (1) can be larger than this
        // value, depending on the block size of the chosen encryption algorithm
        byte buf[] = new byte[LittleEndianConsts.LONG_SIZE];
        LittleEndian.putLong(buf, 0, pos);
        os.write(buf);

        FileInputStream fis = new FileInputStream(fileOut);
        try {
            IOUtils.copy(fis, os);
        } finally {
            fis.close();
        }

        os.close();

        if (!fileOut.delete()) {
            LOG.log(POILogger.ERROR, "Can't delete temporary encryption file: "+fileOut);
        }
    } catch (IOException e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example 21
Source Project: lams   Source File: StandardDecryptor.java    License: GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean verifyPassword(String password) {
    EncryptionVerifier ver = getEncryptionInfo().getVerifier();
    SecretKey skey = generateSecretKey(password, ver, getKeySizeInBytes());
    Cipher cipher = getCipher(skey);

    try {
        byte encryptedVerifier[] = ver.getEncryptedVerifier();
        byte verifier[] = cipher.doFinal(encryptedVerifier);
        setVerifier(verifier);
        MessageDigest sha1 = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm());
        byte[] calcVerifierHash = sha1.digest(verifier);
        byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash();
        byte decryptedVerifierHash[] = cipher.doFinal(encryptedVerifierHash);

        // see 2.3.4.9 Password Verification (Standard Encryption)
        // ... The number of bytes used by the encrypted Verifier hash MUST be 32 ...
        // TODO: check and trim/pad the hashes to 32
        byte[] verifierHash = Arrays.copyOf(decryptedVerifierHash, calcVerifierHash.length);

        if (Arrays.equals(calcVerifierHash, verifierHash)) {
            setSecretKey(skey);
            return true;
        } else {
            return false;
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example 22
Source Project: lams   Source File: StandardEncryptor.java    License: GNU General Public License v2.0 5 votes vote down vote up
/**
 * Fills the fields of verifier and header with the calculated hashes based
 * on the password and a random salt
 * 
 * see [MS-OFFCRYPTO] - 2.3.4.7 ECMA-376 Document Encryption Key Generation
 */
@Override
public void confirmPassword(String password, byte keySpec[], byte keySalt[], byte verifier[], byte verifierSalt[], byte integritySalt[]) {
    StandardEncryptionVerifier ver = (StandardEncryptionVerifier)getEncryptionInfo().getVerifier();

    ver.setSalt(verifierSalt);
    SecretKey secretKey = generateSecretKey(password, ver, getKeySizeInBytes());
    setSecretKey(secretKey);
    Cipher cipher = getCipher(secretKey, null);
    
    try {
        byte encryptedVerifier[] = cipher.doFinal(verifier); 
        MessageDigest hashAlgo = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm());
        byte calcVerifierHash[] = hashAlgo.digest(verifier);
        
        // 2.3.3 EncryptionVerifier ...
        // An array of bytes that contains the encrypted form of the 
        // hash of the randomly generated Verifier value. The length of the array MUST be the size of 
        // the encryption block size multiplied by the number of blocks needed to encrypt the hash of the 
        // Verifier. If the encryption algorithm is RC4, the length MUST be 20 bytes. If the encryption 
        // algorithm is AES, the length MUST be 32 bytes. After decrypting the EncryptedVerifierHash
        // field, only the first VerifierHashSize bytes MUST be used.
        int encVerHashSize = ver.getCipherAlgorithm().encryptedVerifierHashLength; 
        byte encryptedVerifierHash[] = cipher.doFinal(Arrays.copyOf(calcVerifierHash, encVerHashSize));

        ver.setEncryptedVerifier(encryptedVerifier);
        ver.setEncryptedVerifierHash(encryptedVerifierHash);
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException("Password confirmation failed", e);
    }
    
}
 
Example 23
@Override
protected void setSalt(byte salt[]) {
    if (salt == null || salt.length != 16) {
        throw new EncryptedDocumentException("invalid verifier salt");
    }
    super.setSalt(salt);
}
 
Example 24
@Override
public void write(int b) {
    try {
        oneByte[0] = (byte)b;
        cipher.update(oneByte, 0, 1, oneByte, 0);
        super.write(oneByte);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example 25
@Override
public void write(byte[] b, int off, int len) {
    try {
        cipher.update(b, off, len, b, off);
        super.write(b, off, len);
    } catch (Exception e) {
        throw new EncryptedDocumentException(e);
    }
}
 
Example 26
@Override
public synchronized int read() {
    int ch = super.read();
    if (ch == -1) {
        return -1;
    }
    oneByte[0] = (byte) ch;
    try {
        cipher.update(oneByte, 0, 1, oneByte);
    } catch (ShortBufferException e) {
        throw new EncryptedDocumentException(e);
    }
    return oneByte[0];
}
 
Example 27
@Override
public synchronized int read(byte b[], int off, int len) {
    int readLen = super.read(b, off, len);
    if (readLen ==-1) {
        return -1;
    }
    try {
        cipher.update(b, off, readLen, b, off);
    } catch (ShortBufferException e) {
        throw new EncryptedDocumentException(e);
    }
    return readLen;
}
 
Example 28
private int read(byte[] b, int off, int len, boolean readPlain) throws IOException {
    int total = 0;

    if (available() <= 0) {
        return -1;
    }

    final int chunkMask = getChunkMask();
    while (len > 0) {
        if (!chunkIsValid) {
            try {
                nextChunk();
                chunkIsValid = true;
            } catch (GeneralSecurityException e) {
                throw new EncryptedDocumentException(e.getMessage(), e);
            }
        }
        int count = (int)(chunk.length - (pos & chunkMask));
        int avail = available();
        if (avail == 0) {
            return total;
        }
        count = Math.min(avail, Math.min(count, len));

        System.arraycopy(readPlain ? plain : chunk, (int)(pos & chunkMask), b, off, count);

        off += count;
        len -= count;
        pos += count;
        if ((pos & chunkMask) == 0) {
            chunkIsValid = false;
        }
        total += count;
    }

    return total;
}
 
Example 29
Source Project: lams   Source File: Decryptor.java    License: GNU General Public License v2.0 5 votes vote down vote up
public static Decryptor getInstance(EncryptionInfo info) {
    Decryptor d = info.getDecryptor();
    if (d == null) {
        throw new EncryptedDocumentException("Unsupported version");
    }
    return d;
}
 
Example 30
Source Project: lams   Source File: DataSpaceMapUtils.java    License: GNU General Public License v2.0 5 votes vote down vote up
public static DocumentEntry createEncryptionEntry(DirectoryEntry dir, String path, EncryptionRecord out) throws IOException {
    String parts[] = path.split("/");
    for (int i=0; i<parts.length-1; i++) {
        dir = dir.hasEntry(parts[i])
            ? (DirectoryEntry)dir.getEntry(parts[i])
            : dir.createDirectory(parts[i]);
    }
    
    final byte buf[] = new byte[5000];        
    LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(buf, 0);
    out.write(bos);
    
    String fileName = parts[parts.length-1];
    
    if (dir.hasEntry(fileName)) {
        dir.getEntry(fileName).delete();
    }
    
    return dir.createDocument(fileName, bos.getWriteIndex(), new POIFSWriterListener(){
        public void processPOIFSWriterEvent(POIFSWriterEvent event) {
            try {
                event.getStream().write(buf, 0, event.getLimit());
            } catch (IOException e) {
                throw new EncryptedDocumentException(e);
            }
        }
    });
}