Skip to content

Commit 472b664

Browse files
Set private provider field based upon constructor (#927)
The DESedeKey and ChaCha20Key classes do allow for a provider to be used on construction of the key, however the provider is not saved to the private field of the class. This can cause NPE to be visable during serialization operations. This update simply saves the provider to the private field for later use. Fixes: #920 Signed-off-by: Jason Katonica <[email protected]>
1 parent aba91a0 commit 472b664

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

src/main/java/com/ibm/crypto/plus/provider/ChaCha20Key.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ final class ChaCha20Key implements SecretKey, ChaCha20Constants {
4242
throw new InvalidKeyException("Wrong key size");
4343
}
4444

45+
this.provider = provider;
4546
this.key = new byte[key.length];
4647
System.arraycopy(key, 0, this.key, 0, key.length);
4748
}

src/main/java/com/ibm/crypto/plus/provider/DESedeKey.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ final class DESedeKey implements SecretKey, Destroyable {
4141
throw new InvalidKeyException("Wrong key size");
4242
}
4343

44+
this.provider = provider;
4445
this.key = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
4546
System.arraycopy(key, 0, this.key, 0, DESedeKeySpec.DES_EDE_KEY_LEN);
4647
DESedeKeyGenerator.setParityBit(key, 0);

src/test/java/ibm/jceplus/junit/base/BaseTestKeySerialization.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import javax.crypto.KeyGenerator;
2323
import javax.crypto.SecretKey;
2424
import javax.crypto.SecretKeyFactory;
25+
import javax.crypto.spec.ChaCha20ParameterSpec;
2526
import javax.crypto.spec.PBEKeySpec;
2627
import org.junit.jupiter.params.ParameterizedTest;
2728
import org.junit.jupiter.params.provider.CsvSource;
@@ -76,12 +77,20 @@ public void SerializationKeyPairTest (String algorithm, String sigAlg) throws Ex
7677
}
7778

7879
@ParameterizedTest
79-
@CsvSource({"AES, 256, AES/CBC/PKCS5Padding", "AES, 256, AES/GCM/NoPadding"})
80+
@CsvSource({
81+
"AES, 256, AES/CBC/PKCS5Padding",
82+
"AES, 256, AES/GCM/NoPadding",
83+
"DESede, 168, DESede/CBC/PKCS5Padding",
84+
"ChaCha20, 256, ChaCha20/None/NoPadding"})
8085
public void SerializationSecretKeyTest (String algorithm, int size, String cipherName) throws Exception {
8186
KeyGenerator keyGen = null;
8287
SecretKey key = null;
8388
Cipher cp = null;
8489

90+
//DESede and ChaCha20 not supported by FIPS provider.
91+
if ("OpenJCEPlusFIPS".equalsIgnoreCase(getProviderName()) && (algorithm.equalsIgnoreCase("DESede") || algorithm.equalsIgnoreCase("ChaCha20"))) {
92+
return;
93+
}
8594

8695
keyGen = KeyGenerator.getInstance(algorithm, getProviderName());
8796
keyGen.init(size);
@@ -92,18 +101,24 @@ public void SerializationSecretKeyTest (String algorithm, int size, String ciphe
92101
serializeKey(key, keyFile);
93102
SecretKey deserializedKey = (SecretKey) deserializeKey(keyFile);
94103

95-
96104
assertArrayEquals(key.getEncoded(),
97105
deserializedKey.getEncoded(),
98106
"Key deserialized key does not match original");
99107

100108
cp = Cipher.getInstance(cipherName, getProviderName());
101109
cp.init(Cipher.ENCRYPT_MODE, key);
102110
byte[] cipherText = cp.doFinal(plainText);
103-
AlgorithmParameters params = cp.getParameters();
104-
105-
// Verify the text
106-
cp.init(Cipher.DECRYPT_MODE, deserializedKey, params);
111+
112+
// ChaCha20 requires special handling since it uses ChaCha20ParameterSpec instead of AlgorithmParameters
113+
if (algorithm.equalsIgnoreCase("ChaCha20")) {
114+
byte[] nonce = cp.getIV();
115+
ChaCha20ParameterSpec paramSpec = new ChaCha20ParameterSpec(nonce, 1);
116+
cp.init(Cipher.DECRYPT_MODE, deserializedKey, paramSpec);
117+
} else {
118+
AlgorithmParameters params = cp.getParameters();
119+
cp.init(Cipher.DECRYPT_MODE, deserializedKey, params);
120+
}
121+
107122
byte[] newPlainText = cp.doFinal(cipherText, 0, cipherText.length);
108123
assertArrayEquals(plainText, newPlainText, "Secret keys are different");
109124
}

0 commit comments

Comments
 (0)