jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
changeset 16913 a6f4d1626ad9
parent 16126 aad71cf676d7
child 19823 f0fd09e20528
equal deleted inserted replaced
16911:6cc48540fcd7 16913:a6f4d1626ad9
   278     private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
   278     private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
   279 
   279 
   280     /*
   280     /*
   281      * Crypto state that's reinitialized when the session changes.
   281      * Crypto state that's reinitialized when the session changes.
   282      */
   282      */
   283     private MAC                 readMAC, writeMAC;
   283     private Authenticator       readAuthenticator, writeAuthenticator;
   284     private CipherBox           readCipher, writeCipher;
   284     private CipherBox           readCipher, writeCipher;
   285     // NOTE: compression state would be saved here
   285     // NOTE: compression state would be saved here
   286 
   286 
   287     /*
   287     /*
   288      * security parameters for secure renegotiation.
   288      * security parameters for secure renegotiation.
   375          * default read and write side cipher and MAC support
   375          * default read and write side cipher and MAC support
   376          *
   376          *
   377          * Note:  compression support would go here too
   377          * Note:  compression support would go here too
   378          */
   378          */
   379         readCipher = CipherBox.NULL;
   379         readCipher = CipherBox.NULL;
   380         readMAC = MAC.NULL;
   380         readAuthenticator = MAC.NULL;
   381         writeCipher = CipherBox.NULL;
   381         writeCipher = CipherBox.NULL;
   382         writeMAC = MAC.NULL;
   382         writeAuthenticator = MAC.NULL;
   383 
   383 
   384         // default security parameters for secure renegotiation
   384         // default security parameters for secure renegotiation
   385         secureRenegotiation = false;
   385         secureRenegotiation = false;
   386         clientVerifyData = new byte[0];
   386         clientVerifyData = new byte[0];
   387         serverVerifyData = new byte[0];
   387         serverVerifyData = new byte[0];
   584 
   584 
   585         CipherBox oldCipher = readCipher;
   585         CipherBox oldCipher = readCipher;
   586 
   586 
   587         try {
   587         try {
   588             readCipher = handshaker.newReadCipher();
   588             readCipher = handshaker.newReadCipher();
   589             readMAC = handshaker.newReadMAC();
   589             readAuthenticator = handshaker.newReadAuthenticator();
   590         } catch (GeneralSecurityException e) {
   590         } catch (GeneralSecurityException e) {
   591             // "can't happen"
   591             // "can't happen"
   592             throw new SSLException("Algorithm missing:  ", e);
   592             throw new SSLException("Algorithm missing:  ", e);
   593         }
   593         }
   594 
   594 
   620 
   620 
   621         CipherBox oldCipher = writeCipher;
   621         CipherBox oldCipher = writeCipher;
   622 
   622 
   623         try {
   623         try {
   624             writeCipher = handshaker.newWriteCipher();
   624             writeCipher = handshaker.newWriteCipher();
   625             writeMAC = handshaker.newWriteMAC();
   625             writeAuthenticator = handshaker.newWriteAuthenticator();
   626         } catch (GeneralSecurityException e) {
   626         } catch (GeneralSecurityException e) {
   627             // "can't happen"
   627             // "can't happen"
   628             throw new SSLException("Algorithm missing:  ", e);
   628             throw new SSLException("Algorithm missing:  ", e);
   629         }
   629         }
   630 
   630 
   956              * encryption for privacy, and an integrity check ensuring
   956              * encryption for privacy, and an integrity check ensuring
   957              * data origin authentication.  We do them both here, and
   957              * data origin authentication.  We do them both here, and
   958              * throw a fatal alert if the integrity check fails.
   958              * throw a fatal alert if the integrity check fails.
   959              */
   959              */
   960             try {
   960             try {
   961                 decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
   961                 decryptedBB = inputRecord.decrypt(
       
   962                                     readAuthenticator, readCipher, readBB);
   962             } catch (BadPaddingException e) {
   963             } catch (BadPaddingException e) {
   963                 byte alertType = (inputRecord.contentType() ==
   964                 byte alertType = (inputRecord.contentType() ==
   964                     Record.ct_handshake) ?
   965                     Record.ct_handshake) ?
   965                         Alerts.alert_handshake_failure :
   966                         Alerts.alert_handshake_failure :
   966                         Alerts.alert_bad_record_mac;
   967                         Alerts.alert_bad_record_mac;
   967                 fatal(alertType, e.getMessage(), e);
   968                 fatal(alertType, e.getMessage(), e);
   968             }
   969             }
   969 
       
   970 
   970 
   971             // if (!inputRecord.decompress(c))
   971             // if (!inputRecord.decompress(c))
   972             //     fatal(Alerts.alert_decompression_failure,
   972             //     fatal(Alerts.alert_decompression_failure,
   973             //     "decompression failure");
   973             //     "decompression failure");
   974 
   974 
  1115                  * of the last record cannot be wrapped.
  1115                  * of the last record cannot be wrapped.
  1116                  */
  1116                  */
  1117                 hsStatus = getHSStatus(hsStatus);
  1117                 hsStatus = getHSStatus(hsStatus);
  1118                 if (connectionState < cs_ERROR && !isInboundDone() &&
  1118                 if (connectionState < cs_ERROR && !isInboundDone() &&
  1119                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
  1119                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
  1120                     if (checkSequenceNumber(readMAC,
  1120                     if (checkSequenceNumber(readAuthenticator,
  1121                             inputRecord.contentType())) {
  1121                             inputRecord.contentType())) {
  1122                         hsStatus = getHSStatus(null);
  1122                         hsStatus = getHSStatus(null);
  1123                     }
  1123                     }
  1124                 }
  1124                 }
  1125             } // synchronized (this)
  1125             } // synchronized (this)
  1268     private HandshakeStatus writeRecord(EngineOutputRecord eor,
  1268     private HandshakeStatus writeRecord(EngineOutputRecord eor,
  1269             EngineArgs ea) throws IOException {
  1269             EngineArgs ea) throws IOException {
  1270 
  1270 
  1271         // eventually compress as well.
  1271         // eventually compress as well.
  1272         HandshakeStatus hsStatus =
  1272         HandshakeStatus hsStatus =
  1273                 writer.writeRecord(eor, ea, writeMAC, writeCipher);
  1273                 writer.writeRecord(eor, ea, writeAuthenticator, writeCipher);
  1274 
  1274 
  1275         /*
  1275         /*
  1276          * We only need to check the sequence number state for
  1276          * We only need to check the sequence number state for
  1277          * non-handshaking record.
  1277          * non-handshaking record.
  1278          *
  1278          *
  1285          * of the last record cannot be wrapped.
  1285          * of the last record cannot be wrapped.
  1286          */
  1286          */
  1287         hsStatus = getHSStatus(hsStatus);
  1287         hsStatus = getHSStatus(hsStatus);
  1288         if (connectionState < cs_ERROR && !isOutboundDone() &&
  1288         if (connectionState < cs_ERROR && !isOutboundDone() &&
  1289                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
  1289                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
  1290             if (checkSequenceNumber(writeMAC, eor.contentType())) {
  1290             if (checkSequenceNumber(writeAuthenticator, eor.contentType())) {
  1291                 hsStatus = getHSStatus(null);
  1291                 hsStatus = getHSStatus(null);
  1292             }
  1292             }
  1293         }
  1293         }
  1294 
  1294 
  1295         /*
  1295         /*
  1324     /*
  1324     /*
  1325      * Non-application OutputRecords go through here.
  1325      * Non-application OutputRecords go through here.
  1326      */
  1326      */
  1327     void writeRecord(EngineOutputRecord eor) throws IOException {
  1327     void writeRecord(EngineOutputRecord eor) throws IOException {
  1328         // eventually compress as well.
  1328         // eventually compress as well.
  1329         writer.writeRecord(eor, writeMAC, writeCipher);
  1329         writer.writeRecord(eor, writeAuthenticator, writeCipher);
  1330 
  1330 
  1331         /*
  1331         /*
  1332          * Check the sequence number state
  1332          * Check the sequence number state
  1333          *
  1333          *
  1334          * Note that in order to maintain the connection I/O
  1334          * Note that in order to maintain the connection I/O
  1338          * when there is enough sequence number space left to
  1338          * when there is enough sequence number space left to
  1339          * handle a few more records, so the sequence number
  1339          * handle a few more records, so the sequence number
  1340          * of the last record cannot be wrapped.
  1340          * of the last record cannot be wrapped.
  1341          */
  1341          */
  1342         if ((connectionState < cs_ERROR) && !isOutboundDone()) {
  1342         if ((connectionState < cs_ERROR) && !isOutboundDone()) {
  1343             checkSequenceNumber(writeMAC, eor.contentType());
  1343             checkSequenceNumber(writeAuthenticator, eor.contentType());
  1344         }
  1344         }
  1345     }
  1345     }
  1346 
  1346 
  1347     //
  1347     //
  1348     // Close code
  1348     // Close code
  1356      * implementation would need to wrap a sequence number, it must
  1356      * implementation would need to wrap a sequence number, it must
  1357      * renegotiate instead."
  1357      * renegotiate instead."
  1358      *
  1358      *
  1359      * Return true if the handshake status may be changed.
  1359      * Return true if the handshake status may be changed.
  1360      */
  1360      */
  1361     private boolean checkSequenceNumber(MAC mac, byte type)
  1361     private boolean checkSequenceNumber(Authenticator authenticator, byte type)
  1362             throws IOException {
  1362             throws IOException {
  1363 
  1363 
  1364         /*
  1364         /*
  1365          * Don't bother to check the sequence number for error or
  1365          * Don't bother to check the sequence number for error or
  1366          * closed connections, or NULL MAC
  1366          * closed connections, or NULL MAC
  1367          */
  1367          */
  1368         if (connectionState >= cs_ERROR || mac == MAC.NULL) {
  1368         if (connectionState >= cs_ERROR || authenticator == MAC.NULL) {
  1369             return false;
  1369             return false;
  1370         }
  1370         }
  1371 
  1371 
  1372         /*
  1372         /*
  1373          * Conservatively, close the connection immediately when the
  1373          * Conservatively, close the connection immediately when the
  1374          * sequence number is close to overflow
  1374          * sequence number is close to overflow
  1375          */
  1375          */
  1376         if (mac.seqNumOverflow()) {
  1376         if (authenticator.seqNumOverflow()) {
  1377             /*
  1377             /*
  1378              * TLS protocols do not define a error alert for sequence
  1378              * TLS protocols do not define a error alert for sequence
  1379              * number overflow. We use handshake_failure error alert
  1379              * number overflow. We use handshake_failure error alert
  1380              * for handshaking and bad_record_mac for other records.
  1380              * for handshaking and bad_record_mac for other records.
  1381              */
  1381              */
  1394          * Ask for renegotiation when need to renew sequence number.
  1394          * Ask for renegotiation when need to renew sequence number.
  1395          *
  1395          *
  1396          * Don't bother to kickstart the renegotiation when the local is
  1396          * Don't bother to kickstart the renegotiation when the local is
  1397          * asking for it.
  1397          * asking for it.
  1398          */
  1398          */
  1399         if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
  1399         if ((type != Record.ct_handshake) && authenticator.seqNumIsHuge()) {
  1400             if (debug != null && Debug.isOn("ssl")) {
  1400             if (debug != null && Debug.isOn("ssl")) {
  1401                 System.out.println(Thread.currentThread().getName() +
  1401                 System.out.println(Thread.currentThread().getName() +
  1402                         ", request renegotiation " +
  1402                         ", request renegotiation " +
  1403                         "to avoid sequence number overflow");
  1403                         "to avoid sequence number overflow");
  1404             }
  1404             }