commit-classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commit-cp] classpath/gnu/javax/net/ssl/provider ServerHell... [ssl-nio-


From: Casey Marshall
Subject: [commit-cp] classpath/gnu/javax/net/ssl/provider ServerHell... [ssl-nio-branch]
Date: Sun, 11 Jun 2006 07:05:28 +0000

CVSROOT:        /cvsroot/classpath
Module name:    classpath
Branch:         ssl-nio-branch
Changes by:     Casey Marshall <rsdio>  06/06/11 07:05:28

Modified files:
        gnu/javax/net/ssl/provider: ServerHello.java Extension.java 
                                    ClientHello.java 
                                    ServerHandshake.java 
                                    ExtensionList.java 
Added files:
        gnu/javax/net/ssl/provider: MaxFragmentLength.java 
                                    CertificateURL.java 
                                    UnresolvedExtensionValue.java 
                                    TruncatedHMAC.java 
                                    ServerNameList.java 
                                    TrustedAuthorities.java 
                                    CertificateStatusType.java 
                                    CertificateStatusRequest.java 

Log message:
        2006-06-10  Casey Marshall  <address@hidden>
        
                * gnu/javax/net/ssl/provider/ServerHello.java (extensions): 
return
                an ExtensionList.
                (setExtensionsLength): set the length in the buffer.
                (toString): print out individual extensions.
                * gnu/javax/net/ssl/provider/Extension.java (valueBytes): new
                method.
                (valueBuffer): new method.
                (value): return an Extenion.Value.
                (toString): print out extension value.
                (Value): new abstract inner class.
                * gnu/javax/net/ssl/provider/ClientHello.java (extensions): 
return
                an ExtensionList.
                (setExtensionListLength): set the length in the buffer.
                (toString): print out extensions.
                * gnu/javax/net/ssl/provider/ServerHandshake.java
                (chooseSuite, chooseCompression): use generics and foreach 
loops.
                * gnu/javax/net/ssl/provider/ExtensionList.java: new class.
                * gnu/javax/net/ssl/provider/MaxFragmentLength.java: new class.
                * gnu/javax/net/ssl/provider/CertificateURL.java: new class.
                * gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java: new
                class. 
                * gnu/javax/net/ssl/provider/TruncatedHMAC.java: new class.
                * gnu/javax/net/ssl/provider/ServerNameList.java: new class.
                * gnu/javax/net/ssl/provider/TrustedAuthorities.java: new class.
                * gnu/javax/net/ssl/provider/CertificateStatusType.java: new
                class. 
                * gnu/javax/net/ssl/provider/CertificateStatusRequest.java: new
                class.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/ServerHello.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&r1=1.1.4.1.2.1&r2=1.1.4.1.2.2
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/Extension.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&r1=1.1.4.1.2.2&r2=1.1.4.1.2.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/ClientHello.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&r1=1.1.4.1.2.1&r2=1.1.4.1.2.2
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/ServerHandshake.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/ExtensionList.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/MaxFragmentLength.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/CertificateURL.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/TruncatedHMAC.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/ServerNameList.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/TrustedAuthorities.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/CertificateStatusType.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/net/ssl/provider/CertificateStatusRequest.java?cvsroot=classpath&only_with_tag=ssl-nio-branch&rev=1.1.2.1

Patches:
Index: ServerHello.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/ServerHello.java,v
retrieving revision 1.1.4.1.2.1
retrieving revision 1.1.4.1.2.2
diff -u -b -r1.1.4.1.2.1 -r1.1.4.1.2.2
--- ServerHello.java    3 Jun 2006 07:49:53 -0000       1.1.4.1.2.1
+++ ServerHello.java    11 Jun 2006 07:05:28 -0000      1.1.4.1.2.2
@@ -67,6 +67,7 @@
   SessionID session_id;
   CipherSuite cipher_suite;
   CompressionMethod compression_method;
+  Extensions server_hello_extension_list&lt;0..2^16-1&gt;
 } ServerHello;
 </pre>
  *
@@ -171,11 +172,19 @@
     return CompressionMethod.getInstance (buffer.get (offset) & 0xFF);
   }
 
-  public ByteBuffer extensions ()
+  public ExtensionList extensions ()
   {
     int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 4;
-    return ((ByteBuffer) buffer.duplicate ().position (offset)
-            .limit (totalLength)).slice ();
+    if (offset == totalLength)
+      return null;
+    if (buffer.limit() <= offset)
+      return null;
+    int len = buffer.getShort(offset) & 0xFFFF;
+    if (len == 0)
+      len = buffer.limit() - offset - 2;
+    ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate ().position (offset)
+                       .limit (offset + len + 2)).slice ();
+    return new ExtensionList (ebuf);
   }
 
   public void setVersion (final ProtocolVersion version)
@@ -213,7 +222,9 @@
   public void setExtensionsLength (final int length)
   {
     totalLength = (SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF)
-                   + 4 + length);
+                   + 4 + length + 4);
+    buffer.putShort (SESSID_OFFSET + (buffer.get (SESSID_OFFSET) & 0xFF) + 4,
+                     (short) length);
   }
 
   public String toString ()
