summaryrefslogtreecommitdiff
path: root/gnu/javax/net/ssl/provider/ClientHandshake.java
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/javax/net/ssl/provider/ClientHandshake.java')
-rw-r--r--gnu/javax/net/ssl/provider/ClientHandshake.java106
1 files changed, 92 insertions, 14 deletions
diff --git a/gnu/javax/net/ssl/provider/ClientHandshake.java b/gnu/javax/net/ssl/provider/ClientHandshake.java
index 494e66dc7..123137d49 100644
--- a/gnu/javax/net/ssl/provider/ClientHandshake.java
+++ b/gnu/javax/net/ssl/provider/ClientHandshake.java
@@ -56,6 +56,7 @@ import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
+import java.security.KeyManagementException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
@@ -69,11 +70,14 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
@@ -223,6 +227,7 @@ public class ClientHandshake extends AbstractHandshake
}
}
+ KeyExchangeAlgorithm kex = engine.session().suite.keyExchangeAlgorithm();
if (continuedSession)
{
byte[][] keys = generateKeys(clientRandom, serverRandom,
@@ -230,8 +235,13 @@ public class ClientHandshake extends AbstractHandshake
setupSecurityParameters(keys, true, engine, compression);
state = READ_FINISHED;
}
- else
+ else if (kex == RSA || kex == DH_DSS || kex == DH_RSA
+ || kex == DHE_DSS || kex == DHE_RSA || kex == RSA_PSK)
state = READ_CERTIFICATE;
+ else if (kex == DH_anon || kex == PSK || kex == DHE_PSK)
+ state = READ_SERVER_KEY_EXCHANGE;
+ else
+ state = READ_CERTIFICATE_REQUEST;
}
break;
@@ -269,12 +279,15 @@ public class ClientHandshake extends AbstractHandshake
tasks.add(certVerifier);
// If we are doing an RSA key exchange, generate our parameters.
- if (engine.session().suite.keyExchangeAlgorithm()
- == KeyExchangeAlgorithm.RSA)
+ KeyExchangeAlgorithm kea = engine.session().suite.keyExchangeAlgorithm();
+ if (kea == RSA || kea == RSA_PSK)
{
- keyExchange = new RSAGen();
+ keyExchange = new RSAGen(kea == RSA);
tasks.add(keyExchange);
- state = READ_CERTIFICATE_REQUEST;
+ if (kea == RSA)
+ state = READ_CERTIFICATE_REQUEST;
+ else
+ state = READ_SERVER_KEY_EXCHANGE;
}
else
state = READ_SERVER_KEY_EXCHANGE;
@@ -291,6 +304,15 @@ public class ClientHandshake extends AbstractHandshake
&& kexalg != DHE_PSK && kexalg != PSK && kexalg != RSA_PSK)
throw new AlertException(new Alert(Level.FATAL,
Description.UNEXPECTED_MESSAGE));
+
+ if (handshake.type() != Handshake.Type.SERVER_KEY_EXCHANGE)
+ {
+ if (kexalg != RSA_PSK && kexalg != PSK)
+ throw new AlertException(new Alert(Level.FATAL,
+ Description.UNEXPECTED_MESSAGE));
+ state = READ_CERTIFICATE_REQUEST;
+ return HandshakeStatus.NEED_UNWRAP;
+ }
ServerKeyExchange skex = (ServerKeyExchange) handshake.body();
ByteBuffer paramsBuffer = null;
@@ -318,7 +340,21 @@ public class ClientHandshake extends AbstractHandshake
dhParams.y());
DHParameterSpec params = new DHParameterSpec(dhParams.p(),
dhParams.g());
- keyExchange = new ClientDHGen(serverKey, params);
+ keyExchange = new ClientDHGen(serverKey, params, true);
+ tasks.add(keyExchange);
+ }
+ if (kexalg == DHE_PSK)
+ {
+ ServerDHE_PSKParameters pskParams = (ServerDHE_PSKParameters)
+ skex.params();
+ ServerDHParams dhParams = pskParams.params();
+ DHPublicKey serverKey = new GnuDHPublicKey(null,
+ dhParams.p(),
+ dhParams.g(),
+ dhParams.y());
+ DHParameterSpec params = new DHParameterSpec(dhParams.p(),
+ dhParams.g());
+ keyExchange = new ClientDHGen(serverKey, params, false);
tasks.add(keyExchange);
}
state = READ_CERTIFICATE_REQUEST;
@@ -616,13 +652,14 @@ outer_loop:
+ " set the security property"
+ " \"jessie.client.psk.identity\"");
ClientRSA_PSKParameters params =
- new ClientRSA_PSKParameters(identity, epms,
- engine.session().version);
+ new ClientRSA_PSKParameters(identity, epms.buffer());
ckex.setExchangeKeys(params.buffer());
+ generatePSKSecret(identity, preMasterSecret, true);
}
}
if (kea == DHE_PSK)
{
+ assert(keyExchange instanceof ClientDHGen);
assert(dhPair != null);
String identity = getPSKIdentity();
if (identity == null)
@@ -634,6 +671,7 @@ outer_loop:
new ClientDHE_PSKParameters(identity,
new ClientDiffieHellmanPublic(pubkey.getY()));
ckex.setExchangeKeys(params.buffer());
+ generatePSKSecret(identity, preMasterSecret, true);
}
if (kea == PSK)
{
@@ -642,9 +680,27 @@ outer_loop:
throw new SSLException("no pre-shared key identity; set"
+ " the security property"
+ " \"jessie.client.psk.identity\"");
+ generatePSKSecret(identity, null, true);
ClientPSKParameters params = new ClientPSKParameters(identity);
ckex.setExchangeKeys(params.buffer());
}
+ if (kea == NONE)
+ {
+ Inflater inflater = null;
+ Deflater deflater = null;
+ if (compression == CompressionMethod.ZLIB)
+ {
+ inflater = new Inflater();
+ deflater = new Deflater();
+ }
+ inParams = new InputSecurityParameters(null, null, inflater,
+ engine.session(),
+ engine.session().suite);
+ outParams = new OutputSecurityParameters(null, null, deflater,
+ engine.session(),
+ engine.session().suite);
+ engine.session().privateData.masterSecret = new byte[0];
+ }
if (Debug.DEBUG)
logger.logv(Component.SSL_HANDSHAKE, "{0}", ckex);
@@ -894,11 +950,13 @@ outer_loop:
{
private final DHPublicKey serverKey;
private final DHParameterSpec params;
+ private final boolean full;
- ClientDHGen(DHPublicKey serverKey, DHParameterSpec params)
+ ClientDHGen(DHPublicKey serverKey, DHParameterSpec params, boolean full)
{
this.serverKey = serverKey;
this.params = params;
+ this.full = full;
}
public void implRun()
@@ -930,13 +988,19 @@ outer_loop:
"client keys public:{0} private:{1}", dhPair.getPublic(),
dhPair.getPrivate());
- // We have enough info to do the full key exchange; so let's do it.
initDiffieHellman((DHPrivateKey) dhPair.getPrivate(), engine.session().random());
- DHPhase phase = new DHPhase(serverKey);
+
+ // We have enough info to do the full key exchange; so let's do it.
+ DHPhase phase = new DHPhase(serverKey, full);
phase.run();
if (phase.thrown() != null)
throw new SSLException(phase.thrown());
}
+
+ DHPublicKey serverKey()
+ {
+ return serverKey;
+ }
}
class CertLoader extends DelegatedTask
@@ -966,6 +1030,17 @@ outer_loop:
class RSAGen extends DelegatedTask
{
private byte[] encryptedPreMasterSecret;
+ private final boolean full;
+
+ RSAGen()
+ {
+ this(true);
+ }
+
+ RSAGen(boolean full)
+ {
+ this.full = full;
+ }
public void implRun()
throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException,
@@ -998,9 +1073,12 @@ outer_loop:
encryptedPreMasterSecret = rsa.doFinal(preMasterSecret);
// Generate our session keys, because we can.
- generateMasterSecret(clientRandom, serverRandom, engine.session());
- byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
- setupSecurityParameters(keys, true, engine, compression);
+ if (full)
+ {
+ generateMasterSecret(clientRandom, serverRandom, engine.session());
+ byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
+ setupSecurityParameters(keys, true, engine, compression);
+ }
}
byte[] encryptedSecret()