mirror of https://github.com/apache/poi.git
#62994 - IBM JCE workarounds
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1848538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fba0181413
commit
397e568656
|
@ -99,6 +99,13 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
|
||||||
return initCipherForBlock(cipher, block, lastChunk);
|
return initCipherForBlock(cipher, block, lastChunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper method to break a recursion loop introduced because of an IBMJCE bug, i.e. not resetting on Cipher.doFinal()
|
||||||
|
@Internal
|
||||||
|
protected Cipher initCipherForBlockNoFlush(Cipher existing, int block, boolean lastChunk)
|
||||||
|
throws IOException, GeneralSecurityException {
|
||||||
|
return initCipherForBlock(cipher, block, lastChunk);
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk)
|
protected abstract Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk)
|
||||||
throws IOException, GeneralSecurityException;
|
throws IOException, GeneralSecurityException;
|
||||||
|
|
||||||
|
@ -212,13 +219,30 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
|
||||||
* @throws IllegalBlockSizeException
|
* @throws IllegalBlockSizeException
|
||||||
* @throws ShortBufferException
|
* @throws ShortBufferException
|
||||||
*/
|
*/
|
||||||
protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException {
|
protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException, IOException {
|
||||||
byte plain[] = (plainByteFlags.isEmpty()) ? null : chunk.clone();
|
byte plain[] = (plainByteFlags.isEmpty()) ? null : chunk.clone();
|
||||||
|
|
||||||
int ciLen = (doFinal)
|
int ciLen = (doFinal)
|
||||||
? cipher.doFinal(chunk, 0, posInChunk, chunk)
|
? cipher.doFinal(chunk, 0, posInChunk, chunk)
|
||||||
: cipher.update(chunk, 0, posInChunk, chunk);
|
: cipher.update(chunk, 0, posInChunk, chunk);
|
||||||
|
|
||||||
|
if (doFinal && "IBMJCE".equals(cipher.getProvider().getName()) && "RC4".equals(cipher.getAlgorithm())) {
|
||||||
|
// workaround for IBMs cipher not resetting on doFinal
|
||||||
|
|
||||||
|
int index = (int)(pos >> chunkBits);
|
||||||
|
boolean lastChunk;
|
||||||
|
if (posInChunk==0) {
|
||||||
|
index--;
|
||||||
|
posInChunk = chunk.length;
|
||||||
|
lastChunk = false;
|
||||||
|
} else {
|
||||||
|
// pad the last chunk
|
||||||
|
lastChunk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher = initCipherForBlockNoFlush(cipher, index, lastChunk);
|
||||||
|
}
|
||||||
|
|
||||||
if (plain != null) {
|
if (plain != null) {
|
||||||
int i = plainByteFlags.nextSetBit(0);
|
int i = plainByteFlags.nextSetBit(0);
|
||||||
while (i >= 0 && i < posInChunk) {
|
while (i >= 0 && i < posInChunk) {
|
||||||
|
|
|
@ -207,9 +207,15 @@ public class CryptoAPIEncryptor extends Encryptor implements Cloneable {
|
||||||
protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk)
|
protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk)
|
||||||
throws IOException, GeneralSecurityException {
|
throws IOException, GeneralSecurityException {
|
||||||
flush();
|
flush();
|
||||||
|
return initCipherForBlockNoFlush(cipher, block, lastChunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Cipher initCipherForBlockNoFlush(Cipher existing, int block, boolean lastChunk)
|
||||||
|
throws GeneralSecurityException {
|
||||||
EncryptionInfo ei = getEncryptionInfo();
|
EncryptionInfo ei = getEncryptionInfo();
|
||||||
SecretKey sk = getSecretKey();
|
SecretKey sk = getSecretKey();
|
||||||
return CryptoAPIDecryptor.initCipherForBlock(cipher, block, ei, sk, Cipher.ENCRYPT_MODE);
|
return CryptoAPIDecryptor.initCipherForBlock(existing, block, ei, sk, Cipher.ENCRYPT_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.poifs.crypt.dsig;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Security;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
|
|
||||||
|
@ -35,7 +36,12 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
|
||||||
@Override
|
@Override
|
||||||
public void init() throws GeneralSecurityException {
|
public void init() throws GeneralSecurityException {
|
||||||
final String provider = isMSCapi(key) ? "SunMSCAPI" : "SunRsaSign";
|
final String provider = isMSCapi(key) ? "SunMSCAPI" : "SunRsaSign";
|
||||||
signature = Signature.getInstance(algo.ecmaString+"withRSA", provider);
|
if (Security.getProvider(provider) != null) {
|
||||||
|
signature = Signature.getInstance(algo.ecmaString + "withRSA", provider);
|
||||||
|
} else {
|
||||||
|
signature = Signature.getInstance(algo.ecmaString + "withRSA");
|
||||||
|
}
|
||||||
|
|
||||||
signature.initSign(key);
|
signature.initSign(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue