Hi,
I am attaching a patch that follows the behaviour outlined in the JDK
javadoc for javax.crypto.CipherSpi's engineInit methods. I have already
committed a test case
(gnu.testlet.gnu.javax.crypto.jce.TestOfCipherEngineInit) that models
this logic.
Issues related to PR27849 have been addressed here. Comments are welcome.
Thanks,
Vivek
Changelog:
2006-06-15 Vivek Lakshmanan <[EMAIL PROTECTED]>
* gnu/javax/crypto/jce/cipher/CipherAdapter.java
(engineInit(int, Key, AlgorithmParameterSpec, SecureRandom)): When
param is null, use random or default information when possible.
(engineInit(int, Key, SecureRandom)): Seperate common initialization
logic into engineInitHandler and reuse the code in
engineInit(int, Key, AlgorithmSpec, SecureRandom).
(engineInitHandler): New method.
Index: gnu/javax/crypto/jce/cipher/CipherAdapter.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/javax/crypto/jce/cipher/CipherAdapter.java,v
retrieving revision 1.3
diff -u -r1.3 CipherAdapter.java
--- gnu/javax/crypto/jce/cipher/CipherAdapter.java 4 Jun 2006 06:57:26 -0000 1.3
+++ gnu/javax/crypto/jce/cipher/CipherAdapter.java 15 Jun 2006 23:50:09 -0000
@@ -38,6 +38,7 @@
package gnu.javax.crypto.jce.cipher;
+import gnu.java.security.Registry;
import gnu.javax.crypto.cipher.IBlockCipher;
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.jce.spec.BlockCipherParameterSpec;
@@ -246,6 +247,23 @@
protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException
{
+ try
+ {
+ engineInit(opmode, key, (AlgorithmParameterSpec) null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // Being utilized for decryption or unwrapping which may require parameters.
+ throw (InvalidKeyException) (new InvalidKeyException().initCause(e));
+ }
+
+ }
+
+ // Executes initialization logic after all parameters have been handled
+ // by the engineInit()s.
+ private void engineInitHandler(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException
+ {
switch (opmode)
{
case Cipher.ENCRYPT_MODE:
@@ -279,12 +297,34 @@
InvalidAlgorithmParameterException
{
if (params == null)
- {
- byte[] iv = new byte[blockLen];
- random.nextBytes(iv);
- attributes.put(IMode.IV, iv);
+ {
+ // All cipher modes require parameters (like an IV) except ECB. When these
+ // cant be derived from the given key then it must be generated randomly if
+ // in ENCRYPT or WRAP mode. Parameters that have defaults for our cipher
+ // must be set to these defaults.
+ if(!mode.name().toLowerCase().startsWith(Registry.ECB_MODE))
+ {
+ switch (opmode)
+ {
+ case Cipher.ENCRYPT_MODE:
+ case Cipher.WRAP_MODE:
+ // Generate random algorithm parameters if used for ENCRYPT or WRAP
+ byte[] iv = new byte[blockLen];
+ random.nextBytes(iv);
+ attributes.put(IMode.IV, iv);
+ break;
+ default:
+ // If being used for DECRYPT or key UNWRAP,
+ // throw an exception.
+ throw new InvalidAlgorithmParameterException(
+ "Required algorithm parameters missing for mode: "
+ + mode.name());
+ }
+ }
+ // Add default for block length etc.
blockLen = cipher.defaultBlockSize();
- attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(blockLen));
+ attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE,
+ new Integer(blockLen));
keyLen = 0;
}
else if (params instanceof BlockCipherParameterSpec)
@@ -304,7 +344,7 @@
attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(blockLen));
keyLen = 0;
}
- engineInit(opmode, key, random);
+ engineInitHandler(opmode, key, random);
}
protected void engineInit(int opmode, Key key, AlgorithmParameters params,