1 /* ServerHello.java -- SSL ServerHello message.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is a part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.javax.net.ssl.provider;
41 import java.io.PrintWriter;
42 import java.io.StringWriter;
44 import java.nio.ByteBuffer;
47 * The server hello message.
52 ProtocolVersion server_version;
55 CipherSuite cipher_suite;
56 CompressionMethod compression_method;
57 Extensions server_hello_extension_list<0..2^16-1>
61 * <p>Server hello messages may contain extra data after the
62 * <tt>compression_method</tt> field, which are interpreted as
63 * extensions to the basic handshake.
65 public class ServerHello implements Handshake.Body
69 // -------------------------------------------------------------------------
71 protected static final int RANDOM_OFFSET = 2;
72 protected static final int SESSID_OFFSET = 32 + RANDOM_OFFSET;
73 protected static final int SESSID_OFFSET2 = SESSID_OFFSET + 1;
75 protected ByteBuffer buffer;
76 protected boolean disableExtensions;
79 // -------------------------------------------------------------------------
81 public ServerHello (final ByteBuffer buffer)
84 disableExtensions = false;
89 int sessionLen = buffer.get(SESSID_OFFSET) & 0xFF;
90 int len = SESSID_OFFSET2 + sessionLen + 3;
92 if (!disableExtensions && len + 1 < buffer.limit()
93 && (elen = buffer.getShort(len)) != 0)
99 * Returns the server's protocol version. This will read two bytes
100 * from the beginning of the underlying buffer, and return an
101 * instance of the appropriate {@link ProtocolVersion}; if the
102 * version read is a supported version, this method returns a static
105 * @return The server's protocol version.
107 public ProtocolVersion version()
109 return ProtocolVersion.getInstance (buffer.getShort (0));
113 * Returns the server's random value. This method returns a
114 * lightwieght wrapper around the existing bytes; modifications to
115 * the underlying buffer will modify the returned object, and
118 * @return The server's random value.
120 public Random random()
122 ByteBuffer randomBuf =
123 ((ByteBuffer) buffer.duplicate ().position (RANDOM_OFFSET)
124 .limit (SESSID_OFFSET)).slice ();
125 return new Random (randomBuf);
129 * Returns the session ID. This method returns a new byte array with
130 * the session ID bytes.
132 * @return The session ID.
134 public byte[] sessionId()
136 int idlen = buffer.get (SESSID_OFFSET) & 0xFF;
137 byte[] sessionId = new byte[idlen];
138 buffer.position (SESSID_OFFSET2);
139 buffer.get (sessionId);
144 * Returns the server's chosen cipher suite. The returned cipher
145 * suite will be "resolved" to this structure's version.
147 * @return The server's chosen cipher suite.
149 public CipherSuite cipherSuite()
151 int offset = SESSID_OFFSET2 + (buffer.get(SESSID_OFFSET) & 0xFF);
152 return CipherSuite.forValue(buffer.getShort(offset)).resolve();
156 * Returns the server's chosen compression method.
158 * @return The chosen compression method.
160 public CompressionMethod compressionMethod()
162 int offset = SESSID_OFFSET2 + (buffer.get(SESSID_OFFSET) & 0xFF) + 2;
163 return CompressionMethod.getInstance(buffer.get(offset) & 0xFF);
166 public int extensionsLength()
168 int offset = SESSID_OFFSET2 + (buffer.get (SESSID_OFFSET) & 0xFF) + 3;
169 if (offset + 1 >= buffer.limit())
171 return buffer.getShort(offset) & 0xFFFF;
174 public ExtensionList extensions ()
176 int offset = SESSID_OFFSET2 + (buffer.get (SESSID_OFFSET) & 0xFF) + 3;
177 if (offset + 1 >= buffer.limit())
179 int len = buffer.getShort(offset) & 0xFFFF;
181 len = buffer.limit() - offset - 2;
182 ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate().position(offset)
183 .limit(offset + len + 2)).slice();
184 return new ExtensionList(ebuf);
187 public String toString()
189 return toString(null);
192 public String toString (final String prefix)
194 StringWriter str = new StringWriter();
195 PrintWriter out = new PrintWriter(str);
198 out.println ("struct {");
199 String subprefix = " ";
202 out.print (subprefix);
203 out.print ("version: ");
204 out.print (version ());
206 out.print (subprefix);
207 out.println ("random:");
208 out.println (random ().toString (subprefix));
209 out.print (subprefix);
210 out.print ("sessionId: ");
211 out.print (Util.toHexString(sessionId (), ':'));
213 out.print (subprefix);
214 out.print ("cipherSuite: ");
215 out.print (cipherSuite ());
217 out.print (subprefix);
218 out.print ("compressionMethod: ");
219 out.print (compressionMethod ());
221 ExtensionList exts = extensions ();
222 out.print (subprefix);
223 out.println ("extensions:");
224 out.println (exts != null ? exts.toString (subprefix+" ")
225 : subprefix + " (nil)");
228 out.print ("} ServerHello;");
229 return str.toString();