diff options
author | jfrijters <jfrijters> | 2007-08-25 13:13:01 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2007-08-25 13:13:01 +0400 |
commit | c39422e01cccf6b2b510416c6a2408f22ef12c9e (patch) | |
tree | 0124e6d80434156ec67d7d547ccc4f8ffa828b11 /openjdk/icedtea/jce/gnu | |
parent | fff2c860d3ab869a6a7b917109ae1c700e0f3b07 (diff) |
Updated IcedTea crypto classes to support PBEwithMD5andDES.
Diffstat (limited to 'openjdk/icedtea/jce/gnu')
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(); } } |