1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45:
46:
70: public final class Handshake implements Constructed
71: {
72:
73:
74:
75:
76: private final ByteBuffer buffer;
77: private final CipherSuite suite;
78: private final ProtocolVersion version;
79:
80:
81:
82:
83: public Handshake (final ByteBuffer buffer)
84: {
85: this (buffer, null, ProtocolVersion.TLS_1_1);
86: }
87:
88: public Handshake (final ByteBuffer buffer, final CipherSuite suite,
89: final ProtocolVersion version)
90: {
91: this.buffer = buffer;
92: this.suite = suite;
93: this.version = version;
94: }
95:
96:
97:
98:
99:
104: public Type type()
105: {
106: return Type.forInteger (buffer.get (0) & 0xFF);
107: }
108:
109:
114: public int length ()
115: {
116:
117: return buffer.getInt (0) & 0xFFFFFF;
118: }
119:
120:
126: public Body body()
127: {
128: Type type = type ();
129: ByteBuffer bodyBuffer = bodyBuffer ();
130: switch (type)
131: {
132: case HELLO_REQUEST:
133: return new HelloRequest ();
134:
135: case CLIENT_HELLO:
136: return new ClientHello (bodyBuffer);
137:
138: case SERVER_HELLO:
139: return new ServerHello (bodyBuffer);
140:
141: case CERTIFICATE:
142: return new Certificate (bodyBuffer, CertificateType.X509);
143:
144: case SERVER_KEY_EXCHANGE:
145: return new ServerKeyExchange (bodyBuffer, suite);
146:
147: case CERTIFICATE_REQUEST:
148: return new CertificateRequest (bodyBuffer);
149:
150: case SERVER_HELLO_DONE:
151: return new ServerHelloDone ();
152:
153: case CERTIFICATE_VERIFY:
154: return new CertificateVerify (bodyBuffer, suite.signatureAlgorithm ());
155:
156: case CLIENT_KEY_EXCHANGE:
157: return new ClientKeyExchange (bodyBuffer, suite, version);
158:
159: case FINISHED:
160: return new Finished (bodyBuffer, version);
161:
162: case CERTIFICATE_URL:
163: case CERTIFICATE_STATUS:
164: throw new UnsupportedOperationException ("FIXME");
165: }
166: throw new IllegalArgumentException ("unknown handshake type " + type);
167: }
168:
169:
175: public ByteBuffer bodyBuffer ()
176: {
177: int length = length ();
178: return ((ByteBuffer) buffer.position (4).limit (4 + length)).slice ();
179: }
180:
181:
186: public void setType (final Type type)
187: {
188: buffer.put (0, (byte) type.getValue ());
189: }
190:
191:
200: public void setLength (final int length)
201: {
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);
208: }
209:
210: public String toString()
211: {
212: return toString (null);
213: }
214:
215: public String toString (final String prefix)
216: {
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();
230: }
231:
232:
233:
234:
235: public static interface Body extends Constructed
236: {
237: int length ();
238:
239: String toString (String prefix);
240: }
241:
242: public static enum Type
243: {
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);
256:
257: private final int value;
258:
259: private Type(int value)
260: {
261: this.value = value;
262: }
263:
264:
265:
266:
267:
274: public static Type forInteger (final int value)
275: {
276: switch (value & 0xFF)
277: {
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);
291: }
292: }
293:
294: public int getValue()
295: {
296: return value;
297: }
298: }
299: }