1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53:
54: import ;
55:
56: import ;
57: import ;
58:
59: import ;
60:
61:
85: public final class Handshake implements Constructed
86: {
87:
88:
89:
90:
91: private final ByteBuffer buffer;
92: private final CipherSuite suite;
93: private final ProtocolVersion version;
94:
95:
96:
97:
98: public Handshake (final ByteBuffer buffer)
99: {
100: this (buffer, null, ProtocolVersion.TLS_1_1);
101: }
102:
103: public Handshake (final ByteBuffer buffer, final CipherSuite suite,
104: final ProtocolVersion version)
105: {
106: this.buffer = buffer;
107: this.suite = suite;
108: this.version = version;
109: }
110:
111:
112:
113:
114:
119: public Type type()
120: {
121: return Type.forInteger (buffer.get (0) & 0xFF);
122: }
123:
124:
129: public int length ()
130: {
131:
132: return buffer.getInt (0) & 0xFFFFFF;
133: }
134:
135:
141: public Body body()
142: {
143: Type type = type ();
144: ByteBuffer bodyBuffer = bodyBuffer ();
145: switch (type)
146: {
147: case HELLO_REQUEST:
148: return new HelloRequest ();
149:
150: case CLIENT_HELLO:
151: return new ClientHello (bodyBuffer);
152:
153: case SERVER_HELLO:
154: return new ServerHello (bodyBuffer);
155:
156: case CERTIFICATE:
157: return new Certificate (bodyBuffer, CertificateType.X509);
158:
159: case SERVER_KEY_EXCHANGE:
160: return new ServerKeyExchange (bodyBuffer, suite);
161:
162: case CERTIFICATE_REQUEST:
163: return new CertificateRequest (bodyBuffer);
164:
165: case SERVER_HELLO_DONE:
166: return new ServerHelloDone ();
167:
168: case CERTIFICATE_VERIFY:
169: return new CertificateVerify (bodyBuffer, suite.signatureAlgorithm ());
170:
171: case CLIENT_KEY_EXCHANGE:
172: return new ClientKeyExchange (bodyBuffer, suite, version);
173:
174: case FINISHED:
175: return new Finished (bodyBuffer, version);
176:
177: case CERTIFICATE_URL:
178: case CERTIFICATE_STATUS:
179: throw new UnsupportedOperationException ("FIXME");
180: }
181: throw new IllegalArgumentException ("unknown handshake type " + type);
182: }
183:
184:
190: public ByteBuffer bodyBuffer ()
191: {
192: int length = length ();
193: return ((ByteBuffer) buffer.position (4).limit (4 + length)).slice ();
194: }
195:
196:
201: public void setType (final Type type)
202: {
203: buffer.put (0, (byte) type.getValue ());
204: }
205:
206:
215: public void setLength (final int length)
216: {
217: if (length < 0 || length > 0xFFFFFF)
218: throw new IllegalArgumentException ("length " + length + " out of range;"
219: + " must be between 0 and 16777215");
220: buffer.put (1, (byte) (length >>> 16));
221: buffer.put (2, (byte) (length >>> 8));
222: buffer.put (3, (byte) length);
223: }
224:
225: public String toString()
226: {
227: return toString (null);
228: }
229:
230: public String toString (final String prefix)
231: {
232: StringWriter str = new StringWriter();
233: PrintWriter out = new PrintWriter(str);
234: if (prefix != null) out.print (prefix);
235: out.println("struct {");
236: if (prefix != null) out.print (prefix);
237: out.print (" type: ");
238: out.print (type ());
239: out.println (";");
240: Body body = body ();
241: out.println (body.toString (prefix != null ? (prefix + " ") : " "));
242: if (prefix != null) out.print (prefix);
243: out.print ("} Handshake;");
244: return str.toString();
245: }
246:
247:
248:
249:
250: public static interface Body extends Constructed
251: {
252: int length ();
253:
254: String toString (String prefix);
255: }
256:
257: public static enum Type
258: {
259: HELLO_REQUEST ( 0),
260: CLIENT_HELLO ( 1),
261: SERVER_HELLO ( 2),
262: CERTIFICATE (11),
263: SERVER_KEY_EXCHANGE (12),
264: CERTIFICATE_REQUEST (13),
265: SERVER_HELLO_DONE (14),
266: CERTIFICATE_VERIFY (15),
267: CLIENT_KEY_EXCHANGE (16),
268: FINISHED (20),
269: CERTIFICATE_URL (21),
270: CERTIFICATE_STATUS (22);
271:
272: private final int value;
273:
274: private Type(int value)
275: {
276: this.value = value;
277: }
278:
279:
280:
281:
282:
289: public static Type forInteger (final int value)
290: {
291: switch (value & 0xFF)
292: {
293: case 0: return HELLO_REQUEST;
294: case 1: return CLIENT_HELLO;
295: case 2: return SERVER_HELLO;
296: case 11: return CERTIFICATE;
297: case 12: return SERVER_KEY_EXCHANGE;
298: case 13: return CERTIFICATE_REQUEST;
299: case 14: return SERVER_HELLO_DONE;
300: case 15: return CERTIFICATE_VERIFY;
301: case 16: return CLIENT_KEY_EXCHANGE;
302: case 20: return FINISHED;
303: case 21: return CERTIFICATE_URL;
304: case 22: return CERTIFICATE_STATUS;
305: default: throw new IllegalArgumentException ("unsupported value type " + value);
306: }
307: }
308:
309: public int getValue()
310: {
311: return value;
312: }
313: }
314: }