diff options
Diffstat (limited to 'gnu/javax/net/ssl/provider/ServerKeyExchange.java')
-rw-r--r-- | gnu/javax/net/ssl/provider/ServerKeyExchange.java | 311 |
1 files changed, 99 insertions, 212 deletions
diff --git a/gnu/javax/net/ssl/provider/ServerKeyExchange.java b/gnu/javax/net/ssl/provider/ServerKeyExchange.java index 583041593..1206ae6b2 100644 --- a/gnu/javax/net/ssl/provider/ServerKeyExchange.java +++ b/gnu/javax/net/ssl/provider/ServerKeyExchange.java @@ -38,249 +38,136 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.io.OutputStream; import java.io.PrintWriter; -import java.io.StringReader; import java.io.StringWriter; -import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; -import java.security.PublicKey; -import java.security.interfaces.RSAPublicKey; - -import javax.crypto.interfaces.DHPublicKey; -import javax.crypto.spec.DHParameterSpec; - -import javax.net.ssl.SSLProtocolException; - -import gnu.javax.crypto.key.dh.GnuDHPublicKey; -import gnu.javax.crypto.key.srp6.SRPPublicKey; - -class ServerKeyExchange implements Handshake.Body +/** + * The server key exchange message. + * + * <pre> +struct { - - // Fields. - // ------------------------------------------------------------------------- - - private PublicKey publicKey; - private Signature signature; - private byte[] srpSalt; - - // Constructor. - // ------------------------------------------------------------------------- - - ServerKeyExchange(PublicKey publicKey, Signature signature) - { - this(publicKey, signature, null); - } - - ServerKeyExchange(PublicKey publicKey, Signature signature, byte[] srpSalt) + select (KeyExchangeAlgorithm) { - this.publicKey = publicKey; - this.signature = signature; - this.srpSalt = srpSalt; - } - - // Class methods. - // ------------------------------------------------------------------------- - - static ServerKeyExchange read(InputStream in, CipherSuite suite, - PublicKey serverKey) - throws IOException - { - DataInputStream din = new DataInputStream(in); - PublicKey key = null; - byte[] salt = null; - String kex = suite.getKeyExchange(); - if (kex.equals("DHE")) - { - BigInteger p, g, y; - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - p = new BigInteger(1, buf); - buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - g = new BigInteger(1, buf); - buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - y = new BigInteger(1, buf); - key = new GnuDHPublicKey(null, p, g, y); - } - else if (kex.equals("RSA")) - { - BigInteger n, e; - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - n = new BigInteger(1, buf); - buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - e = new BigInteger(1, buf); - key = new JessieRSAPublicKey(n, e); - } - else if (kex.equals("SRP")) - { - BigInteger N, g, B; - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - N = new BigInteger(1, buf); - buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - g = new BigInteger(1, buf); - salt = new byte[din.readUnsignedByte()]; - din.readFully(salt); - buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - B = new BigInteger(1, buf); - try - { - key = new SRPPublicKey(N, g, B); - } - catch (IllegalArgumentException iae) - { - throw new SSLProtocolException(iae.getMessage()); - } - } - else - { - throw new SSLProtocolException("invalid kex algorithm"); - } - - Signature sig = null; - if (!suite.getSignature().equals("anon")) - { - sig = Signature.read(in, suite, serverKey); - } - return new ServerKeyExchange(key, sig, salt); - } + case diffie_hellman: + ServerDHParams params; + Signature signed_params; + case rsa: + ServerRSAParams params; + Signature signed_params; + case srp: + ServerSRPParams params; + Signature signed_params; + }; +} ServerKeyExchange; +</pre> + */ +public class ServerKeyExchange implements Handshake.Body +{ - // Instance methods. - // ------------------------------------------------------------------------- + protected ByteBuffer buffer; + protected final CipherSuite suite; - public void write(OutputStream out) throws IOException + public ServerKeyExchange(final ByteBuffer buffer, final CipherSuite suite) { - write(out, ProtocolVersion.TLS_1); + suite.getClass(); + this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN); + this.suite = suite; } - public void write(OutputStream out, ProtocolVersion version) - throws IOException + public int length () { - if (publicKey instanceof DHPublicKey) - { - writeBigint(out, ((DHPublicKey) publicKey).getParams().getP()); - writeBigint(out, ((DHPublicKey) publicKey).getParams().getG()); - writeBigint(out, ((DHPublicKey) publicKey).getY()); - } - else if (publicKey instanceof RSAPublicKey) - { - writeBigint(out, ((RSAPublicKey) publicKey).getModulus()); - writeBigint(out, ((RSAPublicKey) publicKey).getPublicExponent()); - } - else if (publicKey instanceof SRPPublicKey) - { - writeBigint(out, ((SRPPublicKey) publicKey).getN()); - writeBigint(out, ((SRPPublicKey) publicKey).getG()); - out.write(srpSalt.length); - out.write(srpSalt); - writeBigint(out, ((SRPPublicKey) publicKey).getY()); - } - if (signature != null) - { - signature.write(out, version); - } + if (suite.keyExchangeAlgorithm ().equals (KeyExchangeAlgorithm.NONE)) + return 0; + int len = 0; + ServerKeyExchangeParams params = params(); + Signature sig = signature(); + if (params != null) + len += params.length(); + if (sig != null) + len += sig.length(); + return len; } - PublicKey getPublicKey() + /** + * Returns the server's key exchange parameters. The value returned will + * depend on the key exchange algorithm this object was created with. + * + * @return The server's key exchange parameters. + */ + public ServerKeyExchangeParams params () { - return publicKey; + KeyExchangeAlgorithm kex = suite.keyExchangeAlgorithm (); + if (kex == KeyExchangeAlgorithm.RSA) + return new ServerRSAParams(buffer.duplicate ()); + else if (kex == KeyExchangeAlgorithm.DHE_DSS + || kex == KeyExchangeAlgorithm.DHE_RSA + || kex == KeyExchangeAlgorithm.DH_anon) + return new ServerDHParams(buffer.duplicate()); +// else if (kex.equals (KeyExchangeAlgorithm.SRP)) +// return new ServerSRPParams (buffer.duplicate ()); + else if (kex == KeyExchangeAlgorithm.NONE) + return null; + else if (kex == KeyExchangeAlgorithm.DHE_PSK) + return new ServerDHE_PSKParameters(buffer.duplicate()); + else if (kex == KeyExchangeAlgorithm.PSK) + return new ServerPSKParameters(buffer.duplicate()); + else if (kex == KeyExchangeAlgorithm.RSA_PSK) + return new ServerPSKParameters(buffer.duplicate()); + throw new IllegalArgumentException ("unsupported key exchange: " + kex); } - Signature getSignature() + /** + * Returns the digital signature made over the key exchange parameters. + * + * @return The signature. + */ + public Signature signature () { - return signature; + KeyExchangeAlgorithm kex = suite.keyExchangeAlgorithm(); + if (kex == KeyExchangeAlgorithm.NONE + || kex == KeyExchangeAlgorithm.DH_anon + || kex == KeyExchangeAlgorithm.DHE_PSK + || kex == KeyExchangeAlgorithm.PSK + || kex == KeyExchangeAlgorithm.RSA_PSK) + return null; + ServerKeyExchangeParams params = params(); + ByteBuffer sigbuf = ((ByteBuffer) buffer.position(params.length ())).slice (); + return new Signature (sigbuf, suite.signatureAlgorithm ()); } - byte[] getSRPSalt() + public String toString() { - return srpSalt; + return toString (null); } - public String toString() + public String toString (final String prefix) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); + if (prefix != null) out.print (prefix); out.println("struct {"); - out.println(" publicKey = struct {"); - if (publicKey instanceof DHPublicKey) - { - out.println(" p = " + - ((DHPublicKey) publicKey).getParams().getP().toString(16) + - ";"); - out.println(" g = " + - ((DHPublicKey) publicKey).getParams().getG().toString(16) + - ";"); - out.println(" y = " + ((DHPublicKey) publicKey).getY().toString(16) + - ";"); - out.println(" } DHPublicKey;"); - } - else if (publicKey instanceof RSAPublicKey) + if (prefix != null) out.print (prefix); + out.print (" algorithm: "); + out.print (suite.keyExchangeAlgorithm ()); + out.println (";"); + if (!suite.keyExchangeAlgorithm ().equals (KeyExchangeAlgorithm.NONE)) { - out.println(" modulus = " + - ((RSAPublicKey) publicKey).getModulus().toString(16) + - ";"); - out.println(" exponent = " + - ((RSAPublicKey) publicKey).getPublicExponent().toString(16) + - ";"); - out.println(" } RSAPublicKey;"); + if (prefix != null) out.print (prefix); + out.println (" parameters:"); + out.println (params ().toString (prefix != null ? prefix+" " : " ")); } - else if (publicKey instanceof SRPPublicKey) + if (!suite.signatureAlgorithm ().equals (SignatureAlgorithm.ANONYMOUS)) { - out.println(" N = "+((SRPPublicKey) publicKey).getN().toString(16)+";"); - out.println(" g = "+((SRPPublicKey) publicKey).getG().toString(16)+";"); - out.println(" salt = " + Util.toHexString(srpSalt, ':') + ";"); - out.println(" B = "+((SRPPublicKey) publicKey).getY().toString(16)+";"); - out.println(" } SRPPublicKey;"); + if (prefix != null) out.print (prefix); + out.println (" signature:"); + out.println (signature ().toString (prefix != null ? prefix+" " : " ")); } - if (signature != null) - { - out.println(" signature ="); - BufferedReader r = new BufferedReader(new StringReader(signature.toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - } - out.println("} ServerKeyExchange;"); + if (prefix != null) out.print (prefix); + out.print ("} ServerKeyExchange;"); return str.toString(); } - - private void writeBigint(OutputStream out, BigInteger bigint) - throws IOException - { - byte[] b = bigint.toByteArray(); - if (b[0] == 0x00) - { - out.write((b.length - 1) >>> 8 & 0xFF); - out.write((b.length - 1) & 0xFF); - out.write(b, 1, b.length - 1); - } - else - { - out.write(b.length >>> 8 & 0xFF); - out.write(b.length & 0xFF); - out.write(b); - } - } } |