jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java
changeset 16913 a6f4d1626ad9
parent 16126 aad71cf676d7
child 24263 f95477ce56e4
equal deleted inserted replaced
16911:6cc48540fcd7 16913:a6f4d1626ad9
   184      * If internal data, data is decrypted internally.
   184      * If internal data, data is decrypted internally.
   185      *
   185      *
   186      * If external data(app), return a new ByteBuffer with data to
   186      * If external data(app), return a new ByteBuffer with data to
   187      * process.
   187      * process.
   188      */
   188      */
   189     ByteBuffer decrypt(MAC signer,
   189     ByteBuffer decrypt(Authenticator authenticator,
   190             CipherBox box, ByteBuffer bb) throws BadPaddingException {
   190             CipherBox box, ByteBuffer bb) throws BadPaddingException {
   191 
   191 
   192         if (internalData) {
   192         if (internalData) {
   193             decrypt(signer, box);   // MAC is checked during decryption
   193             decrypt(authenticator, box);   // MAC is checked during decryption
   194             return tmpBB;
   194             return tmpBB;
   195         }
   195         }
   196 
   196 
   197         BadPaddingException reservedBPE = null;
   197         BadPaddingException reservedBPE = null;
   198         int tagLen = signer.MAClen();
   198         int tagLen =
       
   199             (authenticator instanceof MAC) ? ((MAC)authenticator).MAClen() : 0;
   199         int cipheredLength = bb.remaining();
   200         int cipheredLength = bb.remaining();
   200 
   201 
   201         if (!box.isNullCipher()) {
   202         if (!box.isNullCipher()) {
   202             // sanity check length of the ciphertext
       
   203             if (!box.sanityCheck(tagLen, cipheredLength)) {
       
   204                 throw new BadPaddingException(
       
   205                     "ciphertext sanity check failed");
       
   206             }
       
   207 
       
   208             try {
   203             try {
       
   204                 // apply explicit nonce for AEAD/CBC cipher suites if needed
       
   205                 int nonceSize =
       
   206                     box.applyExplicitNonce(authenticator, contentType(), bb);
       
   207 
       
   208                 // decrypt the content
       
   209                 if (box.isAEADMode()) {
       
   210                     // DON'T encrypt the nonce_explicit for AEAD mode
       
   211                     bb.position(bb.position() + nonceSize);
       
   212                 }   // The explicit IV for CBC mode can be decrypted.
       
   213 
   209                 // Note that the CipherBox.decrypt() does not change
   214                 // Note that the CipherBox.decrypt() does not change
   210                 // the capacity of the buffer.
   215                 // the capacity of the buffer.
   211                 box.decrypt(bb, tagLen);
   216                 box.decrypt(bb, tagLen);
       
   217                 bb.position(nonceSize); // We don't actually remove the nonce.
   212             } catch (BadPaddingException bpe) {
   218             } catch (BadPaddingException bpe) {
   213                 // RFC 2246 states that decryption_failed should be used
   219                 // RFC 2246 states that decryption_failed should be used
   214                 // for this purpose. However, that allows certain attacks,
   220                 // for this purpose. However, that allows certain attacks,
   215                 // so we just send bad record MAC. We also need to make
   221                 // so we just send bad record MAC. We also need to make
   216                 // sure to always check the MAC to avoid a timing attack
   222                 // sure to always check the MAC to avoid a timing attack
   217                 // for the same issue. See paper by Vaudenay et al and the
   223                 // for the same issue. See paper by Vaudenay et al and the
   218                 // update in RFC 4346/5246.
   224                 // update in RFC 4346/5246.
   219                 //
   225                 //
   220                 // Failover to message authentication code checking.
   226                 // Failover to message authentication code checking.
   221                 reservedBPE = bpe;
   227                 reservedBPE = bpe;
   222             } finally {
   228             }
   223                 bb.rewind();
   229         }
   224             }
   230 
   225         }
   231         // Requires message authentication code for null, stream and block
   226 
   232         // cipher suites.
   227         if (tagLen != 0) {
   233         if ((authenticator instanceof MAC) && (tagLen != 0)) {
       
   234             MAC signer = (MAC)authenticator;
   228             int macOffset = bb.limit() - tagLen;
   235             int macOffset = bb.limit() - tagLen;
   229 
   236 
   230             // Note that although it is not necessary, we run the same MAC
   237             // Note that although it is not necessary, we run the same MAC
   231             // computation and comparison on the payload for both stream
   238             // computation and comparison on the payload for both stream
   232             // cipher and CBC block cipher.
   239             // cipher and CBC block cipher.
   295      * Please DON'T change the content of the ByteBuffer parameter!
   302      * Please DON'T change the content of the ByteBuffer parameter!
   296      */
   303      */
   297     private static boolean checkMacTags(byte contentType, ByteBuffer bb,
   304     private static boolean checkMacTags(byte contentType, ByteBuffer bb,
   298             MAC signer, boolean isSimulated) {
   305             MAC signer, boolean isSimulated) {
   299 
   306 
       
   307         int position = bb.position();
   300         int tagLen = signer.MAClen();
   308         int tagLen = signer.MAClen();
   301         int lim = bb.limit();
   309         int lim = bb.limit();
   302         int macData = lim - tagLen;
   310         int macData = lim - tagLen;
   303 
   311 
   304         bb.limit(macData);
   312         bb.limit(macData);
   312         bb.limit(lim);
   320         bb.limit(lim);
   313         try {
   321         try {
   314             int[] results = compareMacTags(bb, hash);
   322             int[] results = compareMacTags(bb, hash);
   315             return (results[0] != 0);
   323             return (results[0] != 0);
   316         } finally {
   324         } finally {
   317             bb.rewind();
   325             // reset to the data
       
   326             bb.position(position);
   318             bb.limit(macData);
   327             bb.limit(macData);
   319         }
   328         }
   320     }
   329     }
   321 
   330 
   322     /*
   331     /*
   414         assert(len > 0);
   423         assert(len > 0);
   415 
   424 
   416         if (debug != null && Debug.isOn("packet")) {
   425         if (debug != null && Debug.isOn("packet")) {
   417             try {
   426             try {
   418                 HexDumpEncoder hd = new HexDumpEncoder();
   427                 HexDumpEncoder hd = new HexDumpEncoder();
   419                 srcBB.limit(srcPos + len);
       
   420                 ByteBuffer bb = srcBB.duplicate();  // Use copy of BB
   428                 ByteBuffer bb = srcBB.duplicate();  // Use copy of BB
       
   429                 bb.limit(srcPos + len);
   421 
   430 
   422                 System.out.println("[Raw read (bb)]: length = " + len);
   431                 System.out.println("[Raw read (bb)]: length = " + len);
   423                 hd.encodeBuffer(bb, System.out);
   432                 hd.encodeBuffer(bb, System.out);
   424             } catch (IOException e) { }
   433             } catch (IOException e) { }
   425         }
   434         }