1 /* 2 * Copyright (c) 1996, 2016, 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.*; 29 import java.nio.*; 30 import java.util.Arrays; 31 32 import javax.net.ssl.SSLException; 33 import sun.security.util.HexDumpEncoder; 34 35 36 /** 37 * {@code OutputRecord} takes care of the management of SSL/TLS/DTLS output 38 * records, including buffering, encryption, handshake messages marshal, etc. 39 * 40 * @author David Brownell 41 */ 42 abstract class OutputRecord extends ByteArrayOutputStream 43 implements Record, Closeable { 44 45 /* Class and subclass dynamic debugging support */ 46 static final Debug debug = Debug.getInstance("ssl"); 47 48 Authenticator writeAuthenticator; 49 CipherBox writeCipher; 50 51 HandshakeHash handshakeHash; 52 boolean firstMessage; 53 54 // current protocol version, sent as record version 55 ProtocolVersion protocolVersion; 56 57 // version for the ClientHello message. Only relevant if this is a 58 // client handshake record. If set to ProtocolVersion.SSL20Hello, 59 // the V3 client hello is converted to V2 format. 60 ProtocolVersion helloVersion; 61 62 // Is it the first application record to write? 63 boolean isFirstAppOutputRecord = true; 64 65 // packet size 66 int packetSize; 67 68 // fragment size 69 int fragmentSize; 70 71 // closed or not? 72 boolean isClosed; 73 74 /* 75 * Mappings from V3 cipher suite encodings to their pure V2 equivalents. 76 * This is taken from the SSL V3 specification, Appendix E. 77 */ 78 private static int[] V3toV2CipherMap1 = 79 {-1, -1, -1, 0x02, 0x01, -1, 0x04, 0x05, -1, 0x06, 0x07}; 80 private static int[] V3toV2CipherMap3 = 81 {-1, -1, -1, 0x80, 0x80, -1, 0x80, 0x80, -1, 0x40, 0xC0}; 82 83 OutputRecord() { 84 this.writeCipher = CipherBox.NULL; 85 this.firstMessage = true; 86 this.fragmentSize = Record.maxDataSize; 87 88 // Please set packetSize and protocolVersion in the implementation. 89 } 90 91 void setVersion(ProtocolVersion protocolVersion) { 92 this.protocolVersion = protocolVersion; 93 } 94 95 /* 96 * Updates helloVersion of this record. 97 */ 98 synchronized void setHelloVersion(ProtocolVersion helloVersion) { 99 this.helloVersion = helloVersion; 100 } 101 102 /* 103 * For handshaking, we need to be able to hash every byte above the 104 * record marking layer. This is where we're guaranteed to see those 105 * bytes, so this is where we can hash them. 106 */ 107 void setHandshakeHash(HandshakeHash handshakeHash) { 108 this.handshakeHash = handshakeHash; 109 } 110 111 /* 112 * Return true iff the record is empty -- to avoid doing the work 113 * of sending empty records over the network. 114 */ 115 boolean isEmpty() { 116 return false; 117 } 118 119 boolean seqNumIsHuge() { 120 return (writeAuthenticator != null) && 121 writeAuthenticator.seqNumIsHuge(); 122 } 123 124 // SSLEngine and SSLSocket 125 abstract void encodeAlert(byte level, byte description) throws IOException; 126 127 // SSLEngine and SSLSocket 128 abstract void encodeHandshake(byte[] buffer, 129 int offset, int length) throws IOException; 130 131 // SSLEngine and SSLSocket 132 abstract void encodeChangeCipherSpec() throws IOException; 133 134 // apply to SSLEngine only 135 Ciphertext encode(ByteBuffer[] sources, int offset, int length, 136 ByteBuffer destination) throws IOException { 137 throw new UnsupportedOperationException(); 138 } 139 140 // apply to SSLEngine only 141 void encodeV2NoCipher() throws IOException { 142 throw new UnsupportedOperationException(); 143 } 144 145 // apply to SSLSocket only 146 void deliver(byte[] source, int offset, int length) throws IOException { 147 throw new UnsupportedOperationException(); 148 } 149 150 // apply to SSLSocket only 151 void setDeliverStream(OutputStream outputStream) { 152 throw new UnsupportedOperationException(); 153 } 154 155 // apply to SSLEngine only 156 Ciphertext acquireCiphertext(ByteBuffer destination) throws IOException { 157 throw new UnsupportedOperationException(); 158 } 159 160 void changeWriteCiphers(Authenticator writeAuthenticator, 161 CipherBox writeCipher) throws IOException { 162 163 encodeChangeCipherSpec(); 164 165 /* 166 * Dispose of any intermediate state in the underlying cipher. 167 * For PKCS11 ciphers, this will release any attached sessions, 168 * and thus make finalization faster. 169 * 170 * Since MAC's doFinal() is called for every SSL/TLS packet, it's 171 * not necessary to do the same with MAC's. 172 */ 173 writeCipher.dispose(); 174 175 this.writeAuthenticator = writeAuthenticator; 176 this.writeCipher = writeCipher; 177 this.isFirstAppOutputRecord = true; 178 } 179 180 void changePacketSize(int packetSize) { 181 this.packetSize = packetSize; 182 } 183 184 void changeFragmentSize(int fragmentSize) { 185 this.fragmentSize = fragmentSize; 186 } 187 188 int getMaxPacketSize() { 189 return packetSize; 190 } 191 192 // apply to DTLS SSLEngine 193 void initHandshaker() { 194 // blank 195 } 196 197 // apply to DTLS SSLEngine 198 void launchRetransmission() { 199 // blank 200 } 201 202 @Override 203 public synchronized void close() throws IOException { 204 if (!isClosed) { 205 isClosed = true; 206 writeCipher.dispose(); 207 } 208 } 209 210 // 211 // shared helpers 212 // 213 214 // Encrypt a fragment and wrap up a record. 215 // 216 // To be consistent with the spec of SSLEngine.wrap() methods, the 217 // destination ByteBuffer's position is updated to reflect the amount 218 // of data produced. The limit remains the same. 219 static long encrypt(Authenticator authenticator, 220 CipherBox encCipher, byte contentType, ByteBuffer destination, 221 int headerOffset, int dstLim, int headerSize, 222 ProtocolVersion protocolVersion, boolean isDTLS) { 223 224 byte[] sequenceNumber = null; 225 int dstContent = destination.position(); 226 227 // Acquire the current sequence number before using. 228 if (isDTLS) { 229 sequenceNumber = authenticator.sequenceNumber(); 230 } 231 232 // The sequence number may be shared for different purpose. 233 boolean sharedSequenceNumber = false; 234 235 // "flip" but skip over header again, add MAC & encrypt 236 if (authenticator instanceof MAC) { 237 MAC signer = (MAC)authenticator; 238 if (signer.MAClen() != 0) { 239 byte[] hash = signer.compute(contentType, destination, false); 240 241 /* 242 * position was advanced to limit in MAC compute above. 243 * 244 * Mark next area as writable (above layers should have 245 * established that we have plenty of room), then write 246 * out the hash. 247 */ 248 destination.limit(destination.limit() + hash.length); 249 destination.put(hash); 250 251 // reset the position and limit 252 destination.limit(destination.position()); 253 destination.position(dstContent); 254 255 // The signer has used and increased the sequence number. 256 if (isDTLS) { 257 sharedSequenceNumber = true; 258 } 259 } 260 } 261 262 if (!encCipher.isNullCipher()) { 263 if (protocolVersion.useTLS11PlusSpec() && 264 (encCipher.isCBCMode() || encCipher.isAEADMode())) { 265 byte[] nonce = encCipher.createExplicitNonce( 266 authenticator, contentType, destination.remaining()); 267 destination.position(headerOffset + headerSize); 268 destination.put(nonce); 269 } 270 if (!encCipher.isAEADMode()) { 271 // The explicit IV in TLS 1.1 and later can be encrypted. 272 destination.position(headerOffset + headerSize); 273 } // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode 274 275 // Encrypt may pad, so again the limit may be changed. 276 encCipher.encrypt(destination, dstLim); 277 278 // The cipher has used and increased the sequence number. 279 if (isDTLS && encCipher.isAEADMode()) { 280 sharedSequenceNumber = true; 281 } 282 } else { 283 destination.position(destination.limit()); 284 } 285 286 // Finish out the record header. 287 int fragLen = destination.limit() - headerOffset - headerSize; 288 289 destination.put(headerOffset, contentType); // content type 290 destination.put(headerOffset + 1, protocolVersion.major); 291 destination.put(headerOffset + 2, protocolVersion.minor); 292 if (!isDTLS) { 293 // fragment length 294 destination.put(headerOffset + 3, (byte)(fragLen >> 8)); 295 destination.put(headerOffset + 4, (byte)fragLen); 296 } else { 297 // epoch and sequence_number 298 destination.put(headerOffset + 3, sequenceNumber[0]); 299 destination.put(headerOffset + 4, sequenceNumber[1]); 300 destination.put(headerOffset + 5, sequenceNumber[2]); 301 destination.put(headerOffset + 6, sequenceNumber[3]); 302 destination.put(headerOffset + 7, sequenceNumber[4]); 303 destination.put(headerOffset + 8, sequenceNumber[5]); 304 destination.put(headerOffset + 9, sequenceNumber[6]); 305 destination.put(headerOffset + 10, sequenceNumber[7]); 306 307 // fragment length 308 destination.put(headerOffset + 11, (byte)(fragLen >> 8)); 309 destination.put(headerOffset + 12, (byte)fragLen); 310 311 // Increase the sequence number for next use if it is not shared. 312 if (!sharedSequenceNumber) { 313 authenticator.increaseSequenceNumber(); 314 } 315 } 316 317 // Update destination position to reflect the amount of data produced. 318 destination.position(destination.limit()); 319 320 return Authenticator.toLong(sequenceNumber); 321 } 322 323 // Encrypt a fragment and wrap up a record. 324 // 325 // Uses the internal expandable buf variable and the current 326 // protocolVersion variable. 327 void encrypt(Authenticator authenticator, 328 CipherBox encCipher, byte contentType, int headerSize) { 329 330 int position = headerSize + writeCipher.getExplicitNonceSize(); 331 332 // "flip" but skip over header again, add MAC & encrypt 333 int macLen = 0; 334 if (authenticator instanceof MAC) { 335 MAC signer = (MAC)authenticator; 336 macLen = signer.MAClen(); 337 if (macLen != 0) { 338 byte[] hash = signer.compute(contentType, 339 buf, position, (count - position), false); 340 341 write(hash, 0, hash.length); 342 } 343 } 344 345 if (!encCipher.isNullCipher()) { 346 // Requires explicit IV/nonce for CBC/AEAD cipher suites for 347 // TLS 1.1 or later. 348 if (protocolVersion.useTLS11PlusSpec() && 349 (encCipher.isCBCMode() || encCipher.isAEADMode())) { 350 351 byte[] nonce = encCipher.createExplicitNonce( 352 authenticator, contentType, (count - position)); 353 int noncePos = position - nonce.length; 354 System.arraycopy(nonce, 0, buf, noncePos, nonce.length); 355 } 356 357 if (!encCipher.isAEADMode()) { 358 // The explicit IV in TLS 1.1 and later can be encrypted. 359 position = headerSize; 360 } // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode 361 362 // increase buf capacity if necessary 363 int fragSize = count - position; 364 int packetSize = 365 encCipher.calculatePacketSize(fragSize, macLen, headerSize); 366 if (packetSize > (buf.length - position)) { 367 byte[] newBuf = new byte[position + packetSize]; 368 System.arraycopy(buf, 0, newBuf, 0, count); 369 buf = newBuf; 370 } 371 372 // Encrypt may pad, so again the count may be changed. 373 count = position + 374 encCipher.encrypt(buf, position, (count - position)); 375 } 376 377 // Fill out the header, write it and the message. 378 int fragLen = count - headerSize; 379 buf[0] = contentType; 380 buf[1] = protocolVersion.major; 381 buf[2] = protocolVersion.minor; 382 buf[3] = (byte)((fragLen >> 8) & 0xFF); 383 buf[4] = (byte)(fragLen & 0xFF); 384 } 385 386 static ByteBuffer encodeV2ClientHello( 387 byte[] fragment, int offset, int length) throws IOException { 388 389 int v3SessIdLenOffset = offset + 34; // 2: client_version 390 // 32: random 391 392 int v3SessIdLen = fragment[v3SessIdLenOffset]; 393 int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen; 394 int v3CSLen = ((fragment[v3CSLenOffset] & 0xff) << 8) + 395 (fragment[v3CSLenOffset + 1] & 0xff); 396 int cipherSpecs = v3CSLen / 2; // 2: cipher spec size 397 398 // Estimate the max V2ClientHello message length 399 // 400 // 11: header size 401 // (cipherSpecs * 6): cipher_specs 402 // 6: one cipher suite may need 6 bytes, see V3toV2CipherSuite. 403 // 3: placeholder for the TLS_EMPTY_RENEGOTIATION_INFO_SCSV 404 // signaling cipher suite 405 // 32: challenge size 406 int v2MaxMsgLen = 11 + (cipherSpecs * 6) + 3 + 32; 407 408 // Create a ByteBuffer backed by an accessible byte array. 409 byte[] dstBytes = new byte[v2MaxMsgLen]; 410 ByteBuffer dstBuf = ByteBuffer.wrap(dstBytes); 411 412 /* 413 * Copy over the cipher specs. We don't care about actually 414 * translating them for use with an actual V2 server since 415 * we only talk V3. Therefore, just copy over the V3 cipher 416 * spec values with a leading 0. 417 */ 418 int v3CSOffset = v3CSLenOffset + 2; // skip length field 419 int v2CSLen = 0; 420 421 dstBuf.position(11); 422 boolean containsRenegoInfoSCSV = false; 423 for (int i = 0; i < cipherSpecs; i++) { 424 byte byte1, byte2; 425 426 byte1 = fragment[v3CSOffset++]; 427 byte2 = fragment[v3CSOffset++]; 428 v2CSLen += V3toV2CipherSuite(dstBuf, byte1, byte2); 429 if (!containsRenegoInfoSCSV && 430 byte1 == (byte)0x00 && byte2 == (byte)0xFF) { 431 containsRenegoInfoSCSV = true; 432 } 433 } 434 435 if (!containsRenegoInfoSCSV) { 436 v2CSLen += V3toV2CipherSuite(dstBuf, (byte)0x00, (byte)0xFF); 437 } 438 439 /* 440 * Copy in the nonce. 441 */ 442 dstBuf.put(fragment, (offset + 2), 32); 443 444 /* 445 * Build the first part of the V3 record header from the V2 one 446 * that's now buffered up. (Lengths are fixed up later). 447 */ 448 int msgLen = dstBuf.position() - 2; // Exclude the legth field itself 449 dstBuf.position(0); 450 dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF))); // pos: 0 451 dstBuf.put((byte)(msgLen & 0xFF)); // pos: 1 452 dstBuf.put(HandshakeMessage.ht_client_hello); // pos: 2 453 dstBuf.put(fragment[offset]); // major version, pos: 3 454 dstBuf.put(fragment[offset + 1]); // minor version, pos: 4 455 dstBuf.put((byte)(v2CSLen >>> 8)); // pos: 5 456 dstBuf.put((byte)(v2CSLen & 0xFF)); // pos: 6 457 dstBuf.put((byte)0x00); // session_id_length, pos: 7 458 dstBuf.put((byte)0x00); // pos: 8 459 dstBuf.put((byte)0x00); // challenge_length, pos: 9 460 dstBuf.put((byte)32); // pos: 10 461 462 dstBuf.position(0); 463 dstBuf.limit(msgLen + 2); 464 465 return dstBuf; 466 } 467 468 private static int V3toV2CipherSuite(ByteBuffer dstBuf, 469 byte byte1, byte byte2) { 470 dstBuf.put((byte)0); 471 dstBuf.put(byte1); 472 dstBuf.put(byte2); 473 474 if (((byte2 & 0xff) > 0xA) || (V3toV2CipherMap1[byte2] == -1)) { 475 return 3; 476 } 477 478 dstBuf.put((byte)V3toV2CipherMap1[byte2]); 479 dstBuf.put((byte)0); 480 dstBuf.put((byte)V3toV2CipherMap3[byte2]); 481 482 return 6; 483 } 484 }