Clear the counters for empty or warning records only on actual data. Fixes a minor issue where a peer can alternate between empty and warning-only alert records, which applications might find confusing if they try to account for activity of the connection at an upper layer. Change-Id: I3103e0f4b8979c075eb7f3b5591ec0e66a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/94607 Auto-Submit: Rudolf Polzer <rpolzer@google.com> Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/basic_tests.go b/ssl/test/runner/basic_tests.go index dfd17d5..54d4963 100644 --- a/ssl/test/runner/basic_tests.go +++ b/ssl/test/runner/basic_tests.go
@@ -1116,6 +1116,34 @@ expectedError: ":TOO_MANY_WARNING_ALERTS:", }, { + name: "AlternateEmptyRecordsAndWarningAlerts", + config: Config{ + MaxVersion: VersionTLS12, + }, + sendEmptyRecords: 32, + sendWarningAlerts: 4, + }, + { + name: "AlternateTooManyEmptyRecordsAndWarningAlerts", + config: Config{ + MaxVersion: VersionTLS12, + }, + sendEmptyRecords: 33, + sendWarningAlerts: 4, + shouldFail: true, + expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", + }, + { + name: "AlternateEmptyRecordsAndTooManyWarningAlerts", + config: Config{ + MaxVersion: VersionTLS12, + }, + sendEmptyRecords: 32, + sendWarningAlerts: 5, + shouldFail: true, + expectedError: ":TOO_MANY_WARNING_ALERTS:", + }, + { name: "SendBogusAlertType", sendBogusAlertType: true, shouldFail: true,
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 43b3227..d10b8f1 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -632,9 +632,11 @@ testTLSUnique bool // sendEmptyRecords is the number of consecutive empty records to send // before each test message. + // If both this and `sendWarningAlerts` are set, they alternate at the end. sendEmptyRecords int // sendWarningAlerts is the number of consecutive warning alerts to send // before each test message. + // If both this and `sendWarningAlerts` are set, they alternate at the end. sendWarningAlerts int // sendUserCanceledAlerts is the number of consecutive user_canceled alerts to // send before each test message. @@ -1193,15 +1195,17 @@ } } - for i := 0; i < test.sendEmptyRecords; i++ { - if _, err := tlsConn.Write(nil); err != nil { - return err + // Count _down_, so that in case of differing values for the two counters, the alternating takes place at the _end_. + for i := max(test.sendEmptyRecords, test.sendWarningAlerts); i > 0; i-- { + if i <= test.sendEmptyRecords { + if _, err := tlsConn.Write(nil); err != nil { + return err + } } - } - - for i := 0; i < test.sendWarningAlerts; i++ { - if err := tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage); err != nil { - return err + if i <= test.sendWarningAlerts { + if err := tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage); err != nil { + return err + } } }
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc index ba0c4c1..83f5260 100644 --- a/ssl/tls_record.cc +++ b/ssl/tls_record.cc
@@ -238,8 +238,6 @@ } // Apart from the limit, empty records are returned up to the caller. This // allows the caller to reject records of the wrong type. - } else { - ssl->s3->empty_record_count = 0; } if (type == SSL3_RT_ALERT) { @@ -254,7 +252,12 @@ return ssl_open_record_error; } - ssl->s3->warning_alert_count = 0; + // Only when at least one byte is returned, clear the counters for empty + // records and warnings. + if (!out->empty()) { + ssl->s3->empty_record_count = 0; + ssl->s3->warning_alert_count = 0; + } *out_type = type; return ssl_open_record_success;