Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2007-08-25 13:13:01 +0400
committerjfrijters <jfrijters>2007-08-25 13:13:01 +0400
commitc39422e01cccf6b2b510416c6a2408f22ef12c9e (patch)
tree0124e6d80434156ec67d7d547ccc4f8ffa828b11 /openjdk/icedtea/jce/gnu
parentfff2c860d3ab869a6a7b917109ae1c700e0f3b07 (diff)
Updated IcedTea crypto classes to support PBEwithMD5andDES.
Diffstat (limited to 'openjdk/icedtea/jce/gnu')
-rw-r--r--openjdk/icedtea/jce/gnu/java/security/icedtea/CertBundleKeyStoreImpl.java199
-rw-r--r--openjdk/icedtea/jce/gnu/java/security/icedtea/IcedTls.java4
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java50
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/jce/GnuCrypto.java9
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/jce/PBESecretKeyFactory.java83
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/CipherAdapter.java8
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/PBE.java229
-rw-r--r--openjdk/icedtea/jce/gnu/javax/crypto/key/GnuPBEKey.java5
8 files changed, 579 insertions, 8 deletions
diff --git a/openjdk/icedtea/jce/gnu/java/security/icedtea/CertBundleKeyStoreImpl.java b/openjdk/icedtea/jce/gnu/java/security/icedtea/CertBundleKeyStoreImpl.java
new file mode 100644
index 00000000..00001b42
--- /dev/null
+++ b/openjdk/icedtea/jce/gnu/java/security/icedtea/CertBundleKeyStoreImpl.java
@@ -0,0 +1,199 @@
+/* CertBundleKeyStoreImpl.java
+ Copyright (C) 2007 Casey Marshall <csm@gnu.org>
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.icedtea;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.security.Key;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * A key store implementation for "certificate bundle" files, commonly used
+ * on many free operating systems. Certificate bundles are plain text files
+ * containing one or more "PEM" encoded X.509 certificates, which comprise
+ * a list of trusted root certificates.
+ *
+ * This class implements a read-only key store that reads in one or more
+ * certificate bundles, storing all certificates successfully read. Calling
+ * load multiple times will add certificates to the store.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class CertBundleKeyStoreImpl extends KeyStoreSpi
+{
+ private int x = 0;
+ private Map<String, Certificate> certs = new HashMap<String, Certificate>();
+
+ @Override public Enumeration<String> engineAliases()
+ {
+ return new Vector<String>(certs.keySet()).elements();
+ }
+
+ @Override public boolean engineContainsAlias(String alias)
+ {
+ return certs.containsKey(alias);
+ }
+
+ @Override public void engineDeleteEntry(String alias) throws KeyStoreException
+ {
+ certs.remove(alias);
+ }
+
+ @Override public Certificate engineGetCertificate(String alias)
+ {
+ return certs.get(alias);
+ }
+
+ @Override public String engineGetCertificateAlias(Certificate cert)
+ {
+ for (Map.Entry<String, Certificate> e : certs.entrySet())
+ {
+ if (e.getValue().equals(cert))
+ return e.getKey();
+ }
+ return null;
+ }
+
+ @Override public Certificate[] engineGetCertificateChain(String arg0)
+ {
+ return null;
+ }
+
+ @Override public Date engineGetCreationDate(String alias)
+ {
+ return new Date(0);
+ }
+
+ @Override public Key engineGetKey(String arg0, char[] arg1)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ return null;
+ }
+
+ @Override public boolean engineIsCertificateEntry(String alias)
+ {
+ return certs.containsKey(alias);
+ }
+
+ @Override public boolean engineIsKeyEntry(String arg0)
+ {
+ return false;
+ }
+
+ @Override public void engineLoad(InputStream in, char[] arg1)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ PrintWriter out = new PrintWriter(new OutputStreamWriter(bout));
+ BufferedReader rin = new BufferedReader(new InputStreamReader(in));
+ String line;
+ boolean push = false;
+ while ((line = rin.readLine()) != null)
+ {
+ if (line.equals("-----BEGIN CERTIFICATE-----"))
+ {
+ push = true;
+ out.println(line);
+ }
+ else if (push)
+ {
+ out.println(line);
+ if (line.equals("-----END CERTIFICATE-----"))
+ {
+ push = false;
+ out.flush();
+ byte[] bytes = bout.toByteArray();
+ Certificate cert = cf.generateCertificate(new ByteArrayInputStream(bytes));
+ bout.reset();
+ String alias = "cert-" + (x++);
+ certs.put(alias, cert);
+ }
+ }
+ }
+ }
+
+ @Override public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
+ {
+ certs.put(alias, cert);
+ }
+
+ @Override public void engineSetKeyEntry(String arg0, byte[] arg1,
+ Certificate[] arg2)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException("not supported");
+ }
+
+ @Override public void engineSetKeyEntry(String arg0, Key arg1, char[] arg2,
+ Certificate[] arg3)
+ throws KeyStoreException
+ {
+ throw new KeyStoreException("not supported");
+ }
+
+ @Override public int engineSize()
+ {
+ return certs.size();
+ }
+
+ @Override public void engineStore(OutputStream arg0, char[] arg1)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ throw new UnsupportedOperationException("read-only key stores");
+ }
+}
diff --git a/openjdk/icedtea/jce/gnu/java/security/icedtea/IcedTls.java b/openjdk/icedtea/jce/gnu/java/security/icedtea/IcedTls.java
index 488c1c7f..69589746 100644
--- a/openjdk/icedtea/jce/gnu/java/security/icedtea/IcedTls.java
+++ b/openjdk/icedtea/jce/gnu/java/security/icedtea/IcedTls.java
@@ -48,9 +48,13 @@ public class IcedTls extends Provider
{
super("IcedTls", 1.0, "Free replacements for encumbered Sun sources for TLS");
+ // Key generators for Sun's JSSE.
put("KeyGenerator.SunTlsRsaPremasterSecret", GNUTlsRsaPreMasterSecretGeneratorImpl.class.getName());
put("KeyGenerator.SunTlsMasterSecret", GNUTlsMasterSecretGenerator.class.getName());
put("KeyGenerator.SunTlsKeyMaterial", GNUTlsKeyMaterialGeneratorImpl.class.getName());
put("KeyGenerator.SunTlsPrf", GNUTlsPrfGeneratorImpl.class.getName());
+
+ // Certificate bundle key store.
+ put("KeyStore.CertBundle", CertBundleKeyStoreImpl.class.getName());
}
}
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java b/openjdk/icedtea/jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java
index 4f4d5e47..b8248693 100644
--- a/openjdk/icedtea/jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java
@@ -94,8 +94,54 @@ public final class DiffieHellmanImpl
DHPublicKey pub = (DHPublicKey) incoming;
DHParameterSpec s1 = key.getParams();
DHParameterSpec s2 = pub.getParams();
- if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP())
- || s1.getL() != s2.getL())
+
+/* ICEDTEA LOCAL: This change is not committed to Classpath because
+ it's still waiting a response from Casey Marshall <csm@gnu.org>,
+ the author.
+
+From: Andrew Haley <aph-gcc@littlepinkcloud.COM>
+To: Casey Marshall <csm@gnu.org>, classpath-patches@gnu.org
+CC: Lillian Angel <langel@redhat.com>
+Subject: Fix DiffieHellmanImpl.java
+Date: Fri, 3 Aug 2007 18:19:07 +0100
+
+I came across a problem with GNU Crypto that causes Diffie-Hellman key
+exchange to fail when running on IcedTea. We're doing what looks to
+me like an unnecessary check in DiffieHellmanImpl.engineDoPhase()
+which can fail in some circumstances, and this is triggered when
+running in IcedTea. The code runs correctly on Sun's Java 1.7, not on
+the IcedTea version of Java 1.7, which uses GNU Crypto.
+
+With IcedTea and Classpath we get:
+
+Exception in thread "main" java.security.InvalidKeyException: Incompatible key
+ at gnu.javax.crypto.jce.DiffieHellmanImpl.engineDoPhase(DiffieHellmanImpl.java:99)
+ at javax.crypto.KeyAgreement.doPhase(KeyAgreement.java:224)
+ at Tt.main(Tt.java:35)
+
+Here's my patch:
+
+2007-08-03 Andrew Haley <aph@redhat.com>
+
+ * jce/gnu/javax/crypto/jce/DiffieHellmanImpl.java (engineDoPhase):
+ Don't check the length of q.
+
+--- gnu/javax/crypto/jce/DiffieHellmanImpl.java~ 2007-07-23 14:15:36.000000000 +0100
++++ gnu/javax/crypto/jce/DiffieHellmanImpl.java 2007-08-03 17:49:09.000000000 +0100
+@@ -94,8 +94,7 @@
+ DHPublicKey pub = (DHPublicKey) incoming;
+ DHParameterSpec s1 = key.getParams();
+ DHParameterSpec s2 = pub.getParams();
+- if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP())
+- || s1.getL() != s2.getL())
++ if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP()))
+ throw new InvalidKeyException("Incompatible key");
+ if (! lastPhase)
+ throw new IllegalArgumentException(
+
+*/
+
+ if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP()))
throw new InvalidKeyException("Incompatible key");
if (! lastPhase)
throw new IllegalArgumentException(
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/jce/GnuCrypto.java b/openjdk/icedtea/jce/gnu/javax/crypto/jce/GnuCrypto.java
index 464234fe..1cfa4482 100644
--- a/openjdk/icedtea/jce/gnu/javax/crypto/jce/GnuCrypto.java
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/jce/GnuCrypto.java
@@ -316,6 +316,9 @@ public final class GnuCrypto
gnu.javax.crypto.jce.cipher.PBES2.HMacWhirlpool.TripleDES.class.getName());
put("Cipher.PBEWithHMacWhirlpoolAndTwofish",
gnu.javax.crypto.jce.cipher.PBES2.HMacWhirlpool.Twofish.class.getName());
+ put("Cipher.PBE",
+ gnu.javax.crypto.jce.cipher.PBE.MD5.DES.class.getName());
+ put("Alg.Alias.Cipher.PBEWithMD5AndDES", "PBE");
// Key Wrapping Algorithm cipher
put("Cipher." + Registry.AES128_KWA,
@@ -348,7 +351,11 @@ public final class GnuCrypto
gnu.javax.crypto.jce.PBKDF2SecretKeyFactory.HMacTiger.class.getName());
put("SecretKeyFactory.PBKDF2WithHMacWhirlpool",
gnu.javax.crypto.jce.PBKDF2SecretKeyFactory.HMacWhirlpool.class.getName());
+ put("SecretKeyFactory.PBEWithMD5AndDES",
+ gnu.javax.crypto.jce.PBESecretKeyFactory.class.getName());
+ put("Alg.Alias.AlgorithmParameters.PBEWithMD5AndDES", "PBEWithMD5AndDES");
+
// Simple SecretKeyFactory implementations.
put("SecretKeyFactory.Anubis",
gnu.javax.crypto.jce.key.AnubisSecretKeyFactoryImpl.class.getName());
@@ -553,7 +560,7 @@ public final class GnuCrypto
put("KeyFactory.DH",
gnu.javax.crypto.jce.sig.DHKeyFactory.class.getName());
- put("Alg.Alias,KeyFactory.DiffieHellman", "DH");
+ put("Alg.Alias.KeyFactory.DiffieHellman", "DH");
// Algorithm Parameters -----------------------------------------------
put("AlgorithmParameters.DH",
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/jce/PBESecretKeyFactory.java b/openjdk/icedtea/jce/gnu/javax/crypto/jce/PBESecretKeyFactory.java
new file mode 100644
index 00000000..4a988f41
--- /dev/null
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/jce/PBESecretKeyFactory.java
@@ -0,0 +1,83 @@
+/* PBESecretKeyFactory.java --
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This file is a part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+
+package gnu.javax.crypto.jce;
+
+import gnu.javax.crypto.key.GnuPBEKey;
+
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+import javax.crypto.spec.PBEKeySpec;
+
+public class PBESecretKeyFactory
+ extends SecretKeyFactorySpi
+{
+ protected String name;
+
+ public PBESecretKeyFactory()
+ {
+ super();
+ }
+
+ protected PBESecretKeyFactory(String name)
+ {
+ this.name = name;
+ }
+
+ protected SecretKey engineGenerateSecret(KeySpec spec)
+ throws InvalidKeySpecException
+ {
+ if (! (spec instanceof PBEKeySpec))
+ throw new InvalidKeySpecException("not a PBEKeySpec");
+ return new GnuPBEKey((PBEKeySpec) spec);
+ }
+
+ protected KeySpec engineGetKeySpec(SecretKey key, Class clazz)
+ throws InvalidKeySpecException
+ {
+ throw new InvalidKeySpecException("not supported");
+ }
+
+ protected SecretKey engineTranslateKey(SecretKey key)
+ {
+ return null;
+ }
+}
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/CipherAdapter.java b/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/CipherAdapter.java
index 0863b1f1..1314c1a3 100644
--- a/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/CipherAdapter.java
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/CipherAdapter.java
@@ -386,7 +386,7 @@ class CipherAdapter
&& ((Integer) attributes.get(IMode.STATE)).intValue() == IMode.DECRYPTION
&& (partLen + inLen) % blockSize == 0)
blockCount--;
-
+
final byte[] out = new byte[blockCount * blockSize];
try
{
@@ -406,23 +406,23 @@ class CipherAdapter
return 0;
final int blockSize = mode.currentBlockSize();
int blockCount = (partLen + inLen) / blockSize;
-
// always keep data for unpadding in padded decryption mode;
// might even be a complete block
if (pad != null
&& ((Integer) attributes.get(IMode.STATE)).intValue() == IMode.DECRYPTION
&& (partLen + inLen) % blockSize == 0)
blockCount--;
-
final int result = blockCount * blockSize;
if (result > out.length - outOff)
throw new ShortBufferException();
+
if (blockCount == 0) // not enough bytes for even 1 block
{
System.arraycopy(in, inOff, partBlock, partLen, inLen);
partLen += inLen;
return 0;
}
+
final byte[] buf;
// we have enough bytes for at least 1 block
if (partLen == 0) // if no cached bytes use input
@@ -435,12 +435,14 @@ class CipherAdapter
System.arraycopy(in, inOff, buf, partLen, inLen);
inOff = 0;
}
+
for (int i = 0; i < blockCount; i++) // update blockCount * blockSize
{
mode.update(buf, inOff, out, outOff);
inOff += blockSize;
outOff += blockSize;
}
+
partLen += inLen - result;
if (partLen > 0) // cache remaining bytes from buf
System.arraycopy(buf, inOff, partBlock, 0, partLen);
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/PBE.java b/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/PBE.java
new file mode 100644
index 00000000..2ef0065a
--- /dev/null
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/jce/cipher/PBE.java
@@ -0,0 +1,229 @@
+/* PBE.java --
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This file is a part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.cipher;
+
+import gnu.java.security.Registry;
+import gnu.javax.crypto.jce.spec.BlockCipherParameterSpec;
+import gnu.javax.crypto.key.GnuPBEKey;
+import gnu.javax.crypto.mode.BaseMode;
+
+import java.io.UnsupportedEncodingException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ */
+public abstract class PBE
+ extends CipherAdapter
+{
+ MessageDigest hash;
+
+ protected PBE(String cipherName, String hashName)
+ {
+ super(cipherName);
+ try
+ {
+ this.hash = MessageDigest.getInstance(hashName);
+ }
+ catch (NoSuchAlgorithmException ignored)
+ {
+ }
+ }
+
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException
+ {
+ if (! (key instanceof GnuPBEKey))
+ throw new InvalidKeyException("not a GNU PBE key");
+ GnuPBEKey k = (GnuPBEKey) key;
+ int c1 = k.getIterationCount();
+ byte[] s1 = k.getSalt();
+ PBEPKCS5_V1Params pkcs5 = genParams(c1, s1, k.getPassword());
+ initInternal(opmode, pkcs5.skSpec, pkcs5.ivSpec, random);
+ }
+
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ if (! (key instanceof GnuPBEKey))
+ throw new InvalidKeyException("not a GNU PBE key");
+ GnuPBEKey k = (GnuPBEKey) key;
+ int c1 = k.getIterationCount();
+ byte[] s1 = k.getSalt();
+ if (params != null)
+ {
+ if (! (params instanceof PBEParameterSpec))
+ throw new InvalidAlgorithmParameterException(
+ "The algorithm-parameter-spec, when not null, MUST be of type "
+ + "PBEParameterSpec or one of its subclasses");
+ PBEParameterSpec ps = (PBEParameterSpec) params;
+ // it must share the same salt and iteration count as the secret key
+ int c2 = ps.getIterationCount();
+ if (c1 == 0)
+ c1 = c2;
+ else if (c1 != c2)
+ throw new InvalidAlgorithmParameterException(
+ "The algorithm-parameter-spec and the key MUST share the same "
+ + "iteration count");
+ byte[] s2 = ps.getSalt();
+ // salt may be unspecified
+ if (s1 == null)
+ s1 = s2;
+ else if ((s1 != null && s1.length > 0 && s2 == null)
+ || (s1 == null && s2 != null && s2.length > 0)
+ || (s1 != null && s2 != null && !Arrays.equals(s1, s2)))
+ throw new InvalidAlgorithmParameterException(
+ "The algorithm-parameter-spec and the key MUST share the same salt");
+ }
+ PBEPKCS5_V1Params pkcs5 = genParams(c1, s1, k.getPassword());
+ initInternal(opmode, pkcs5.skSpec, pkcs5.ivSpec, random);
+ }
+
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException
+ {
+ if (! (key instanceof GnuPBEKey))
+ throw new InvalidKeyException("not a GNU PBE key");
+ GnuPBEKey k = (GnuPBEKey) key;
+ int c1 = k.getIterationCount();
+ byte[] s1 = k.getSalt();
+ if (params != null)
+ throw new InvalidAlgorithmParameterException(
+ "We [MUST] supply our own algorithm-parameter");
+ PBEPKCS5_V1Params pkcs5 = genParams(c1, s1, k.getPassword());
+ initInternal(opmode, pkcs5.skSpec, pkcs5.ivSpec, random);
+ }
+
+ private void initInternal(int opmode, SecretKeySpec key,
+ BlockCipherParameterSpec params,
+ SecureRandom random) throws InvalidKeyException
+ {
+ try {
+ super.engineInit(opmode, key, params, random);
+ } catch (InvalidAlgorithmParameterException x) {
+ // this should not happen since 'params' is generated by us with
+ // the genParams() method. if it does re-throw as IKE
+ throw new InvalidKeyException(x);
+ }
+ }
+
+ private PBEPKCS5_V1Params genParams(int c, byte[] s, char[] password)
+ throws InvalidKeyException
+ {
+ // transform the password's chars into bytes assuming UTF-8
+ byte[] p;
+ try {
+ p = new String(password).getBytes("UTF-8");
+ } catch (UnsupportedEncodingException x) {
+ throw new InvalidKeyException(x);
+ }
+
+ String name = cipher.name();
+ int blockSize = cipher.defaultBlockSize();
+ int keySize = cipher.defaultKeySize();
+ int hashSize = this.hash.getDigestLength();
+ Integer att_ivSize = (Integer) attributes.get(mode.MODE_BLOCK_SIZE);
+ int ivSize = (att_ivSize == null ? blockSize : att_ivSize.intValue());
+
+ // digest once
+ this.hash.update(p);
+ byte[] buffer = s == null ? this.hash.digest() : this.hash.digest(s);
+
+ // and now complete the remaining iterations
+ for (int i = 1; i < c; i++)
+ buffer = this.hash.digest(buffer);
+
+ PBEPKCS5_V1Params result = new PBEPKCS5_V1Params();
+ result.skSpec = new SecretKeySpec(buffer, 0, blockSize, name.substring(0, name.indexOf('-')));
+ byte[] iv = new byte[ivSize];
+ System.arraycopy(buffer, blockSize, iv, 0, hashSize - blockSize);
+ result.ivSpec = new BlockCipherParameterSpec(iv, blockSize, keySize);
+ return result;
+ }
+
+ static class PBEPKCS5_V1Params {
+ SecretKeySpec skSpec;
+ BlockCipherParameterSpec ivSpec;
+ }
+
+ public static class MD5
+ extends PBE
+ {
+ public MD5(String cipher)
+ {
+ super(cipher, "MD5");
+ }
+
+ public static class DES
+ extends MD5
+ {
+ public DES()
+ {
+ // we really need a DES/CBC/PKCS5 combined padded block cipher
+ super(Registry.DES_CIPHER);
+
+ // the superclass's field 'cipher' has a plain DES-ECB so we need to
+ // change its mode and padding
+ try {
+ this.engineSetMode(Registry.CBC_MODE);
+ } catch (NoSuchAlgorithmException ignored) {
+ ignored.printStackTrace(System.err);
+ }
+ try {
+ this.engineSetPadding(Registry.PKCS5_PAD);
+ } catch (NoSuchPaddingException ignored) {
+ ignored.printStackTrace(System.err);
+ }
+ }
+ }
+ }
+}
diff --git a/openjdk/icedtea/jce/gnu/javax/crypto/key/GnuPBEKey.java b/openjdk/icedtea/jce/gnu/javax/crypto/key/GnuPBEKey.java
index 6f4bcb1b..69ae9b66 100644
--- a/openjdk/icedtea/jce/gnu/javax/crypto/key/GnuPBEKey.java
+++ b/openjdk/icedtea/jce/gnu/javax/crypto/key/GnuPBEKey.java
@@ -85,11 +85,12 @@ public class GnuPBEKey
public String getFormat ()
{
- return "NONE"; // FIXME?
+ return "RAW";
}
public byte[] getEncoded ()
{
- return null; // FIXME?
+ String pass = new String(getPassword());
+ return pass.getBytes();
}
}