@@ -250,13 +261,11 @@
     out.print ("compressionMethod: ");
     out.print (compressionMethod ());
     out.println (";");
-    ByteBuffer extbuf = extensions ();
-    if (extbuf.limit () > 0)
-      {
+    ExtensionList exts = extensions ();
         out.print (subprefix);
         out.println ("extensions:");
-        out.print (Util.hexDump (extbuf, subprefix));
-      }
+    out.println (exts != null ? exts.toString (subprefix+"  ")
+                                : subprefix + "  (nil)");
     if (prefix != null)
       out.print (prefix);
     out.print ("} ServerHello;");

Index: Extension.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/Extension.java,v
retrieving revision 1.1.4.1.2.2
retrieving revision 1.1.4.1.2.3
diff -u -b -r1.1.4.1.2.2 -r1.1.4.1.2.3
--- Extension.java      6 Jun 2006 01:01:19 -0000       1.1.4.1.2.2
+++ Extension.java      11 Jun 2006 07:05:28 -0000      1.1.4.1.2.3
@@ -83,7 +83,7 @@
     return Type.forValue (buffer.getShort (0) & 0xFFFF);
   }
 
-  public byte[] value()
+  public byte[] valueBytes()
   {
     int len = buffer.getShort (2) & 0xFFFF;
     byte[] value = new byte[len];
@@ -91,6 +91,48 @@
     return value;
   }
   
+  public ByteBuffer valueBuffer()
+  {
+    int len = buffer.getShort(2) & 0xFFFF;
+    return ((ByteBuffer) buffer.duplicate().position(4).limit(len+4)).slice();
+  }
+  
+  public Value value()
+  {
+    switch (type ())
+      {
+        case SERVER_NAME:
+          return new ServerNameList(valueBuffer());
+          
+        case MAX_FRAGMENT_LENGTH:
+          switch (valueBuffer().get() & 0xFF)
+            {
+              case 1: return MaxFragmentLength.LEN_2_9;
+              case 2: return MaxFragmentLength.LEN_2_10;
+              case 3: return MaxFragmentLength.LEN_2_11;
+              case 4: return MaxFragmentLength.LEN_2_12;
+              default:
+                throw new IllegalArgumentException("invalid max_fragment_len");
+            }
+          
+        case TRUNCATED_HMAC:
+          return new TruncatedHMAC();
+
+        case CLIENT_CERTIFICATE_URL:
+          return new CertificateURL(valueBuffer());
+          
+        case TRUSTED_CA_KEYS:
+          return new TrustedAuthorities(valueBuffer());
+          
+        case STATUS_REQUEST:
+          return new CertificateStatusRequest(valueBuffer());
+          
+        case SRP:
+        case CERT_TYPE:
+      }
+    return new UnresolvedExtensionValue(valueBuffer());
+  }
+  
   public void setLength (final int newLength)
   {
     if (newLength < 0 || newLength > 65535)
@@ -130,13 +172,14 @@
     out.println("  type = " + type () + ";");
     if (prefix != null) out.print (prefix);
     out.println("  value =");
-    out.println(Util.hexDump(value (), (prefix != null) ? prefix + "    " : "  
  "));
+//    out.println(Util.hexDump(value (), (prefix != null) ? prefix + "    " : 
"    "));
+    out.println(value());
     if (prefix != null) out.print (prefix);
     out.print("} Extension;");
     return str.toString();
   }
 
-  // Inner class.
+  // Inner classes.
   // -------------------------------------------------------------------------
 
   public static enum Type
@@ -178,4 +221,8 @@
       return value;
     }
   }
+  
+  public static abstract class Value implements Constructed
+  {
+  }
 }

Index: ClientHello.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/ClientHello.java,v
retrieving revision 1.1.4.1.2.1
retrieving revision 1.1.4.1.2.2
diff -u -b -r1.1.4.1.2.1 -r1.1.4.1.2.2
--- ClientHello.java    3 Jun 2006 07:49:53 -0000       1.1.4.1.2.1
+++ ClientHello.java    11 Jun 2006 07:05:28 -0000      1.1.4.1.2.2
@@ -67,6 +67,7 @@
   SessionID         session_id;                    // 1 + 0..32
   CipherSuite       cipher_suites&lt;2..2^16-1&gt;
   CompressionMethod compression_methods&lt;1..2^8-1&gt;
+  Extension         client_hello_extension_list&lt;0..2^16-1&gt;
 } ClientHello;
 </pre>
  */
@@ -156,11 +157,17 @@
     return new CompressionMethodList (listBuf);
   }
 
-  public ByteBuffer extensions()
+  public ExtensionList extensions()
   {
     int offset = getExtensionsOffset ();
-    return ((ByteBuffer) buffer.duplicate ().position (offset)
-            .limit (totalLength)).slice ();
+    if (offset >= buffer.limit())
+      return null;
+    int len = buffer.getShort(offset) & 0xFFFF;
+    if (len == 0)
+      len = buffer.limit() - offset - 2;
+    ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate ().position (offset)
+                       .limit (offset + len + 2)).slice ();
+    return new ExtensionList (ebuf);
   }
 
   public void setVersion (final ProtocolVersion version)
