diff -r d3dc9041b126 jce/gnu/javax/crypto/RSACipherImpl.java --- a/jce/gnu/javax/crypto/RSACipherImpl.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/gnu/javax/crypto/RSACipherImpl.java Sun Jul 01 16:26:04 2007 -0700 @@ -61,6 +61,7 @@ import javax.crypto.IllegalBlockSizeExce import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; +import javax.crypto.spec.SecretKeySpec; public class RSACipherImpl extends CipherSpi @@ -78,12 +79,14 @@ public class RSACipherImpl protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - throw new NoSuchAlgorithmException("only one mode available"); + if (!mode.equalsIgnoreCase("ECB")) + throw new NoSuchAlgorithmException("only one mode available"); } protected void engineSetPadding(String pad) throws NoSuchPaddingException { - throw new NoSuchPaddingException("only one padding available"); + if (!pad.equalsIgnoreCase("PKCS1") && !pad.equalsIgnoreCase("PKCS#1")) + throw new NoSuchPaddingException("only one padding available"); } protected int engineGetBlockSize() @@ -127,7 +130,7 @@ public class RSACipherImpl throws InvalidKeyException { int outputLen = 0; - if (opmode == Cipher.ENCRYPT_MODE) + if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { if (! (key instanceof RSAPublicKey)) throw new InvalidKeyException("expecting a RSAPublicKey"); @@ -136,7 +139,7 @@ public class RSACipherImpl blindingKey = null; outputLen = (encipherKey.getModulus().bitLength() + 7) / 8; } - else if (opmode == Cipher.DECRYPT_MODE) + else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { if (key instanceof RSAPrivateKey) { @@ -180,7 +183,8 @@ public class RSACipherImpl protected byte[] engineUpdate(byte[] in, int offset, int length) { - if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE) + if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE + && opmode != Cipher.WRAP_MODE && opmode != Cipher.UNWRAP_MODE) throw new IllegalStateException("not initialized"); System.arraycopy(in, offset, dataBuffer, pos, length); pos += length; @@ -198,7 +202,7 @@ public class RSACipherImpl throws IllegalBlockSizeException, BadPaddingException { engineUpdate(in, offset, length); - if (opmode == Cipher.DECRYPT_MODE) + if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { BigInteger enc = new BigInteger (1, dataBuffer); byte[] dec = rsaDecrypt (enc); @@ -208,7 +212,7 @@ public class RSACipherImpl byte[] result = pkcs.decode(dec); return result; } - else + else if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { offset = dataBuffer.length - pos; if (offset < 3) @@ -234,6 +238,8 @@ public class RSACipherImpl pos = 0; return enc; } + else + throw new IllegalStateException("invalid cipher mode"); } protected int engineDoFinal(byte[] out, int offset) @@ -296,4 +302,46 @@ public class RSACipherImpl } return decb; } + + @Override + protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, + int wrappedKeyType) + throws InvalidKeyException, NoSuchAlgorithmException + { + if (wrappedKeyType != Cipher.SECRET_KEY) + throw new IllegalArgumentException("can only unwrap secret keys"); + if (decipherKey == null) + throw new IllegalStateException("not configured for key unwrapping"); + try + { + byte[] dec = engineDoFinal(wrappedKey, 0, wrappedKey.length); + return new SecretKeySpec(dec, wrappedKeyAlgorithm); + } + catch (IllegalBlockSizeException ibse) + { + throw new InvalidKeyException(ibse); + } + catch (BadPaddingException bpe) + { + throw new InvalidKeyException(bpe); + } + } + + @Override + protected byte[] engineWrap(Key key) + throws InvalidKeyException, IllegalBlockSizeException + { + if (encipherKey == null) + throw new IllegalStateException("not configured for key wrapping"); + byte[] kb = key.getEncoded(); + try + { + return engineDoFinal(kb, 0, kb.length); + } + catch (BadPaddingException bpe) + { + // We're encrypting, we should not see this. + throw new InvalidKeyException(bpe); + } + } } diff -r d3dc9041b126 jce/gnu/javax/crypto/jce/GnuCrypto.java --- a/jce/gnu/javax/crypto/jce/GnuCrypto.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/gnu/javax/crypto/jce/GnuCrypto.java Sun Jul 01 14:04:00 2007 -0700 @@ -517,6 +517,7 @@ public final class GnuCrypto put("Cipher.RSAES-PKCS1-v1_5", gnu.javax.crypto.RSACipherImpl.class.getName()); put("Alg.Alias.Cipher.RSA", "RSAES-PKCS1-v1_5"); + put("Alg.Alias.Cipher.RSA/ECB/PKCS1Padding", "RSAES-PKCS1-v1_5"); // SecureRandom put("SecureRandom.ARCFOUR", diff -r d3dc9041b126 jce/javax/crypto/KeyGenerator.java --- a/jce/javax/crypto/KeyGenerator.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/javax/crypto/KeyGenerator.java Tue Jul 03 19:16:28 2007 -0700 @@ -295,20 +295,4 @@ public class KeyGenerator { kgSpi.engineInit(random); } - - public final void init(TlsPrfParameterSpec spec) - { - } - - public final void init(TlsMasterSecretParameterSpec spec) - { - } - - public final void init(TlsKeyMaterialParameterSpec spec) - { - } - - public final void init(TlsRsaPremasterSecretParameterSpec spec) - { - } } diff -r d3dc9041b126 jce/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java --- a/jce/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java Tue Jul 03 19:18:44 2007 -0700 @@ -1,5 +1,6 @@ -/* TlsKeyMaterialParameterSpec.java -- stub file. +/* TlsKeyMaterialParameterSpec.java -- parameters for TLS session key gen. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007 Casey Marshall This file is part of IcedTea. @@ -34,16 +35,44 @@ obligated to do so. If you do not wish obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ + package sun.security.internal.spec; +import java.security.spec.AlgorithmParameterSpec; import javax.crypto.SecretKey; -public class TlsKeyMaterialParameterSpec +public class TlsKeyMaterialParameterSpec implements AlgorithmParameterSpec { - public TlsKeyMaterialParameterSpec(SecretKey key, byte arg1, byte arg2, - byte[] arg3, byte[] arg4, String arg5, - int arg6, int arg7 , int arg8 , int arg9) + public final SecretKey masterSecret; + public final byte major, minor; + public final byte[] client_random; + public final byte[] server_random; + public final String algorithm; + public final int keySize; + public final int expandedKeySize; + public final int ivSize; + public final int hashSize; + + public TlsKeyMaterialParameterSpec(final SecretKey masterSecret, + final byte major, final byte minor, + final byte[] client_random, + final byte[] server_random, + final String algorithm, + final int keySize, + final int expandedKeySize, + final int ivSize, final int hashSize) { - throw new RuntimeException("Not implemented."); + super(); + this.masterSecret = masterSecret; + this.major = major; + this.minor = minor; + this.client_random = (byte[]) client_random.clone(); + this.server_random = (byte[]) server_random.clone(); + this.algorithm = algorithm; + this.keySize = keySize; + this.expandedKeySize = expandedKeySize; + this.ivSize = ivSize; + this.hashSize = hashSize; } + } diff -r d3dc9041b126 jce/sun/security/internal/spec/TlsKeyMaterialSpec.java --- a/jce/sun/security/internal/spec/TlsKeyMaterialSpec.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/sun/security/internal/spec/TlsKeyMaterialSpec.java Tue Jul 03 19:19:09 2007 -0700 @@ -1,5 +1,6 @@ -/* TlsKeyMaterialSpec.java -- stub file. +/* TlsKeyMaterialSpec.java -- TLS session keys. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007 Casey Marshall This file is part of IcedTea. @@ -34,40 +35,84 @@ obligated to do so. If you do not wish obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ + package sun.security.internal.spec; + +import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; -public class TlsKeyMaterialSpec +public class TlsKeyMaterialSpec implements KeySpec, SecretKey { + private static final long serialVersionUID = 0L; + + private final SecretKey clientCipherKey; + private final SecretKey serverCipherKey; + private final IvParameterSpec clientIv; + private final IvParameterSpec serverIv; + private final SecretKey clientMacKey; + private final SecretKey serverMacKey; + + public TlsKeyMaterialSpec(SecretKey clientCipherKey, + SecretKey serverCipherKey, + IvParameterSpec clientIv, + IvParameterSpec serverIv, + SecretKey clientMacKey, + SecretKey serverMacKey) + { + super(); + this.clientCipherKey = clientCipherKey; + this.serverCipherKey = serverCipherKey; + this.clientIv = clientIv; + this.serverIv = serverIv; + this.clientMacKey = clientMacKey; + this.serverMacKey = serverMacKey; + } + public SecretKey getClientCipherKey() { - throw new RuntimeException("Not implemented."); + return clientCipherKey; } public SecretKey getServerCipherKey() { - throw new RuntimeException("Not implemented."); + return serverCipherKey; } public IvParameterSpec getClientIv() { - throw new RuntimeException("Not implemented."); + return clientIv; } public IvParameterSpec getServerIv() { - throw new RuntimeException("Not implemented."); + return serverIv; } public SecretKey getClientMacKey() { - throw new RuntimeException("Not implemented."); + return clientMacKey; } public SecretKey getServerMacKey() { - throw new RuntimeException("Not implemented."); + return serverMacKey; + } + + public String getAlgorithm() + { + return "TLS"; + } + + public byte[] getEncoded() + { + // TODO Auto-generated method stub + return null; + } + + public String getFormat() + { + return "RAW"; } } diff -r d3dc9041b126 jce/sun/security/internal/spec/TlsMasterSecretParameterSpec.java --- a/jce/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Tue Jul 03 21:02:17 2007 -0700 @@ -1,5 +1,6 @@ -/* TlsMasterSecretParameterSpec.java -- stub file. +/* TlsMasterSecretParameterSpec.java -- parameters for TLS master secret gen. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007 Casey Marshall This file is part of IcedTea. @@ -36,13 +37,24 @@ exception statement from your version. * package sun.security.internal.spec; +import java.security.spec.AlgorithmParameterSpec; import javax.crypto.SecretKey; -public class TlsMasterSecretParameterSpec +public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec { - public TlsMasterSecretParameterSpec(SecretKey key,byte arg1, byte arg2, - byte[] arg3, byte[] arg4) + public final SecretKey key; + public final byte major; + public final byte minor; + public final byte[] client_random; + public final byte[] server_random; + + public TlsMasterSecretParameterSpec(SecretKey key, byte major, byte minor, + byte[] client_random, byte[] server_random) { - throw new RuntimeException("Not implemented."); + this.key = key; + this.major = major; + this.minor = minor; + this.client_random = (byte[]) client_random.clone(); + this.server_random = (byte[]) server_random.clone(); } } diff -r d3dc9041b126 jce/sun/security/internal/spec/TlsPrfParameterSpec.java --- a/jce/sun/security/internal/spec/TlsPrfParameterSpec.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/sun/security/internal/spec/TlsPrfParameterSpec.java Sat Jun 30 13:24:20 2007 -0700 @@ -1,5 +1,6 @@ -/* TlsPrfParameterSpec.java -- stub file. +/* TlsPrfParameterSpec.java -- TLS PRF parameters. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007 Casey Marshall This file is part of IcedTea. @@ -36,12 +37,22 @@ exception statement from your version. * package sun.security.internal.spec; +import java.security.spec.AlgorithmParameterSpec; + import javax.crypto.SecretKey; -public class TlsPrfParameterSpec +public class TlsPrfParameterSpec implements AlgorithmParameterSpec { - public TlsPrfParameterSpec(SecretKey key, String arg1, byte[] arg2, int arg3) + public final SecretKey key; + public final String label; + public final byte[] seed; + public final int size; + + public TlsPrfParameterSpec(SecretKey key, String label, byte[] seed, int size) { - throw new RuntimeException("Not implemented."); + this.key = key; + this.label = label; + this.seed = (byte[]) seed.clone(); + this.size = size; } } diff -r d3dc9041b126 jce/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java --- a/jce/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Fri Jun 29 12:34:07 2007 -0400 +++ b/jce/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Sat Jun 30 13:25:25 2007 -0700 @@ -1,5 +1,6 @@ -/* TlsRsaParameterSecretParameterSpec.java -- stub file. +/* TlsRsaParameterSecretParameterSpec.java -- version number for RSA key ex. Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007 Casey Marshall This file is part of IcedTea. @@ -36,15 +37,33 @@ exception statement from your version. * package sun.security.internal.spec; +import java.security.spec.AlgorithmParameterSpec; + public class TlsRsaPremasterSecretParameterSpec + implements AlgorithmParameterSpec { + private final int major; + private final int minor; + public TlsRsaPremasterSecretParameterSpec(int major, int minor) { - throw new RuntimeException("Not implemented."); + this.major = major; + this.minor = minor; } public TlsRsaPremasterSecretParameterSpec(byte arg1, byte arg2) { - throw new RuntimeException("Not implemented."); + this.major = arg1 & 0xFF; + this.minor = arg2 & 0xFF; + } + + public int getMajorVersion() + { + return major; + } + + public int getMinorVersion() + { + return minor; } } diff -r d3dc9041b126 jce/gnu/java/security/icedtea/GNUTlsKeyMaterialGeneratorImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jce/gnu/java/security/icedtea/GNUTlsKeyMaterialGeneratorImpl.java Wed Jul 04 15:02:54 2007 -0700 @@ -0,0 +1,201 @@ +/* GNUTlsKeyMaterialGeneratorImpl.java -- + Copyright (C) 2007 Casey Marshall + +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.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGenerator; +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import sun.security.internal.spec.TlsKeyMaterialParameterSpec; +import sun.security.internal.spec.TlsKeyMaterialSpec; +import sun.security.internal.spec.TlsPrfParameterSpec; + +/** + * @author Casey Marshall (csm@gnu.org) + */ +public class GNUTlsKeyMaterialGeneratorImpl extends KeyGeneratorSpi +{ + static final String PRF_LABEL = "key expansion"; + static final String PRF_EXPORT_CLIENT_LABEL = "client write key"; + static final String PRF_EXPORT_SERVER_LABEL = "server write key"; + static final String PRF_EXPORT_IV_LABEL = "IV block"; + private final KeyGenerator kg; + private TlsKeyMaterialParameterSpec params; + + public GNUTlsKeyMaterialGeneratorImpl() throws NoSuchAlgorithmException + { + super(); + this.kg = KeyGenerator.getInstance("SunTlsPrf"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineGenerateKey() + */ + @Override + protected SecretKey engineGenerateKey() + { + if (params == null) + throw new IllegalStateException("not initialized"); + + byte[] seed = new byte[params.client_random.length + + params.server_random.length]; + System.arraycopy(params.server_random, 0, seed, 0, params.server_random.length); + System.arraycopy(params.client_random, 0, seed, params.server_random.length, + params.client_random.length); + int kmlen = (2 * params.keySize) + (2 * params.ivSize) + (2 * params.hashSize); + TlsPrfParameterSpec prfParams = new TlsPrfParameterSpec(params.masterSecret, + PRF_LABEL, seed, + kmlen); + try + { + kg.init(prfParams); + } + catch (InvalidAlgorithmParameterException iape) + { + throw new IllegalArgumentException(iape); + } + SecretKey keyMaterial = kg.generateKey(); + byte[] keyMBytes = keyMaterial.getEncoded(); + + SecretKey clientMacKey = new SecretKeySpec(keyMBytes, 0, + params.hashSize, "HMac"); + SecretKey serverMacKey = new SecretKeySpec(keyMBytes, params.hashSize, + params.hashSize, "HMac"); + SecretKey clientWriteKey = new SecretKeySpec(keyMBytes, 2 * params.hashSize, + params.keySize, + params.algorithm); + SecretKey serverWriteKey = new SecretKeySpec(keyMBytes, + 2 * params.hashSize + params.keySize, + params.keySize, + params.algorithm); + IvParameterSpec clientIv = new IvParameterSpec(keyMBytes, + 2 * (params.keySize + params.hashSize), + params.ivSize); + IvParameterSpec serverIv = new IvParameterSpec(keyMBytes, + 2 * (params.hashSize + params.keySize) + params.ivSize, + params.ivSize); + + // This is set for exportable ciphers; need to transform these + // keys a little more. + if (params.expandedKeySize > 0) + { + prfParams = new TlsPrfParameterSpec(clientWriteKey, + PRF_EXPORT_CLIENT_LABEL, seed, + params.expandedKeySize); + try + { + kg.init(prfParams); + } + catch (InvalidAlgorithmParameterException iape) + { + throw new IllegalArgumentException(iape); + } + clientWriteKey = new SecretKeySpec(kg.generateKey().getEncoded(), + params.algorithm); + prfParams = new TlsPrfParameterSpec(serverWriteKey, + PRF_EXPORT_SERVER_LABEL, seed, + params.expandedKeySize); + try + { + kg.init(prfParams); + } + catch (InvalidAlgorithmParameterException iape) + { + throw new IllegalArgumentException(iape); + } + serverWriteKey = new SecretKeySpec(kg.generateKey().getEncoded(), + params.algorithm); + prfParams = new TlsPrfParameterSpec(new SecretKeySpec(new byte[0], ""), + PRF_EXPORT_IV_LABEL, seed, + 2 *params.ivSize); + try + { + kg.init(prfParams); + } + catch (InvalidAlgorithmParameterException iape) + { + throw new IllegalArgumentException(iape); + } + byte[] newIv = kg.generateKey().getEncoded(); + clientIv = new IvParameterSpec(newIv, 0, params.ivSize); + serverIv = new IvParameterSpec(newIv, params.ivSize, params.ivSize); + } + + return new TlsKeyMaterialSpec(clientWriteKey, serverWriteKey, + clientIv, serverIv, clientMacKey, + serverMacKey); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) + */ + @Override + protected void engineInit(final AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + this.params = null; + if (!(params instanceof TlsKeyMaterialParameterSpec)) + throw new InvalidAlgorithmParameterException("not a TlsKeyMaterialParameterSpec"); + this.params = (TlsKeyMaterialParameterSpec) params; + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(int, java.security.SecureRandom) + */ + @Override + protected void engineInit(int keySize, SecureRandom random) + { + throw new IllegalArgumentException("need a TlsKeyMaterialParameterSpec"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.SecureRandom) + */ + @Override + protected void engineInit(SecureRandom random) + { + } + +} diff -r d3dc9041b126 jce/gnu/java/security/icedtea/GNUTlsMasterSecretGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jce/gnu/java/security/icedtea/GNUTlsMasterSecretGenerator.java Wed Jul 04 15:04:00 2007 -0700 @@ -0,0 +1,122 @@ +/* GNUTlsMasterSecretGenerator.java -- + Copyright (C) 2007 Casey Marshall + +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.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGenerator; +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import sun.security.internal.spec.TlsMasterSecretParameterSpec; +import sun.security.internal.spec.TlsPrfParameterSpec; + +/** + * @author Casey Marshall (csm@gnu.org) + */ +public class GNUTlsMasterSecretGenerator extends KeyGeneratorSpi +{ + static final String PRF_LABEL = "master secret"; + static final int MASTER_SECRET_LEN = 48; + private TlsMasterSecretParameterSpec params; + private final KeyGenerator kg; + + public GNUTlsMasterSecretGenerator() throws NoSuchAlgorithmException + { + kg = KeyGenerator.getInstance("SunTlsPrf"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineGenerateKey() + */ + @Override + protected SecretKey engineGenerateKey() + { + if (kg == null) + throw new IllegalStateException("not initialized"); + + SecretKey sk = kg.generateKey(); + return new SecretKeySpec(sk.getEncoded(), "TLS"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) + */ + @Override + protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + this.params = null; + if (!(params instanceof TlsMasterSecretParameterSpec)) + throw new InvalidAlgorithmParameterException("expecting a TlsMasterSecretParameterSpec"); + this.params = (TlsMasterSecretParameterSpec) params; + byte[] seed = new byte[this.params.client_random.length + + this.params.server_random.length]; + System.arraycopy(this.params.client_random, 0, seed, 0, + this.params.client_random.length); + System.arraycopy(this.params.server_random, 0, seed, + this.params.client_random.length, + this.params.server_random.length); + TlsPrfParameterSpec prfSpec = new TlsPrfParameterSpec(this.params.key, + PRF_LABEL, seed, + MASTER_SECRET_LEN); + kg.init(prfSpec); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(int, java.security.SecureRandom) + */ + @Override + protected void engineInit(int keySize, SecureRandom random) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.SecureRandom) + */ + @Override + protected void engineInit(SecureRandom random) + { + } +} diff -r d3dc9041b126 jce/gnu/java/security/icedtea/GNUTlsPrfGeneratorImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jce/gnu/java/security/icedtea/GNUTlsPrfGeneratorImpl.java Wed Jul 04 14:11:28 2007 -0700 @@ -0,0 +1,180 @@ +/* GNUTlsPrfGeneratorImpl.java -- TLS PRF. + Copyright (C) 2007 Casey Marshall + +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.UnsupportedEncodingException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import sun.security.internal.spec.TlsPrfParameterSpec; + +/** + * @author csm + * + */ +public class GNUTlsPrfGeneratorImpl extends KeyGeneratorSpi +{ + private TlsPrfParameterSpec params; + private final Mac hmac_md5; + private byte[] md5_A; + private final Mac hmac_sha; + private byte[] sha_A; + private byte[] labelBytes; + + public GNUTlsPrfGeneratorImpl() throws NoSuchAlgorithmException + { + hmac_md5 = Mac.getInstance("HmacMD5"); + hmac_sha = Mac.getInstance("HMacSHA1"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineGenerateKey() + */ + @Override + protected SecretKey engineGenerateKey() + { + if (params == null) + throw new IllegalStateException("not initialized"); + + final byte[] buf = new byte[params.size]; + + for (int i = 0; i < buf.length; i += hmac_sha.getMacLength()) + { + hmac_sha.update(sha_A); + hmac_sha.update(labelBytes); + hmac_sha.update(params.seed); + byte[] x = hmac_sha.doFinal(); + hmac_sha.reset(); + System.arraycopy(x, 0, buf, i, + Math.min(x.length, buf.length - i)); + hmac_sha.update(sha_A); + sha_A = hmac_sha.doFinal(); + hmac_sha.reset(); + } + + for (int i = 0; i < buf.length; i += hmac_md5.getMacLength()) + { + hmac_md5.update(md5_A); + hmac_md5.update(labelBytes); + hmac_md5.update(params.seed); + byte[] x = hmac_md5.doFinal(); + hmac_md5.reset(); + for (int j = 0; j < x.length && i + j < buf.length; j++) + buf[i+j] ^= x[j]; + hmac_md5.update(md5_A); + md5_A = hmac_md5.doFinal(); + hmac_md5.reset(); + } + return new SecretKeySpec(buf, "TLS"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) + */ + @Override + protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + if (!(params instanceof TlsPrfParameterSpec)) + throw new InvalidAlgorithmParameterException("expecting TlsPrfParameterSpec"); + this.params = (TlsPrfParameterSpec) params; + + byte[] keyb = this.params.key.getEncoded(); + int l = (keyb.length >>> 1) + (keyb.length & 1); + try + { + hmac_md5.init(new SecretKeySpec(keyb, 0, l, "HMacMD5")); + } + catch (InvalidKeyException ike) + { + throw new InvalidAlgorithmParameterException(ike); + } + try + { + labelBytes = this.params.label.getBytes("ASCII"); + } + catch (UnsupportedEncodingException uee) + { + throw new InvalidAlgorithmParameterException(uee); + } + hmac_md5.update(labelBytes); + hmac_md5.update(this.params.seed); + md5_A = hmac_md5.doFinal(); + hmac_md5.reset(); + + try + { + hmac_sha.init(new SecretKeySpec(keyb, keyb.length - l, l, "HMacSHA1")); + } + catch (InvalidKeyException ike) + { + throw new InvalidAlgorithmParameterException(ike); + } + hmac_sha.update(labelBytes); + hmac_sha.update(this.params.seed); + sha_A = hmac_sha.doFinal(); + hmac_sha.reset(); + + // SecureRandom is ignored. + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(int, java.security.SecureRandom) + */ + @Override + protected void engineInit(int keySize, SecureRandom random) + { + throw new IllegalArgumentException("need TlsPrfParameterSpec argument"); + } + + /* (non-Javadoc) + * @see javax.crypto.KeyGeneratorSpi#engineInit(java.security.SecureRandom) + */ + @Override + protected void engineInit(SecureRandom random) + { + } +} diff -r d3dc9041b126 jce/gnu/java/security/icedtea/GNUTlsRsaPreMasterSecretGeneratorImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jce/gnu/java/security/icedtea/GNUTlsRsaPreMasterSecretGeneratorImpl.java Sun Jul 01 17:07:59 2007 -0700 @@ -0,0 +1,120 @@ +/* GNUTlsRsaPreMasterSecretGeneratorImpl.java -- TLS pre-master secrets. + Copyright (C) 2007 Casey Marshall + +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.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; + +/** + * Implementation of a TLS pre-master secret generator. + * + * This is used in the client-side handshake for RSA cipher suites. It + * basically generates a 48 byte random string, where the first two + * bytes are a protocol version. + * + * @author csm + * + */ +public class GNUTlsRsaPreMasterSecretGeneratorImpl extends KeyGeneratorSpi +{ + private TlsRsaPremasterSecretParameterSpec params; + private SecureRandom random; + + public GNUTlsRsaPreMasterSecretGeneratorImpl() + { + params = null; + random = null; + } + + @Override + protected SecretKey engineGenerateKey() + { + if (params == null || random == null) + throw new IllegalStateException("not ready to generate keys"); + final byte[] key = new byte[48]; + random.nextBytes(key); + key[0] = (byte) params.getMajorVersion(); + key[1] = (byte) params.getMinorVersion(); + return new SecretKeySpec(key, "TLS"); + }; + + @Override + protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) + throw new InvalidAlgorithmParameterException("not a TlsRsaPremasterSecretParameterSpec"); + this.params = (TlsRsaPremasterSecretParameterSpec) params; + if (random == null) + { + if (this.random == null) + this.random = new SecureRandom(); + } + else + this.random = random; + } + + @Override + protected void engineInit(int keySize, SecureRandom random) + { + throw new IllegalArgumentException("needs to be passed a TlsRsaPremasterSecretParameterSpec"); + } + + @Override + protected void engineInit(SecureRandom random) + { + // XXX + params = new TlsRsaPremasterSecretParameterSpec(0, 0); + if (random != null) + { + this.random = random; + } + else + { + if (this.random == null) + this.random = new SecureRandom(); + } + } +} diff -r d3dc9041b126 jce/gnu/java/security/icedtea/IcedTls.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jce/gnu/java/security/icedtea/IcedTls.java Sat Jun 30 23:39:50 2007 -0700 @@ -0,0 +1,56 @@ +/* IcedTls.java -- provider for IcedTea replacements. + Copyright (C) 2007 Casey Marshall + +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.security.Provider; + +/** + * @author csm + */ +public class IcedTls extends Provider +{ + public IcedTls() + { + super("IcedTls", 1.0, "Free replacements for encumbered Sun sources for TLS"); + + put("KeyGenerator.SunTlsRsaPremasterSecret", GNUTlsRsaPreMasterSecretGeneratorImpl.class.getName()); + put("KeyGenerator.SunTlsMasterSecret", GNUTlsMasterSecretGenerator.class.getName()); + put("KeyGenerator.SunTlsKeyMaterial", GNUTlsKeyMaterialGeneratorImpl.class.getName()); + put("KeyGenerator.SunTlsPrf", GNUTlsPrfGeneratorImpl.class.getName()); + } +}