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