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