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 }