|
1 /* |
|
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package sun.security.ssl; |
|
27 |
|
28 import java.io.ByteArrayInputStream; |
|
29 import java.io.IOException; |
|
30 import java.nio.ByteBuffer; |
|
31 |
|
32 import javax.net.ssl.SSLException; |
|
33 |
|
34 /** |
|
35 * InputStream for handshake data, used internally only. Contains the |
|
36 * handshake message buffer and methods to parse them. |
|
37 * |
|
38 * Once a new handshake record arrives, it is buffered in this class until |
|
39 * processed by the Handshaker. The buffer may also contain incomplete |
|
40 * handshake messages in case the message is split across multiple records. |
|
41 * Handshaker.processRecord deals with all that. It may also contain |
|
42 * handshake messages larger than the default buffer size (e.g. large |
|
43 * certificate messages). The buffer is grown dynamically to handle that. |
|
44 * |
|
45 * Note that this class only handles Handshake messages in TLS format. |
|
46 * DTLS Handshake messages should be converted into TLS format before |
|
47 * calling into this method. |
|
48 * |
|
49 * @author David Brownell |
|
50 */ |
|
51 |
|
52 // This class is used to handle plain text handshake messages. |
|
53 // |
|
54 public final class HandshakeInStream extends ByteArrayInputStream { |
|
55 |
|
56 /* |
|
57 * Construct the stream; we'll be accumulating hashes of the |
|
58 * input records using two sets of digests. |
|
59 */ |
|
60 HandshakeInStream() { |
|
61 super(new byte[0]); // lazy to alloacte the internal buffer |
|
62 } |
|
63 |
|
64 // |
|
65 // overridden ByteArrayInputStream methods |
|
66 // |
|
67 |
|
68 @Override |
|
69 public int read(byte[] b) throws IOException { |
|
70 if (super.read(b) != b.length) { |
|
71 throw new SSLException("Unexpected end of handshake data"); |
|
72 } |
|
73 |
|
74 return b.length; |
|
75 } |
|
76 |
|
77 // |
|
78 // handshake input stream management functions |
|
79 // |
|
80 |
|
81 /* |
|
82 * Here's an incoming record with handshake data. Queue the contents; |
|
83 * it might be one or more entire messages, complete a message that's |
|
84 * partly queued, or both. |
|
85 */ |
|
86 void incomingRecord(ByteBuffer in) throws IOException { |
|
87 int len; |
|
88 |
|
89 // Move any unread data to the front of the buffer. |
|
90 if (pos != 0) { |
|
91 len = count - pos; |
|
92 if (len != 0) { |
|
93 System.arraycopy(buf, pos, buf, 0, len); |
|
94 } |
|
95 pos = 0; |
|
96 count = len; |
|
97 } |
|
98 |
|
99 // Grow buffer if needed. |
|
100 len = in.remaining() + count; |
|
101 if (buf.length < len) { |
|
102 byte[] newbuf = new byte[len]; |
|
103 if (count != 0) { |
|
104 System.arraycopy(buf, 0, newbuf, 0, count); |
|
105 } |
|
106 buf = newbuf; |
|
107 } |
|
108 |
|
109 // Append the incoming record to the buffer |
|
110 in.get(buf, count, in.remaining()); |
|
111 count = len; |
|
112 } |
|
113 |
|
114 // |
|
115 // Message parsing methods |
|
116 // |
|
117 |
|
118 /* |
|
119 * Read 8, 16, 24, and 32 bit SSL integer data types, encoded |
|
120 * in standard big-endian form. |
|
121 */ |
|
122 int getInt8() throws IOException { |
|
123 verifyLength(1); |
|
124 return read(); |
|
125 } |
|
126 |
|
127 int getInt16() throws IOException { |
|
128 verifyLength(2); |
|
129 return (getInt8() << 8) | getInt8(); |
|
130 } |
|
131 |
|
132 int getInt24() throws IOException { |
|
133 verifyLength(3); |
|
134 return (getInt8() << 16) | (getInt8() << 8) | getInt8(); |
|
135 } |
|
136 |
|
137 int getInt32() throws IOException { |
|
138 verifyLength(4); |
|
139 return (getInt8() << 24) | (getInt8() << 16) |
|
140 | (getInt8() << 8) | getInt8(); |
|
141 } |
|
142 |
|
143 /* |
|
144 * Read byte vectors with 8, 16, and 24 bit length encodings. |
|
145 */ |
|
146 byte[] getBytes8() throws IOException { |
|
147 int len = getInt8(); |
|
148 verifyLength(len); |
|
149 byte[] b = new byte[len]; |
|
150 |
|
151 read(b); |
|
152 return b; |
|
153 } |
|
154 |
|
155 public byte[] getBytes16() throws IOException { |
|
156 int len = getInt16(); |
|
157 verifyLength(len); |
|
158 byte[] b = new byte[len]; |
|
159 |
|
160 read(b); |
|
161 return b; |
|
162 } |
|
163 |
|
164 byte[] getBytes24() throws IOException { |
|
165 int len = getInt24(); |
|
166 verifyLength(len); |
|
167 byte[] b = new byte[len]; |
|
168 |
|
169 read(b); |
|
170 return b; |
|
171 } |
|
172 |
|
173 // Is a length greater than available bytes in the record? |
|
174 private void verifyLength(int len) throws SSLException { |
|
175 if (len > available()) { |
|
176 throw new SSLException("Unexpected end of handshake data"); |
|
177 } |
|
178 } |
|
179 } |