@@ -183,7 +190,9 @@
 
   public void setExtensionsLength (final int length)
   {
-    this.totalLength = getExtensionsOffset () + length;
+    int offset = getExtensionsOffset();
+    this.totalLength = offset + length + 4;
+    buffer.putShort(offset, (short) length);
   }
 
   private int getCipherSuitesOffset ()
@@ -238,13 +247,10 @@
     out.print (subprefix);
     out.println ("compression_methods:");
     out.println (compressionMethods ().toString (subprefix));
-    ByteBuffer extbuf = extensions ();
-    if (extbuf.limit () > 0)
-      {
         out.print (subprefix);
-        out.println ("extensions:");
-        out.print (Util.hexDump (extbuf, subprefix));
-      }
+    out.print ("extensions: ");
+    ExtensionList el = extensions();
+    out.println (el != null ? el.toString(subprefix+"  ") : "(nil)");
     if (prefix != null)
       out.print (prefix);
     out.print ("} ClientHello;");

Index: ServerHandshake.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/Attic/ServerHandshake.java,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- ServerHandshake.java        3 Jun 2006 07:49:53 -0000       1.1.2.1
+++ ServerHandshake.java        11 Jun 2006 07:05:28 -0000      1.1.2.2
@@ -127,19 +127,18 @@
                                           final ProtocolVersion version)
     throws SSLException
   {
-    HashSet suites = new HashSet (enabledSuites.length);
-    for (int i = 0; i < enabledSuites.length; i++)
+    HashSet<CipherSuite> suites = new HashSet<CipherSuite> 
(enabledSuites.length);
+    for (String s : enabledSuites)
       {
-        CipherSuite suite = CipherSuite.forName (enabledSuites[i]);
+        CipherSuite suite = CipherSuite.forName (s);
         if (suite != null)
           {
             suite = suite.resolve (version);
             suites.add (suite);
           }
       }
-    for (int i = 0; i < clientSuites.size (); i++)
+    for (CipherSuite suite : clientSuites)
       {
-        CipherSuite suite = clientSuites.get (i);
         if (suites.contains (suite))
           return suite.resolve (version);
       }
@@ -159,14 +158,14 @@
     throws SSLException
   {
     // Scan for ZLIB first.
-    for (int i = 0; i < comps.size (); i++)
+    for (CompressionMethod cm : comps)
       {
-        if (comps.get (i).equals (CompressionMethod.ZLIB))
+        if (cm.equals (CompressionMethod.ZLIB))
           return CompressionMethod.ZLIB;
       }
-    for (int i = 0; i < comps.size (); i++)
+    for (CompressionMethod cm : comps)
       {
-        if (comps.get (i).equals (CompressionMethod.NULL))
+        if (cm.equals (CompressionMethod.NULL))
           return CompressionMethod.NULL;
       }
 

Index: ExtensionList.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/Attic/ExtensionList.java,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- ExtensionList.java  6 Jun 2006 01:01:19 -0000       1.1.2.1
+++ ExtensionList.java  11 Jun 2006 07:05:28 -0000      1.1.2.2
@@ -113,7 +113,7 @@
                                          + "list length");
     buffer.putShort(i, (short) e.type().getValue());
     buffer.putShort(i+2, (short) e.length());
-    ((ByteBuffer) buffer.duplicate().position(i+4)).put (e.value());
+    ((ByteBuffer) buffer.duplicate().position(i+4)).put (e.valueBuffer());
     modCount++;
   }
   

