1 /*
   2  * Copyright (c) 1996, 2013, 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     @Override
 198     public synchronized void close() throws IOException {
 199         if (!isClosed) {
 200             isClosed = true;
 201             writeCipher.dispose();
 202         }
 203     }
 204 
 205     //
 206     // shared helpers
 207     //
 208 
 209     // Encrypt a fragment and wrap up a record.
 210     //
 211     // To be consistent with the spec of SSLEngine.wrap() methods, the
 212     // destination ByteBuffer's position is updated to reflect the amount
 213     // of data produced.  The limit remains the same.
 214     static long encrypt(Authenticator authenticator,
 215             CipherBox encCipher, byte contentType, ByteBuffer destination,
 216             int headerOffset, int dstLim, int headerSize,
 217             ProtocolVersion protocolVersion, boolean isDTLS) {
 218 
 219         byte[] sequenceNumber = null;
 220         int dstContent = destination.position();
 221 
 222         // Acquire the current sequence number before using.
 223         if (isDTLS) {
 224             sequenceNumber = authenticator.sequenceNumber();
 225         }
 226 
 227         // "flip" but skip over header again, add MAC & encrypt
 228         if (authenticator instanceof MAC) {
 229             MAC signer = (MAC)authenticator;
 230             if (signer.MAClen() != 0) {
 231                 byte[] hash = signer.compute(contentType, destination, false);
 232 
 233                 /*
 234                  * position was advanced to limit in MAC compute above.
 235                  *
 236                  * Mark next area as writable (above layers should have
 237                  * established that we have plenty of room), then write
 238                  * out the hash.
 239                  */
 240                 destination.limit(destination.limit() + hash.length);
 241                 destination.put(hash);
 242 
 243                 // reset the position and limit
 244                 destination.limit(destination.position());
 245                 destination.position(dstContent);
 246             }
 247         }
 248 
 249         if (!encCipher.isNullCipher()) {
 250             if (protocolVersion.useTLS11PlusSpec() &&
 251                     (encCipher.isCBCMode() || encCipher.isAEADMode())) {
 252                 byte[] nonce = encCipher.createExplicitNonce(
 253                         authenticator, contentType, destination.remaining());
 254                 destination.position(headerOffset + headerSize);
 255                 destination.put(nonce);
 256             }
 257             if (!encCipher.isAEADMode()) {
 258                 // The explicit IV in TLS 1.1 and later can be encrypted.
 259                 destination.position(headerOffset + headerSize);
 260             }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
 261 
 262             // Encrypt may pad, so again the limit may be changed.
 263             encCipher.encrypt(destination, dstLim);
 264         } else {
 265             destination.position(destination.limit());
 266         }
 267 
 268         // Finish out the record header.
 269         int fragLen = destination.limit() - headerOffset - headerSize;
 270 
 271         destination.put(headerOffset, contentType);         // content type
 272         destination.put(headerOffset + 1, protocolVersion.major);
 273         destination.put(headerOffset + 2, protocolVersion.minor);
 274         if (!isDTLS) {
 275             // fragment length
 276             destination.put(headerOffset + 3, (byte)(fragLen >> 8));
 277             destination.put(headerOffset + 4, (byte)fragLen);
 278         } else {
 279             // epoch and sequence_number
 280             destination.put(headerOffset + 3, sequenceNumber[0]);
 281             destination.put(headerOffset + 4, sequenceNumber[1]);
 282             destination.put(headerOffset + 5, sequenceNumber[2]);
 283             destination.put(headerOffset + 6, sequenceNumber[3]);
 284             destination.put(headerOffset + 7, sequenceNumber[4]);
 285             destination.put(headerOffset + 8, sequenceNumber[5]);
 286             destination.put(headerOffset + 9, sequenceNumber[6]);
 287             destination.put(headerOffset + 10, sequenceNumber[7]);
 288 
 289             // fragment length
 290             destination.put(headerOffset + 11, (byte)(fragLen >> 8));
 291             destination.put(headerOffset + 12, (byte)fragLen);
 292 
 293             // Increase the sequence number for next use.
 294             authenticator.increaseSequenceNumber();
 295         }
 296 
 297         // Update destination position to reflect the amount of data produced.
 298         destination.position(destination.limit());
 299 
 300         return Authenticator.toLong(sequenceNumber);
 301     }
 302 
 303     // Encrypt a fragment and wrap up a record.
 304     //
 305     // Uses the internal expandable buf variable and the current
 306     // protocolVersion variable.
 307     void encrypt(Authenticator authenticator,
 308             CipherBox encCipher, byte contentType, int headerSize) {
 309 
 310         int position = headerSize + writeCipher.getExplicitNonceSize();
 311 
 312         // "flip" but skip over header again, add MAC & encrypt
 313         int macLen = 0;
 314         if (authenticator instanceof MAC) {
 315             MAC signer = (MAC)authenticator;
 316             macLen = signer.MAClen();
 317             if (macLen != 0) {
 318                 byte[] hash = signer.compute(contentType,
 319                         buf, position, (count - position), false);
 320 
 321                 write(hash, 0, hash.length);
 322             }
 323         }
 324 
 325         if (!encCipher.isNullCipher()) {
 326             // Requires explicit IV/nonce for CBC/AEAD cipher suites for
 327             // TLS 1.1 or later.
 328             if (protocolVersion.useTLS11PlusSpec() &&
 329                     (encCipher.isCBCMode() || encCipher.isAEADMode())) {
 330 
 331                 byte[] nonce = encCipher.createExplicitNonce(
 332                         authenticator, contentType, (count - position));
 333                 int noncePos = position - nonce.length;
 334                 System.arraycopy(nonce, 0, buf, noncePos, nonce.length);
 335             }
 336 
 337             if (!encCipher.isAEADMode()) {
 338                 // The explicit IV in TLS 1.1 and later can be encrypted.
 339                 position = headerSize;
 340             }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
 341 
 342             // increase buf capacity if necessary
 343             int fragSize = count - position;
 344             int packetSize =
 345                     encCipher.calculatePacketSize(fragSize, macLen, headerSize);
 346             if (packetSize > (buf.length - position)) {
 347                 byte[] newBuf = new byte[position + packetSize];
 348                 System.arraycopy(buf, 0, newBuf, 0, count);
 349                 buf = newBuf;
 350             }
 351 
 352             // Encrypt may pad, so again the count may be changed.
 353             count = position +
 354                     encCipher.encrypt(buf, position, (count - position));
 355         }
 356 
 357         // Fill out the header, write it and the message.
 358         int fragLen = count - headerSize;
 359         buf[0] = contentType;
 360         buf[1] = protocolVersion.major;
 361         buf[2] = protocolVersion.minor;
 362         buf[3] = (byte)((fragLen >> 8) & 0xFF);
 363         buf[4] = (byte)(fragLen & 0xFF);
 364     }
 365 
 366     static ByteBuffer encodeV2ClientHello(
 367             byte[] fragment, int offset, int length) throws IOException {
 368 
 369         int v3SessIdLenOffset = offset + 34;      //  2: client_version
 370                                                   // 32: random
 371 
 372         int v3SessIdLen = fragment[v3SessIdLenOffset];
 373         int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen;
 374         int v3CSLen = ((fragment[v3CSLenOffset] & 0xff) << 8) +
 375                        (fragment[v3CSLenOffset + 1] & 0xff);
 376         int cipherSpecs = v3CSLen / 2;        // 2: cipher spec size
 377 
 378         // Estimate the max V2ClientHello message length
 379         //
 380         // 11: header size
 381         // (cipherSpecs * 6): cipher_specs
 382         //    6: one cipher suite may need 6 bytes, see V3toV2CipherSuite.
 383         // 3: placeholder for the TLS_EMPTY_RENEGOTIATION_INFO_SCSV
 384         //    signaling cipher suite
 385         // 32: challenge size
 386         int v2MaxMsgLen = 11 + (cipherSpecs * 6) + 3 + 32;
 387 
 388         // Create a ByteBuffer backed by an accessible byte array.
 389         byte[] dstBytes = new byte[v2MaxMsgLen];
 390         ByteBuffer dstBuf = ByteBuffer.wrap(dstBytes);
 391 
 392         /*
 393          * Copy over the cipher specs. We don't care about actually
 394          * translating them for use with an actual V2 server since
 395          * we only talk V3.  Therefore, just copy over the V3 cipher
 396          * spec values with a leading 0.
 397          */
 398         int v3CSOffset = v3CSLenOffset + 2;   // skip length field
 399         int v2CSLen = 0;
 400 
 401         dstBuf.position(11);
 402         boolean containsRenegoInfoSCSV = false;
 403         for (int i = 0; i < cipherSpecs; i++) {
 404             byte byte1, byte2;
 405 
 406             byte1 = fragment[v3CSOffset++];
 407             byte2 = fragment[v3CSOffset++];
 408             v2CSLen += V3toV2CipherSuite(dstBuf, byte1, byte2);
 409             if (!containsRenegoInfoSCSV &&
 410                     byte1 == (byte)0x00 && byte2 == (byte)0xFF) {
 411                 containsRenegoInfoSCSV = true;
 412             }
 413         }
 414 
 415         if (!containsRenegoInfoSCSV) {
 416             v2CSLen += V3toV2CipherSuite(dstBuf, (byte)0x00, (byte)0xFF);
 417         }
 418 
 419         /*
 420          * Copy in the nonce.
 421          */
 422         dstBuf.put(fragment, (offset + 2), 32);
 423 
 424         /*
 425          * Build the first part of the V3 record header from the V2 one
 426          * that's now buffered up.  (Lengths are fixed up later).
 427          */
 428         int msgLen = dstBuf.position() - 2;   // Exclude the legth field itself
 429         dstBuf.position(0);
 430         dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF)));  // pos: 0
 431         dstBuf.put((byte)(msgLen & 0xFF));                   // pos: 1
 432         dstBuf.put(HandshakeMessage.ht_client_hello);        // pos: 2
 433         dstBuf.put(fragment[offset]);         // major version, pos: 3
 434         dstBuf.put(fragment[offset + 1]);     // minor version, pos: 4
 435         dstBuf.put((byte)(v2CSLen >>> 8));                   // pos: 5
 436         dstBuf.put((byte)(v2CSLen & 0xFF));                  // pos: 6
 437         dstBuf.put((byte)0x00);           // session_id_length, pos: 7
 438         dstBuf.put((byte)0x00);                              // pos: 8
 439         dstBuf.put((byte)0x00);           // challenge_length,  pos: 9
 440         dstBuf.put((byte)32);                                // pos: 10
 441 
 442         dstBuf.position(0);
 443         dstBuf.limit(msgLen + 2);
 444 
 445         return dstBuf;
 446     }
 447 
 448     private static int V3toV2CipherSuite(ByteBuffer dstBuf,
 449             byte byte1, byte byte2) {
 450         dstBuf.put((byte)0);
 451         dstBuf.put(byte1);
 452         dstBuf.put(byte2);
 453 
 454         if (((byte2 & 0xff) > 0xA) || (V3toV2CipherMap1[byte2] == -1)) {
 455             return 3;
 456         }
 457 
 458         dstBuf.put((byte)V3toV2CipherMap1[byte2]);
 459         dstBuf.put((byte)0);
 460         dstBuf.put((byte)V3toV2CipherMap3[byte2]);
 461 
 462         return 6;
 463     }
 464 }