1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45: import ;
46:
47:
62: public class ClientHello implements Handshake.Body
63: {
64:
65:
66:
67:
68:
69:
70: protected static final int RANDOM_OFFSET = 2;
71:
72: protected static final int SESSID_OFFSET = 32 + RANDOM_OFFSET;
73:
74: protected static final int SESSID_OFFSET2 = SESSID_OFFSET + 1;
75:
76: protected ByteBuffer buffer;
77: protected boolean disableExtensions;
78:
79:
80:
81:
82: public ClientHello (final ByteBuffer buffer)
83: {
84: this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
85: disableExtensions = false;
86: }
87:
88:
89:
90:
91: public int length()
92: {
93: int len = SESSID_OFFSET2 + buffer.get(SESSID_OFFSET);
94: len += (buffer.getShort(len) & 0xFFFF) + 2;
95: len += (buffer.get(len) & 0xFF) + 1;
96: if (!disableExtensions && len + 1 < buffer.capacity())
97: len += (buffer.getShort(len) & 0xFFFF) + 2;
98: return len;
99: }
100:
101:
106: public ProtocolVersion version()
107: {
108: return ProtocolVersion.getInstance (buffer.getShort (0));
109: }
110:
111:
116: public Random random()
117: {
118: ByteBuffer randomBuf =
119: ((ByteBuffer) buffer.duplicate ().position (RANDOM_OFFSET)
120: .limit (SESSID_OFFSET)).slice ();
121: return new Random (randomBuf);
122: }
123:
124: public byte[] sessionId()
125: {
126: int idlen = buffer.get (SESSID_OFFSET) & 0xFF;
127: byte[] sessionId = new byte[idlen];
128: buffer.position (SESSID_OFFSET2);
129: buffer.get (sessionId);
130: return sessionId;
131: }
132:
133: public CipherSuiteList cipherSuites()
134: {
135: int offset = getCipherSuitesOffset ();
136:
137:
138:
139:
140: ByteBuffer listBuf = ((ByteBuffer) buffer.duplicate ().position (offset)
141: .limit (buffer.capacity ())).slice ();
142: return new CipherSuiteList (listBuf, version ());
143: }
144:
145: public CompressionMethodList compressionMethods()
146: {
147: int offset = getCompressionMethodsOffset ();
148: ByteBuffer listBuf = ((ByteBuffer) buffer.duplicate ().position (offset)
149: .limit (buffer.capacity ())).slice ();
150: return new CompressionMethodList (listBuf);
151: }
152:
153: public boolean hasExtensions()
154: {
155: int offset = getExtensionsOffset();
156: return (offset + 1 < buffer.limit());
157: }
158:
159: public ExtensionList extensions()
160: {
161: int offset = getExtensionsOffset ();
162: if (offset + 1 >= buffer.limit())
163: return null;
164: int len = buffer.getShort(offset) & 0xFFFF;
165: if (len == 0)
166: len = buffer.limit() - offset - 2;
167: ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate().position(offset)
168: .limit(offset + len + 2)).slice ();
169: return new ExtensionList(ebuf);
170: }
171:
172: public int extensionsLength()
173: {
174: if (hasExtensions())
175: return 0;
176: return buffer.getShort(getExtensionsOffset()) & 0xFFFF;
177: }
178:
179: protected int getCipherSuitesOffset ()
180: {
181: return (SESSID_OFFSET2 + (buffer.get (SESSID_OFFSET) & 0xFF));
182: }
183:
184: protected int getCompressionMethodsOffset ()
185: {
186: int csOffset = getCipherSuitesOffset ();
187: int csLen = buffer.getShort (csOffset) & 0xFFFF;
188: return csOffset + csLen + 2;
189: }
190:
191: protected int getExtensionsOffset ()
192: {
193: int cmOffset = getCompressionMethodsOffset ();
194: return (buffer.get (cmOffset) & 0xFF) + cmOffset + 1;
195: }
196:
197: public String toString ()
198: {
199: return toString (null);
200: }
201:
202: public String toString (final String prefix)
203: {
204: StringWriter str = new StringWriter ();
205: PrintWriter out = new PrintWriter (str);
206: String subprefix = " ";
207: if (prefix != null)
208: subprefix += prefix;
209: if (prefix != null)
210: out.print (prefix);
211: out.println ("struct {");
212: if (prefix != null)
213: out.print (prefix);
214: out.print (" version: ");
215: out.print (version ());
216: out.println (";");
217: out.print (subprefix);
218: out.println ("random:");
219: out.print (random ().toString (subprefix));
220: if (prefix != null)
221: out.print (prefix);
222: out.print (" sessionId: ");
223: out.print (Util.toHexString (sessionId (), ':'));
224: out.println (";");
225: out.print (subprefix);
226: out.println ("cipher_suites:");
227: out.println (cipherSuites ().toString (subprefix));
228: out.print (subprefix);
229: out.println ("compression_methods:");
230: out.println (compressionMethods ().toString (subprefix));
231: out.print (subprefix);
232: out.print ("extensions: ");
233: ExtensionList el = extensions();
234: out.println (el != null ? el.toString(subprefix+" ") : "(nil)");
235: if (prefix != null)
236: out.print (prefix);
237: out.print ("} ClientHello;");
238: return str.toString();
239: }
240: }