libjava/
[official-gcc.git] / libjava / classpath / gnu / javax / net / ssl / provider / Handshake.java
blobdd36f2b3fc5e85b8618e41d7e130e3cdc0d90150
1 /* Handshake.java -- SSL Handshake 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
19 USA
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
24 combination.
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;
46 /**
47 * An SSL handshake message. SSL handshake messages have the following
48 * form:
50 * <pre>
51 struct
53 HandshakeType msg_type;
54 uint24 length;
55 select (msg_type)
57 case hello_request: HelloRequest;
58 case client_hello: ClientHello;
59 case server_hello: ServerHello;
60 case certificate: Certificate;
61 case server_key_exchange: ServerKeyExchange;
62 case certificate_request: CertificateRequest;
63 case server_hello_done: ServerHelloDone;
64 case certificate_verify: CertificateVerify;
65 case client_key_exchange: ClientKeyExchange;
66 case finished: Finished;
67 } body;
68 };</pre>
70 public final class Handshake implements Constructed
73 // Fields.
74 // -------------------------------------------------------------------------
76 private final ByteBuffer buffer;
77 private final CipherSuite suite;
78 private final ProtocolVersion version;
80 // Constructors.
81 // -------------------------------------------------------------------------
83 public Handshake (final ByteBuffer buffer)
85 this (buffer, null, ProtocolVersion.TLS_1_1);
88 public Handshake (final ByteBuffer buffer, final CipherSuite suite,
89 final ProtocolVersion version)
91 this.buffer = buffer;
92 this.suite = suite;
93 this.version = version;
96 // Instance methods.
97 // -------------------------------------------------------------------------
99 /**
100 * Returns the handshake type.
102 * @return The handshake type.
104 public Type type()
106 return Type.forInteger (buffer.get (0) & 0xFF);
110 * Returns the message length.
112 * @return The message length.
114 public int length ()
116 // Length is a uint24.
117 return buffer.getInt (0) & 0xFFFFFF;
121 * Returns the handshake message body. Depending on the handshake
122 * type, some implementation of the Body interface is returned.
124 * @return The handshake body.
126 public Body body()
128 Type type = type ();
129 ByteBuffer bodyBuffer = bodyBuffer ();
130 switch (type)
132 case HELLO_REQUEST:
133 return new HelloRequest ();
135 case CLIENT_HELLO:
136 return new ClientHello (bodyBuffer);
138 case SERVER_HELLO:
139 return new ServerHello (bodyBuffer);
141 case CERTIFICATE:
142 return new Certificate (bodyBuffer, CertificateType.X509);
144 case SERVER_KEY_EXCHANGE:
145 return new ServerKeyExchange (bodyBuffer, suite);
147 case CERTIFICATE_REQUEST:
148 return new CertificateRequest (bodyBuffer);
150 case SERVER_HELLO_DONE:
151 return new ServerHelloDone ();
153 case CERTIFICATE_VERIFY:
154 return new CertificateVerify (bodyBuffer, suite.signatureAlgorithm ());
156 case CLIENT_KEY_EXCHANGE:
157 return new ClientKeyExchange (bodyBuffer, suite, version);
159 case FINISHED:
160 return new Finished (bodyBuffer, version);
162 case CERTIFICATE_URL:
163 case CERTIFICATE_STATUS:
164 throw new UnsupportedOperationException ("FIXME");
166 throw new IllegalArgumentException ("unknown handshake type " + type);
170 * Returns a subsequence of the underlying buffer, containing only
171 * the bytes that compose the handshake body.
173 * @return The body's byte buffer.
175 public ByteBuffer bodyBuffer ()
177 int length = length ();
178 return ((ByteBuffer) buffer.position (4).limit (4 + length)).slice ();
182 * Sets the handshake body type.
184 * @param type The handshake type.
186 public void setType (final Type type)
188 buffer.put (0, (byte) type.getValue ());
192 * Sets the length of the handshake body.
194 * @param length The handshake body length.
195 * @throws java.nio.ReadOnlyBufferException If the underlying buffer
196 * is not writable.
197 * @throws IllegalArgumentException of <code>length</code> is not
198 * between 0 and 16777215, inclusive.
200 public void setLength (final int length)
202 if (length < 0 || length > 0xFFFFFF)
203 throw new IllegalArgumentException ("length " + length + " out of range;"
204 + " must be between 0 and 16777215");
205 buffer.put (1, (byte) (length >>> 16));
206 buffer.put (2, (byte) (length >>> 8));
207 buffer.put (3, (byte) length);
210 public String toString()
212 return toString (null);
215 public String toString (final String prefix)
217 StringWriter str = new StringWriter();
218 PrintWriter out = new PrintWriter(str);
219 if (prefix != null) out.print (prefix);
220 out.println("struct {");
221 if (prefix != null) out.print (prefix);
222 out.print (" type: ");
223 out.print (type ());
224 out.println (";");
225 Body body = body ();
226 out.println (body.toString (prefix != null ? (prefix + " ") : " "));
227 if (prefix != null) out.print (prefix);
228 out.print ("} Handshake;");
229 return str.toString();
232 // Inner class.
233 // -------------------------------------------------------------------------
235 public static interface Body extends Constructed
237 int length ();
239 String toString (String prefix);
242 public static enum Type
244 HELLO_REQUEST ( 0),
245 CLIENT_HELLO ( 1),
246 SERVER_HELLO ( 2),
247 CERTIFICATE (11),
248 SERVER_KEY_EXCHANGE (12),
249 CERTIFICATE_REQUEST (13),
250 SERVER_HELLO_DONE (14),
251 CERTIFICATE_VERIFY (15),
252 CLIENT_KEY_EXCHANGE (16),
253 FINISHED (20),
254 CERTIFICATE_URL (21),
255 CERTIFICATE_STATUS (22);
257 private final int value;
259 private Type(int value)
261 this.value = value;
264 // Class methods.
265 // -----------------------------------------------------------------------
268 * Convert a raw handshake type value to a type enum value.
270 * @return The corresponding enum value for the raw integer value.
271 * @throws IllegalArgumentException If the value is not a known handshake
272 * type.
274 public static Type forInteger (final int value)
276 switch (value & 0xFF)
278 case 0: return HELLO_REQUEST;
279 case 1: return CLIENT_HELLO;
280 case 2: return SERVER_HELLO;
281 case 11: return CERTIFICATE;
282 case 12: return SERVER_KEY_EXCHANGE;
283 case 13: return CERTIFICATE_REQUEST;
284 case 14: return SERVER_HELLO_DONE;
285 case 15: return CERTIFICATE_VERIFY;
286 case 16: return CLIENT_KEY_EXCHANGE;
287 case 20: return FINISHED;
288 case 21: return CERTIFICATE_URL;
289 case 22: return CERTIFICATE_STATUS;
290 default: throw new IllegalArgumentException ("unsupported value type " + value);
294 public int getValue()
296 return value;