1 /*
   2  * Copyright (c) 1996, 2014, 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.*;
  31 
  32 import javax.crypto.BadPaddingException;
  33 
  34 import javax.net.ssl.*;
  35 
  36 import sun.security.util.HexDumpEncoder;
  37 
  38 
  39 /**
  40  * {@code InputRecord} takes care of the management of SSL/TLS/DTLS input
  41  * records, including buffering, decryption, handshake messages marshal, etc.
  42  *
  43  * @author David Brownell
  44  */
  45 class InputRecord implements Record, Closeable {
  46 
  47     /* Class and subclass dynamic debugging support */
  48     static final Debug debug = Debug.getInstance("ssl");
  49 
  50     Authenticator       readAuthenticator;
  51     CipherBox           readCipher;
  52 
  53     HandshakeHash       handshakeHash;
  54     boolean             isClosed;
  55 
  56     // The ClientHello version to accept. If set to ProtocolVersion.SSL20Hello
  57     // and the first message we read is a ClientHello in V2 format, we convert
  58     // it to V3. Otherwise we throw an exception when encountering a V2 hello.
  59     ProtocolVersion     helloVersion;
  60 
  61     // fragment size
  62     int                 fragmentSize;
  63 
  64     InputRecord() {
  65         this.readCipher = CipherBox.NULL;
  66         this.readAuthenticator = null;      // Please override this assignment.
  67         this.helloVersion = ProtocolVersion.DEFAULT_HELLO;
  68         this.fragmentSize = Record.maxDataSize;
  69     }
  70 
  71     void setHelloVersion(ProtocolVersion helloVersion) {
  72         this.helloVersion = helloVersion;
  73     }
  74 
  75     ProtocolVersion getHelloVersion() {
  76         return helloVersion;
  77     }
  78 
  79     /*
  80      * Set instance for the computation of handshake hashes.
  81      *
  82      * For handshaking, we need to be able to hash every byte above the
  83      * record marking layer.  This is where we're guaranteed to see those
  84      * bytes, so this is where we can hash them ... especially in the
  85      * case of hashing the initial V2 message!
  86      */
  87     void setHandshakeHash(HandshakeHash handshakeHash) {
  88         if (handshakeHash != null) {
  89             byte[] reserved = null;
  90             if (this.handshakeHash != null) {
  91                 reserved = this.handshakeHash.getAllHandshakeMessages();
  92             }
  93             if ((reserved != null) && (reserved.length != 0)) {
  94                 handshakeHash.update(reserved, 0, reserved.length);
  95 
  96                if (debug != null && Debug.isOn("data")) {
  97                     Debug.printHex(
  98                         "[reserved] handshake hash: len = " + reserved.length,
  99                         reserved);
 100                }
 101             }
 102         }
 103 
 104         this.handshakeHash = handshakeHash;
 105     }
 106 
 107     boolean seqNumIsHuge() {
 108         return (readAuthenticator != null) &&
 109                         readAuthenticator.seqNumIsHuge();
 110     }
 111 
 112     boolean isEmpty() {
 113         return false;
 114     }
 115 
 116     // apply to DTLS SSLEngine
 117     void expectingFinishFlight() {
 118         // blank
 119     }
 120 
 121     /**
 122      * Prevent any more data from being read into this record,
 123      * and flag the record as holding no data.
 124      */
 125     @Override
 126     public synchronized void close() throws IOException {
 127         if (!isClosed) {
 128             isClosed = true;
 129             readCipher.dispose();
 130         }
 131     }
 132 
 133     // apply to SSLSocket and SSLEngine
 134     void changeReadCiphers(
 135             Authenticator readAuthenticator, CipherBox readCipher) {
 136 
 137         /*
 138          * Dispose of any intermediate state in the underlying cipher.
 139          * For PKCS11 ciphers, this will release any attached sessions,
 140          * and thus make finalization faster.
 141          *
 142          * Since MAC's doFinal() is called for every SSL/TLS packet, it's
 143          * not necessary to do the same with MAC's.
 144          */
 145         readCipher.dispose();
 146 
 147         this.readAuthenticator = readAuthenticator;
 148         this.readCipher = readCipher;
 149     }
 150 
 151     // change fragment size
 152     void changeFragmentSize(int fragmentSize) {
 153         this.fragmentSize = fragmentSize;
 154     }
 155 
 156     /*
 157      * Check if there is enough inbound data in the ByteBuffer to make
 158      * a inbound packet.
 159      *
 160      * @return -1 if there are not enough bytes to tell (small header),
 161      */
 162     // apply to SSLEngine only
 163     int bytesInCompletePacket(ByteBuffer buf) throws SSLException {
 164         throw new UnsupportedOperationException();
 165     }
 166 
 167     // apply to SSLSocket only
 168     int bytesInCompletePacket(InputStream is) throws IOException {
 169         throw new UnsupportedOperationException();
 170     }
 171 
 172     /**
 173      * Return true if the specified record protocol version is out of the
 174      * range of the possible supported versions.
 175      */
 176     void checkRecordVersion(ProtocolVersion version,
 177             boolean allowSSL20Hello) throws SSLException {
 178         // blank
 179     }
 180 
 181     // apply to DTLS SSLEngine only
 182     Plaintext acquirePlaintext()
 183             throws IOException, BadPaddingException {
 184         throw new UnsupportedOperationException();
 185     }
 186 
 187     // read, decrypt and decompress the network record.
 188     //
 189     // apply to SSLEngine only
 190     Plaintext decode(ByteBuffer netData)
 191             throws IOException, BadPaddingException {
 192         throw new UnsupportedOperationException();
 193     }
 194 
 195     // apply to SSLSocket only
 196     Plaintext decode(InputStream is, ByteBuffer destination)
 197             throws IOException, BadPaddingException {
 198         throw new UnsupportedOperationException();
 199     }
 200 
 201     // apply to SSLSocket only
 202     void setDeliverStream(OutputStream outputStream) {
 203         throw new UnsupportedOperationException();
 204     }
 205 
 206     // calculate plaintext fragment size
 207     //
 208     // apply to SSLEngine only
 209     int estimateFragmentSize(int packetSize) {
 210         throw new UnsupportedOperationException();
 211     }
 212 
 213     //
 214     // shared helpers
 215     //
 216 
 217     // Not apply to DTLS
 218     static ByteBuffer convertToClientHello(ByteBuffer packet) {
 219 
 220         int srcPos = packet.position();
 221         int srcLim = packet.limit();
 222 
 223         byte firstByte = packet.get();
 224         byte secondByte = packet.get();
 225         int recordLen = (((firstByte & 0x7F) << 8) | (secondByte & 0xFF)) + 2;
 226 
 227         packet.position(srcPos + 3);        // the V2ClientHello record header
 228 
 229         byte majorVersion = packet.get();
 230         byte minorVersion = packet.get();
 231 
 232         int cipherSpecLen = ((packet.get() & 0xFF) << 8) +
 233                              (packet.get() & 0xFF);
 234         int sessionIdLen  = ((packet.get() & 0xFF) << 8) +
 235                              (packet.get() & 0xFF);
 236         int nonceLen      = ((packet.get() & 0xFF) << 8) +
 237                              (packet.get() & 0xFF);
 238 
 239         // Required space for the target SSLv3 ClientHello message.
 240         //  5: record header size
 241         //  4: handshake header size
 242         //  2: ClientHello.client_version
 243         // 32: ClientHello.random
 244         //  1: length byte of ClientHello.session_id
 245         //  2: length bytes of ClientHello.cipher_suites
 246         //  2: empty ClientHello.compression_methods
 247         int requiredSize = 48 + sessionIdLen + ((cipherSpecLen * 2 ) / 3 );
 248         byte[] converted = new byte[requiredSize];
 249 
 250         /*
 251          * Build the first part of the V3 record header from the V2 one
 252          * that's now buffered up.  (Lengths are fixed up later).
 253          */
 254         // Note: need not to set the header actually.
 255         converted[0] = ct_handshake;
 256         converted[1] = majorVersion;
 257         converted[2] = minorVersion;
 258         // header [3..4] for handshake message length
 259         // required size is 5;
 260 
 261         /*
 262          * Store the generic V3 handshake header:  4 bytes
 263          */
 264         converted[5] = 1;    // HandshakeMessage.ht_client_hello
 265         // buf [6..8] for length of ClientHello (int24)
 266         // required size += 4;
 267 
 268         /*
 269          * ClientHello header starts with SSL version
 270          */
 271         converted[9] = majorVersion;
 272         converted[10] = minorVersion;
 273         // required size += 2;
 274         int pointer = 11;
 275 
 276         /*
 277          * Copy Random value/nonce ... if less than the 32 bytes of
 278          * a V3 "Random", right justify and zero pad to the left.  Else
 279          * just take the last 32 bytes.
 280          */
 281         int offset = srcPos + 11 + cipherSpecLen + sessionIdLen;
 282 
 283         if (nonceLen < 32) {
 284             for (int i = 0; i < (32 - nonceLen); i++) {
 285                 converted[pointer++] = 0;
 286             }
 287             packet.position(offset);
 288             packet.get(converted, pointer, nonceLen);
 289 
 290             pointer += nonceLen;
 291         } else {
 292             packet.position(offset + nonceLen - 32);
 293             packet.get(converted, pointer, 32);
 294 
 295             pointer += 32;
 296         }
 297 
 298         /*
 299          * Copy session ID (only one byte length!)
 300          */
 301         offset -= sessionIdLen;
 302         converted[pointer++] = (byte)(sessionIdLen & 0xFF);
 303         packet.position(offset);
 304         packet.get(converted, pointer, sessionIdLen);
 305 
 306         /*
 307          * Copy and translate cipher suites ... V2 specs with first byte zero
 308          * are really V3 specs (in the last 2 bytes), just copy those and drop
 309          * the other ones.  Preference order remains unchanged.
 310          *
 311          * Example:  Netscape Navigator 3.0 (exportable) says:
 312          *
 313          * 0/3,     SSL_RSA_EXPORT_WITH_RC4_40_MD5
 314          * 0/6,     SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
 315          *
 316          * Microsoft Internet Explorer 3.0 (exportable) supports only
 317          *
 318          * 0/3,     SSL_RSA_EXPORT_WITH_RC4_40_MD5
 319          */
 320         int j;
 321 
 322         offset -= cipherSpecLen;
 323         packet.position(offset);
 324 
 325         j = pointer + 2;
 326         for (int i = 0; i < cipherSpecLen; i += 3) {
 327             if (packet.get() != 0) {
 328                 // Ignore version 2.0 specifix cipher suite.  Clients
 329                 // should also include the version 3.0 equivalent in
 330                 // the V2ClientHello message.
 331                 packet.get();           // ignore the 2nd byte
 332                 packet.get();           // ignore the 3rd byte
 333                 continue;
 334             }
 335 
 336             converted[j++] = packet.get();
 337             converted[j++] = packet.get();
 338         }
 339 
 340         j -= pointer + 2;
 341         converted[pointer++] = (byte)((j >>> 8) & 0xFF);
 342         converted[pointer++] = (byte)(j & 0xFF);
 343         pointer += j;
 344 
 345         /*
 346          * Append compression methods (default/null only)
 347          */
 348         converted[pointer++] = 1;
 349         converted[pointer++] = 0;      // Session.compression_null
 350 
 351         /*
 352          * Fill in lengths of the messages we synthesized (nested:
 353          * V3 handshake message within V3 record).
 354          */
 355         // Note: need not to set the header actually.
 356         int fragLen = pointer - 5;                      // TLSPlaintext.length
 357         converted[3] = (byte)((fragLen >>> 8) & 0xFF);
 358         converted[4] = (byte)(fragLen & 0xFF);
 359 
 360         /*
 361          * Handshake.length, length of ClientHello message
 362          */
 363         fragLen = pointer - 9;                          // Handshake.length
 364         converted[6] = (byte)((fragLen >>> 16) & 0xFF);
 365         converted[7] = (byte)((fragLen >>> 8) & 0xFF);
 366         converted[8] = (byte)(fragLen & 0xFF);
 367 
 368         // consume the full record
 369         packet.position(srcPos + recordLen);
 370 
 371         // Need no header bytes.
 372         return ByteBuffer.wrap(converted, 5, pointer - 5);  // 5: header size
 373     }
 374 
 375     static ByteBuffer decrypt(Authenticator authenticator, CipherBox box,
 376             byte contentType, ByteBuffer bb) throws BadPaddingException {
 377 
 378         return decrypt(authenticator, box, contentType, bb, null);
 379     }
 380 
 381     static ByteBuffer decrypt(Authenticator authenticator,
 382             CipherBox box, byte contentType, ByteBuffer bb,
 383             byte[] sequence) throws BadPaddingException {
 384 
 385         BadPaddingException reservedBPE = null;
 386         int tagLen =
 387             (authenticator instanceof MAC) ? ((MAC)authenticator).MAClen() : 0;
 388         int cipheredLength = bb.remaining();
 389         int srcPos = bb.position();
 390         if (!box.isNullCipher()) {
 391             try {
 392                 // apply explicit nonce for AEAD/CBC cipher suites if needed
 393                 int nonceSize = box.applyExplicitNonce(
 394                         authenticator, contentType, bb, sequence);
 395 
 396                 // decrypt the content
 397                 if (box.isAEADMode()) {
 398                     // DON'T decrypt the nonce_explicit for AEAD mode
 399                     bb.position(srcPos + nonceSize);
 400                 }   // The explicit IV for CBC mode can be decrypted.
 401 
 402                 // Note that the CipherBox.decrypt() does not change
 403                 // the capacity of the buffer.
 404                 box.decrypt(bb, tagLen);
 405                 // We don't actually remove the nonce.
 406                 bb.position(srcPos + nonceSize);
 407             } catch (BadPaddingException bpe) {
 408                 // RFC 2246 states that decryption_failed should be used
 409                 // for this purpose. However, that allows certain attacks,
 410                 // so we just send bad record MAC. We also need to make
 411                 // sure to always check the MAC to avoid a timing attack
 412                 // for the same issue. See paper by Vaudenay et al and the
 413                 // update in RFC 4346/5246.
 414                 //
 415                 // Failover to message authentication code checking.
 416                 reservedBPE = bpe;
 417             }
 418         }
 419 
 420         // Requires message authentication code for null, stream and block
 421         // cipher suites.
 422         if ((authenticator instanceof MAC) && (tagLen != 0)) {
 423             MAC signer = (MAC)authenticator;
 424             int contentLen = bb.remaining() - tagLen;
 425 
 426             // Note that although it is not necessary, we run the same MAC
 427             // computation and comparison on the payload for both stream
 428             // cipher and CBC block cipher.
 429             if (contentLen < 0) {
 430                 // negative data length, something is wrong
 431                 if (reservedBPE == null) {
 432                     reservedBPE = new BadPaddingException("bad record");
 433                 }
 434 
 435                 // set offset of the dummy MAC
 436                 contentLen = cipheredLength - tagLen;
 437                 bb.limit(srcPos + cipheredLength);
 438             }
 439 
 440             // Run MAC computation and comparison on the payload.
 441             //
 442             // MAC data would be stripped off during the check.
 443             if (checkMacTags(contentType, bb, signer, sequence, false)) {
 444                 if (reservedBPE == null) {
 445                     reservedBPE = new BadPaddingException("bad record MAC");
 446                 }
 447             }
 448 
 449             // Run MAC computation and comparison on the remainder.
 450             //
 451             // It is only necessary for CBC block cipher.  It is used to get a
 452             // constant time of MAC computation and comparison on each record.
 453             if (box.isCBCMode()) {
 454                 int remainingLen = calculateRemainingLen(
 455                                         signer, cipheredLength, contentLen);
 456 
 457                 // NOTE: remainingLen may be bigger (less than 1 block of the
 458                 // hash algorithm of the MAC) than the cipheredLength.
 459                 //
 460                 // Is it possible to use a static buffer, rather than allocate
 461                 // it dynamically?
 462                 remainingLen += signer.MAClen();
 463                 ByteBuffer temporary = ByteBuffer.allocate(remainingLen);
 464 
 465                 // Won't need to worry about the result on the remainder. And
 466                 // then we won't need to worry about what's actual data to
 467                 // check MAC tag on.  We start the check from the header of the
 468                 // buffer so that we don't need to construct a new byte buffer.
 469                 checkMacTags(contentType, temporary, signer, sequence, true);
 470             }
 471         }
 472 
 473         // Is it a failover?
 474         if (reservedBPE != null) {
 475             throw reservedBPE;
 476         }
 477 
 478         return bb.slice();
 479     }
 480 
 481     /*
 482      * Run MAC computation and comparison
 483      *
 484      */
 485     private static boolean checkMacTags(byte contentType, ByteBuffer bb,
 486             MAC signer, byte[] sequence, boolean isSimulated) {
 487 
 488         int tagLen = signer.MAClen();
 489         int position = bb.position();
 490         int lim = bb.limit();
 491         int macOffset = lim - tagLen;
 492 
 493         bb.limit(macOffset);
 494         byte[] hash = signer.compute(contentType, bb, sequence, isSimulated);
 495         if (hash == null || tagLen != hash.length) {
 496             // Something is wrong with MAC implementation.
 497             throw new RuntimeException("Internal MAC error");
 498         }
 499 
 500         bb.position(macOffset);
 501         bb.limit(lim);
 502         try {
 503             int[] results = compareMacTags(bb, hash);
 504             return (results[0] != 0);
 505         } finally {
 506             // reset to the data
 507             bb.position(position);
 508             bb.limit(macOffset);
 509         }
 510     }
 511 
 512     /*
 513      * A constant-time comparison of the MAC tags.
 514      *
 515      * Please DON'T change the content of the ByteBuffer parameter!
 516      */
 517     private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
 518 
 519         // An array of hits is used to prevent Hotspot optimization for
 520         // the purpose of a constant-time check.
 521         int[] results = {0, 0};     // {missed #, matched #}
 522 
 523         // The caller ensures there are enough bytes available in the buffer.
 524         // So we won't need to check the remaining of the buffer.
 525         for (int i = 0; i < tag.length; i++) {
 526             if (bb.get() != tag[i]) {
 527                 results[0]++;       // mismatched bytes
 528             } else {
 529                 results[1]++;       // matched bytes
 530             }
 531         }
 532 
 533         return results;
 534     }
 535 
 536     /*
 537      * Run MAC computation and comparison
 538      *
 539      * Please DON'T change the content of the byte buffer parameter!
 540      */
 541     private static boolean checkMacTags(byte contentType, byte[] buffer,
 542             int offset, int contentLen, MAC signer, boolean isSimulated) {
 543 
 544         int tagLen = signer.MAClen();
 545         byte[] hash = signer.compute(
 546                 contentType, buffer, offset, contentLen, isSimulated);
 547         if (hash == null || tagLen != hash.length) {
 548             // Something is wrong with MAC implementation.
 549             throw new RuntimeException("Internal MAC error");
 550         }
 551 
 552         int[] results = compareMacTags(buffer, offset + contentLen, hash);
 553         return (results[0] != 0);
 554     }
 555 
 556     /*
 557      * A constant-time comparison of the MAC tags.
 558      *
 559      * Please DON'T change the content of the byte buffer parameter!
 560      */
 561     private static int[] compareMacTags(
 562             byte[] buffer, int offset, byte[] tag) {
 563 
 564         // An array of hits is used to prevent Hotspot optimization for
 565         // the purpose of a constant-time check.
 566         int[] results = {0, 0};    // {missed #, matched #}
 567 
 568         // The caller ensures there are enough bytes available in the buffer.
 569         // So we won't need to check the length of the buffer.
 570         for (int i = 0; i < tag.length; i++) {
 571             if (buffer[offset + i] != tag[i]) {
 572                 results[0]++;       // mismatched bytes
 573             } else {
 574                 results[1]++;       // matched bytes
 575             }
 576         }
 577 
 578         return results;
 579     }
 580 
 581     /*
 582      * Calculate the length of a dummy buffer to run MAC computation
 583      * and comparison on the remainder.
 584      *
 585      * The caller MUST ensure that the fullLen is not less than usedLen.
 586      */
 587     private static int calculateRemainingLen(
 588             MAC signer, int fullLen, int usedLen) {
 589 
 590         int blockLen = signer.hashBlockLen();
 591         int minimalPaddingLen = signer.minimalPaddingLen();
 592 
 593         // (blockLen - minimalPaddingLen) is the maximum message size of
 594         // the last block of hash function operation. See FIPS 180-4, or
 595         // MD5 specification.
 596         fullLen += 13 - (blockLen - minimalPaddingLen);
 597         usedLen += 13 - (blockLen - minimalPaddingLen);
 598 
 599         // Note: fullLen is always not less than usedLen, and blockLen
 600         // is always bigger than minimalPaddingLen, so we don't worry
 601         // about negative values. 0x01 is added to the result to ensure
 602         // that the return value is positive.  The extra one byte does
 603         // not impact the overall MAC compression function evaluations.
 604         return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
 605                 Math.ceil(usedLen/(1.0d * blockLen))) * blockLen;
 606     }
 607 }
 608