Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/main/java/com/ibm/crypto/plus/provider/AESKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package com.ibm.crypto.plus.provider;

import java.security.InvalidKeyException;
import java.security.KeyRep;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
Expand All @@ -26,6 +25,8 @@ final class AESKey implements SecretKey {

private transient boolean destroyed = false;

private OpenJCEPlusProvider provider = null;

/**
* Create an AES key from a given key
*
Expand All @@ -35,12 +36,13 @@ final class AESKey implements SecretKey {
* @exception InvalidKeyException
* if the given key has wrong size
*/
AESKey(byte[] key) throws InvalidKeyException {
AESKey(OpenJCEPlusProvider provider, byte[] key) throws InvalidKeyException {
if ((key == null) || !AESUtils.isKeySizeValid(key.length)) {
throw new InvalidKeyException("Wrong key size");
}

this.key = new byte[key.length];
this.provider = provider;
System.arraycopy(key, 0, this.key, 0, key.length);
}

Expand Down Expand Up @@ -117,7 +119,7 @@ private void readObject(java.io.ObjectInputStream s)
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public AESKeyFactory(OpenJCEPlusProvider provider) {
protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
try {
if (keySpec instanceof SecretKeySpec) {
return new AESKey(((SecretKeySpec) keySpec).getEncoded());
return new AESKey(provider, ((SecretKeySpec) keySpec).getEncoded());
}
throw new InvalidKeySpecException("Inappropriate key specification");
} catch (InvalidKeyException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected SecretKey engineGenerateKey() {
cryptoRandom.nextBytes(keyBytes);

try {
return new AESKey(keyBytes);
return new AESKey(provider, keyBytes);
} catch (InvalidKeyException e) {
// Should never happen
throw new ProviderException(e.getMessage());
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/ibm/crypto/plus/provider/ChaCha20Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package com.ibm.crypto.plus.provider;

import java.security.InvalidKeyException;
import java.security.KeyRep;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
Expand All @@ -26,6 +25,8 @@ final class ChaCha20Key implements SecretKey, ChaCha20Constants {

private transient boolean destroyed = false;

private OpenJCEPlusProvider provider = null;

/**
* Create an ChaCha20 key from a given key
*
Expand All @@ -35,7 +36,7 @@ final class ChaCha20Key implements SecretKey, ChaCha20Constants {
* @exception InvalidKeyException
* if the given key has wrong size
*/
ChaCha20Key(byte[] key) throws InvalidKeyException {
ChaCha20Key(OpenJCEPlusProvider provider, byte[] key) throws InvalidKeyException {

if ((key == null) || (key.length != ChaCha20_KEY_SIZE)) {
throw new InvalidKeyException("Wrong key size");
Expand Down Expand Up @@ -118,7 +119,7 @@ private void readObject(java.io.ObjectInputStream s)
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public ChaCha20KeyFactory(OpenJCEPlusProvider provider) {
protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
try {
if (keySpec instanceof SecretKeySpec) {
return new ChaCha20Key(((SecretKeySpec) keySpec).getEncoded());
return new ChaCha20Key(provider, ((SecretKeySpec) keySpec).getEncoded());
}
throw new InvalidKeySpecException("Inappropriate key specification");
} catch (InvalidKeyException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected SecretKey engineGenerateKey() {
cryptoRandom.nextBytes(keyBytes);

try {
return new ChaCha20Key(keyBytes);
return new ChaCha20Key(provider, keyBytes);
} catch (InvalidKeyException e) {
// Should never happen
throw new ProviderException(e.getMessage());
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/ibm/crypto/plus/provider/DESedeKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package com.ibm.crypto.plus.provider;

import java.security.InvalidKeyException;
import java.security.KeyRep;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESedeKeySpec;
Expand All @@ -28,14 +27,16 @@ final class DESedeKey implements SecretKey, Destroyable {

private transient boolean destroyed = false;

private OpenJCEPlusProvider provider = null;

/**
* Creates a DES-EDE key from a given key.
*
* @param key the given key
*
* @exception InvalidKeyException if the given key has a wrong size
*/
DESedeKey(byte[] key) throws InvalidKeyException {
DESedeKey(OpenJCEPlusProvider provider, byte[] key) throws InvalidKeyException {
if ((key == null) || (key.length < DESedeKeySpec.DES_EDE_KEY_LEN)) {
throw new InvalidKeyException("Wrong key size");
}
Expand Down Expand Up @@ -120,7 +121,7 @@ private void readObject(java.io.ObjectInputStream s)
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public DESedeKeyFactory(OpenJCEPlusProvider provider) {
protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
try {
if (keySpec instanceof DESedeKeySpec) {
return new DESedeKey(((DESedeKeySpec) keySpec).getKey());
return new DESedeKey(provider, ((DESedeKeySpec) keySpec).getKey());
}
if (keySpec instanceof SecretKeySpec) {
return new DESedeKey(((SecretKeySpec) keySpec).getEncoded());
return new DESedeKey(provider, ((SecretKeySpec) keySpec).getEncoded());
}
throw new InvalidKeySpecException("Inappropriate key specification");
} catch (InvalidKeyException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected SecretKey engineGenerateKey() {
}

try {
return new DESedeKey(rawkey);
return new DESedeKey(provider, rawkey);
} catch (InvalidKeyException e) {
// Should never happen
throw new ProviderException(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ protected SecretKey engineGenerateSecret(String algorithm)
byte[] secret = engineGenerateSecret();
if (algorithm.equalsIgnoreCase("DESede") || algorithm.equalsIgnoreCase("TripleDES")) {
// Triple DES
return new DESedeKey(secret);
return new DESedeKey(provider, secret);
} else if (algorithm.equalsIgnoreCase("AES")) {
// AES
int keysize = secret.length;
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/ibm/crypto/plus/provider/DHPrivateKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ public String getAlgorithm() {
return "DH";
}

@java.io.Serial
protected Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PRIVATE, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
* Returns the encoding format of this key: "PKCS#8"
*/
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/ibm/crypto/plus/provider/DHPublicKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyRep;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.spec.DHParameterSpec;
import javax.security.auth.DestroyFailedException;
Expand Down Expand Up @@ -394,7 +393,7 @@ private void checkDestroyed() {
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

public String toString() {
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/ibm/crypto/plus/provider/DSAPrivateKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ private void checkDestroyed() {
}
}

@java.io.Serial
protected Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PRIVATE, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

public static boolean equals(DSAParams spec1, DSAParams spec2) {
if (spec1 == spec2) {
return true;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/ibm/crypto/plus/provider/DSAPublicKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.KeyRep;
import java.security.interfaces.DSAParams;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
Expand Down Expand Up @@ -229,7 +228,7 @@ public String toString() {
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/ibm/crypto/plus/provider/ECPrivateKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,12 @@ public PublicKey calculatePublicKey() {
"Unexpected error calculating public key", exc);
}
}

@java.io.Serial
protected Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PRIVATE, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
* Parse the key. Called by PKCS8Key. "key" is a byte array containing the
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/ibm/crypto/plus/provider/ECPublicKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyRep;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.InvalidParameterSpecException;
Expand Down Expand Up @@ -191,7 +190,7 @@ ECKey getOCKKey() {
*/
private Object writeReplace() throws java.io.ObjectStreamException {
checkDestroyed();
return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyRep;
import java.security.interfaces.EdECPrivateKey;
import java.security.spec.NamedParameterSpec;
import java.util.Optional;
Expand Down Expand Up @@ -329,8 +328,9 @@ public String getAlgorithm() {
return "EdDSA";
}

@java.io.Serial
protected Object writeReplace() throws java.io.ObjectStreamException {
return new KeyRep(KeyRep.Type.PRIVATE, getAlgorithm(), getFormat(), getEncoded());
}
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PRIVATE, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyRep;
import java.security.interfaces.EdECPublicKey;
import java.security.spec.EdECPoint;
import java.security.spec.NamedParameterSpec;
Expand Down Expand Up @@ -311,7 +310,7 @@ public void decode(byte[] encoded) throws InvalidKeyException {
}

protected Object writeReplace() throws java.io.ObjectStreamException {
return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded());
return new JCEPlusKeyRep(JCEPlusKeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded(), provider.getName());
}

/**
Expand Down
94 changes: 94 additions & 0 deletions src/main/java/com/ibm/crypto/plus/provider/JCEPlusKeyRep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright IBM Corp. 2025
*
* This code is free software; you can redistribute it and/or modify it
* under the terms provided by IBM in the LICENSE file that accompanied
* this code, including the "Classpath" Exception described therein.
*/

package com.ibm.crypto.plus.provider;

import java.io.NotSerializableException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Locale;
import javax.crypto.spec.SecretKeySpec;

class JCEPlusKeyRep implements Serializable {

@java.io.Serial
private static final long serialVersionUID = -4441922173618237196L;

protected enum Type {

/** Type for secret keys. */
SECRET,

/** Type for public keys. */
PUBLIC,

/** Type for private keys. */
PRIVATE
}

private static final String PKCS8 = "PKCS#8";
private static final String X509 = "X.509";
private static final String RAW = "RAW";

private final Type keyType;

private final String keyAlg;

private final String encodingFormat;

private final byte[] encodedKey;

private final String provider;

public JCEPlusKeyRep(Type type, String algorithm,
String format, byte[] encoded, String oJcePlusProvider) {

if (oJcePlusProvider == null || type == null || algorithm == null ||
format == null || encoded == null) {
throw new NullPointerException("invalid null input(s)");
}

this.keyType = type;
this.keyAlg = algorithm;
this.encodingFormat = format.toUpperCase(Locale.ENGLISH);
this.encodedKey = encoded.clone();
this.provider = oJcePlusProvider;
}

@java.io.Serial
protected Object readResolve() throws ObjectStreamException {
try {
if (keyType == Type.SECRET && RAW.equals(encodingFormat)) {
return new SecretKeySpec(encodedKey, keyAlg);
} else if (keyType == Type.PUBLIC && X509.equals(encodingFormat)) {
KeyFactory f = KeyFactory.getInstance(keyAlg, provider);
return f.generatePublic(new X509EncodedKeySpec(encodedKey));
} else if (keyType == Type.PRIVATE && PKCS8.equals(encodingFormat)) {
KeyFactory f = KeyFactory.getInstance(keyAlg, provider);
return f.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
} else {
throw new NotSerializableException("Key type and format combination invalid: " +
keyType + " " + encodingFormat);
}
} catch (NotSerializableException nse) {
throw nse;
} catch (Exception e) {
System.out.println(e.getMessage());
NotSerializableException nse = new NotSerializableException("java.security.Key: " +
"[" + keyType + "] " +
"[" + keyAlg + "] " +
"[" + encodingFormat +
"[" + provider + "]");
nse.initCause(e);
throw nse;
}
}
}
Loading