jdk/src/share/classes/sun/security/ssl/InputRecord.java
changeset 16067 36055e4b5305
parent 16045 9d08c3b9a6a0
child 16126 aad71cf676d7
equal deleted inserted replaced
16066:b9fb0d9c58ec 16067:36055e4b5305
     1 /*
     1 /*
     2  * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    75     private byte v2Buf[];
    75     private byte v2Buf[];
    76 
    76 
    77     /*
    77     /*
    78      * Construct the record to hold the maximum sized input record.
    78      * Construct the record to hold the maximum sized input record.
    79      * Data will be filled in separately.
    79      * Data will be filled in separately.
    80      *
       
    81      * The structure of the byte buffer looks like:
       
    82      *
       
    83      *     |--------+---------+---------------------------------|
       
    84      *     | header |   IV    | content, MAC/TAG, padding, etc. |
       
    85      *     | headerPlusIVSize |
       
    86      *
       
    87      * header: the header of an SSL records
       
    88      * IV:     the optional IV/nonce field, it is only required for block
       
    89      *         (TLS 1.1 or later) and AEAD cipher suites.
       
    90      *
       
    91      */
    80      */
    92     InputRecord() {
    81     InputRecord() {
    93         super(new byte[maxRecordSize]);
    82         super(new byte[maxRecordSize]);
    94         setHelloVersion(ProtocolVersion.DEFAULT_HELLO);
    83         setHelloVersion(ProtocolVersion.DEFAULT_HELLO);
    95         pos = headerSize;
    84         pos = headerSize;
   142 
   131 
   143     HandshakeHash getHandshakeHash() {
   132     HandshakeHash getHandshakeHash() {
   144         return handshakeHash;
   133         return handshakeHash;
   145     }
   134     }
   146 
   135 
   147     void decrypt(Authenticator authenticator,
   136     /*
   148             CipherBox box) throws BadPaddingException {
   137      * Verify and remove the MAC ... used for all records.
   149 
   138      */
   150         BadPaddingException bpe = null;
   139     boolean checkMAC(MAC signer) {
   151         if (!box.isNullCipher()) {
   140         int len = signer.MAClen();
   152             try {
   141         if (len == 0) { // no mac
   153                 int cipheredLength = count - headerSize;
   142             return true;
   154 
   143         }
   155                 // apply explicit nonce for AEAD/CBC cipher suites if needed
   144 
   156                 int nonceSize = box.applyExplicitNonce(authenticator,
   145         int offset = count - len;
   157                             contentType(), buf, headerSize, cipheredLength);
   146 
   158                 pos = headerSize + nonceSize;
   147         if (offset < headerSize) {
   159                 lastHashed = pos;   // don't digest the explicit nonce
   148             // data length would be negative, something is wrong
   160 
   149             return false;
   161                 // decrypt the content
   150         }
   162                 int offset = headerSize;
   151 
   163                 if (box.isAEADMode()) {
   152         byte[] mac = signer.compute(contentType(), buf,
   164                     // DON'T encrypt the nonce_explicit for AEAD mode
   153             headerSize, offset - headerSize);
   165                     offset += nonceSize;
   154 
   166                 }   // The explicit IV for CBC mode can be decrypted.
   155         if (len != mac.length) {
   167 
   156             throw new RuntimeException("Internal MAC error");
   168                 count = offset + box.decrypt(buf, offset, count - offset);
   157         }
   169 
   158 
   170                 // Note that we don't remove the nonce from the buffer.
   159         for (int i = 0; i < len; i++) {
   171             } catch (BadPaddingException e) {
   160             if (buf[offset + i] != mac[i]) {
   172                 // RFC 2246 states that decryption_failed should be used
   161                 return false;
   173                 // for this purpose. However, that allows certain attacks,
   162             }
   174                 // so we just send bad record MAC. We also need to make
   163         }
   175                 // sure to always check the MAC to avoid a timing attack
   164         count -= len;
   176                 // for the same issue. See paper by Vaudenay et al and the
   165         return true;
   177                 // update in RFC 4346/5246.
   166     }
   178                 //
   167 
   179                 // Failover to message authenticatoin code checking.
   168     void decrypt(CipherBox box) throws BadPaddingException {
   180                 bpe = new BadPaddingException("invalid padding");
   169         int len = count - headerSize;
   181             }
   170         count = headerSize + box.decrypt(buf, headerSize, len);
   182         }
   171     }
   183 
   172 
   184         // Requires message authentication code for null, stream and block
       
   185         // cipher suites.
       
   186         if (authenticator instanceof MAC) {
       
   187             MAC signer = (MAC)authenticator;
       
   188             int macLen = signer.MAClen();
       
   189             if (macLen != 0) {
       
   190                 int macOffset = count - macLen;
       
   191                 int contentLen = macOffset - pos;
       
   192                 if (contentLen < 0) {
       
   193                     // negative data length, something is wrong
       
   194                     throw new BadPaddingException("bad record");
       
   195                 }
       
   196 
       
   197                 count -= macLen;  // Set the count before any MAC checking
       
   198                                   // exception occurs, so that the following
       
   199                                   // process can read the actual decrypted
       
   200                                   // content (minus the MAC) in the fragment
       
   201                                   // if necessary.
       
   202                 byte[] hash = signer.compute(contentType(),
       
   203                                             buf, pos, contentLen);
       
   204                 if (hash == null || macLen != hash.length) {
       
   205                     // something is wrong with MAC implementation
       
   206                     throw new RuntimeException("Internal MAC error");
       
   207                 }
       
   208 
       
   209                 int offset = macOffset;
       
   210                 for (byte b : hash) {
       
   211                     if (buf[offset++] != b) {
       
   212                         throw new BadPaddingException("bad record MAC");
       
   213                     }
       
   214                 }
       
   215             }
       
   216         }
       
   217 
       
   218         // Is it a failover?
       
   219         if (bpe != null) {
       
   220             throw bpe;
       
   221         }
       
   222     }
       
   223 
   173 
   224     /*
   174     /*
   225      * Well ... hello_request messages are _never_ hashed since we can't
   175      * Well ... hello_request messages are _never_ hashed since we can't
   226      * know when they'd appear in the sequence.
   176      * know when they'd appear in the sequence.
   227      */
   177      */