Index: MaxFragmentLength.java
===================================================================
RCS file: MaxFragmentLength.java
diff -N MaxFragmentLength.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ MaxFragmentLength.java      11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,52 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+/**
+ * Extension value 
+ * @author csm
+ */
+public class MaxFragmentLength extends Value
+{
+  public static final MaxFragmentLength LEN_2_9 = new MaxFragmentLength(1, 1 
<< 9);
+  public static final MaxFragmentLength LEN_2_10 = new MaxFragmentLength(2, 1 
<< 10);
+  public static final MaxFragmentLength LEN_2_11 = new MaxFragmentLength(3, 1 
<< 11);
+  public static final MaxFragmentLength LEN_2_12 = new MaxFragmentLength(4, 1 
<< 12);
+  
+  private final int value;
+  private final int length;
+  
+  private MaxFragmentLength(int value, int length)
+  {
+    this.value = value;
+    this.length = length;
+  }
+  
+  public int length()
+  {
+    return 1;
+  }
+
+  public int getValue ()
+  {
+    return value;
+  }
+  
+  public int maxLength()
+  {
+    return length;
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+  
+  public String toString(String prefix)
+  {
+    String s = "max_fragment_length = ";
+    if (prefix != null)
+      s = prefix + s;
+    return s + maxLength() + ";";
+  }
+}

Index: CertificateURL.java
===================================================================
RCS file: CertificateURL.java
diff -N CertificateURL.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ CertificateURL.java 11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,300 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.NoSuchElementException;
+
+/**
+ * The CertificateURL extension value.
+ * 
+ * <pre>
+enum {
+  individual_certs(0), pkipath(1), (255)
+} CertChainType;
+
+enum {
+  false(0), true(1)
+} Boolean;
+
+struct {
+  CertChainType type;
+  URLAndOptionalHash url_and_hash_list&lt;1..2^16-1&gt;;
+} CertificateURL;
+
+struct {
+  opaque url&lt;1..2^16-1&gt;;
+  Boolean hash_present;
+  select (hash_present) {
+    case false: struct {};
+    case true: SHA1Hash;
+  } hash;
+} URLAndOptionalHash;
+
+opaque SHA1Hash[20];</pre>
+ *
+ * @author csm
+ *
+ */
+public class CertificateURL extends Value implements 
Iterable<CertificateURL.URLAndOptionalHash>
+{
+  private final ByteBuffer buffer;
+  
+  public CertificateURL(final ByteBuffer buffer)
+  {
+    this.buffer = buffer;
+  }
+  
+  public int length()
+  {
+    return 3 + (buffer.getShort(1) & 0xFFFF);
+  }
+
+  public CertChainType type()
+  {
+    switch (buffer.get(0))
+      {
+        case 0: return CertChainType.INDIVIDUAL_CERTS;
+        case 1: return CertChainType.PKIPATH;
+      }
+    throw new IllegalArgumentException("unknown certificate URL type");
+  }
+  
+  public int size()
+  {
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    for (int i = 3; i < len; )
+      {
+        URLAndOptionalHash u
+          = new URLAndOptionalHash((ByteBuffer) 
buffer.duplicate().position(i));
+        int l = u.length();
+        i += l;
+        n++;
+      }
+    return n;
+  }
+  
+  public URLAndOptionalHash get(int index)
+  {
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    int l = 0;
+    int i;
+    for (i = 3; i < len && n < index; )
+      {
+        URLAndOptionalHash u
+          = new URLAndOptionalHash((ByteBuffer) 
buffer.duplicate().position(i));
+        l = u.length();
+        i += l;
+        n++;
+      }
+    if (n < index)
+      throw new IndexOutOfBoundsException();
+    return new URLAndOptionalHash(((ByteBuffer) 
buffer.duplicate().position(i).limit(i+l)).slice());
+  }
+  
+  public void set(int index, URLAndOptionalHash url)
+  {
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    int i;
+    for (i = 3; i < len && n < index-1; )
+      {
+        URLAndOptionalHash u
+          = new URLAndOptionalHash((ByteBuffer) 
buffer.duplicate().position(i));
+        int l = u.length();
+        i += l;
+        n++;
+      }
+    if (n < index - 1)
+      throw new IndexOutOfBoundsException();
+    int l = url.urlLength();
+    buffer.putShort(i, (short) l);
+    ((ByteBuffer) buffer.duplicate().position(i+2)).put(url.urlBuffer());
+    buffer.put(i+l+2, (byte) (url.hashPresent() ? 1 : 0));
+    if (url.hashPresent())
+      ((ByteBuffer) buffer.duplicate().position(i+l+3)).put (url.sha1Hash());
+  }
+  
+  public void setLength(final int length)
+  {
+    if (length < 0 || length > 65535)
+      throw new IllegalArgumentException("length must be between 0 and 65535");
+    buffer.putShort(1, (short) length);
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+  
+  public String toString(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("  type = ");
+    out.print(type());
+    out.println(";");
+    if (prefix != null) out.print(prefix);
+    out.println("  url_and_hash_list = {");
+    String subprefix = "  ";
+    if (prefix != null) subprefix = prefix + subprefix;
+    for (URLAndOptionalHash url : this)
+      {
+        out.println(url.toString(subprefix));
+      }
+    if (prefix != null) out.print(prefix);
+    out.println("  };");
+    if (prefix != null) out.print(prefix);
+    out.print("} CertificateURL;");
+    return str.toString();
+  }
+
+  public java.util.Iterator<URLAndOptionalHash> iterator()
+  {
+    return new Iterator();
+  }
+  
+  public class Iterator implements java.util.Iterator<URLAndOptionalHash>
+  {
+    private int index;
+    
+    public Iterator()
+    {
+      index = 0;
+    }
+    
+    public URLAndOptionalHash next() throws NoSuchElementException
+    {
+      try
+        {
+          return get(index++);
+        }
+      catch (IndexOutOfBoundsException ioobe)
+        {
+          throw new NoSuchElementException();
+        }
+    }
+    
+    public boolean hasNext()
+    {
+      return index < size();
+    }
+    
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+  }
+  
+  public static enum CertChainType
+  {
+    INDIVIDUAL_CERTS (0), PKIPATH (1);
+    
+    private final int value;
+    
+    private CertChainType (final int value)
+    {
+      this.value = value;
+    }
+    
+    public int getValue()
+    {
+      return value;
+    }
+  }
+  
+  public static class URLAndOptionalHash implements Constructed
+  {
+    private final ByteBuffer buffer;
+    
+    public URLAndOptionalHash (final ByteBuffer buffer)
+    {
+      this.buffer = buffer;
+    }
+    
+    public int length()
+    {
+      return ((buffer.getShort(0) & 0xFFFF)
+              + (hashPresent() ? 23 : 3));
+    }
+    
+    public String url()
+    {
+      Charset cs = Charset.forName("ASCII");
+      return cs.decode(urlBuffer()).toString();
+    }
+    
+    public int urlLength()
+    {
+      return buffer.getShort(0) & 0xFFFF;
+    }
+    
+    public ByteBuffer urlBuffer()
+    {
+      int len = urlLength();
+      return ((ByteBuffer) 
buffer.duplicate().position(2).limit(2+len)).slice();
+    }
+    
+    public boolean hashPresent()
+    {
+      int i = (buffer.getShort(0) & 0xFFFF) + 2;
+      byte b = buffer.get(i);
+      if (b == 0)
+        return false;
+      if (b == 1)
+        return true;
+      throw new IllegalArgumentException("expecting 0 or 1: " + (b & 0xFF));
+    }
+    
+    public byte[] sha1Hash()
+    {
+      int i = (buffer.getShort(0) & 0xFFFF) + 2;
+      byte b = buffer.get(i);
+      if (b == 0)
+        return null;
+      byte[] buf = new byte[20];
+      ((ByteBuffer) buffer.duplicate().position(i+1)).get(buf);
+      return buf;
+    }
+    
+    public String toString()
+    {
+      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("  url = ");
+      out.print(url());
+      out.println(";");
+      boolean has_hash = hashPresent();
+      if (prefix != null) out.print(prefix);
+      out.print("  hash_present = ");
+      out.print(has_hash);
+      out.println(";");
+      if (has_hash)
+        {
+          if (prefix != null) out.print(prefix);
+          out.print("  sha1Hash = ");
+          out.print(Util.toHexString(sha1Hash(), ':'));
+          out.println(";");
+        }
+      if (prefix != null) out.print(prefix);
+      out.print("} URLAndOptionalHash;");
+      return str.toString();
+    }
+  }
+}

Index: UnresolvedExtensionValue.java
===================================================================
RCS file: UnresolvedExtensionValue.java
diff -N UnresolvedExtensionValue.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ UnresolvedExtensionValue.java       11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,40 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+
+public class UnresolvedExtensionValue extends Value
+{
+  private final ByteBuffer buffer;
+  
+  public UnresolvedExtensionValue (final ByteBuffer buffer)
+  {
+    this.buffer = buffer;
+  }
+  
+  public int length()
+  {
+    return buffer.limit();
+  }
+  
+  public ByteBuffer value()
+  {
+    return buffer.slice();
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+  
+  public String toString(final String prefix)
+  {
+    String s = Util.hexDump(buffer);
+    if (prefix != null)
+      s = prefix + s;
+    return s;
+  }
+}

Index: TruncatedHMAC.java
===================================================================
RCS file: TruncatedHMAC.java
diff -N TruncatedHMAC.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ TruncatedHMAC.java  11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,31 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+/**
+ * The value type for the address@hidden Extension.Type#TRUNCATED_HMAC} 
extension.
+ * This extension has an empty value; this class is thusly empty.
+ * 
+ * @author csm
+ */
+public class TruncatedHMAC extends Value
+{
+
+  public int length()
+  {
+    return 0;
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+
+  public String toString(String prefix)
+  {
+    String s = "TruncatedHMAC;";
+    if (prefix != null)
+      s = prefix + s;
+    return s;
+  }
+}

Index: ServerNameList.java
===================================================================
RCS file: ServerNameList.java
diff -N ServerNameList.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ServerNameList.java 11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,225 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.NoSuchElementException;
+
+/**
+ * The ServerName extension.
+ * 
+ * <pre>
+ struct {
+   NameType name_type;
+   select (name_type) {
+     case host_name: HostName;
+   } name;
+} ServerName;
+
+enum {
+  host_name(0), (255)
+} NameType;
+
+opaque HostName<1..2^16-1>;
+
+struct {
+  ServerName server_name_list<1..2^16-1>
+} ServerNameList;</pre>
+ *
+ * <p><b>Implementation note: this class does not currently contain a
+ * <code>set</code> method. If you are modifying this list, then use the
+ * address@hidden #get(int)} method, and modify the returned address@hidden 
ServerName}.
+ *
+ * @author csm
+ */
+public class ServerNameList extends Value implements 
Iterable<ServerNameList.ServerName>
+{
+  private final ByteBuffer buffer;
+  
+  public ServerNameList (final ByteBuffer buffer)
+  {
+    this.buffer = buffer;
+  }
+
+  public int length()
+  {
+    return buffer.getShort(0) & 0xFFFF;
+  }
+  
+  public int size()
+  {
+    int n = 0;
+    final int len = length();
+    for (int i = 2; i < len; )
+      {
+        int l = buffer.getShort(i+1);
+        i += l + 3;
+        n++;
+      }
+    return n;
+  }
+  
+  public ServerName get (int index)
+  {
+    final int len = length();
+    if (len == 0)
+      throw new IndexOutOfBoundsException("0; " + index);
+    int n = 0;
+    int i;
+    int l = 0;
+    for (i = 2; i < len && n < index; )
+      {
+        l = buffer.getShort(i+1);
+        i += l + 3;
+        n++;
+      }
+    if (n < index)
+      throw new IndexOutOfBoundsException(n + "; " + index);
+    ByteBuffer buf = ((ByteBuffer) 
buffer.duplicate().position(i).limit(i+l+3)).slice();
+    return new ServerName (buf);
+  }
+  
+  public void setLength(final int newLength)
+  {
+    if (newLength < 0 || newLength > 65535)
+      throw new IllegalArgumentException("length must be between 0 and 65535");
+    buffer.putShort(0, (short) newLength);
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+
+  public String toString(String prefix)
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    if (prefix != null) out.print(prefix);
+    out.println ("ServerNameList {");
+    String subprefix = "  ";
+    if (prefix != null)
+      subprefix = prefix + subprefix;
+    for (ServerName name : this)
+      {
+        out.println (name.toString(subprefix));
+      }
+    if (prefix != null) out.print(prefix);
+    out.print ("};");
+    return str.toString();
+  }
+  
+  public java.util.Iterator<ServerName> iterator()
+  {
+    return new Iterator();
+  }
+
+  public class Iterator implements java.util.Iterator<ServerName>
+  {
+    private int index;
+    
+    public Iterator()
+    {
+      index = 0;
+    }
+    
+    public boolean hasNext()
+    {
+      return index < size();
+    }
+    
+    public ServerName next() throws NoSuchElementException
+    {
+      try
+        {
+          return get (index++);
+        }
+      catch (IndexOutOfBoundsException ioobe)
+        {
+          throw new NoSuchElementException();
+        }
+    }
+    
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  public static class ServerName implements Constructed
+  {
+    private final ByteBuffer buffer;
+    
+    public ServerName(final ByteBuffer buffer)
+    {
+      this.buffer = buffer;
+    }
+    
+    public int length()
+    {
+      return buffer.getShort(1) & 0xFFFF;
+    }
+
+    public NameType type()
+    {
+      int v = (buffer.get(0) & 0xFF);
+      if (v == 0)
+        {
+          return NameType.HOST_NAME;
+        }
+      throw new IllegalArgumentException ("illegal name type: " + v);
+    }
+    
+    public String name()
+    {
+      int len = length();
+      Charset cs = Charset.forName ("UTF-8");
+      return cs.decode(((ByteBuffer) 
buffer.duplicate().position(3).limit(len))).toString();
+    }
+    
+    public String toString()
+    {
+      return toString (null);
+    }
+    
+    public String toString(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 ("  name_type = ");
+      out.print (type());
+      out.println (";");
+      if (prefix != null) out.print (prefix);
+      out.print ("  server_name = ");
+      out.print (name());
+      out.println (";");
+      if (prefix != null) out.print (prefix);
+      out.print ("} ServerName;");
+      return str.toString();
+    }
+  }
+
+  public static enum NameType
+  {
+    HOST_NAME (0);
+    
+    private final int value;
+    
+    private NameType (int value)
+    {
+      this.value = value;
+    }
+    
+    public int getValue()
+    {
+      return value;
+    }
+  }
+}

Index: TrustedAuthorities.java
===================================================================
RCS file: TrustedAuthorities.java
diff -N TrustedAuthorities.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ TrustedAuthorities.java     11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,252 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.java.security.x509.X500DistinguishedName;
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * The trusted authorities hello extension.
+ * 
+ * <pre>
+struct {
+  TrustedAuthority trusted_authorities_list&lt;0..2^16-1&gt;;
+} TrustedAuthorities;
+
+struct {
+  IdentifierType identifier_type;
+  select (identifier_type) {
+    case pre_agreed: struct {};
+    case key_sha1_hash: SHA1Hash;
+    case x509_name: DistinguishedName;
+    case cert_sha1_hash: SHA1Hash;
+  } identifier;
+} TrustedAuthority;
+
+enum {
+  pre_agreed(0), key_sha1_hash(1), x509_name(2),
+  cert_sha1_hash(3), (255)
+} IdentifierType;
+
+opaque DistinguishedName&lt;1..2^16-1&gt;;</pre>
+ * 
+ * @author csm
+ */
+public class TrustedAuthorities extends Value
+  implements Iterable<TrustedAuthorities.TrustedAuthority>
+{
+  private final ByteBuffer buffer;
+
+  public TrustedAuthorities(final ByteBuffer buffer)
+  {
+    this.buffer = buffer;
+  }
+  
+  public int length()
+  {
+    return 2 + (buffer.getShort(0) & 0xFFFF);
+  }
+  
+  public int size()
+  {
+    int len = buffer.getShort(0) & 0xFFFF;
+    int n = 0;
+    for (int i = 2; i < len; i++)
+      {
+        TrustedAuthority auth =
+          new TrustedAuthority((ByteBuffer) buffer.duplicate().position(i));
+        i += auth.length();
+        n++;
+      }
+    return n;
+  }
+
+  public TrustedAuthority get(final int index)
+  {
+    int len = buffer.getShort(0) & 0xFFFF;
+    int n = 0;
+    int i = 2;
+    while (i < len && n <= index)
+      {
+        TrustedAuthority auth =
+          new TrustedAuthority((ByteBuffer) buffer.duplicate().position(i));
+        if (n == index)
+          return auth;
+        i += auth.length();
+        n++;
+      }
+    throw new IndexOutOfBoundsException();
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+  
+  public String toString(String prefix)
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    if (prefix != null) out.print(prefix);
+    out.println("struct {");
+    String subprefix = "  ";
+    if (prefix != null)
+      subprefix = prefix + subprefix;
+    for(TrustedAuthority ta : this)
+      out.println(ta);
+    if (prefix != null) out.print(prefix);
+    out.print("} TrustedAuthorities;");
+    return str.toString();
+  }
+  
+  public Iterator<TrustedAuthority> iterator()
+  {
+    return new AuthoritiesIterator();
+  }
+  
+  public class AuthoritiesIterator implements Iterator<TrustedAuthority>
+  {
+    private int index;
+    
+    public AuthoritiesIterator()
+    {
+      index = 0;
+    }
+    
+    public TrustedAuthority next() throws NoSuchElementException
+    {
+      try
+        {
+          return get(index++);
+        }
+      catch (IndexOutOfBoundsException ioobe)
+        {
+          throw new NoSuchElementException();
+        }
+    }
+    
+    public boolean hasNext()
+    {
+      return index < size();
+    }
+    
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  public static class TrustedAuthority implements Constructed
+  {
+    private final ByteBuffer buffer;
+    
+    public TrustedAuthority(final ByteBuffer buffer)
+    {
+      this.buffer = buffer;
+    }
+    
+    public int length()
+    {
+      switch (type().getValue())
+      {
+        case 0: return 1;
+        case 1:
+        case 3: return 21;
+        case 2: return 3 + (buffer.getShort(1) & 0xFFFF);
+      }
+      throw new IllegalArgumentException("unknown authority type");
+    }
+    
+    public byte[] sha1Hash()
+    {
+      IdentifierType t = type();
+      if (t != IdentifierType.CERT_SHA1_HASH
+          && t != IdentifierType.KEY_SHA1_HASH)
+        throw new IllegalArgumentException(t + " does not have a hash value");
+      byte[] b = new byte[20];
+      ((ByteBuffer) buffer.duplicate().position(1)).get(b);
+      return b;
+    }
+    
+    public X500Principal name()
+    {
+      int len = buffer.getShort(1) & 0xFFFF;
+      byte[] b = new byte[len];
+      ((ByteBuffer) buffer.duplicate().position(3)).get(b);
+      return new X500Principal(b);
+    }
+    
+    public IdentifierType type()
+    {
+      switch (buffer.get(0))
+      {
+        case 0: return IdentifierType.PRE_AGREED;
+        case 1: return IdentifierType.KEY_SHA1_HASH;
+        case 2: return IdentifierType.X509_NAME;
+        case 3: return IdentifierType.CERT_SHA1_HASH;
+      }
+      
+      throw new IllegalArgumentException("invalid IdentifierType");
+    }
+    
+    public String toString()
+    {
+      return toString(null);
+    }
+    
+    public String toString(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("  identifier_type = ");
+      out.print(type());
+      out.println(";");
+      switch (type().getValue())
+      {
+        case 0: break;
+        case 1:
+        case 3:
+          if (prefix != null) out.print(prefix);
+          out.print("  sha1_hash = ");
+          out.print(Util.toHexString(sha1Hash(), ':'));
+          out.println(";");
+          break;
+          
+        case 2:
+          if (prefix != null) out.print(prefix);
+          out.print("  name = ");
+          out.print(name());
+          out.println(";");
+      }
+      if (prefix != null) out.print(prefix);
+      out.print("} TrustedAuthority;");
+      return str.toString();
+    }
+  }
+  
+  public static enum IdentifierType
+  {
+    PRE_AGREED (0), KEY_SHA1_HASH (1), X509_NAME (2), CERT_SHA1_HASH (3);
+    
+    private final int value;
+    
+    private IdentifierType(final int value)
+    {
+      this.value = value;
+    }
+    
+    public int getValue()
+    {
+      return value;
+    }
+  }
+}

Index: CertificateStatusType.java
===================================================================
RCS file: CertificateStatusType.java
diff -N CertificateStatusType.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ CertificateStatusType.java  11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,13 @@
+package gnu.javax.net.ssl.provider;
+
+public enum CertificateStatusType
+{
+  OCSP (1);
+  
+  public final int value;
+  
+  private CertificateStatusType (final int value)
+  {
+    this.value = value;
+  }
+}

Index: CertificateStatusRequest.java
===================================================================
RCS file: CertificateStatusRequest.java
diff -N CertificateStatusRequest.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ CertificateStatusRequest.java       11 Jun 2006 07:05:28 -0000      1.1.2.1
@@ -0,0 +1,204 @@
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.provider.Extension.Value;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * <pre>
+struct {
+  CertificateStatusType status_type;
+  select (status_type) {
+    case ocsp: OCSPStatusRequest;
+  } request;
+} CertificateStatusRequest;
+
+enum { ocsp(1), (255) } CertificateStatusType;
+
+struct {
+  ResponderID responder_id_list&lt;0..2^16-1&gt;;
+  Extensions  request_extensions;
+} OCSPStatusRequest;
+
+opaque ResponderID&lt;1..2^16-1&gt;;
+opaque Extensions&lt;0..2^16-1&gt;;</pre>
+ *
+ * @author csm
+ */
+public class CertificateStatusRequest extends Value implements Iterable<byte[]>
+{
+  private final ByteBuffer buffer;
+  
+  public CertificateStatusRequest(final ByteBuffer buffer)
+  {
+    this.buffer = buffer;
+  }
+
+  public int length()
+  {
+    int l = 3 + (buffer.getShort(1) & 0xFFFF);
+    return l + (buffer.getShort(l) & 0xFFFF) + 2;
+  }
+  
+  public CertificateStatusType statusType()
+  {
+    int x = buffer.get(0) & 0xFF;
+    if (x == 1)
+      return CertificateStatusType.OCSP;
+    throw new IllegalArgumentException ("invalid type: " + x);
+  }
+
+  public int size()
+  {
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    for (int i = 3; i < len; )
+      {
+        int l = buffer.getShort(i);
+        i += l + 2;
+        n++;
+      }
+    return n;
+  }
+  
+  public byte[] responderId(int index)
+  {
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    int i = 3;
+    while (i < len && n <= index)
+      {
+        int l = buffer.getShort(i) & 0xFFFF;
+        if (n == index)
+          {
+            byte[] b = new byte[l];
+            ((ByteBuffer) buffer.duplicate().position(i+2)).get(b);
+            return b;
+          }
+        i += l + 2;
+        n++;
+      }
+    throw new IndexOutOfBoundsException();
+  }
+  
+  public byte[] requestExtensions()
+  {
+    int l = 2 + (buffer.getShort(0) & 0xFFFF);
+    int ll = buffer.getShort(l) & 0xFFFF;
+    byte[] b = new byte[ll];
+    ((ByteBuffer) buffer.duplicate().position(ll+2)).get(b);
+    return b;
+  }
+  
+  public void setStatusType(CertificateStatusType type)
+  {
+    buffer.put(0, (byte) type.value);
+  }
+  
+  public void setRequestIdListLength(int newLength)
+  {
+    if (newLength < 0 || newLength > 0xFFFF)
+      throw new IllegalArgumentException("length out of range");
+    buffer.putShort(1, (short) newLength);
+  }
+  
+  public void putRequestId(int index, byte[] id)
+  {
+    if (id.length > 0xFFFF)
+      throw new IllegalArgumentException("request ID too large");
+    int len = buffer.getShort(1) & 0xFFFF;
+    int n = 0;
+    int i = 3;
+    while (i < len && n < index)
+      {
+        int l = buffer.getShort(i) & 0xFFFF;
+        i += l + 2;
+        n++;
+      }
+    if (n < index)
+      throw new IndexOutOfBoundsException();
+    buffer.putShort(i, (short) id.length);
+    ((ByteBuffer) buffer.duplicate().position(i)).put(id);
+  }
+  
+  public void setRequestExtensions(int index, byte[] ext)
+  {
+    if (ext.length > 0xFFFF)
+      throw new IllegalArgumentException("exceptions too large");
+    int off = 3 + (buffer.getShort(1) & 0xFFFF);
+    buffer.putShort(off, (short) ext.length);
+    ((ByteBuffer) buffer.duplicate().position(off+2)).put(ext);
+  }
+  
+  public Iterator<byte[]> iterator()
+  {
+    return new ResponderIdIterator();
+  }
+  
+  public String toString()
+  {
+    return toString(null);
+  }
+  
+  public String toString(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("  status_type = ");
+    out.print(statusType());
+    out.println(";");
+    String subprefix = "    ";
+    if (prefix != null) subprefix = prefix + subprefix;
+    if (prefix != null) out.print(prefix);
+    out.println("  responder_id_list = {");
+    for (byte[] b : this)
+      out.print(Util.hexDump(b, subprefix));
+    if (prefix != null) out.print(prefix);
+    out.println("  };");
+    if (prefix != null) out.print(prefix);
+    out.println("  request_extensions =");
+    out.print(Util.hexDump(requestExtensions(), subprefix));
+    if (prefix != null) out.print(prefix);
+    out.print("} CertificateStatus;");
+    return str.toString();
+  }
+  
+  public class ResponderIdIterator implements Iterator<byte[]>
+  {
+    private int index;
+    
+    public ResponderIdIterator()
+    {
+      index = 0;
+    }
+    
+    public byte[] next() throws NoSuchElementException
+    {
+      try
+        {
+          return responderId(index++);
+        }
+      catch (IndexOutOfBoundsException ioobe)
+        {
+          throw new NoSuchElementException();
+        }
+    }
+    
+    public boolean hasNext()
+    {
+      return index < size();
+    }
+    
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+  }
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]