290 private InputRecord inrec; |
290 private InputRecord inrec; |
291 |
291 |
292 /* |
292 /* |
293 * Crypto state that's reinitialized when the session changes. |
293 * Crypto state that's reinitialized when the session changes. |
294 */ |
294 */ |
295 private MAC readMAC, writeMAC; |
295 private Authenticator readAuthenticator, writeAuthenticator; |
296 private CipherBox readCipher, writeCipher; |
296 private CipherBox readCipher, writeCipher; |
297 // NOTE: compression state would be saved here |
297 // NOTE: compression state would be saved here |
298 |
298 |
299 /* |
299 /* |
300 * security parameters for secure renegotiation. |
300 * security parameters for secure renegotiation. |
584 * default read and write side cipher and MAC support |
584 * default read and write side cipher and MAC support |
585 * |
585 * |
586 * Note: compression support would go here too |
586 * Note: compression support would go here too |
587 */ |
587 */ |
588 readCipher = CipherBox.NULL; |
588 readCipher = CipherBox.NULL; |
589 readMAC = MAC.NULL; |
589 readAuthenticator = MAC.NULL; |
590 writeCipher = CipherBox.NULL; |
590 writeCipher = CipherBox.NULL; |
591 writeMAC = MAC.NULL; |
591 writeAuthenticator = MAC.NULL; |
592 |
592 |
593 // initial security parameters for secure renegotiation |
593 // initial security parameters for secure renegotiation |
594 secureRenegotiation = false; |
594 secureRenegotiation = false; |
595 clientVerifyData = new byte[0]; |
595 clientVerifyData = new byte[0]; |
596 serverVerifyData = new byte[0]; |
596 serverVerifyData = new byte[0]; |
827 |
827 |
828 private void writeRecordInternal(OutputRecord r, |
828 private void writeRecordInternal(OutputRecord r, |
829 boolean holdRecord) throws IOException { |
829 boolean holdRecord) throws IOException { |
830 |
830 |
831 // r.compress(c); |
831 // r.compress(c); |
832 r.addMAC(writeMAC); |
832 r.encrypt(writeAuthenticator, writeCipher); |
833 r.encrypt(writeCipher); |
|
834 |
833 |
835 if (holdRecord) { |
834 if (holdRecord) { |
836 // If we were requested to delay the record due to possibility |
835 // If we were requested to delay the record due to possibility |
837 // of Nagle's being active when finally got to writing, and |
836 // of Nagle's being active when finally got to writing, and |
838 // it's actually not, we don't really need to delay it. |
837 // it's actually not, we don't really need to delay it. |
859 * when there is enough sequence number space left to |
858 * when there is enough sequence number space left to |
860 * handle a few more records, so the sequence number |
859 * handle a few more records, so the sequence number |
861 * of the last record cannot be wrapped. |
860 * of the last record cannot be wrapped. |
862 */ |
861 */ |
863 if (connectionState < cs_ERROR) { |
862 if (connectionState < cs_ERROR) { |
864 checkSequenceNumber(writeMAC, r.contentType()); |
863 checkSequenceNumber(writeAuthenticator, r.contentType()); |
865 } |
864 } |
866 |
865 |
867 // turn off the flag of the first application record |
866 // turn off the flag of the first application record |
868 if (isFirstAppOutputRecord && |
867 if (isFirstAppOutputRecord && |
869 r.contentType() == Record.ct_application_data) { |
868 r.contentType() == Record.ct_application_data) { |
984 * encryption for privacy, and an integrity check ensuring |
983 * encryption for privacy, and an integrity check ensuring |
985 * data origin authentication. We do them both here, and |
984 * data origin authentication. We do them both here, and |
986 * throw a fatal alert if the integrity check fails. |
985 * throw a fatal alert if the integrity check fails. |
987 */ |
986 */ |
988 try { |
987 try { |
989 r.decrypt(readMAC, readCipher); |
988 r.decrypt(readAuthenticator, readCipher); |
990 } catch (BadPaddingException e) { |
989 } catch (BadPaddingException e) { |
991 byte alertType = (r.contentType() == Record.ct_handshake) |
990 byte alertType = (r.contentType() == Record.ct_handshake) |
992 ? Alerts.alert_handshake_failure |
991 ? Alerts.alert_handshake_failure |
993 : Alerts.alert_bad_record_mac; |
992 : Alerts.alert_bad_record_mac; |
994 fatal(alertType, e.getMessage(), e); |
993 fatal(alertType, e.getMessage(), e); |
1141 * when there is enough sequence number space left to |
1140 * when there is enough sequence number space left to |
1142 * handle a few more records, so the sequence number |
1141 * handle a few more records, so the sequence number |
1143 * of the last record cannot be wrapped. |
1142 * of the last record cannot be wrapped. |
1144 */ |
1143 */ |
1145 if (connectionState < cs_ERROR) { |
1144 if (connectionState < cs_ERROR) { |
1146 checkSequenceNumber(readMAC, r.contentType()); |
1145 checkSequenceNumber(readAuthenticator, r.contentType()); |
1147 } |
1146 } |
1148 |
1147 |
1149 return; |
1148 return; |
1150 } // synchronized (this) |
1149 } // synchronized (this) |
1151 } |
1150 } |
1164 * RFC 4346 states that, "Sequence numbers are of type uint64 and |
1163 * RFC 4346 states that, "Sequence numbers are of type uint64 and |
1165 * may not exceed 2^64-1. Sequence numbers do not wrap. If a TLS |
1164 * may not exceed 2^64-1. Sequence numbers do not wrap. If a TLS |
1166 * implementation would need to wrap a sequence number, it must |
1165 * implementation would need to wrap a sequence number, it must |
1167 * renegotiate instead." |
1166 * renegotiate instead." |
1168 */ |
1167 */ |
1169 private void checkSequenceNumber(MAC mac, byte type) |
1168 private void checkSequenceNumber(Authenticator authenticator, byte type) |
1170 throws IOException { |
1169 throws IOException { |
1171 |
1170 |
1172 /* |
1171 /* |
1173 * Don't bother to check the sequence number for error or |
1172 * Don't bother to check the sequence number for error or |
1174 * closed connections, or NULL MAC. |
1173 * closed connections, or NULL MAC. |
1175 */ |
1174 */ |
1176 if (connectionState >= cs_ERROR || mac == MAC.NULL) { |
1175 if (connectionState >= cs_ERROR || authenticator == MAC.NULL) { |
1177 return; |
1176 return; |
1178 } |
1177 } |
1179 |
1178 |
1180 /* |
1179 /* |
1181 * Conservatively, close the connection immediately when the |
1180 * Conservatively, close the connection immediately when the |
1182 * sequence number is close to overflow |
1181 * sequence number is close to overflow |
1183 */ |
1182 */ |
1184 if (mac.seqNumOverflow()) { |
1183 if (authenticator.seqNumOverflow()) { |
1185 /* |
1184 /* |
1186 * TLS protocols do not define a error alert for sequence |
1185 * TLS protocols do not define a error alert for sequence |
1187 * number overflow. We use handshake_failure error alert |
1186 * number overflow. We use handshake_failure error alert |
1188 * for handshaking and bad_record_mac for other records. |
1187 * for handshaking and bad_record_mac for other records. |
1189 */ |
1188 */ |
1201 * Ask for renegotiation when need to renew sequence number. |
1200 * Ask for renegotiation when need to renew sequence number. |
1202 * |
1201 * |
1203 * Don't bother to kickstart the renegotiation when the local is |
1202 * Don't bother to kickstart the renegotiation when the local is |
1204 * asking for it. |
1203 * asking for it. |
1205 */ |
1204 */ |
1206 if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) { |
1205 if ((type != Record.ct_handshake) && authenticator.seqNumIsHuge()) { |
1207 if (debug != null && Debug.isOn("ssl")) { |
1206 if (debug != null && Debug.isOn("ssl")) { |
1208 System.out.println(Thread.currentThread().getName() + |
1207 System.out.println(Thread.currentThread().getName() + |
1209 ", request renegotiation " + |
1208 ", request renegotiation " + |
1210 "to avoid sequence number overflow"); |
1209 "to avoid sequence number overflow"); |
1211 } |
1210 } |
2063 |
2062 |
2064 CipherBox oldCipher = readCipher; |
2063 CipherBox oldCipher = readCipher; |
2065 |
2064 |
2066 try { |
2065 try { |
2067 readCipher = handshaker.newReadCipher(); |
2066 readCipher = handshaker.newReadCipher(); |
2068 readMAC = handshaker.newReadMAC(); |
2067 readAuthenticator = handshaker.newReadAuthenticator(); |
2069 } catch (GeneralSecurityException e) { |
2068 } catch (GeneralSecurityException e) { |
2070 // "can't happen" |
2069 // "can't happen" |
2071 throw new SSLException("Algorithm missing: ", e); |
2070 throw new SSLException("Algorithm missing: ", e); |
2072 } |
2071 } |
2073 |
2072 |
2094 |
2093 |
2095 CipherBox oldCipher = writeCipher; |
2094 CipherBox oldCipher = writeCipher; |
2096 |
2095 |
2097 try { |
2096 try { |
2098 writeCipher = handshaker.newWriteCipher(); |
2097 writeCipher = handshaker.newWriteCipher(); |
2099 writeMAC = handshaker.newWriteMAC(); |
2098 writeAuthenticator = handshaker.newWriteAuthenticator(); |
2100 } catch (GeneralSecurityException e) { |
2099 } catch (GeneralSecurityException e) { |
2101 // "can't happen" |
2100 // "can't happen" |
2102 throw new SSLException("Algorithm missing: ", e); |
2101 throw new SSLException("Algorithm missing: ", e); |
2103 } |
2102 } |
2104 |
2103 |