• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1996, 2012, 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 
27 package sun.security.ssl;
28 
29 import java.io.InputStream;
30 import java.io.IOException;
31 import java.security.MessageDigest;
32 
33 import javax.net.ssl.SSLException;
34 
35 /**
36  * InputStream for handshake data, used internally only. Contains the
37  * handshake message buffer and methods to parse them.
38  *
39  * Once a new handshake record arrives, it is buffered in this class until
40  * processed by the Handshaker. The buffer may also contain incomplete
41  * handshake messages in case the message is split across multiple records.
42  * Handshaker.process_record deals with all that. It may also contain
43  * handshake messages larger than the default buffer size (e.g. large
44  * certificate messages). The buffer is grown dynamically to handle that
45  * (see InputRecord.queueHandshake()).
46  *
47  * Note that the InputRecord used as a buffer here is separate from the
48  * AppInStream.r, which is where data from the socket is initially read
49  * into. This is because once the initial handshake has been completed,
50  * handshake and application data messages may be interleaved arbitrarily
51  * and must be processed independently.
52  *
53  * @author David Brownell
54  */
55 public class HandshakeInStream extends InputStream {
56 
57     InputRecord r;
58 
59     /*
60      * Construct the stream; we'll be accumulating hashes of the
61      * input records using two sets of digests.
62      */
HandshakeInStream(HandshakeHash handshakeHash)63     HandshakeInStream(HandshakeHash handshakeHash) {
64         r = new InputRecord();
65         r.setHandshakeHash(handshakeHash);
66     }
67 
68 
69     // overridden InputStream methods
70 
71     /*
72      * Return the number of bytes available for read().
73      *
74      * Note that this returns the bytes remaining in the buffer, not
75      * the bytes remaining in the current handshake message.
76      */
available()77     public int available() {
78         return r.available();
79     }
80 
81     /*
82      * Get a byte of handshake data.
83      */
read()84     public int read() throws IOException {
85         int n = r.read();
86         if (n == -1) {
87             throw new SSLException("Unexpected end of handshake data");
88         }
89         return n;
90     }
91 
92     /*
93      * Get a bunch of bytes of handshake data.
94      */
read(byte b [], int off, int len)95     public int read(byte b [], int off, int len) throws IOException {
96         // we read from a ByteArrayInputStream, it always returns the
97         // data in a single read if enough is available
98         int n = r.read(b, off, len);
99         if (n != len) {
100             throw new SSLException("Unexpected end of handshake data");
101         }
102         return n;
103     }
104 
105     /*
106      * Skip some handshake data.
107      */
skip(long n)108     public long skip(long n) throws IOException {
109         return r.skip(n);
110     }
111 
112     /*
113      * Mark/ reset code, implemented using InputRecord mark/ reset.
114      *
115      * Note that it currently provides only a limited mark functionality
116      * and should be used with care (once a new handshake record has been
117      * read, data that has already been consumed is lost even if marked).
118      */
119 
mark(int readlimit)120     public void mark(int readlimit) {
121         r.mark(readlimit);
122     }
123 
reset()124     public void reset() {
125         r.reset();
126     }
127 
markSupported()128     public boolean markSupported() {
129         return true;
130     }
131 
132 
133     // handshake management functions
134 
135     /*
136      * Here's an incoming record with handshake data.  Queue the contents;
137      * it might be one or more entire messages, complete a message that's
138      * partly queued, or both.
139      */
incomingRecord(InputRecord in)140     void incomingRecord(InputRecord in) throws IOException {
141         r.queueHandshake(in);
142     }
143 
144     /*
145      * Hash any data we've consumed but not yet hashed.  Useful mostly
146      * for processing client certificate messages (so we can check the
147      * immediately following cert verify message) and finished messages
148      * (so we can compute our own finished message).
149      */
digestNow()150     void digestNow() {
151         r.doHashes();
152     }
153 
154     /*
155      * Do more than skip that handshake data ... totally ignore it.
156      * The difference is that the data does not get hashed.
157      */
ignore(int n)158     void ignore(int n) {
159         r.ignore(n);
160     }
161 
162 
163     // Message parsing methods
164 
165     /*
166      * Read 8, 16, 24, and 32 bit SSL integer data types, encoded
167      * in standard big-endian form.
168      */
169 
getInt8()170     int getInt8() throws IOException {
171         return read();
172     }
173 
getInt16()174     int getInt16() throws IOException {
175         return (getInt8() << 8) | getInt8();
176     }
177 
getInt24()178     int getInt24() throws IOException {
179         return (getInt8() << 16) | (getInt8() << 8) | getInt8();
180     }
181 
getInt32()182     int getInt32() throws IOException {
183         return (getInt8() << 24) | (getInt8() << 16)
184              | (getInt8() << 8) | getInt8();
185     }
186 
187     /*
188      * Read byte vectors with 8, 16, and 24 bit length encodings.
189      */
190 
getBytes8()191     byte[] getBytes8() throws IOException {
192         int len = getInt8();
193         verifyLength(len);
194         byte b[] = new byte[len];
195 
196         read(b, 0, len);
197         return b;
198     }
199 
getBytes16()200     public byte[] getBytes16() throws IOException {
201         int len = getInt16();
202         verifyLength(len);
203         byte b[] = new byte[len];
204 
205         read(b, 0, len);
206         return b;
207     }
208 
getBytes24()209     byte[] getBytes24() throws IOException {
210         int len = getInt24();
211         verifyLength(len);
212         byte b[] = new byte[len];
213 
214         read(b, 0, len);
215         return b;
216     }
217 
218     // Is a length greater than available bytes in the record?
verifyLength(int len)219     private void verifyLength(int len) throws SSLException {
220         if (len > available()) {
221             throw new SSLException(
222                         "Not enough data to fill declared vector size");
223         }
224     }
225 
226 }
227