summaryrefslogtreecommitdiff
path: root/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java123
1 files changed, 92 insertions, 31 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index 8fead80a..2e4f96b5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -1,26 +1,27 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
+import java.lang.reflect.Method;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.SecretKey;
+// BEGIN android-added
+import javax.crypto.spec.IvParameterSpec;
+// END android-added
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.PBEParametersGenerator;
+// BEGIN android-added
+import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END android-added
// BEGIN android-removed
// import org.bouncycastle.crypto.digests.GOST3411Digest;
// import org.bouncycastle.crypto.digests.MD2Digest;
-// import org.bouncycastle.crypto.digests.MD5Digest;
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
-// import org.bouncycastle.crypto.digests.SHA1Digest;
-// import org.bouncycastle.crypto.digests.SHA256Digest;
// import org.bouncycastle.crypto.digests.TigerDigest;
// END android-removed
-// BEGIN android-added
-import org.bouncycastle.crypto.digests.AndroidDigestFactory;
-// END android-added
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
@@ -28,6 +29,9 @@ import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
public interface PBE
{
@@ -45,6 +49,9 @@ public interface PBE
// static final int MD2 = 5;
// static final int GOST3411 = 6;
// END android-removed
+ static final int SHA224 = 7;
+ static final int SHA384 = 8;
+ static final int SHA512 = 9;
static final int PKCS5S1 = 0;
static final int PKCS5S2 = 1;
@@ -53,6 +60,7 @@ public interface PBE
static final int PKCS5S1_UTF8 = 4;
static final int PKCS5S2_UTF8 = 5;
+
/**
* uses the appropriate mixer to generate the key and IV if necessary.
*/
@@ -101,6 +109,7 @@ public interface PBE
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
// END android-changed
break;
+
case SHA1:
// BEGIN android-changed
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
@@ -114,16 +123,24 @@ public interface PBE
// generator = new PKCS5S2ParametersGenerator(new TigerDigest());
// break;
// END android-removed
+ // BEGIN android-added
+ case SHA224:
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224());
+ break;
+ // END android-added
case SHA256:
// BEGIN android-changed
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA256());
// END android-changed
break;
- // BEGIN android-removed
- // case GOST3411:
- // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
- // break;
- // END android-removed
+ // BEGIN android-added
+ case SHA384:
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384());
+ break;
+ case SHA512:
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
+ break;
+ // END android-added
default:
throw new IllegalStateException("unknown digest scheme for PBE PKCS5S2 encryption.");
}
@@ -155,16 +172,23 @@ public interface PBE
// generator = new PKCS12ParametersGenerator(new TigerDigest());
// break;
// END android-removed
+ // BEGIN android-added
+ case SHA224:
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224());
+ break;
+ // END android-added
case SHA256:
// BEGIN android-changed
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
// END android-changed
break;
- // BEGIN android-removed
- // case GOST3411:
- // generator = new PKCS12ParametersGenerator(new GOST3411Digest());
- // break;
- // END android-removed
+ // BEGIN android-added
+ case SHA384:
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384());
+ break;
+ case SHA512:
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
+ break;
default:
throw new IllegalStateException("unknown digest scheme for PBE encryption.");
}
@@ -211,6 +235,21 @@ public interface PBE
if (ivSize != 0)
{
param = generator.generateDerivedParameters(keySize, ivSize);
+ // BEGIN ANDROID-ADDED
+ // PKCS5S2 doesn't specify that the IV must be generated from the password. If the
+ // IV is passed as a parameter, use it.
+ AlgorithmParameterSpec parameterSpecFromPBEParameterSpec =
+ getParameterSpecFromPBEParameterSpec(pbeParam);
+ if ((scheme == PKCS5S2 || scheme == PKCS5S2_UTF8)
+ && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) {
+ ParametersWithIV parametersWithIV = (ParametersWithIV) param;
+ IvParameterSpec ivParameterSpec =
+ (IvParameterSpec) parameterSpecFromPBEParameterSpec;
+ param = new ParametersWithIV(
+ (KeyParameter) parametersWithIV.getParameters(),
+ ivParameterSpec.getIV());
+ }
+ // END ANDROID-ADDED
}
else
{
@@ -233,11 +272,6 @@ public interface PBE
}
}
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
-
return param;
}
@@ -270,6 +304,21 @@ public interface PBE
if (pbeKey.getIvSize() != 0)
{
param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize());
+ // BEGIN ANDROID-ADDED
+ // PKCS5S2 doesn't specify that the IV must be generated from the password. If the
+ // IV is passed as a parameter, use it.
+ AlgorithmParameterSpec parameterSpecFromPBEParameterSpec =
+ getParameterSpecFromPBEParameterSpec(pbeParam);
+ if ((pbeKey.getType() == PKCS5S2 || pbeKey.getType() == PKCS5S2_UTF8)
+ && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) {
+ ParametersWithIV parametersWithIV = (ParametersWithIV) param;
+ IvParameterSpec ivParameterSpec =
+ (IvParameterSpec) parameterSpecFromPBEParameterSpec;
+ param = new ParametersWithIV(
+ (KeyParameter) parametersWithIV.getParameters(),
+ ivParameterSpec.getIV());
+ }
+ // END ANDROID-ADDED
}
else
{
@@ -292,11 +341,6 @@ public interface PBE
}
}
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
-
return param;
}
@@ -322,11 +366,6 @@ public interface PBE
generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
param = generator.generateDerivedMacParameters(pbeKey.getKeySize());
-
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
return param;
}
@@ -425,6 +464,28 @@ public interface PBE
return param;
}
+ // BEGIN android-added
+ /**
+ * Invokes the method {@link PBEParameterSpec#getParameterSpec()} via reflection.
+ *
+ * Needed as the method was introduced in Java 1.8 and Bouncycastle level is 1.5.
+ *
+ * @return the parameter spec, or null if the method is not available.
+ */
+ public static AlgorithmParameterSpec getParameterSpecFromPBEParameterSpec(
+ PBEParameterSpec pbeParameterSpec) {
+ try {
+ Method getParameterSpecMethod = PBE.class.getClassLoader()
+ .loadClass("javax.crypto.spec.PBEParameterSpec")
+ .getMethod("getParameterSpec");
+ return (AlgorithmParameterSpec) getParameterSpecMethod.invoke(pbeParameterSpec);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ // END android-added
+
+
private static byte[] convertPassword(int type, PBEKeySpec keySpec)
{
byte[] key;