diff options
author | Casey Marshall <csm@gnu.org> | 2006-03-07 06:41:35 +0000 |
---|---|---|
committer | Casey Marshall <csm@gnu.org> | 2006-03-07 06:41:35 +0000 |
commit | 85cc85d08891c53fd53d2eb8c06d4b8955f8fc9b (patch) | |
tree | 2c3856b69406c6bf9f1902393072ff08280cedaa | |
parent | 16686bdca47f2b74a410ade1d9d8510fa3084f72 (diff) | |
download | classpath-85cc85d08891c53fd53d2eb8c06d4b8955f8fc9b.tar.gz |
2006-03-06 Casey Marshall <csm@gnu.org>
* gnu/javax/net/ssl/provider/Alert.java: modified to use backing
byte buffer.
* gnu/javax/net/ssl/provider/Certificate.java: likewise.
* gnu/javax/net/ssl/provider/CertificateRequest.java: likewise.
* gnu/javax/net/ssl/provider/CertificateVerify.java: likewise.
* gnu/javax/net/ssl/provider/CipherSuite.java: modified to use
backing byte buffer; use enumerations instead of string constants;
use JCE instead of GNU Crypto API.
* gnu/javax/net/ssl/provider/ClientHello.java: modified to use
backing byte buffer.
* gnu/javax/net/ssl/provider/ClientKeyExchange.java: likewise.
* gnu/javax/net/ssl/provider/CompressionMethod.java: likewise.
* gnu/javax/net/ssl/provider/Constructed.java
(getLength): new method.
(write): removed.
(toString): new method.
* gnu/javax/net/ssl/provider/ContentType.java
(forInteger): new method.
* gnu/javax/net/ssl/provider/Finished.java: modified to use
backing byte buffer.
* gnu/javax/net/ssl/provider/Handshake.java: likewise.
* gnu/javax/net/ssl/provider/ProtocolVersion.java
(getInstance): new method.
(write): removed.
(getLength): new method.
(getRawValue): new method.
(toString): new method.
* gnu/javax/net/ssl/provider/Random.java: modified to use backing
byte buffer.
* gnu/javax/net/ssl/provider/ServerHello.java: likewise.
* gnu/javax/net/ssl/provider/ServerKeyExchange.java: likewise.
* gnu/javax/net/ssl/provider/Signature.java: likewise.
* gnu/javax/net/ssl/provider/Util.java
(hexDump, hexDump): new methods.
18 files changed, 2058 insertions, 1805 deletions
diff --git a/gnu/javax/net/ssl/provider/Alert.java b/gnu/javax/net/ssl/provider/Alert.java index c31e1bef5..9f768dbc5 100644 --- a/gnu/javax/net/ssl/provider/Alert.java +++ b/gnu/javax/net/ssl/provider/Alert.java @@ -38,10 +38,10 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; -import java.io.EOFException; -import java.io.InputStream; -import java.io.IOException; -import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; + +import java.nio.ByteBuffer; /** * An alert message in the SSL protocol. Alerts are sent both as warnings @@ -52,7 +52,7 @@ import java.io.OutputStream; * * <pre> * struct { - * AlertLevel level; + * AlertLevel level; * AlertDescription description; * } * </pre> @@ -63,197 +63,88 @@ final class Alert implements Constructed // Fields. // ------------------------------------------------------------------------- - /** The alert level enumerated. */ - private final Level level; - - /** The alert description enumerated. */ - private final Description description; + /** The underlying byte buffer. */ + private final ByteBuffer buffer; // Constructor. // ------------------------------------------------------------------------- - Alert(Level level, Description description) + Alert (final ByteBuffer buffer) { - this.level = level; - this.description = description; + this.buffer = buffer; } - // Class method. + // Instance methods. // ------------------------------------------------------------------------- - static Alert read(InputStream in) throws IOException + public int getLength () { - Level level = Level.read(in); - Description desc = Description.read(in); - return new Alert(level, desc); + return 2; } - static Alert forName(String name) + byte[] getEncoded() { - if (name == null) - { - return new Alert(Level.FATAL, Description.INTERNAL_ERROR); - } - Description desc = Description.INTERNAL_ERROR; - if (name.equals("close_notify")) - { - desc = Description.CLOSE_NOTIFY; - } - else if (name.equals("unexpected_message")) - { - desc = Description.UNEXPECTED_MESSAGE; - } - else if (name.equals("bad_record_mac")) - { - desc = Description.BAD_RECORD_MAC; - } - else if (name.equals("DECRYPTION_FAILED")) - { - desc = Description.DECRYPTION_FAILED; - } - else if (name.equals("record_overflow")) - { - desc = Description.RECORD_OVERFLOW; - } - else if (name.equals("decompression_failure")) - { - desc = Description.DECOMPRESSION_FAILURE; - } - else if (name.equals("handshake_failure")) - { - desc = Description.HANDSHAKE_FAILURE; - } - else if (name.equals("no_certificate")) - { - desc = Description.NO_CERTIFICATE; - } - else if (name.equals("bad_certificate")) - { - desc = Description.BAD_CERTIFICATE; - } - else if (name.equals("unsupported_certificate")) - { - desc = Description.UNSUPPORTED_CERTIFICATE; - } - else if (name.equals("certificate_revoked")) - { - desc = Description.CERTIFICATE_REVOKED; - } - else if (name.equals("certificate_expired")) - { - desc = Description.CERTIFICATE_EXPIRED; - } - else if (name.equals("certificate_unknown")) - { - desc = Description.CERTIFICATE_UNKNOWN; - } - else if (name.equals("illegal_parameter")) - { - desc = Description.ILLEGAL_PARAMETER; - } - else if (name.equals("unknown_ca")) - { - desc = Description.UNKNOWN_CA; - } - else if (name.equals("access_denied")) - { - desc = Description.ACCESS_DENIED; - } - else if (name.equals("decode_error")) - { - desc = Description.DECODE_ERROR; - } - else if (name.equals("decrypt_error")) - { - desc = Description.DECRYPT_ERROR; - } - else if (name.equals("export_restriction")) - { - desc = Description.EXPORT_RESTRICTION; - } - else if (name.equals("protocol_version")) - { - desc = Description.PROTOCOL_VERSION; - } - else if (name.equals("insufficient_security")) - { - desc = Description.INSUFFICIENT_SECURITY; - } - else if (name.equals("internal_error")) - { - desc = Description.INTERNAL_ERROR; - } - else if (name.equals("user_canceled")) - { - desc = Description.USER_CANCELED; - } - else if (name.equals("no_renegotiation")) - { - desc = Description.NO_RENEGOTIATION; - } - else if (name.equals("unsupported_extension")) - { - desc = Description.UNSUPPORTED_EXTENSION; - } - else if (name.equals("certificate_unobtainable")) - { - desc = Description.CERTIFICATE_UNOBTAINABLE; - } - else if (name.equals("unrecognized_name")) - { - desc = Description.UNRECOGNIZED_NAME; - } - else if (name.equals("bad_certificate_status_response")) - { - desc = Description.BAD_CERTIFICATE_STATUS_RESPONSE; - } - else if (name.equals("bad_certificate_hash_value")) - { - desc = Description.BAD_CERTIFICATE_HASH_VALUE; - } - else if (name.equals("unknown_srp_username")) - { - desc = Description.UNKNOWN_SRP_USERNAME; - } - else if (name.equals("missing_srp_username")) - { - desc = Description.MISSING_SRP_USERNAME; - } - return new Alert(Level.FATAL, desc); + byte[] buf = new byte[2]; + buffer.position (0); + buffer.get (buf); + return buf; } - // Instance methods. - // ------------------------------------------------------------------------- + Level getLevel() + { + return Level.forInteger (buffer.get (0) & 0xFF); + } - public void write(OutputStream out) throws IOException + Description getDescription() { - out.write((byte) level.getValue()); - out.write((byte) description.getValue()); + return Description.forInteger (buffer.get (1) & 0xFF); } - byte[] getEncoded() + void setLevel (final Level level) { - return new byte[] { (byte) level.getValue(), - (byte) description.getValue() }; + buffer.put (0, (byte) level.getValue ()); } - Level getLevel() + void setDescription (final Description description) { - return level; + buffer.put (1, (byte) description.getValue ()); } - Description getDescription() + public boolean equals (Object o) { - return description; + if (!(o instanceof Alert)) + return false; + Alert that = (Alert) o; + return that.buffer.position (0).equals (buffer.position (0)); + } + + public int hashCode () + { + return buffer.getShort (0) & 0xFFFF; } public String toString() { - String nl = System.getProperty("line.separator"); - return "struct {" + nl + - " level = " + level + ";" + nl + - " description = " + description + ";" + nl + - "} Alert;" + nl; + return toString (null); + } + + public String toString (final String prefix) + { + StringWriter str = new StringWriter (); + PrintWriter out = new PrintWriter (str); + if (prefix != null) out.print (prefix); + out.println ("struct {"); + if (prefix != null) out.print (prefix); + out.print (" level: "); + out.print (getLevel ()); + out.println (";"); + if (prefix != null) out.print (prefix); + out.print (" description: "); + out.print (getDescription ()); + out.println (";"); + if (prefix != null) out.print (prefix); + out.print ("} Alert;"); + return str.toString (); } // Inner classes. @@ -287,18 +178,13 @@ final class Alert implements Constructed // Class method. // ----------------------------------------------------------------------- - static Level read(InputStream in) throws IOException + static Level forInteger (final int value) { - int i = in.read(); - if (i == -1) - { - throw new EOFException("unexpected end of stream"); - } - switch (i & 0xFF) + switch (value & 0xFF) { case 1: return WARNING; case 2: return FATAL; - default: return new Level(i); + default: return new Level (value); } } @@ -315,6 +201,18 @@ final class Alert implements Constructed return value; } + public boolean equals (Object o) + { + if (!(o instanceof Level)) + return false; + return ((Level) o).value == value; + } + + public int hashCode () + { + return value; + } + public String toString() { switch (value) @@ -381,14 +279,16 @@ final class Alert implements Constructed // Class method. // ----------------------------------------------------------------------- - static Description read(InputStream in) throws IOException + /** + * Return an alert description object based on the specified integer + * value. + * + * @param value The raw description value. + * @return The appropriate description object. + */ + static Description forInteger (final int value) { - int i = in.read(); - if (i == -1) - { - throw new EOFException("unexpected end of input stream"); - } - switch (i) + switch (value & 0xFF) { case 0: return CLOSE_NOTIFY; case 10: return UNEXPECTED_MESSAGE; @@ -416,7 +316,7 @@ final class Alert implements Constructed case 100: return NO_RENEGOTIATION; case 120: return UNKNOWN_SRP_USERNAME; case 121: return MISSING_SRP_USERNAME; - default: return new Description(i); + default: return new Description (value); } } @@ -433,6 +333,18 @@ final class Alert implements Constructed return value; } + public boolean equals (Object o) + { + if (!(o instanceof Description)) + return false; + return ((Description) o).value == value; + } + + public int hashCode () + { + return value; + } + public String toString() { switch (value) diff --git a/gnu/javax/net/ssl/provider/Certificate.java b/gnu/javax/net/ssl/provider/Certificate.java index b1d6b2a01..287fd7a9a 100644 --- a/gnu/javax/net/ssl/provider/Certificate.java +++ b/gnu/javax/net/ssl/provider/Certificate.java @@ -1,4 +1,4 @@ -/* Certificate.java -- SSL Certificate message. +/* Certificate.java -- SSL certificate message. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -49,12 +49,17 @@ import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; +import java.nio.ByteBuffer; + +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import javax.net.ssl.SSLProtocolException; @@ -64,131 +69,124 @@ final class Certificate implements Handshake.Body // Fields. // ------------------------------------------------------------------------- - private final X509Certificate[] certs; + private final ByteBuffer buffer; + private final CertificateType type; // Constructors. // ------------------------------------------------------------------------- - Certificate(X509Certificate[] certs) + Certificate (final ByteBuffer buffer, final CertificateType type) { - if (certs == null) - { - throw new NullPointerException(); - } - this.certs = certs; + buffer.getClass (); + type.getClass (); + this.buffer = buffer; + this.type = type; } - // Class methods. + // Instance methods. // ------------------------------------------------------------------------- - static Certificate read(InputStream in, CertificateType type) - throws IOException + public int getLength () { - if (type == CertificateType.X509) - { - int len = (in.read() & 0xFF) << 16 | (in.read() & 0xFF) << 8 - | (in.read() & 0xFF); - byte[] buf = new byte[len]; - int count = 0; - while (count < len) - { - int l = in.read(buf, count, len - count); - if (l == -1) - { - throw new EOFException("unexpected end of stream"); - } - count += l; - } - try - { - LinkedList certs = new LinkedList(); - CertificateFactory fact = CertificateFactory.getInstance("X.509"); - ByteArrayInputStream bin = new ByteArrayInputStream(buf); - count = 0; - while (count < len) - { - int len2 = (bin.read() & 0xFF) << 16 | (bin.read() & 0xFF) << 8 - | (bin.read() & 0xFF); - certs.add(fact.generateCertificate(bin)); - count += len2 + 3; - } - return new Certificate((X509Certificate[]) - certs.toArray(new X509Certificate[certs.size()])); - } - catch (CertificateException ce) - { - SSLProtocolException sslpe = new SSLProtocolException(ce.getMessage()); - sslpe.initCause (ce); - throw sslpe; - } - } - else if (type == CertificateType.OPEN_PGP) - { - throw new UnsupportedOperationException("not yet implemented"); - } - else - throw new Error("unsupported certificate type "+type); + return (((buffer.get (0) & 0xFF) << 24) + | buffer.getShort (1)) + 3; } - // Instance methods. - // ------------------------------------------------------------------------- - - public void write(OutputStream out) throws IOException + List getCertificates () + throws CertificateException, NoSuchAlgorithmException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try - { - for (int i = 0; i < certs.length; i++) - { - byte[] enc = certs[i].getEncoded(); - bout.write((enc.length >>> 16) & 0xFF); - bout.write((enc.length >>> 8) & 0xFF); - bout.write( enc.length & 0xFF); - bout.write(enc); - } - } - catch (CertificateEncodingException cee) + LinkedList list = new LinkedList (); + CertificateFactory factory = CertificateFactory.getInstance (type.toString ()); + int length = (((buffer.get (0) & 0xFF) << 16) + | (buffer.getShort (1) & 0xFFFF)); + buffer.position (3); + for (int i = 0; i < length; ) { - throw new Error("cannot encode certificates"); + int length2 = (((buffer.get () & 0xFF) << 16) + | (buffer.getShort () & 0xFFFF)); + byte[] buf = new byte[length2]; + buffer.get (buf); + list.add (factory.generateCertificate (new ByteArrayInputStream (buf))); + i += length2 + 3; } - catch (IOException ignored) + return list; + } + + void setCertificates (final List certificates) + throws CertificateException + { + X509Certificate cert = null; + for (Iterator it = certificates.iterator (); it.hasNext (); ) + cert = (X509Certificate) it.next (); + int length = 0; + buffer.position (3); + for (Iterator it = certificates.iterator (); it.hasNext (); ) { + cert = (X509Certificate) it.next (); + byte[] buf = cert.getEncoded (); + buffer.put ((byte) (buf.length >>> 16)); + buffer.putShort ((short) buf.length); + buffer.put (buf); + length += buf.length + 3; } - out.write(bout.size() >>> 16 & 0xFF); - out.write(bout.size() >>> 8 & 0xFF); - out.write(bout.size() & 0xFF); - bout.writeTo(out); + buffer.put (0, (byte) (length >>> 16)); + buffer.putShort (1, (short) length); } - X509Certificate[] getCertificates() + public String toString () { - return certs; + return toString (null); } - public String toString() + public String toString (final String prefix) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); - out.println("struct {"); - out.println(" certificateList ="); - for (int i = 0; i < certs.length; i++) + if (prefix != null) + out.print (prefix); + out.println ("struct {"); + try { - BufferedReader r = - new BufferedReader(new StringReader(certs[i].toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) + List certs = getCertificates (); + if (prefix != null) + out.print (prefix); + out.print (" certificateList: ["); + out.print (certs.size ()); + out.println ("] {"); + for (Iterator it = certs.iterator (); it.hasNext (); ) { + java.security.cert.Certificate cert = + (java.security.cert.Certificate) it.next (); + if (prefix != null) + out.print (prefix); + out.print (" "); + if (cert instanceof X509Certificate) + out.print (((X509Certificate) cert).getSubjectDN ()); + else + out.print (cert); + out.println (";"); } + if (prefix != null) + out.print (prefix); + out.println (" };"); + } + catch (CertificateException ce) + { + if (prefix != null) + out.print (prefix); + out.print (" "); + out.print (ce); + out.println (";"); + } + catch (NoSuchAlgorithmException nsae) + { + if (prefix != null) + out.print (prefix); + out.print (" "); + out.print (nsae); + out.println (";"); } - out.println("} Certificate;"); + out.print ("} Certificate;"); return str.toString(); } } diff --git a/gnu/javax/net/ssl/provider/CertificateRequest.java b/gnu/javax/net/ssl/provider/CertificateRequest.java index 0f788039b..1340a2e4a 100644 --- a/gnu/javax/net/ssl/provider/CertificateRequest.java +++ b/gnu/javax/net/ssl/provider/CertificateRequest.java @@ -51,188 +51,107 @@ import java.io.StringWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.nio.ByteBuffer; + import java.util.LinkedList; import java.security.Principal; +/** + * A request by the server for a client certificate. + * + * <pre> +struct +{ + ClientCertificateType certificate_types<1..2^8-1>; + DistinguishedName certificate_authorities<3..2^16-1>; +} CertificateRequest; +</pre> + */ final class CertificateRequest implements Handshake.Body { // Fields. // ------------------------------------------------------------------------- - private final ClientType[] types; - private final Principal[] authorities; + private final ByteBuffer buffer; // Constructor. // ------------------------------------------------------------------------- - CertificateRequest(ClientType[] types, Principal[] authorities) - { - if (types == null) - { - throw new NullPointerException(); - } - this.types = types; - if (authorities == null) - { - throw new NullPointerException(); - } - this.authorities = authorities; - } - - // Class methods. - // ------------------------------------------------------------------------- - - static CertificateRequest read(InputStream in) throws IOException + CertificateRequest (final ByteBuffer buffer) { - DataInputStream din = new DataInputStream(in); - ClientType[] types = new ClientType[din.readUnsignedByte()]; - for (int i = 0; i < types.length; i++) - { - types[i] = ClientType.read(din); - } - - LinkedList authorities = new LinkedList(); - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - ByteArrayInputStream bin = new ByteArrayInputStream(buf); - try - { - String x500name = Util.getSecurityProperty("jessie.x500.class"); - if (x500name == null) - { - x500name = "org.metastatic.jessie.pki.X500Name"; - } - Class x500class = null; - ClassLoader cl = ClassLoader.getSystemClassLoader(); - if (cl != null) - { - x500class = cl.loadClass(x500name); - } - else - { - x500class = Class.forName(x500name); - } - Constructor c = x500class.getConstructor(new Class[] { new byte[0].getClass() }); - while (bin.available() > 0) - { - buf = new byte[(bin.read() & 0xFF) << 8 | (bin.read() & 0xFF)]; - bin.read(buf); - authorities.add(c.newInstance(new Object[] { buf })); - } - } - catch (IOException ioe) - { - throw ioe; - } - catch (Exception ex) - { - throw new Error(ex.toString()); - } - return new CertificateRequest(types, - (Principal[]) authorities.toArray(new Principal[authorities.size()])); + this.buffer = buffer; } // Instance methods. // ------------------------------------------------------------------------- - public void write(OutputStream out) throws IOException + public int getLength () { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - out.write(types.length); - for (int i = 0; i < types.length; i++) - { - out.write(types[i].getValue()); - } - - try - { - Class x500class = authorities[0].getClass(); - Method m = x500class.getMethod("getEncoded", null); - for (int i = 0; i < authorities.length; i++) - { - byte[] buf = (byte[]) m.invoke(authorities[i], null); - bout.write(buf.length >>> 8 & 0xFF); - bout.write(buf.length & 0xFF); - bout.write(buf, 0, buf.length); - } - } - catch (Exception ex) - { - throw new Error(ex.toString()); - } - out.write(bout.size() >>> 8 & 0xFF); - out.write(bout.size() & 0xFF); - bout.writeTo(out); + int o1 = (buffer.get (0) & 0xFF) + 1; + return o1 + (buffer.getShort (o1) & 0xFFFF) + 2; } - ClientType[] getTypes() + ClientCertificateTypeList getTypes () { - return types; + return new ClientCertificateTypeList (buffer.duplicate ()); } - String[] getTypeStrings() + X500PrincipalList getAuthorities () { - try - { - return (String[]) Util.transform(types, String.class, "toString", null); - } - catch (Exception x) - { - return null; - } + int offset = (buffer.get (0) & 0xFF) + 1; + return new X500PrincipalList (((ByteBuffer) buffer.position (offset)).slice ()); } - Principal[] getAuthorities() + public String toString() { - return authorities; + return toString (null); } - public String toString() + public String toString (final String prefix) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); + String subprefix = " "; + if (prefix != null) subprefix = prefix + " "; + if (prefix != null) out.print (prefix); out.println("struct {"); - out.print(" types = "); - for (int i = 0; i < types.length; i++) - { - out.print(types[i]); - if (i != types.length - 1) - out.print(", "); - } - out.println(";"); + if (prefix != null) out.print (prefix); + out.println (" types ="); + out.println (getTypes ().toString (subprefix)); + if (prefix != null) out.print (prefix); out.println(" authorities ="); - for (int i = 0; i < authorities.length; i++) - { - out.print(" "); - out.print(authorities[i].getName()); - if (i != types.length - 1) - out.println(","); - } - out.println(";"); - out.println("} CertificateRequest;"); + out.println (getAuthorities ().toString (subprefix)); + if (prefix != null) out.print (prefix); + out.print ("} CertificateRequest;"); return str.toString(); } // Inner class. // ------------------------------------------------------------------------- - static final class ClientType implements Enumerated + static final class ClientCertificateType implements Enumerated { // Constants and fields. // ----------------------------------------------------------------------- - static final ClientType - RSA_SIGN = new ClientType(1), DSS_SIGN = new ClientType(2), - RSA_FIXED_DH = new ClientType(3), DSS_FIXED_DH = new ClientType(4); + private static final int RSA_SIGN_VALUE = 1; + private static final int DSS_SIGN_VALUE = 2; + private static final int RSA_FIXED_DH_VALUE = 3; + private static final int DSS_FIXED_DH_VALUE = 4; + + static final ClientCertificateType RSA_SIGN = new ClientCertificateType (RSA_SIGN_VALUE); + static final ClientCertificateType DSS_SIGN = new ClientCertificateType (DSS_SIGN_VALUE); + static final ClientCertificateType RSA_FIXED_DH = new ClientCertificateType (RSA_FIXED_DH_VALUE); + static final ClientCertificateType DSS_FIXED_DH = new ClientCertificateType (DSS_FIXED_DH_VALUE); private final int value; // Constructor. // ----------------------------------------------------------------------- - private ClientType(int value) + private ClientCertificateType (final int value) { this.value = value; } @@ -240,21 +159,16 @@ final class CertificateRequest implements Handshake.Body // Class method. // ----------------------------------------------------------------------- - static ClientType read(InputStream in) throws IOException + static ClientCertificateType forValue (final int value) { - int i = in.read(); - if (i == -1) - { - throw new EOFException("unexpected end of input stream"); - } - switch (i & 0xFF) + switch (value) { - case 1: return RSA_SIGN; - case 2: return DSS_SIGN; - case 3: return RSA_FIXED_DH; - case 4: return DSS_FIXED_DH; - default: return new ClientType(i); + case RSA_SIGN_VALUE: return RSA_SIGN; + case DSS_SIGN_VALUE: return DSS_SIGN; + case RSA_FIXED_DH_VALUE: return RSA_FIXED_DH; + case DSS_FIXED_DH_VALUE: return DSS_FIXED_DH; } + return new ClientCertificateType (value); } // Instance methods. @@ -274,10 +188,10 @@ final class CertificateRequest implements Handshake.Body { switch (value) { - case 1: return "rsa_sign"; - case 2: return "dss_sign"; - case 3: return "rsa_fixed_dh"; - case 4: return "dss_fixed_dh"; + case RSA_SIGN_VALUE: return "rsa_sign"; + case DSS_SIGN_VALUE: return "dss_sign"; + case RSA_FIXED_DH_VALUE: return "rsa_fixed_dh"; + case DSS_FIXED_DH_VALUE: return "dss_fixed_dh"; default: return "unknown(" + value + ")"; } } diff --git a/gnu/javax/net/ssl/provider/CertificateVerify.java b/gnu/javax/net/ssl/provider/CertificateVerify.java index e0bf130f1..2d08b8b73 100644 --- a/gnu/javax/net/ssl/provider/CertificateVerify.java +++ b/gnu/javax/net/ssl/provider/CertificateVerify.java @@ -45,6 +45,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; +import java.nio.ByteBuffer; import java.security.PublicKey; final class CertificateVerify extends Signature implements Handshake.Body @@ -53,19 +54,9 @@ final class CertificateVerify extends Signature implements Handshake.Body // Contstructor. // ------------------------------------------------------------------------- - CertificateVerify(Object sigValue, String sigAlg) + CertificateVerify (final ByteBuffer buffer, final SignatureAlgorithm sigAlg) { - super(sigValue, sigAlg); - } - - // Class method. - // -------------------------------------------------------------------------- - - static Signature read(InputStream in, CipherSuite suite, PublicKey key) - throws IOException - { - Signature sig = Signature.read(in, suite, key); - return new CertificateVerify(sig.getSigValue(), sig.getSigAlg()); + super (buffer, sigAlg); } // Instance method. @@ -73,23 +64,21 @@ final class CertificateVerify extends Signature implements Handshake.Body public String toString() { - StringWriter str = new StringWriter(); - PrintWriter out = new PrintWriter(str); + return toString (null); + } + + public String toString (final String prefix) + { + StringWriter str = new StringWriter (); + PrintWriter out = new PrintWriter (str); + if (prefix != null) out.print (prefix); out.println("struct {"); - BufferedReader r = new BufferedReader(new StringReader(super.toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - out.println("} CertificateVerify;"); + String subprefix = " "; + if (prefix != null) + subprefix = prefix + subprefix; + out.println (super.toString (subprefix)); + if (prefix != null) out.print (prefix); + out.print ("} CertificateVerify;"); return str.toString(); } } diff --git a/gnu/javax/net/ssl/provider/CipherSuite.java b/gnu/javax/net/ssl/provider/CipherSuite.java index de916817b..509e4bfcd 100644 --- a/gnu/javax/net/ssl/provider/CipherSuite.java +++ b/gnu/javax/net/ssl/provider/CipherSuite.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; +import gnu.java.security.action.GetSecurityPropertyAction; + import java.io.DataInputStream; import java.io.InputStream; import java.io.IOException; @@ -45,6 +47,9 @@ import java.io.OutputStream; import java.lang.reflect.Field; +import java.nio.ByteBuffer; + +import java.security.AccessController; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; @@ -59,13 +64,7 @@ import java.util.Set; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.NoSuchPaddingException; - -import gnu.javax.crypto.cipher.CipherFactory; -import gnu.javax.crypto.cipher.IBlockCipher; -import gnu.javax.crypto.mac.IMac; -import gnu.javax.crypto.mac.MacFactory; -import gnu.javax.crypto.mode.IMode; -import gnu.javax.crypto.mode.ModeFactory; +import javax.crypto.NullCipher; final class CipherSuite implements Constructed { @@ -78,324 +77,729 @@ final class CipherSuite implements Constructed // SSL CipherSuites. static final CipherSuite SSL_NULL_WITH_NULL_NULL = - new CipherSuite("null", "null", "null", "null", 0, 0x00, 0x00, - "SSL_NULL_WITH_NULL_NULL", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.NONE, + SignatureAlgorithm.ANONYMOUS, + MacAlgorithm.NULL, 0, 0x00, 0x00, + "SSL_NULL_WITH_NULL_NULL", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_NULL_MD5 = - new CipherSuite("null", "RSA", "RSA", "SSLMAC-MD5", 0, 0x00, 0x01, - "SSL_RSA_WITH_NULL_MD5", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_MD5, 0, 0x00, 0x01, + "SSL_RSA_WITH_NULL_MD5", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_NULL_SHA = - new CipherSuite("null", "RSA", "RSA", "SSLMAC-SHA", 0, 0x00, 0x02, - "SSL_RSA_WITH_NULL_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 0, 0x00, 0x02, + "SSL_RSA_WITH_NULL_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 = - new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-MD5", 5, 0x00, 0x03, - "SSL_RSA_EXPORT_WITH_RC4_40_MD5", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_MD5, 5, 0x00, 0x03, + "SSL_RSA_EXPORT_WITH_RC4_40_MD5", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 = - new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-MD5", 16, 0x00, 0x04, - "SSL_RSA_WITH_RC4_128_MD5", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_MD5, 16, 0x00, 0x04, + "SSL_RSA_WITH_RC4_128_MD5", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_RC4_128_SHA = - new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-SHA", 16, 0x00, 0x05, - "SSL_RSA_WITH_RC4_128_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x05, + "SSL_RSA_WITH_RC4_128_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "RSA", "RSA", "SSLMAC-SHA", 5, 0x00, 0x08, - "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 5, 0x00, 0x08, + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "RSA", "RSA", "SSLMAC-SHA", 8, 0x00, 0x09, - "SSL_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 8, 0x00, 0x09, + "SSL_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "RSA", "RSA", "SSLMAC-SHA", 24, 0x00, 0x0A, - "SSL_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 24, 0x00, 0x0A, + "SSL_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DH", "DSS", "SSLMAC-SHA", 5, 0x00, 0x0B, - "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 5, 0x00, 0x0B, + "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DH", "DSS", "SSLMAC-SHA", 8, 0x00, 0x0C, - "SSL_DH_DSS_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 8, 0x00, 0x0C, + "SSL_DH_DSS_WITH_DES_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DH", "DSS", "SSLMAC-SHA", 24, 0x00, 0x0D, - "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 24, 0x00, 0x0D, + "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DH", "RSA", "SSLMAC-SHA", 5, 0x00, 0x0E, - "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 5, 0x00, 0x0E, + "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DH", "RSA", "SSLMAC-SHA", 8, 0x00, 0x0F, - "SSL_DH_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 8, 0x00, 0x0F, + "SSL_DH_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DH", "RSA", "SSLMAC-SHA", 24, 0x00, 0x10, - "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 24, 0x00, 0x10, + "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DHE", "DSS", "SSLMAC-SHA", 5, 0x00, 0x11, - "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 5, 0x00, 0x11, + "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DHE", "DSS", "SSLMAC-SHA", 8, 0x00, 0x12, - "SSL_DHE_DSS_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 8, 0x00, 0x12, + "SSL_DHE_DSS_WITH_DES_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DHE", "DSS", "SSLMAC-SHA", 24, 0x00, 0x13, - "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 24, 0x00, 0x13, + "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DHE", "RSA", "SSLMAC-SHA", 5, 0x00, 0x14, - "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 5, 0x00, 0x14, + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DHE", "RSA", "SSLMAC-SHA", 8, 0x00, 0x15, - "SSL_DHE_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 8, 0x00, 0x15, + "SSL_DHE_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DHE", "RSA", "SSLMAC-SHA", 24, 0x00, 0x16, - "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 24, 0x00, 0x16, + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.SSL_3); // AES CipherSuites. static final CipherSuite SSL_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "RSA", "RSA", "SSLMAC-SHA", 16, 0x00, 0x2F, - "SSL_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x2F, + "SSL_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_DSS_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DH", "DSS", "SSLMAC-SHA", 16, 0x00, 0x30, - "SSL_DH_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x30, + "SSL_DH_DSS_WITH_AES_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DH", "RSA", "SSLMAC-SHA", 16, 0x00, 0x31, - "SSL_DH_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x31, + "SSL_DH_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DHE", "DSS", "SSLMAC-SHA", 16, 0x00, 0x32, - "SSL_DHE_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x32, + "SSL_DHE_DSS_WITH_AES_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DHE", "RSA", "SSLMAC-SHA", 16, 0x00, 0x33, - "SSL_DHE_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 16, 0x00, 0x33, + "SSL_DHE_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "RSA", "RSA", "SSLMAC-SHA", 32, 0x00, 0x35, - "SSL_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 32, 0x00, 0x35, + "SSL_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_DSS_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DH", "DSS", "SSLMAC-SHA", 32, 0x00, 0x36, - "SSL_DH_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 32, 0x00, 0x36, + "SSL_DH_DSS_WITH_AES_256_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DH_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DH", "RSA", "SSLMAC-SHA", 32, 0x00, 0x37, - "SSL_DH_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 32, 0x00, 0x37, + "SSL_DH_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DHE", "DSS", "SSLMAC-SHA", 32, 0x00, 0x38, - "SSL_DHE_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.SSLMAC_SHA, 32, 0x00, 0x38, + "SSL_DHE_DSS_WITH_AES_256_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DHE", "RSA", "SSLMAC-SHA", 32, 0x00, 0x39, - "SSL_DHE_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.SSLMAC_SHA, 32, 0x00, 0x39, + "SSL_DHE_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.SSL_3); // Ciphersuites from the OpenPGP extension draft. static final CipherSuite SSL_DHE_DSS_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x70, - "SSL_DHE_DSS_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x70, + "SSL_DHE_DSS_WITH_CAST_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x71, - "SSL_DHE_DSS_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x71, + "SSL_DHE_DSS_WITH_CAST_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-RIPEMD-160", 24, 0x00, 0x72, - "SSL_DHE_DSS_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x72, + "SSL_DHE_DSS_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x73, - "SSL_DHE_DSS_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x73, + "SSL_DHE_DSS_WITH_AES_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_DSS_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 32, 0x00, 0x74, - "SSL_DHE_DSS_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x74, + "SSL_DHE_DSS_WITH_AES_256_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x75, - "SSL_DHE_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x75, + "SSL_DHE_RSA_WITH_CAST_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x76, - "SSL_DHE_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x76, + "SSL_DHE_RSA_WITH_CAST_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x77, - "SSL_DHE_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x77, + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x78, - "SSL_DHE_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x78, + "SSL_DHE_RSA_WITH_AES_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_DHE_RSA_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x79, - "SSL_DHE_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x79, + "SSL_DHE_RSA_WITH_AES_256_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x7A, - "SSL_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x7A, + "SSL_RSA_WITH_CAST_128_CBC_SHA", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7B, - "SSL_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7B, + "SSL_RSA_WITH_CAST_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x7C, - "SSL_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x7C, + "SSL_RSA_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7D, - "SSL_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7D, + "SSL_RSA_WITH_AES_128_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite SSL_RSA_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x7E, - "SSL_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x7E, + "SSL_RSA_WITH_AES_256_CBC_RMD", + ProtocolVersion.SSL_3); static final CipherSuite TLS_NULL_WITH_NULL_NULL = - new CipherSuite("null", "null", "null", "null", 0, 0x00, 0x00, - "TLS_NULL_WITH_NULL_NULL", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.NONE, + SignatureAlgorithm.ANONYMOUS, + MacAlgorithm.NULL, 0, 0x00, 0x00, + "TLS_NULL_WITH_NULL_NULL", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_NULL_MD5 = - new CipherSuite("null", "RSA", "RSA", "HMAC-MD5", 0, 0x00, 0x01, - "TLS_RSA_WITH_NULL_MD5", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_MD5, 0, 0x00, 0x01, + "TLS_RSA_WITH_NULL_MD5", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_NULL_SHA = - new CipherSuite("null", "RSA", "RSA", "HMAC-SHA", 0, 0x00, 0x02, - "TLS_RSA_WITH_NULL_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.NULL, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 0, 0x00, 0x02, + "TLS_RSA_WITH_NULL_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = - new CipherSuite("RC4", "RSA", "RSA", "HMAC-MD5", 5, 0x00, 0x03, - "TLS_RSA_EXPORT_WITH_RC4_40_MD5", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_MD5, 5, 0x00, 0x03, + "TLS_RSA_EXPORT_WITH_RC4_40_MD5", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_RC4_128_MD5 = - new CipherSuite("RC4", "RSA", "RSA", "HMAC-MD5", 16, 0x00, 0x04, - "TLS_RSA_WITH_RC4_128_MD5", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_MD5, 16, 0x00, 0x04, + "TLS_RSA_WITH_RC4_128_MD5", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_RC4_128_SHA = - new CipherSuite("RC4", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x05, - "TLS_RSA_WITH_RC4_128_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.RC4, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x05, + "TLS_RSA_WITH_RC4_128_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "RSA", "RSA", "HMAC-SHA", 5, 0x00, 0x08, - "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 5, 0x00, 0x08, + "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "RSA", "RSA", "HMAC-SHA", 8, 0x00, 0x09, - "TLS_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 8, 0x00, 0x09, + "TLS_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-SHA", 24, 0x00, 0x0A, - "TLS_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x0A, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DH", "DSS", "HMAC-SHA", 5, 0x00, 0x0B, - "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 5, 0x00, 0x0B, + "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DH", "DSS", "HMAC-SHA", 8, 0x00, 0x0C, - "TLS_DH_DSS_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 8, 0x00, 0x0C, + "TLS_DH_DSS_WITH_DES_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DH", "DSS", "HMAC-SHA", 24, 0x00, 0x0D, - "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x0D, + "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DH", "RSA", "HMAC-SHA", 5, 0x00, 0x0E, - "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 5, 0x00, 0x0E, + "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DH", "RSA", "HMAC-SHA", 8, 0x00, 0x0F, - "TLS_DH_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 8, 0x00, 0x0F, + "TLS_DH_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DH", "RSA", "HMAC-SHA", 24, 0x00, 0x10, - "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x10, + "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DHE", "DSS", "HMAC-SHA", 5, 0x00, 0x11, - "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 5, 0x00, 0x11, + "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DHE", "DSS", "HMAC-SHA", 8, 0x00, 0x12, - "TLS_DHE_DSS_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 8, 0x00, 0x12, + "TLS_DHE_DSS_WITH_DES_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-SHA", 24, 0x00, 0x13, - "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x13, + "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = - new CipherSuite("DES", "DHE", "RSA", "HMAC-SHA", 5, 0x00, 0x14, - "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 5, 0x00, 0x14, + "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = - new CipherSuite("DES", "DHE", "RSA", "HMAC-SHA", 8, 0x00, 0x15, - "TLS_DHE_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 8, 0x00, 0x15, + "TLS_DHE_RSA_WITH_DES_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-SHA", 24, 0x00, 0x16, - "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x16, + "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); // AES CipherSuites. static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x2F, - "TLS_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x2F, + "TLS_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DH", "DSS", "HMAC-SHA", 16, 0x00, 0x30, - "TLS_DH_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x30, + "TLS_DH_DSS_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DH", "RSA", "HMAC-SHA", 16, 0x00, 0x31, - "TLS_DH_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x31, + "TLS_DH_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x32, - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x32, + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x33, - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x33, + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "RSA", "RSA", "HMAC-SHA", 32, 0x00, 0x35, - "TLS_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x35, + "TLS_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DH", "DSS", "HMAC-SHA", 32, 0x00, 0x36, - "TLS_DH_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x36, + "TLS_DH_DSS_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DH", "RSA", "HMAC-SHA", 32, 0x00, 0x37, - "TLS_DH_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x37, + "TLS_DH_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DHE", "DSS", "HMAC-SHA", 32, 0x00, 0x38, - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x38, + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "DHE", "RSA", "HMAC-SHA", 32, 0x00, 0x39, - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x39, + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); // Secure remote password (SRP) ciphersuites static final CipherSuite TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "SRP", "anon", "HMAC-SHA", 24, 0x00, 0x50, - "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.ANONYMOUS, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x50, + "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "SRP", "RSA", "HMAC-SHA", 24, 0x00, 0x51, - "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x51, + "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = - new CipherSuite("TripleDES", "SRP", "DSS", "HMAC-SHA", 24, 0x00, 0x52, - "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 24, 0x00, 0x52, + "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "SRP", "anon", "HMAC-SHA", 16, 0x00, 0x53, - "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.ANONYMOUS, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x53, + "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "SRP", "RSA", "HMAC-SHA", 16, 0x00, 0x54, - "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x54, + "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = - new CipherSuite("AES", "SRP", "DSS", "HMAC-SHA", 16, 0x00, 0x55, - "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x55, + "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "SRP", "anon", "HMAC-SHA", 32, 0x00, 0x56, - "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.ANONYMOUS, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x56, + "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "SRP", "RSA", "HMAC-SHA", 32, 0x00, 0x57, - "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x57, + "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = - new CipherSuite("AES", "SRP", "DSS", "HMAC-SHA", 32, 0x00, 0x58, - "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.SRP, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 32, 0x00, 0x58, + "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", + ProtocolVersion.TLS_1); // Ciphersuites from the OpenPGP extension draft. static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x70, - "TLS_DHE_DSS_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x70, + "TLS_DHE_DSS_WITH_CAST_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x71, - "TLS_DHE_DSS_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x71, + "TLS_DHE_DSS_WITH_CAST_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-RIPEMD-160", 24, 0x00, 0x72, - "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x72, + "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x73, - "TLS_DHE_DSS_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x73, + "TLS_DHE_DSS_WITH_AES_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 32, 0x00, 0x74, - "TLS_DHE_DSS_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.DSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x74, + "TLS_DHE_DSS_WITH_AES_256_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x75, - "TLS_DHE_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x75, + "TLS_DHE_RSA_WITH_CAST_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x76, - "TLS_DHE_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x76, + "TLS_DHE_RSA_WITH_CAST_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x77, - "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x77, + "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x78, - "TLS_DHE_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x78, + "TLS_DHE_RSA_WITH_AES_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x79, - "TLS_DHE_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.DIFFIE_HELLMAN, true, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x79, + "TLS_DHE_RSA_WITH_AES_256_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_SHA = - new CipherSuite("CAST5", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x7A, - "TLS_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_SHA, 16, 0x00, 0x7A, + "TLS_RSA_WITH_CAST_128_CBC_SHA", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_RMD = - new CipherSuite("CAST5", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7B, - "TLS_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.CAST5, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7B, + "TLS_RSA_WITH_CAST_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_RMD = - new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x7C, - "TLS_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.DESede, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 24, 0x00, 0x7C, + "TLS_RSA_WITH_3DES_EDE_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_AES_128_CBC_RMD = - new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7D, - "TLS_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7D, + "TLS_RSA_WITH_AES_128_CBC_RMD", + ProtocolVersion.TLS_1); static final CipherSuite TLS_RSA_WITH_AES_256_CBC_RMD = - new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x7E, - "TLS_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1); + new CipherSuite (CipherAlgorithm.AES, + KeyExchangeAlgorithm.RSA, + SignatureAlgorithm.RSA, + MacAlgorithm.HMAC_RMD, 32, 0x00, 0x7E, + "TLS_RSA_WITH_AES_256_CBC_RMD", + ProtocolVersion.TLS_1); - private final String cipherName; - private final String kexName; - private final String sigName; - private final String macName; + private final CipherAlgorithm cipherAlgorithm; + private final KeyExchangeAlgorithm keyExchangeAlgorithm; + private final SignatureAlgorithm signatureAlgorithm; + private final MacAlgorithm macAlgorithm; + private final boolean ephemeralDH; private final boolean exportable; private final boolean isStream; private final int keyLength; @@ -406,16 +810,39 @@ final class CipherSuite implements Constructed // Constructors. // ------------------------------------------------------------------------- - private CipherSuite(String cipherName, String kexName, String sigName, - String macName, int keyLength, int id1, int id2, - String name, ProtocolVersion version) + private CipherSuite (final CipherAlgorithm cipherAlgorithm, + final KeyExchangeAlgorithm keyExchangeAlgorithm, + final SignatureAlgorithm signatureAlgorithm, + final MacAlgorithm macAlgorithm, + final int keyLength, + final int id1, + final int id2, + final String name, + final ProtocolVersion version) { - this.cipherName = cipherName.intern(); - this.kexName = kexName.intern(); - this.sigName = sigName.intern(); - this.macName = macName.intern(); + this (cipherAlgorithm, keyExchangeAlgorithm, false, signatureAlgorithm, + macAlgorithm, keyLength, id1, id2, name, version); + } + + private CipherSuite (final CipherAlgorithm cipherAlgorithm, + final KeyExchangeAlgorithm keyExchangeAlgorithm, + final boolean ephemeralDH, + final SignatureAlgorithm signatureAlgorithm, + final MacAlgorithm macAlgorithm, + final int keyLength, + final int id1, + final int id2, + final String name, + final ProtocolVersion version) + { + this.cipherAlgorithm = cipherAlgorithm; + this.keyExchangeAlgorithm = keyExchangeAlgorithm; + this.ephemeralDH = ephemeralDH; + this.signatureAlgorithm = signatureAlgorithm; + this.macAlgorithm = macAlgorithm; this.exportable = keyLength <= 5; - this.isStream = cipherName.equals("null") || cipherName.equals("RC4"); + this.isStream = (cipherAlgorithm == CipherAlgorithm.NULL + || cipherAlgorithm == CipherAlgorithm.RC4); this.keyLength = keyLength; this.id = new byte[] { (byte) id1, (byte) id2 }; this.name = name.intern(); @@ -429,10 +856,11 @@ final class CipherSuite implements Constructed private CipherSuite(byte[] id) { - cipherName = null; - kexName = null; - sigName = null; - macName = null; + cipherAlgorithm = null; + keyExchangeAlgorithm = null; + signatureAlgorithm = null; + macAlgorithm = null; + ephemeralDH = false; exportable = false; isStream = false; keyLength = 0; @@ -452,112 +880,123 @@ final class CipherSuite implements Constructed */ static CipherSuite forName(String name) { - return (CipherSuite) namesToSuites.get(name); + return (CipherSuite) namesToSuites.get (name); } - static List availableSuiteNames() + static CipherSuite forValue (final short raw_value) { - return tlsSuiteNames; + byte[] b = new byte[] { (byte) (raw_value >>> 8), (byte) raw_value }; + return new CipherSuite (b); } - static CipherSuite read(InputStream in) throws IOException + static CipherSuite forValue (final short raw_value, final ProtocolVersion version) { - DataInputStream din = new DataInputStream(in); - byte[] id = new byte[2]; - din.readFully(id); - return new CipherSuite(id); + return forValue (raw_value).resolve (version); } - static IMode getCipher(String cbcCipherName) + static List availableSuiteNames() { - IBlockCipher cipher = CipherFactory.getInstance(cbcCipherName); - if (cipher == null) - { - return null; - } - return ModeFactory.getInstance("CBC", cipher, cipher.defaultBlockSize()); + return tlsSuiteNames; } - static Cipher getJCECipher (final String name) - throws NoSuchAlgorithmException, NoSuchPaddingException + // Intance methods. + // ------------------------------------------------------------------------- + + CipherAlgorithm getCipherAlgorithm () { - final String provider = Util.getSecurityProperty ("jessie.with.jce.provider"); - if (name.equals ("RC4")) - { - if (provider != null) - { - try - { - return Cipher.getInstance (name, provider); - } - catch (NoSuchProviderException nsae) - { - // Fall through. Try any available provider. - } - } + return cipherAlgorithm; + } - return Cipher.getInstance (name); - } + Cipher getCipher () throws NoSuchAlgorithmException, NoSuchPaddingException + { + if (cipherAlgorithm == null) + throw new NoSuchAlgorithmException (toString () + ": unresolved cipher suite"); + if (cipherAlgorithm == CipherAlgorithm.NULL) + return new NullCipher (); + + String alg = null; + if (cipherAlgorithm == CipherAlgorithm.RC4) + alg = "RC4"; else + alg = cipherAlgorithm + "/CBC/SSL3Padding"; + GetSecurityPropertyAction gspa = + new GetSecurityPropertyAction ("jessie.jce.provider"); + final String provider = (String) AccessController.doPrivileged (gspa); + if (provider != null) { - // Oh, hey! Look! Something else Sun doesn't understand: SSLv3 padding - // is different than TLSv1 in subtle, but important, ways. But they - // sorta look the same, so why not make them equivalent? - // - // There should be a seperate padding "TLS1Padding". - if (provider != null) + try + { + return Cipher.getInstance (alg, provider); + } + catch (NoSuchProviderException nspe) { - try - { - return Cipher.getInstance (name + "/CBC/SSL3Padding", provider); - } - catch (NoSuchProviderException nspe) - { - // Fall through. Try any available provider. - } } - return Cipher.getInstance (name + "/CBC/SSL3Padding"); } + return Cipher.getInstance (alg); } - static IMac getMac(String macName) + MacAlgorithm getMacAlgorithm () { - if (macName.startsWith("SSLMAC-")) - { - return new SSLHMac(macName.substring(7)); - } - else - { - return MacFactory.getInstance(macName); - } + return macAlgorithm; } - static Mac getJCEMac (final String name) - throws NoSuchAlgorithmException + Mac getMac () throws NoSuchAlgorithmException { - final String provider = Util.getSecurityProperty ("jessie.with.jce.provider"); + if (macAlgorithm == null) + throw new NoSuchAlgorithmException (toString () + ": unresolved cipher suite"); + if (macAlgorithm == MacAlgorithm.NULL) + return null; + GetSecurityPropertyAction gspa = + new GetSecurityPropertyAction ("jessie.jce.provider"); + final String provider = (String) AccessController.doPrivileged (gspa); if (provider != null) { try { - return Mac.getInstance (name, provider); + return Mac.getInstance (macAlgorithm.toString (), provider); } catch (NoSuchProviderException nspe) { - // Fall through. Try any available provider. } } - return Mac.getInstance (name); + return Mac.getInstance (macAlgorithm.toString ()); } - // Intance methods. - // ------------------------------------------------------------------------- + SignatureAlgorithm getSignatureAlgorithm () + { + return signatureAlgorithm; + } + + KeyExchangeAlgorithm getKeyExchangeAlgorithm () + { + return keyExchangeAlgorithm; + } + + boolean isEphemeralDH () + { + return ephemeralDH; + } + + public int getLength () + { + return 2; + } public void write(OutputStream out) throws IOException { out.write(id); } + void put (final ByteBuffer buf) + { + buf.put (id); + } + + boolean isResolved () + { + return (version != null); + } + CipherSuite resolve(ProtocolVersion version) { if (version == ProtocolVersion.SSL_3) @@ -662,31 +1101,11 @@ final class CipherSuite implements Constructed return this; } - String getCipher() - { - return cipherName; - } - int getKeyLength() { return keyLength; } - String getKeyExchange() - { - return kexName; - } - - String getSignature() - { - return sigName; - } - - String getMac() - { - return macName; - } - boolean isExportable() { return exportable; @@ -697,18 +1116,18 @@ final class CipherSuite implements Constructed return isStream; } - String getAuthType() - { - if (kexName.equals("RSA")) - { - if (isExportable()) - { - return "RSA_EXPORT"; - } - return "RSA"; - } - return kexName + "_" + sigName; - } +// String getAuthType() +// { +// if (keyExchangeAlgorithm == KeyExchangeAlgorithm.RSA) +// { +// if (isExportable()) +// { +// return "RSA_EXPORT"; +// } +// return "RSA"; +// } +// return kexName + "_" + sigName; +// } byte[] getId() { @@ -729,8 +1148,8 @@ final class CipherSuite implements Constructed if (o == this) return true; byte[] id = ((CipherSuite) o).getId(); - return id[0] == this.id[0] && - id[1] == this.id[1]; + return (id[0] == this.id[0] && + id[1] == this.id[1]); } public int hashCode() @@ -739,15 +1158,20 @@ final class CipherSuite implements Constructed { return 0xFFFF0000 | (id[0] & 0xFF) << 8 | (id[1] & 0xFF); } - return version.getMajor() << 24 | version.getMinor() << 16 - | (id[0] & 0xFF) << 8 | (id[1] & 0xFF); + return (version.getMajor() << 24 | version.getMinor() << 16 + | (id[0] & 0xFF) << 8 | (id[1] & 0xFF)); + } + + public String toString (String prefix) + { + return toString (); } public String toString() { if (name == null) { - return "UNKNOWN { " + (id[0] & 0xFF) + ", " + (id[1] & 0xFF) + " }"; + return "{ " + (id[0] & 0xFF) + ", " + (id[1] & 0xFF) + " }"; } return name; } diff --git a/gnu/javax/net/ssl/provider/ClientHello.java b/gnu/javax/net/ssl/provider/ClientHello.java index 259051df1..aa0433ede 100644 --- a/gnu/javax/net/ssl/provider/ClientHello.java +++ b/gnu/javax/net/ssl/provider/ClientHello.java @@ -47,6 +47,8 @@ import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; +import java.nio.ByteBuffer; + import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; @@ -54,200 +56,198 @@ import java.util.List; import javax.net.ssl.SSLProtocolException; +/** + * A ClientHello handshake message. + * + * <pre> +struct +{ + ProtocolVersion client_version; // 2 + Random random; // 32 + SessionID session_id; // 1 + 0..32 + CipherSuite cipher_suites<2..2^16-1> + CompressionMethod compression_methods<1..2^8-1> +} ClientHello; +</pre> + */ final class ClientHello implements Handshake.Body { // Fields. // ------------------------------------------------------------------------- - private ProtocolVersion version; - private Random random; - private byte[] sessionId; - private List suites; - private List comp; - private List extensions; + // To help track offsets into the message: + // The location of the 'random' field. + private static final int RANDOM_OFFSET = 2; + // The location of the sesion_id length. + private static final int SESSID_OFFSET = 32 + RANDOM_OFFSET; + // The location of the session_id bytes (if any). + private static final int SESSID_OFFSET2 = SESSID_OFFSET + 1; + + private final ByteBuffer buffer; + private int totalLength; // Constructor. // ------------------------------------------------------------------------- - ClientHello(ProtocolVersion version, Random random, - byte[] sessionId, List suites, List comp) + ClientHello (final ByteBuffer buffer) { - this(version, random, sessionId, suites, comp, null); + this.buffer = buffer; + totalLength = buffer.limit (); } - ClientHello(ProtocolVersion version, Random random, - byte[] sessionId, List suites, List comp, List extensions) + // Instance methods. + // ------------------------------------------------------------------------- + + public int getLength () { - this.version = version; - this.random = random; - this.sessionId = sessionId; - this.suites = suites; - this.comp = comp; - this.extensions = extensions; + return totalLength; } - // Class methods. - // ------------------------------------------------------------------------- + /** + * Gets the protocol version field. + * + * @return The protocol version field. + */ + ProtocolVersion getProtocolVersion() + { + return ProtocolVersion.getInstance (buffer.getShort (0)); + } - static ClientHello read(InputStream in) throws IOException + /** + * Gets the SSL nonce. + * + * @return The nonce. + */ + Random getRandom() { - ProtocolVersion vers = ProtocolVersion.read(in); - Random rand = Random.read(in); - byte[] id = new byte[in.read() & 0xFF]; - in.read(id); - int len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF); - ArrayList suites = new ArrayList(len / 2); - for (int i = 0; i < len; i += 2) - { - suites.add(CipherSuite.read(in).resolve(vers)); - } - len = in.read() & 0xFF; - ArrayList comp = new ArrayList(len); - for (int i = 0; i < len; i++) - { - comp.add(CompressionMethod.read(in)); - } + ByteBuffer randomBuf = + ((ByteBuffer) buffer.duplicate ().position (RANDOM_OFFSET) + .limit (SESSID_OFFSET)).slice (); + return new Random (randomBuf); + } - List ext = null; - // Since parsing MAY need to continue into the extensions fields, or it - // may end here, the specified input stream MUST be a ByteArrayInputStream - // over all the data this hello contains. Otherwise this will mess up - // the data stream. - if (in.available() > 0) // then we have extensions. - { - ext = new LinkedList(); - len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF); - int count = 0; - while (count < len) - { - Extension e = Extension.read(in); - ext.add(e); - count += e.getValue().length + 4; - } - } - return new ClientHello(vers, rand, id, suites, comp, ext); + byte[] getSessionId() + { + int idlen = buffer.get (SESSID_OFFSET) & 0xFF; + byte[] sessionId = new byte[idlen]; + buffer.position (SESSID_OFFSET2); + buffer.get (sessionId); + return sessionId; } - // Instance methods. - // ------------------------------------------------------------------------- + CipherSuiteList getCipherSuites() + { + int offset = getCipherSuitesOffset (); + + // We give the CipherSuiteList all the remaining bytes to play with, + // since this might be an in-construction packet that will fill in + // the length field itself. + ByteBuffer listBuf = ((ByteBuffer) buffer.duplicate ().position (offset) + .limit (buffer.capacity ())).slice (); + return new CipherSuiteList (listBuf, getProtocolVersion ()); + } - public void write(OutputStream out) throws IOException + CompressionMethodList getCompressionMethods() { - version.write(out); - random.write(out); - out.write(sessionId.length); - out.write(sessionId); - out.write((suites.size() << 1) >>> 8 & 0xFF); - out.write((suites.size() << 1) & 0xFF); - for (Iterator i = suites.iterator(); i.hasNext(); ) - { - ((CipherSuite) i.next()).write(out); - } - out.write(comp.size()); - for (Iterator i = comp.iterator(); i.hasNext(); ) - { - out.write(((CompressionMethod) i.next()).getValue()); - } - if (extensions != null) - { - ByteArrayOutputStream out2 = new ByteArrayOutputStream(); - for (Iterator i = extensions.iterator(); i.hasNext(); ) - { - ((Extension) i.next()).write(out2); - } - out.write(out2.size() >>> 8 & 0xFF); - out.write(out2.size() & 0xFF); - out2.writeTo(out); - } + int offset = getCompressionMethodsOffset (); + ByteBuffer listBuf = ((ByteBuffer) buffer.duplicate ().position (offset) + .limit (buffer.capacity ())).slice (); + return new CompressionMethodList (listBuf); } - ProtocolVersion getVersion() + ByteBuffer getExtensions() { - return version; + int offset = getExtensionsOffset (); + return ((ByteBuffer) buffer.duplicate ().position (offset) + .limit (totalLength)).slice (); } - Random getRandom() + void setProtocolVersion (final ProtocolVersion version) { - return random; + buffer.putShort (0, (short) version.getRawValue ()); } - byte[] getSessionId() + void setSessionId (final byte[] buffer) { - return sessionId; + setSessionId (buffer, 0, buffer.length); } - List getCipherSuites() + void setSessionId (final byte[] buffer, final int offset, final int length) { - return suites; + int len = Math.min (32, length); + this.buffer.put (SESSID_OFFSET, (byte) len); + this.buffer.position (SESSID_OFFSET2); + this.buffer.put (buffer, offset, len); } - List getCompressionMethods() + void setExtensionsLength (final int length) { - return comp; + this.totalLength = getExtensionsOffset () + length; } - List getExtensions() + private int getCipherSuitesOffset () { - return extensions; + return (SESSID_OFFSET2 + (buffer.get (SESSID_OFFSET) & 0xFF)); } - public String toString() + private int getCompressionMethodsOffset () { - StringWriter str = new StringWriter(); - PrintWriter out = new PrintWriter(str); - out.println("struct {"); - out.println(" version = " + version + ";"); - BufferedReader r = new BufferedReader(new StringReader(random.toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - out.println(" sessionId = " + Util.toHexString(sessionId, ':') + ";"); - out.println(" cipherSuites = {"); - for (Iterator i = suites.iterator(); i.hasNext(); ) - { - out.print(" "); - out.println(i.next()); - } - out.println(" };"); - out.print(" compressionMethods = { "); - for (Iterator i = comp.iterator(); i.hasNext(); ) - { - out.print(i.next()); - if (i.hasNext()) - out.print(", "); - } - out.println(" };"); - if (extensions != null) + int csOffset = getCipherSuitesOffset (); + int csLen = buffer.getShort (csOffset) & 0xFFFF; + return csOffset + csLen + 2; + } + + private int getExtensionsOffset () + { + int cmOffset = getCompressionMethodsOffset (); + return (buffer.get (cmOffset) & 0xFF) + cmOffset + 1; + } + + public String toString () + { + return toString (null); + } + + public String toString (final String prefix) + { + StringWriter str = new StringWriter (); + PrintWriter out = new PrintWriter (str); + String subprefix = " "; + if (prefix != null) + subprefix += prefix; + if (prefix != null) + out.print (prefix); + out.println ("struct {"); + if (prefix != null) + out.print (prefix); + out.print (" version: "); + out.print (getProtocolVersion ()); + out.println (";"); + out.print (subprefix); + out.println ("random:"); + out.print (getRandom ().toString (subprefix)); + if (prefix != null) + out.print (prefix); + out.print (" sessionId: "); + out.print (Util.toHexString (getSessionId (), ':')); + out.println (";"); + out.print (subprefix); + out.println ("cipher_suites:"); + out.println (getCipherSuites ().toString (subprefix)); + out.print (subprefix); + out.println ("compression_methods:"); + out.println (getCompressionMethods ().toString (subprefix)); + ByteBuffer extbuf = getExtensions (); + if (extbuf.limit () > 0) { - out.println(" extensions = {"); - for (Iterator i = extensions.iterator(); i.hasNext(); ) - { - r = new BufferedReader(new StringReader(i.next().toString())); - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - } - out.println(" };"); + out.print (subprefix); + out.println ("extensions:"); + out.print (Util.hexDump (extbuf, subprefix)); } - out.println("} ClientHello;"); + if (prefix != null) + out.print (prefix); + out.print ("} ClientHello;"); return str.toString(); } } diff --git a/gnu/javax/net/ssl/provider/ClientKeyExchange.java b/gnu/javax/net/ssl/provider/ClientKeyExchange.java index 828aa8d5e..0c4513273 100644 --- a/gnu/javax/net/ssl/provider/ClientKeyExchange.java +++ b/gnu/javax/net/ssl/provider/ClientKeyExchange.java @@ -49,132 +49,79 @@ import java.io.StringWriter; import java.math.BigInteger; +import java.nio.ByteBuffer; + import java.security.PublicKey; import java.security.interfaces.RSAKey; import javax.crypto.interfaces.DHPublicKey; +/** + * The client key exchange message. + * + * <pre> +struct { + select (KeyExchangeAlgorithm) { + case rsa: EncryptedPreMasterSecret; + case diffie_hellman: ClientDiffieHellmanPublic; + } exchange_keys; +} ClientKeyExchange;</pre> + */ final class ClientKeyExchange implements Handshake.Body { // Fields. // ------------------------------------------------------------------------- - private final Object exObject; + private final ByteBuffer buffer; + private final CipherSuite suite; // Constructors. // ------------------------------------------------------------------------- - ClientKeyExchange(byte[] encryptedSecret) - { - exObject = encryptedSecret; - } - - ClientKeyExchange(BigInteger bigint) - { - exObject = bigint; - } - - // Class method. - // ------------------------------------------------------------------------- - - static ClientKeyExchange read(InputStream in, CipherSuite suite, - PublicKey key) - throws IOException + ClientKeyExchange (final ByteBuffer buffer, final CipherSuite suite) { - DataInputStream din = new DataInputStream(in); - if (suite.getKeyExchange().equals("RSA")) - { - int len = 0; - if (suite.getVersion() == ProtocolVersion.SSL_3) - { - len = (((RSAKey) key).getModulus().bitLength()+7) / 8; - } - else - { - len = din.readUnsignedShort(); - } - byte[] buf = new byte[len]; - din.readFully(buf); - return new ClientKeyExchange(buf); - } - else if (suite.getKeyExchange().equals("SRP")) - { - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - return new ClientKeyExchange(new BigInteger(1, buf)); - } - else if (key == null || !(key instanceof DHPublicKey)) // explicit. - { - byte[] buf = new byte[din.readUnsignedShort()]; - din.readFully(buf); - return new ClientKeyExchange(new BigInteger(1, buf)); - } - else - { - return new ClientKeyExchange(new byte[0]); - } + buffer.getClass (); + suite.getClass (); + this.buffer = buffer; + this.suite = suite; } // Instance methods. // ------------------------------------------------------------------------- - public void write(OutputStream out) throws IOException + ExchangeKeys getExchangeKeys () { - throw new UnsupportedOperationException("use write(java.io.OutputStream,ProtocolVersion) instead"); + KeyExchangeAlgorithm alg = suite.getKeyExchangeAlgorithm (); + if (alg == KeyExchangeAlgorithm.RSA) + return new EncryptedPreMasterSecret (buffer, suite.getVersion ()); + else if (alg == KeyExchangeAlgorithm.DIFFIE_HELLMAN) + return new ClientDiffieHellmanPublic (buffer); + throw new IllegalArgumentException ("unsupported key exchange"); } - public void write(OutputStream out, ProtocolVersion version) throws IOException + public int getLength () { - if (exObject instanceof byte[]) - { - byte[] b = (byte[]) exObject; - if (b.length > 0) - { - if (version != ProtocolVersion.SSL_3) - { - out.write(b.length >>> 8 & 0xFF); - out.write(b.length & 0xFF); - } - out.write(b); - } - } - else - { - byte[] bigint = ((BigInteger) exObject).toByteArray(); - if (bigint[0] == 0x00) - { - out.write(bigint.length - 1 >>> 8 & 0xFF); - out.write(bigint.length - 1 & 0xFF); - out.write(bigint, 1, bigint.length - 1); - } - else - { - out.write(bigint.length >>> 8 & 0xFF); - out.write(bigint.length & 0xFF); - out.write(bigint); - } - } + return getExchangeKeys ().getLength (); } - Object getExchangeObject() + public String toString () { - return exObject; + 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 {"); - if (exObject instanceof byte[] && ((byte[]) exObject).length > 0) - { - out.println(" encryptedPreMasterSecret ="); - out.print(Util.hexDump((byte[]) exObject, " ")); - } - else if (exObject instanceof BigInteger) - { - out.println(" clientPublic = " + ((BigInteger) exObject).toString(16) + ";"); - } + String subprefix = " "; + if (prefix != null) + subprefix = prefix + subprefix; + out.println (getExchangeKeys ().toString (subprefix)); + if (prefix != null) + out.print (prefix); out.println("} ClientKeyExchange;"); return str.toString(); } diff --git a/gnu/javax/net/ssl/provider/CompressionMethod.java b/gnu/javax/net/ssl/provider/CompressionMethod.java index c2fdf05f9..34c05d4e4 100644 --- a/gnu/javax/net/ssl/provider/CompressionMethod.java +++ b/gnu/javax/net/ssl/provider/CompressionMethod.java @@ -1,4 +1,4 @@ -/* CompressionMethod.java -- the compression method enum. +/* CompressionMethod.java -- The CompressionMethod enum. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -64,13 +64,8 @@ final class CompressionMethod implements Enumerated // Class method. // ------------------------------------------------------------------------- - static CompressionMethod read(InputStream in) throws IOException + static CompressionMethod getInstance (final int value) { - int value = in.read(); - if (value == -1) - { - throw new EOFException("unexpected end of input stream"); - } switch (value & 0xFF) { case 0: return NULL; @@ -92,6 +87,18 @@ final class CompressionMethod implements Enumerated return value; } + public boolean equals (final Object o) + { + if (!(o instanceof CompressionMethod)) + return false; + return ((CompressionMethod) o).value == value; + } + + public int hashCode () + { + return value; + } + public String toString() { switch (value) diff --git a/gnu/javax/net/ssl/provider/Constructed.java b/gnu/javax/net/ssl/provider/Constructed.java index ee3f56a7f..fbf591ada 100644 --- a/gnu/javax/net/ssl/provider/Constructed.java +++ b/gnu/javax/net/ssl/provider/Constructed.java @@ -1,4 +1,4 @@ -/* Constructed.java -- constructed type. +/* Constructed.java -- Constructed type. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -38,20 +38,25 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; -import java.io.IOException; -import java.io.OutputStream; - /** * The base interface to SSL constructed types. */ interface Constructed { + /** + * Returns the total length, in bytes, of this structure. + * + * @return The length of this structure. + */ + int getLength (); /** - * Writes this structure's encoded form to the given output stream. + * Returns a printable representation of this structure, with the + * given prefix prepended to each line. * - * @param out The output stream. - * @throws IOException If an I/O error occurs. + * @param prefix The prefix to prepend to each line of the + * output. This value may be <code>null</code>. + * @return A printable representation of this structure. */ - void write(OutputStream out) throws IOException; + String toString (String prefix); } diff --git a/gnu/javax/net/ssl/provider/ContentType.java b/gnu/javax/net/ssl/provider/ContentType.java index 336809467..b011ae532 100644 --- a/gnu/javax/net/ssl/provider/ContentType.java +++ b/gnu/javax/net/ssl/provider/ContentType.java @@ -1,4 +1,4 @@ -/* ContentType.java -- record layer content type. +/* ContentType.java -- SSL record layer content type. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -45,8 +45,12 @@ import java.io.IOException; /** * The content type enumeration, which marks packets in the record layer. * - * <pre>enum { change_cipher_spec(20), alert(21), handshake(22), - * application_data(23), (255) } ContentType;</pre> + * <pre> +enum { change_cipher_spec(20), alert(21), handshake(22), + application_data(23), (255) } ContentType;</pre> + * + * <p>There is also a "pseudo" content type, <code>client_hello_v2 + * (1)</code>, which is used for backwards compatibility with SSLv2. * * @author Casey Marshall (rsdio@metastatic.org) */ @@ -82,6 +86,11 @@ final class ContentType implements Enumerated { throw new EOFException("unexpected end of input stream"); } + return forInteger (value); + } + + static final ContentType forInteger (final int value) + { switch (value & 0xFF) { case 1: return CLIENT_HELLO_V2; diff --git a/gnu/javax/net/ssl/provider/Finished.java b/gnu/javax/net/ssl/provider/Finished.java index 8b9c220a5..585e00c17 100644 --- a/gnu/javax/net/ssl/provider/Finished.java +++ b/gnu/javax/net/ssl/provider/Finished.java @@ -38,10 +38,10 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; -import java.io.DataInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; + +import java.nio.ByteBuffer; final class Finished implements Handshake.Body { @@ -49,95 +49,125 @@ final class Finished implements Handshake.Body // Fields. // ------------------------------------------------------------------------- - /** TLSv1.x verify data. */ - private final byte[] verifyData; - - /** SSLv3 message digest pair. */ - private final byte[] md5, sha; + private final ByteBuffer buffer; + private final ProtocolVersion version; // Constructor. // ------------------------------------------------------------------------- - Finished(byte[] verifyData) + Finished (final ByteBuffer buffer, final ProtocolVersion version) { - this.verifyData = verifyData; - md5 = sha = null; + buffer.getClass (); + version.getClass (); + this.buffer = buffer; + this.version = version; } - Finished(byte[] md5, byte[] sha) + // Instance methods. + // ------------------------------------------------------------------------- + + public int getLength () { - this.md5 = md5; - this.sha = sha; - verifyData = null; + if (version == ProtocolVersion.TLS_1) + return 12; + if (version == ProtocolVersion.SSL_3) + return 36; + throw new IllegalArgumentException ("length for this version unknown"); } - // Class methods. - // ------------------------------------------------------------------------- - - static Finished read(InputStream in, CipherSuite suite) - throws IOException + byte[] getVerifyData() { - DataInputStream din = new DataInputStream(in); - if (suite.getVersion().equals(ProtocolVersion.SSL_3)) + if (version == ProtocolVersion.TLS_1) { - byte[] md5 = new byte[16]; - byte[] sha = new byte[20]; - din.readFully(md5); - din.readFully(sha); - return new Finished(md5, sha); + byte[] verify = new byte[12]; + buffer.position (0); + buffer.get (verify); + return verify; } - else + throw new IllegalArgumentException ("not TLSv1"); + } + + byte[] getMD5Hash() + { + if (version == ProtocolVersion.SSL_3) { - byte[] buf = new byte[12]; - din.readFully(buf); - return new Finished(buf); + byte[] md5 = new byte[16]; + buffer.position (0); + buffer.get (md5); + return md5; } + throw new IllegalArgumentException ("not SSLv3"); } - // Instance methods. - // ------------------------------------------------------------------------- - - public void write(OutputStream out) throws IOException + byte[] getSHAHash() { - if (verifyData != null) - out.write(verifyData); - else + if (version == ProtocolVersion.SSL_3) { - out.write(md5); - out.write(sha); + byte[] sha = new byte[20]; + buffer.position (16); + buffer.get (sha); + return sha; } + throw new IllegalArgumentException ("not SSLv3"); } - byte[] getVerifyData() + void setVerifyData (final byte[] verifyData, final int offset) { - return verifyData; + if (version != ProtocolVersion.TLS_1) + throw new IllegalArgumentException ("not TLSv1"); + buffer.position (0); + buffer.put (verifyData, offset, 12); } - byte[] getMD5Hash() + void setMD5Hash (final byte[] md5, final int offset) { - return md5; + if (version != ProtocolVersion.SSL_3) + throw new IllegalArgumentException ("not SSLv3"); + buffer.position (0); + buffer.put (md5, offset, 16); } - byte[] getSHAHash() + void setSHAHash (final byte[] sha, final int offset) + { + if (version != ProtocolVersion.SSL_3) + throw new IllegalArgumentException ("not SSLv3"); + buffer.position (16); + buffer.put (sha, offset, 20); + } + + public String toString () { - return sha; + return toString (null); } - public String toString() + public String toString (final String prefix) { - String nl = System.getProperty("line.separator"); - if (verifyData != null) + StringWriter str = new StringWriter (); + PrintWriter out = new PrintWriter (str); + if (prefix != null) + out.print (prefix); + out.println ("struct {"); + if (prefix != null) + out.print (prefix); + if (version == ProtocolVersion.TLS_1) { - return "struct {" + nl + - " verifyData = " + Util.toHexString(verifyData, ':') + ";" + nl + - "} Finished;" + nl; + out.print (" verifyData = "); + out.print (Util.toHexString (getVerifyData (), ':')); } - else + else if (version == ProtocolVersion.SSL_3) { - return "struct {" + nl + - " md5Hash = " + Util.toHexString(md5, ':') + ";" + nl + - " shaHash = " + Util.toHexString(sha, ':') + ";" + nl + - "} Finished;" + nl; + out.print (" md5 = "); + out.print (Util.toHexString (getMD5Hash (), ':')); + out.println (';'); + if (prefix != null) + out.print (prefix); + out.print (" sha = "); + out.print (Util.toHexString (getSHAHash (), ':')); } + out.println (';'); + if (prefix != null) + out.print (prefix); + out.print ("} Finished;"); + return str.toString (); } } diff --git a/gnu/javax/net/ssl/provider/Handshake.java b/gnu/javax/net/ssl/provider/Handshake.java index ef9e72381..cc7662453 100644 --- a/gnu/javax/net/ssl/provider/Handshake.java +++ b/gnu/javax/net/ssl/provider/Handshake.java @@ -1,4 +1,4 @@ -/* Handshake.java -- SSL handshake message. +/* Handshake.java -- SSL Handshake message. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -49,6 +49,8 @@ import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; +import java.nio.ByteBuffer; + import java.security.PublicKey; import java.util.ArrayList; @@ -56,277 +58,186 @@ import java.util.Collections; import javax.net.ssl.SSLProtocolException; +/** + * An SSL handshake message. SSL handshake messages have the following + * form: + * + * <pre> +struct +{ + HandshakeType msg_type; + uint24 length; + select (msg_type) + { + case hello_request: HelloRequest; + case client_hello: ClientHello; + case server_hello: ServerHello; + case certificate: Certificate; + case server_key_exchange: ServerKeyExchange; + case certificate_request: CertificateRequest; + case server_hello_done: ServerHelloDone; + case certificate_verify: CertificateVerify; + case client_key_exchange: ClientKeyExchange; + case finished: Finished; + } body; +};</pre> + */ final class Handshake implements Constructed { // Fields. // ------------------------------------------------------------------------- - private static final buffer BUF = new buffer(); - - private final Type type; - private final Body body; + private final ByteBuffer buffer; + private final CipherSuite suite; // Constructors. // ------------------------------------------------------------------------- - Handshake(Type type, Body body) - { - this.type = type; - this.body = body; - } - - // Class methods. - // ------------------------------------------------------------------------- - - static Handshake read(byte[] buffer) throws IOException + Handshake (final ByteBuffer buffer) { - return read(new ByteArrayInputStream(buffer)); + this (buffer, null); } - static Handshake read(byte[] buffer, CipherSuite suite, PublicKey key) - throws IOException + Handshake (final ByteBuffer buffer, final CipherSuite suite) { - return read(new ByteArrayInputStream(buffer), suite, key); + this.buffer = buffer; + this.suite = suite; } - static Handshake read(InputStream in) throws IOException - { - return read(in, null, null); - } + // Instance methods. + // ------------------------------------------------------------------------- - static Handshake read(InputStream in, CipherSuite suite, PublicKey key) - throws IOException + /** + * Returns the handshake type. + * + * @return The handshake type. + */ + Type getType() { - return read(in, suite, key, null); + return Type.forInteger (buffer.get (0) & 0xFF); } - static Handshake read(InputStream in, CertificateType certType) - throws IOException + /** + * Returns the message length. + * + * @return The message length. + */ + public int getLength () { - return read(in, null, null, certType); + // Length is a uint24. + return buffer.getInt (0) & 0xFFFFFF; } - static Handshake read(InputStream in, CipherSuite suite, PublicKey key, - CertificateType certType) - throws IOException + /** + * Returns the handshake message body. Depending on the handshake + * type, some implementation of the Body interface is returned. + * + * @return The handshake body. + */ + Body getBody() { - Type type = Type.read(in); - byte[] lenbuf = new byte[3]; - in.read(lenbuf); - int len = (lenbuf[0] & 0xFF) << 16 | (lenbuf[1] & 0xFF) << 8 - | (lenbuf[2] & 0xFF); - Body body = null; - if (type == Type.HELLO_REQUEST) - { - body = null; - } - else if (type == Type.CLIENT_HELLO) - { - // Most likely a V2 hello. If the first byte is 0x30, and if this - // is not a V2 client hello, then it is a V3 client hello with - // at least 1.5 million cipher specs, which is unlikely. - if (lenbuf[0] == 3 && (lenbuf[1] >= 0 && lenbuf[1] <= 2)) - { - ProtocolVersion vers = null; - switch (lenbuf[1]) - { - case 0: - vers = ProtocolVersion.SSL_3; - break; - case 1: - vers = ProtocolVersion.TLS_1; - break; - case 2: - vers = ProtocolVersion.TLS_1_1; - break; - } - int specLen = (lenbuf[2] & 0xFF) << 8 | (in.read() & 0xFF); - int idLen = (in.read() & 0xFF) << 8 | (in.read() & 0xFF); - int chalLen = (in.read() & 0xFF) << 8 | (in.read() & 0xFF); - - ArrayList suites = new ArrayList(specLen / 3); - for (int i = 0; i < specLen; i += 3) - { - if (in.read() == 0) - { - suites.add(CipherSuite.read(in).resolve(vers)); - } - else - { - in.read(); - in.read(); - } - } - byte[] id = new byte[idLen]; - in.read(id); - byte[] challenge = new byte[chalLen]; - in.read(challenge); - if (challenge.length > 32) - challenge = Util.trim(challenge, 32); - else if (challenge.length < 32) - { - byte[] b = new byte[32]; - System.arraycopy(challenge, 0, b, b.length - challenge.length, - challenge.length); - challenge = b; - } - int time = (challenge[0] & 0xFF) << 24 | (challenge[1] & 0xFF) << 16 - | (challenge[2] & 0xFF) << 8 | (challenge[3] & 0xFF); - Random rand = new Random(time, Util.trim(challenge, 4, 28)); - return new Handshake(Handshake.Type.CLIENT_HELLO, - new ClientHello(vers, rand, id, suites, - Collections.singletonList(CompressionMethod.NULL))); - } - // Since hello messages may contain extensions, we read the whole - // thing here. - byte[] buf = new byte[len]; - int count = 0; - while (count < len) - { - int l = in.read(buf, count, len - count); - if (l == -1) - { - throw new EOFException("unexpected end of input stream"); - } - count += l; - } - body = ClientHello.read(new ByteArrayInputStream(buf)); - } - else if (type == Type.SERVER_HELLO) + int type = buffer.get (0) & 0xFF; + ByteBuffer bodyBuffer = getBodyBuffer (); + switch (type) { - byte[] buf = new byte[len]; - int count = 0; - while (count < len) - { - int l = in.read(buf, count, len - count); - if (l == -1) - { - throw new EOFException("unexpected end of input stream"); - } - count += l; - } - body = ServerHello.read(new ByteArrayInputStream(buf)); - } - else if (type == Type.CERTIFICATE) - { - body = Certificate.read(in, certType); - } - else if (type == Type.SERVER_KEY_EXCHANGE) - { - body = ServerKeyExchange.read(in, suite, key); - } - else if (type == Type.CERTIFICATE_REQUEST) - { - body = CertificateRequest.read(in); - } - else if (type == Type.CERTIFICATE_VERIFY) - { - body = (CertificateVerify) CertificateVerify.read(in, suite, key); - } - else if (type == Type.CLIENT_KEY_EXCHANGE) - { - body = ClientKeyExchange.read(in, suite, key); - } - else if (type == Type.SERVER_HELLO_DONE) - { - body = null; - } - else if (type == Type.FINISHED) - { - body = Finished.read(in, suite); - } - else - { - throw new SSLProtocolException("unknown HandshakeType: " + - type.getValue()); - } + case Type.HELLO_REQUEST_VALUE: + return new HelloRequest (); - return new Handshake(type, body); - } + case Type.CLIENT_HELLO_VALUE: + return new ClientHello (bodyBuffer); - // Instance methods. - // ------------------------------------------------------------------------- + case Type.SERVER_HELLO_VALUE: + return new ServerHello (bodyBuffer); - public void write(OutputStream out) - { - throw new UnsupportedOperationException(); + case Type.CERTIFICATE_VALUE: + return new Certificate (bodyBuffer, CertificateType.X509); + + case Type.SERVER_KEY_EXCHANGE_VALUE: + return new ServerKeyExchange (bodyBuffer, suite); + + case Type.CERTIFICATE_REQUEST_VALUE: + return new CertificateRequest (bodyBuffer); + + case Type.SERVER_HELLO_DONE_VALUE: + return new ServerHelloDone (); + + case Type.CERTIFICATE_VERIFY_VALUE: + return new CertificateVerify (bodyBuffer, suite.getSignatureAlgorithm ()); + + case Type.CLIENT_KEY_EXCHANGE_VALUE: + return new ClientKeyExchange (bodyBuffer, suite); + + case Type.FINISHED_VALUE: + return new Finished (bodyBuffer, suite.getVersion ()); + + case Type.CERTIFICATE_URL_VALUE: + case Type.CERTIFICATE_STATUS_VALUE: + throw new UnsupportedOperationException ("FIXME"); + } + throw new IllegalArgumentException ("unknown handshake type " + type); } - public int write(OutputStream out, ProtocolVersion version) - throws IOException + /** + * Returns a subsequence of the underlying buffer, containing only + * the bytes that compose the handshake body. + * + * @return The body's byte buffer. + */ + ByteBuffer getBodyBuffer () { - out.write(type.getValue()); - if (body == null) - { - out.write(0); - out.write(0); - out.write(0); - return 4; - } - else - { - ByteArrayOutputStream bout = BUF.getBuffer(); - bout.reset(); - if (body instanceof ServerKeyExchange) - { - ((ServerKeyExchange) body).write(bout, version); - } - else if (body instanceof ClientKeyExchange) - { - ((ClientKeyExchange) body).write(bout, version); - } - else if (body instanceof CertificateVerify) - { - ((CertificateVerify) body).write(bout, version); - } - else - { - body.write(bout); - } - out.write(bout.size() >>> 16 & 0xFF); - out.write(bout.size() >>> 8 & 0xFF); - out.write(bout.size() & 0xFF); - bout.writeTo(out); - return 4 + bout.size(); - } + int length = getLength (); + return ((ByteBuffer) buffer.position (4).limit (4 + length)).slice (); } - Type getType() + /** + * Sets the handshake body type. + * + * @param type The handshake type. + */ + void setType (final Type type) { - return type; + buffer.put (0, (byte) type.getValue ()); } - Body getBody() + /** + * Sets the length of the handshake body. + * + * @param length The handshake body length. + * @throws java.nio.ReadOnlyBufferException If the underlying buffer + * is not writable. + * @throws IllegalArgumentException of <code>length</code> is not + * between 0 and 16777215, inclusive. + */ + void setLength (final int length) { - return body; + if (length < 0 || length > 0xFFFFFF) + throw new IllegalArgumentException ("length " + length + " out of range;" + + " must be between 0 and 16777215"); + buffer.put (1, (byte) (length >>> 16)); + buffer.put (2, (byte) (length >>> 8)); + buffer.put (3, (byte) length); } public String toString() { + return toString (null); + } + + public String toString (final String prefix) + { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); - String nl = System.getProperty("line.separator"); - StringBuffer buf = new StringBuffer(); + if (prefix != null) out.print (prefix); out.println("struct {"); - out.println(" type = " + type + ";"); - if (body != null) - { - BufferedReader r = new BufferedReader(new StringReader(body.toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - } - out.println("} Handshake;"); + if (prefix != null) out.print (prefix); + out.print (" type: "); + out.print (getType ()); + out.println (";"); + Body body = getBody (); + out.println (body.toString (prefix != null ? (prefix + " ") : " ")); + if (prefix != null) out.print (prefix); + out.print ("} Handshake;"); return str.toString(); } @@ -335,6 +246,9 @@ final class Handshake implements Constructed static interface Body extends Constructed { + int getLength (); + + String toString (String prefix); } static class Type implements Enumerated @@ -343,13 +257,33 @@ final class Handshake implements Constructed // Constants and fields. // ----------------------------------------------------------------------- - public static final Type - HELLO_REQUEST = new Type( 0), CLIENT_HELLO = new Type( 1), - SERVER_HELLO = new Type( 2), CERTIFICATE = new Type(11), - SERVER_KEY_EXCHANGE = new Type(12), CERTIFICATE_REQUEST = new Type(13), - SERVER_HELLO_DONE = new Type(14), CERTIFICATE_VERIFY = new Type(15), - CLIENT_KEY_EXCHANGE = new Type(16), FINISHED = new Type(20), - CERTIFICATE_URL = new Type(21), CERTIFICATE_STATUS = new Type(22); + private static final int + HELLO_REQUEST_VALUE = 0, + CLIENT_HELLO_VALUE = 1, + SERVER_HELLO_VALUE = 2, + CERTIFICATE_VALUE = 11, + SERVER_KEY_EXCHANGE_VALUE = 12, + CERTIFICATE_REQUEST_VALUE = 13, + SERVER_HELLO_DONE_VALUE = 14, + CERTIFICATE_VERIFY_VALUE = 15, + CLIENT_KEY_EXCHANGE_VALUE = 16, + FINISHED_VALUE = 20, + CERTIFICATE_URL_VALUE = 21, + CERTIFICATE_STATUS_VALUE = 22; + + static final Type + HELLO_REQUEST = new Type (HELLO_REQUEST_VALUE), + CLIENT_HELLO = new Type (CLIENT_HELLO_VALUE), + SERVER_HELLO = new Type (SERVER_HELLO_VALUE), + CERTIFICATE = new Type (CERTIFICATE_VALUE), + SERVER_KEY_EXCHANGE = new Type (SERVER_KEY_EXCHANGE_VALUE), + CERTIFICATE_REQUEST = new Type (CERTIFICATE_REQUEST_VALUE), + SERVER_HELLO_DONE = new Type (SERVER_HELLO_DONE_VALUE), + CERTIFICATE_VERIFY = new Type (CERTIFICATE_VERIFY_VALUE), + CLIENT_KEY_EXCHANGE = new Type (CLIENT_KEY_EXCHANGE_VALUE), + FINISHED = new Type (FINISHED_VALUE), + CERTIFICATE_URL = new Type (CERTIFICATE_URL_VALUE), + CERTIFICATE_STATUS = new Type (CERTIFICATE_STATUS_VALUE); private final int value; @@ -364,28 +298,23 @@ final class Handshake implements Constructed // Class methods. // ----------------------------------------------------------------------- - public static Type read(InputStream in) throws IOException + static Type forInteger (final int value) { - int i = in.read(); - if (i == -1) - { - throw new EOFException("unexpected end of input stream"); - } - switch (i & 0xFF) + switch (value & 0xFF) { - case 0: return HELLO_REQUEST; - case 1: return CLIENT_HELLO; - case 2: return SERVER_HELLO; - case 11: return CERTIFICATE; - case 12: return SERVER_KEY_EXCHANGE; - case 13: return CERTIFICATE_REQUEST; - case 14: return SERVER_HELLO_DONE; - case 15: return CERTIFICATE_VERIFY; - case 16: return CLIENT_KEY_EXCHANGE; - case 20: return FINISHED; - case 21: return CERTIFICATE_URL; - case 22: return CERTIFICATE_STATUS; - default: return new Type(i); + case HELLO_REQUEST_VALUE: return HELLO_REQUEST; + case CLIENT_HELLO_VALUE: return CLIENT_HELLO; + case SERVER_HELLO_VALUE: return SERVER_HELLO; + case CERTIFICATE_VALUE: return CERTIFICATE; + case SERVER_KEY_EXCHANGE_VALUE: return SERVER_KEY_EXCHANGE; + case CERTIFICATE_REQUEST_VALUE: return CERTIFICATE_REQUEST; + case SERVER_HELLO_DONE_VALUE: return SERVER_HELLO_DONE; + case CERTIFICATE_VERIFY_VALUE: return CERTIFICATE_VERIFY; + case CLIENT_KEY_EXCHANGE_VALUE: return CLIENT_KEY_EXCHANGE; + case FINISHED_VALUE: return FINISHED; + case CERTIFICATE_URL_VALUE: return CERTIFICATE_URL; + case CERTIFICATE_STATUS_VALUE: return CERTIFICATE_STATUS; + default: throw new IllegalArgumentException ("unsupported value type " + value); } } @@ -402,39 +331,36 @@ final class Handshake implements Constructed return value; } - public String toString() + public boolean equals (Object o) { - switch (value) - { - case 0: return "hello_request"; - case 1: return "client_hello"; - case 2: return "server_hello"; - case 11: return "certificate"; - case 12: return "server_key_exchange"; - case 13: return "certificate_request"; - case 14: return "server_hello_done"; - case 15: return "certificate_verify"; - case 16: return "client_key_exchange"; - case 20: return "finished"; - case 21: return "certificate_url"; - case 22: return "certificate_status"; - default: return "unknown(" + value + ")"; - } + if (!(o instanceof Type)) + return false; + return ((Type) o).value == value; } - } - - private static class buffer extends ThreadLocal - { - static final int SIZE = 2048; - protected Object initialValue() + public int hashCode () { - return new ByteArrayOutputStream(SIZE); + return value; } - ByteArrayOutputStream getBuffer() + public String toString() { - return (ByteArrayOutputStream) get(); + switch (value) + { + case HELLO_REQUEST_VALUE: return "hello_request"; + case CLIENT_HELLO_VALUE: return "client_hello"; + case SERVER_HELLO_VALUE: return "server_hello"; + case CERTIFICATE_VALUE: return "certificate"; + case SERVER_KEY_EXCHANGE_VALUE: return "server_key_exchange"; + case CERTIFICATE_REQUEST_VALUE: return "certificate_request"; + case SERVER_HELLO_DONE_VALUE: return "server_hello_done"; + case CERTIFICATE_VERIFY_VALUE: return "certificate_verify"; + case CLIENT_KEY_EXCHANGE_VALUE: return "client_key_exchange"; + case FINISHED_VALUE: return "finished"; + case CERTIFICATE_URL_VALUE: return "certificate_url"; + case CERTIFICATE_STATUS_VALUE: return "certificate_status"; + default: return "unknown(" + value + ")"; + } } } } diff --git a/gnu/javax/net/ssl/provider/ProtocolVersion.java b/gnu/javax/net/ssl/provider/ProtocolVersion.java index 5f5d1d979..a5aef7151 100644 --- a/gnu/javax/net/ssl/provider/ProtocolVersion.java +++ b/gnu/javax/net/ssl/provider/ProtocolVersion.java @@ -74,7 +74,7 @@ final class ProtocolVersion implements Comparable, Constructed return getInstance(major, minor); } - static ProtocolVersion getInstance(int major, int minor) + static ProtocolVersion getInstance(final int major, final int minor) { if (major == 3) { @@ -88,13 +88,25 @@ final class ProtocolVersion implements Comparable, Constructed return new ProtocolVersion(major, minor); } + static ProtocolVersion getInstance (final short raw_value) + { + int major = raw_value >>> 8 & 0xFF; + int minor = raw_value & 0xFF; + return getInstance (major, minor); + } + // Instance methods. // ------------------------------------------------------------------------- - public void write(OutputStream out) throws IOException +// public void write(OutputStream out) throws IOException +// { +// out.write(major); +// out.write(minor); +// } + + public int getLength () { - out.write(major); - out.write(minor); + return 2; } byte[] getEncoded() @@ -114,9 +126,14 @@ final class ProtocolVersion implements Comparable, Constructed return minor; } + int getRawValue () + { + return (major << 8) | minor; + } + public boolean equals(Object o) { - if (o == null || !(o instanceof ProtocolVersion)) + if (!(o instanceof ProtocolVersion)) { return false; } @@ -131,33 +148,32 @@ final class ProtocolVersion implements Comparable, Constructed public int compareTo(Object o) { - if (o == null || !(o instanceof ProtocolVersion)) - { - return 1; - } - if (this.equals(o)) - { - return 0; - } - if (major > ((ProtocolVersion) o).major) + ProtocolVersion that = (ProtocolVersion) o; + if (major > that.major) { return 1; } - else if (major < ((ProtocolVersion) o).major) + else if (major < that.major) { return -1; } - if (minor > ((ProtocolVersion) o).minor) + + if (minor > that.minor) { return 1; } - else if (minor < ((ProtocolVersion) o).minor) + else if (minor < that.minor) { return -1; } return 0; } + public String toString (String prefix) + { + return toString (); + } + public String toString() { if (this == SSL_3) diff --git a/gnu/javax/net/ssl/provider/Random.java b/gnu/javax/net/ssl/provider/Random.java index c42592b14..cfada42eb 100644 --- a/gnu/javax/net/ssl/provider/Random.java +++ b/gnu/javax/net/ssl/provider/Random.java @@ -45,80 +45,135 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.nio.ByteBuffer; + +/** + * An SSL nonce. + * + * <pre> +struct +{ + uint32 gmt_unix_time; + opaque random_bytes[28]; +} Random; + */ class Random implements Constructed { // Fields. // ------------------------------------------------------------------------- - private final int gmtUnixTime; - private final byte[] randomBytes; + static final int RANDOM_LENGTH = 28; + + private final ByteBuffer buffer; // Constructors. // ------------------------------------------------------------------------- - Random(int gmtUnixTime, byte[] randomBytes) + Random (final ByteBuffer buffer) { - this.gmtUnixTime = gmtUnixTime; - this.randomBytes = (byte[]) randomBytes.clone(); + this.buffer = buffer; } // Class methods. // ------------------------------------------------------------------------- - static Random read(InputStream in) throws IOException - { - int time = (in.read() & 0xFF) << 24 | (in.read() & 0xFF) << 16 - | (in.read() & 0xFF) << 8 | (in.read() & 0xFF); - byte[] buf = new byte[28]; - in.read(buf); - return new Random(time, buf); - } +// static Random read(InputStream in) throws IOException +// { +// int time = (in.read() & 0xFF) << 24 | (in.read() & 0xFF) << 16 +// | (in.read() & 0xFF) << 8 | (in.read() & 0xFF); +// byte[] buf = new byte[28]; +// in.read(buf); +// return new Random(time, buf); +// } // Instance methods. // ------------------------------------------------------------------------- - public void write(OutputStream out) throws IOException +// public void write(OutputStream out) throws IOException +// { +// out.write((gmtUnixTime >>> 24) & 0xFF); +// out.write((gmtUnixTime >>> 16) & 0xFF); +// out.write((gmtUnixTime >>> 8) & 0xFF); +// out.write(gmtUnixTime & 0xFF); +// out.write(randomBytes); +// } + +// byte[] getEncoded() +// { +// ByteArrayOutputStream bout = new ByteArrayOutputStream(32); +// try +// { +// write(bout); +// } +// catch (IOException cantHappen) +// { +// throw new Error(cantHappen.toString()); +// } +// return bout.toByteArray(); +// } + + public int getLength () { - out.write((gmtUnixTime >>> 24) & 0xFF); - out.write((gmtUnixTime >>> 16) & 0xFF); - out.write((gmtUnixTime >>> 8) & 0xFF); - out.write(gmtUnixTime & 0xFF); - out.write(randomBytes); + return RANDOM_LENGTH + 4; } - byte[] getEncoded() + int getGMTUnixTime () { - ByteArrayOutputStream bout = new ByteArrayOutputStream(32); - try - { - write(bout); - } - catch (IOException cantHappen) - { - throw new Error(cantHappen.toString()); - } - return bout.toByteArray(); + return buffer.getInt (0); } - int getTime() + byte[] getRandomBytes() { - return gmtUnixTime; + byte[] buf = new byte[28]; + buffer.position (4); + buffer.get (buf); + return buf; } - byte[] getRandomBytes() + void setGMTUnixTime (final int gmtUnixTime) { - return randomBytes; + buffer.putInt (0, gmtUnixTime); } - public String toString() + void setRandomBytes (final byte[] randomBytes) + { + setRandomBytes (randomBytes, 0); + } + + void setRandomBytes (final byte[] randomBytes, final int offset) + { + if (randomBytes.length - offset < RANDOM_LENGTH) + throw new IllegalArgumentException ("random value too short"); + buffer.position (4); + buffer.put (randomBytes, offset, RANDOM_LENGTH); + } + + 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(" gmt_unix_time = " + gmtUnixTime + ";"); - out.println(" random_bytes = " + Util.toHexString(randomBytes, ':') + ";"); - out.println("} Random;"); + if (prefix != null) + out.print (prefix); + out.print (" gmt_unix_time: "); + out.print (getGMTUnixTime ()); + out.println (";"); + if (prefix != null) + out.print (prefix); + out.print (" random_bytes: "); + out.print (Util.toHexString (getRandomBytes (), ':')); + out.println (";"); + if (prefix != null) + out.print (prefix); + out.print ("} Random;"); return str.toString(); } + + public String toString () + { + return toString (null); + } } diff --git a/gnu/javax/net/ssl/provider/ServerHello.java b/gnu/javax/net/ssl/provider/ServerHello.java index 8b7853c7f..ca31a5dff 100644 --- a/gnu/javax/net/ssl/provider/ServerHello.java +++ b/gnu/javax/net/ssl/provider/ServerHello.java @@ -47,6 +47,8 @@ import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; +import java.nio.ByteBuffer; + import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; @@ -54,163 +56,259 @@ import java.util.List; import javax.net.ssl.SSLProtocolException; +/** + * The server hello message. + * + * <pre> +struct +{ + ProtocolVersion server_version; + Random random; + SessionID session_id; + CipherSuite cipher_suite; + CompressionMethod compression_method; +} ServerHello; +</pre> + * + * <p>Server hello messages may contain extra data after the + * <tt>compression_method</tt> field, which are interpreted as + * extensions to the basic handshake. + */ class ServerHello implements Handshake.Body { // Fields. // ------------------------------------------------------------------------- - private final ProtocolVersion version; - private final Random random; - private final byte[] sessionId; - private final CipherSuite suite; - private final CompressionMethod comp; - private final List extensions; + private static final int RANDOM_OFFSET = 2; + private static final int SESSID_OFFSET = 32 + RANDOM_OFFSET; + private static final int SESSID_OFFSET2 = SESSID_OFFSET + 1; + + private final ByteBuffer buffer; + + /** The total length of the message, including the extensions. */ + private int totalLength; // Constructor. // ------------------------------------------------------------------------- - ServerHello(ProtocolVersion version, Random random, - byte[] sessionId, CipherSuite suite, - CompressionMethod comp) - { - this(version, random, sessionId, suite, comp, null); - } - - ServerHello(ProtocolVersion version, Random random, - byte[] sessionId, CipherSuite suite, - CompressionMethod comp, List extensions) + ServerHello (final ByteBuffer buffer) { - this.version = version; - this.random = random; - this.sessionId = sessionId; - this.suite = suite; - this.comp = comp; - this.extensions = extensions; + this.buffer = buffer; } // Class methods. // ------------------------------------------------------------------------- - static ServerHello read(InputStream in) throws IOException - { - ProtocolVersion vers = ProtocolVersion.read(in); - Random rand = Random.read(in); - byte[] id = new byte[in.read() & 0xFF]; - in.read(id); - CipherSuite suite = CipherSuite.read(in).resolve(vers); - CompressionMethod comp = CompressionMethod.read(in); - List ext = null; - if (in.available() > 0) - { - ext = new LinkedList(); - int len = (in.read() >>> 8 & 0xFF) | (in.read() & 0xFF); - int count = 0; - while (count < len) - { - Extension e = Extension.read(in); - ext.add(e); - count += e.getValue().length + 4; - } - } - return new ServerHello(vers, rand, id, suite, comp, ext); - } +// static ServerHello read(InputStream in) throws IOException +// { +// ProtocolVersion vers = ProtocolVersion.read(in); +// Random rand = Random.read(in); +// byte[] id = new byte[in.read() & 0xFF]; +// in.read(id); +// CipherSuite suite = CipherSuite.read(in).resolve(vers); +// CompressionMethod comp = CompressionMethod.read(in); +// List ext = null; +// if (in.available() > 0) +// { +// ext = new LinkedList(); +// int len = (in.read() >>> 8 & 0xFF) | (in.read() & 0xFF); +// int count = 0; +// while (count < len) +// { +// Extension e = Extension.read(in); +// ext.add(e); +// count += e.getValue().length + 4; +// } +// } +// return new ServerHello(vers, rand, id, suite, comp, ext); +// } // Instance methods. // ------------------------------------------------------------------------- - public void write(OutputStream out) throws IOException +// public void write(OutputStream out) throws IOException +// { +// version.write(out); +// random.write(out); +// out.write(sessionId.length); +// out.write(sessionId); +// suite.write(out); +// out.write(comp.getValue()); +// if (extensions != null) +// { +// ByteArrayOutputStream out2 = new ByteArrayOutputStream(); +// for (Iterator i = extensions.iterator(); i.hasNext(); ) +// ((Extension) i.next()).write(out2); +// out.write(out2.size() >>> 8 & 0xFF); +// out.write(out2.size() & 0xFF); +// out2.writeTo(out); +// } +// } + + public int getLength () { - version.write(out); - random.write(out); - out.write(sessionId.length); - out.write(sessionId); - suite.write(out); - out.write(comp.getValue()); - if (extensions != null) - { - ByteArrayOutputStream out2 = new ByteArrayOutputStream(); - for (Iterator i = extensions.iterator(); i.hasNext(); ) - ((Extension) i.next()).write(out2); - out.write(out2.size() >>> 8 & 0xFF); - out.write(out2.size() & 0xFF); - out2.writeTo(out); - } + return totalLength; } - ProtocolVersion getVersion() + /** + * Returns the server's protocol version. This will read two bytes + * from the beginning of the underlying buffer, and return an + * instance of the appropriate {@link ProtocolVersion}; if the + * version read is a supported version, this method returns a static + * constant instance. + * + * @return The server's protocol version. + */ + ProtocolVersion getProtocolVersion() { - return version; + return ProtocolVersion.getInstance (buffer.getShort (0)); } + /** + * Returns the server's random value. This method returns a + * lightwieght wrapper around the existing bytes; modifications to + * the underlying buffer will modify the returned object, and + * vice-versa. + * + * @return The server's random value. + */ Random getRandom() { - return random; + ByteBuffer randomBuf = + ((ByteBuffer) buffer.duplicate ().position (RANDOM_OFFSET) + .limit (SESSID_OFFSET)).slice (); + return new Random (randomBuf); } + /** + * Returns the session ID. This method returns a new byte array with + * the session ID bytes. + * + * @return The session ID. + */ byte[] getSessionId() { - return (byte[]) sessionId.clone(); + int idlen = buffer.get (SESSID_OFFSET) & 0xFF; + byte[] sessionId = new byte[idlen]; + buffer.position (SESSID_OFFSET2); + buffer.get (sessionId); + return sessionId; + } + + /** + * Returns the server's chosen cipher suite. The returned cipher + * suite will be "resolved" to this structure's version. + * + * @return The server's chosen cipher suite. + */ + CipherSuite getCipherSuite () + { + int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 1; + return (CipherSuite.forValue (buffer.getShort (offset)) + .resolve (getProtocolVersion ())); + } + + /** + * Returns the server's chosen compression method. + * + * @return The chosen compression method. + */ + CompressionMethod getCompressionMethod () + { + int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 3; + return CompressionMethod.getInstance (buffer.get (offset) & 0xFF); } - CipherSuite getCipherSuite() + ByteBuffer getExtensions () { - return suite; + int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 4; + return ((ByteBuffer) buffer.duplicate ().position (offset) + .limit (totalLength)).slice (); } - CompressionMethod getCompressionMethod() + void setProtocolVersion (final ProtocolVersion version) { - return comp; + buffer.putShort (0, (short) version.getRawValue ()); } - List getExtensions() + void setSessionId (final byte[] sessionId) { - return extensions; + setSessionId (sessionId, 0, sessionId.length); } - public String toString() + void setSessionId (final byte[] sessionId, final int offset, + final int length) + { + int len = Math.min (length, 32); + buffer.put (SESSID_OFFSET, (byte) len); + buffer.position (SESSID_OFFSET2); + buffer.put (sessionId, offset, len); + } + + void setCipherSuite (final CipherSuite suite) + { + int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 1; + buffer.position (offset); + buffer.put (suite.getId ()); + } + + void setCompressionMethod (final CompressionMethod comp) + { + int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 3; + buffer.put (offset, (byte) comp.getValue ()); + } + + void setExtensionsLength (final int length) + { + totalLength = (SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + + 4 + length); + } + + public String toString () + { + return toString (null); + } + + public String toString (final String prefix) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); - out.println("struct {"); - out.println(" version = " + version + ";"); - BufferedReader r = new BufferedReader(new StringReader(random.toString())); - String s; - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - out.println(" sessionId = " + Util.toHexString(sessionId, ':') + ";"); - out.println(" cipherSuite = " + suite + ";"); - out.println(" compressionMethod = " + comp + ";"); - if (extensions != null) + if (prefix != null) + out.print (prefix); + out.println ("struct {"); + String subprefix = " "; + if (prefix != null) + subprefix += prefix; + out.print (subprefix); + out.print ("version: "); + out.print (getProtocolVersion ()); + out.println (";"); + out.print (subprefix); + out.println ("random:"); + out.println (getRandom ().toString (subprefix)); + out.print (subprefix); + out.print ("sessionId: "); + out.print (Util.toHexString(getSessionId (), ':')); + out.println (";"); + out.print (subprefix); + out.print ("cipherSuite: "); + out.print (getCipherSuite ()); + out.println (";"); + out.print (subprefix); + out.print ("compressionMethod: "); + out.print (getCompressionMethod ()); + out.println (";"); + ByteBuffer extbuf = getExtensions (); + if (extbuf.limit () > 0) { - out.println(" extensions = {"); - for (Iterator i = extensions.iterator(); i.hasNext(); ) - { - r = new BufferedReader(new StringReader(i.next().toString())); - try - { - while ((s = r.readLine()) != null) - { - out.print(" "); - out.println(s); - } - } - catch (IOException ignored) - { - } - } - out.println(" };"); + out.print (subprefix); + out.println ("extensions:"); + out.print (Util.hexDump (extbuf, subprefix)); } - out.println("} ServerHello;"); + if (prefix != null) + out.print (prefix); + out.print ("} ServerHello;"); return str.toString(); } } diff --git a/gnu/javax/net/ssl/provider/ServerKeyExchange.java b/gnu/javax/net/ssl/provider/ServerKeyExchange.java index 583041593..85038a963 100644 --- a/gnu/javax/net/ssl/provider/ServerKeyExchange.java +++ b/gnu/javax/net/ssl/provider/ServerKeyExchange.java @@ -50,237 +50,116 @@ import java.io.StringWriter; import java.math.BigInteger; -import java.security.PublicKey; -import java.security.interfaces.RSAPublicKey; - -import javax.crypto.interfaces.DHPublicKey; -import javax.crypto.spec.DHParameterSpec; +import java.nio.ByteBuffer; 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) + select (KeyExchangeAlgorithm) { - this(publicKey, signature, null); - } - - ServerKeyExchange(PublicKey publicKey, Signature signature, byte[] srpSalt) - { - 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> + */ +class ServerKeyExchange implements Handshake.Body +{ - // Instance methods. - // ------------------------------------------------------------------------- + private final ByteBuffer buffer; + private final CipherSuite suite; - public void write(OutputStream out) throws IOException + ServerKeyExchange (final ByteBuffer buffer, final CipherSuite suite) { - write(out, ProtocolVersion.TLS_1); + suite.getClass (); + this.buffer = buffer; + this.suite = suite; + if (suite.isResolved ()) + throw new IllegalArgumentException ("requires resolved cipher suite"); } - public void write(OutputStream out, ProtocolVersion version) - throws IOException + public int getLength () { - 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.getKeyExchangeAlgorithm ().equals (KeyExchangeAlgorithm.NONE)) + return 0; + return getParams ().getLength () + getSignature ().getLength (); } - 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. + */ + ServerKeyExchangeParams getParams () { - return publicKey; + KeyExchangeAlgorithm kex = suite.getKeyExchangeAlgorithm (); + if (kex.equals (KeyExchangeAlgorithm.RSA)) + return new ServerRSAParams (buffer.duplicate ()); + else if (kex.equals (KeyExchangeAlgorithm.DIFFIE_HELLMAN)) + return new ServerDHParams (buffer.duplicate ()); +// else if (kex.equals (KeyExchangeAlgorithm.SRP)) +// return new ServerSRPParams (buffer.duplicate ()); + else if (kex.equals (KeyExchangeAlgorithm.NONE)) + return null; + throw new IllegalArgumentException ("unsupported key exchange: " + kex); } - Signature getSignature() + /** + * Returns the digital signature made over the key exchange parameters. + * + * @return The signature. + */ + Signature getSignature () { - return signature; + if (suite.getKeyExchangeAlgorithm ().equals (KeyExchangeAlgorithm.NONE)) + return null; + ServerKeyExchangeParams params = getParams (); + ByteBuffer sigbuf = ((ByteBuffer) buffer.position (params.getLength ())).slice (); + return new Signature (sigbuf, suite.getSignatureAlgorithm ()); } - 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.getKeyExchangeAlgorithm ()); + out.println (";"); + if (!suite.getKeyExchangeAlgorithm ().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 (getParams ().toString (prefix != null ? prefix+" " : " ")); } - else if (publicKey instanceof SRPPublicKey) + if (!suite.getSignatureAlgorithm ().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 (getSignature ().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); - } - } } diff --git a/gnu/javax/net/ssl/provider/Signature.java b/gnu/javax/net/ssl/provider/Signature.java index c9be64143..2e1229e6e 100644 --- a/gnu/javax/net/ssl/provider/Signature.java +++ b/gnu/javax/net/ssl/provider/Signature.java @@ -1,4 +1,4 @@ -/* Signature.java -- SSL signature message. +/* Signature.java -- SSL Signature structure. Copyright (C) 2006 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -49,6 +49,8 @@ import java.io.StringWriter; import java.math.BigInteger; +import java.nio.ByteBuffer; + import java.security.PublicKey; import java.security.interfaces.RSAKey; @@ -56,103 +58,102 @@ import java.util.Arrays; import gnu.java.security.der.*; +/** + * The signature structure. + * + * <pre> +select (SignatureAlgorithm) +{ +case anonymous: + struct { }; +case rsa: + digitally-signed struct + { + opaque md5_hash[16]; + opaque sha_hash[20]; + }; +case dsa: + digitally-signed struct + { + opaque sha_hash[20]; + }; +} Signature;</pre> + */ class Signature implements Constructed { // Fields. // ------------------------------------------------------------------------- - private final Object sigValue; - private final String sigAlg; + private final ByteBuffer buffer; + private final SignatureAlgorithm alg; // Constructor. // ------------------------------------------------------------------------- - Signature(Object sigValue, String sigAlg) + Signature (final ByteBuffer buffer, final SignatureAlgorithm alg) { - this.sigValue = sigValue; - this.sigAlg = sigAlg; + this.buffer = buffer; + this.alg = alg; } - // Class method. + // Instance methods. // ------------------------------------------------------------------------- - static Signature read(InputStream in, CipherSuite suite, PublicKey key) - throws IOException + public int getLength () { - Object sigValue = null; - DataInputStream din = new DataInputStream(in); - int len = din.readUnsignedShort(); - sigValue = new byte[len]; - din.readFully((byte[]) sigValue); - if (suite.getSignature() == "DSS") - { - DERReader der = new DERReader(new ByteArrayInputStream((byte[]) sigValue)); - if (der.read().getTag() != DER.SEQUENCE) - { - throw new IOException("expecting DER SEQUENCE"); - } - BigInteger r = (BigInteger) der.read().getValue(); - BigInteger s = (BigInteger) der.read().getValue(); - sigValue = new BigInteger[] { r, s }; - } - return new Signature(sigValue, suite.getSignature()); + if (alg.equals (SignatureAlgorithm.ANONYMOUS)) + return 0; + return (buffer.getShort (0) & 0xFFFF) + 2; } - // Instance methods. - // ------------------------------------------------------------------------- - - public void write(OutputStream out) throws IOException + byte[] getSignature () { - write(out, ProtocolVersion.TLS_1); + if (alg.equals (SignatureAlgorithm.ANONYMOUS)) + return new byte[0]; + int length = buffer.getShort (0) & 0xFFFF; + byte[] buf = new byte[length]; + buffer.position (2); + buffer.get (buf); + return buf; } - public void write(OutputStream out, ProtocolVersion version) - throws IOException + void setSignature (final byte[] signature) { - byte[] result = null; - if (sigValue instanceof byte[]) - { - result = (byte[]) sigValue; - } - else - { - DERValue r = new DERValue(DER.INTEGER, ((BigInteger[]) sigValue)[0]); - DERValue s = new DERValue(DER.INTEGER, ((BigInteger[]) sigValue)[1]); - DERValue sig = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, - Arrays.asList(new Object[] { r, s })); - result = sig.getEncoded(); - } - out.write(result.length >>> 8 & 0xFF); - out.write(result.length & 0xFF); - out.write(result); + setSignature (signature, 0, signature.length); } - Object getSigValue() + void setSignature (final byte[] signature, final int offset, final int length) { - return sigValue; + if (alg.equals (SignatureAlgorithm.ANONYMOUS)) + return; + buffer.putShort (0, (short) length); + buffer.position (2); + buffer.put (signature, offset, length); } - String getSigAlg() + public String toString () { - return sigAlg; + 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 {"); - if (sigAlg.equals("RSA")) - { - out.print(Util.hexDump((byte[]) sigValue, " ")); - } - else + if (!alg.equals (SignatureAlgorithm.ANONYMOUS)) { - out.println(" r = " + ((BigInteger[]) sigValue)[0].toString(16) + ";"); - out.println(" s = " + ((BigInteger[]) sigValue)[1].toString(16) + ";"); + String subprefix = " "; + if (prefix != null) + subprefix = prefix + subprefix; + out.print (Util.hexDump (getSignature (), subprefix)); } - out.println("} Signature;"); + if (prefix != null) + out.print (prefix); + out.print ("} Signature;"); return str.toString(); } } diff --git a/gnu/javax/net/ssl/provider/Util.java b/gnu/javax/net/ssl/provider/Util.java index 15790dd26..f541c6c5c 100644 --- a/gnu/javax/net/ssl/provider/Util.java +++ b/gnu/javax/net/ssl/provider/Util.java @@ -38,11 +38,16 @@ exception statement from your version. */ package gnu.javax.net.ssl.provider; +import java.io.PrintWriter; +import java.io.StringWriter; + import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigInteger; +import java.nio.ByteBuffer; + import java.security.AccessController; import java.security.PrivilegedAction; import java.security.Security; @@ -172,7 +177,7 @@ final class Util str.append(" "); String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' '); str.append(s); - for (int j = 56 - (56 - s.length()); j < 56; j++) + for (int j = s.length(); j < 49; j++) str.append(" "); for (int j = 0; j < Math.min(16, len - i); j++) { @@ -187,6 +192,44 @@ final class Util return str.toString(); } + static String hexDump (ByteBuffer buf) + { + return hexDump (buf, null); + } + + static String hexDump (ByteBuffer buf, String prefix) + { + StringWriter str = new StringWriter (); + PrintWriter out = new PrintWriter (str); + int i = 0; + int len = buf.limit (); + byte[] line = new byte[16]; + while (i < len) + { + if (prefix != null) + out.print (prefix); + out.print (Util.formatInt (i, 16, 8)); + out.print (" "); + int l = Math.min (16, len - i); + buf.get (line, 0, l); + String s = Util.toHexString (line, 0, l, ' '); + out.print (s); + for (int j = s.length (); j < 49; j++) + out.print (' '); + for (int j = 0; j < l; j++) + { + int c = line[j] & 0xFF; + if (c < 0x20 || c > 0x7E) + out.print ('.'); + else + out.print ((char) c); + } + out.println (); + i += 16; + } + return str.toString (); + } + /** * See {@link #hexDump(byte[],int,int,String)}. */ |