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