Remove redundant have_version bit

The version is non-zero exactly when have_version is set.

Change-Id: I8624ab0b7cc44c09fef05879f960687a1ba922b2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/71532
Reviewed-by: Nick Harper <nharper@chromium.org>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc
index c07636e..8ca7b63 100644
--- a/ssl/dtls_record.cc
+++ b/ssl/dtls_record.cc
@@ -432,7 +432,7 @@
 static bool use_dtls13_record_header(const SSL *ssl, uint16_t epoch) {
   // Plaintext records in DTLS 1.3 also use the DTLSPlaintext structure for
   // backwards compatibility.
-  return ssl->s3->have_version && ssl_protocol_version(ssl) > TLS1_2_VERSION &&
+  return ssl->s3->version != 0 && ssl_protocol_version(ssl) > TLS1_2_VERSION &&
          epoch > 0;
 }
 
diff --git a/ssl/handoff.cc b/ssl/handoff.cc
index 2032042..438f899 100644
--- a/ssl/handoff.cc
+++ b/ssl/handoff.cc
@@ -638,7 +638,6 @@
   }
 
   ssl->s3->version = session->ssl_version;
-  s3->have_version = true;
   if (!ssl_method_supports_version(ssl->method, ssl->s3->version) ||
       session->cipher != hs->new_cipher ||
       ssl_protocol_version(ssl) < SSL_CIPHER_get_min_version(session->cipher) ||
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc
index be24ea0..8bc35e6 100644
--- a/ssl/handshake_client.cc
+++ b/ssl/handshake_client.cc
@@ -723,12 +723,11 @@
     return ssl_hs_error;
   }
 
-  assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete);
-  if (!ssl->s3->have_version) {
+  assert((ssl->s3->version != 0) == ssl->s3->initial_handshake_complete);
+  if (ssl->s3->version == 0) {
     ssl->s3->version = server_version;
     // At this point, the connection's version is known and ssl->s3->version is
     // fixed. Begin enforcing the record-layer version.
-    ssl->s3->have_version = true;
     ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->s3->version);
   } else if (server_version != ssl->s3->version) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc
index 1c433ce..4b68ebc 100644
--- a/ssl/handshake_server.cc
+++ b/ssl/handshake_server.cc
@@ -196,7 +196,7 @@
 static bool negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                               const SSL_CLIENT_HELLO *client_hello) {
   SSL *const ssl = hs->ssl;
-  assert(!ssl->s3->have_version);
+  assert(ssl->s3->version == 0);
   CBS supported_versions, versions;
   if (ssl_client_hello_get_extension(client_hello, &supported_versions,
                                      TLSEXT_TYPE_supported_versions)) {
@@ -247,7 +247,6 @@
 
   // At this point, the connection's version is known and |ssl->s3->version| is
   // fixed. Begin enforcing the record-layer version.
-  ssl->s3->have_version = true;
   ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->s3->version);
 
   // Handle FALLBACK_SCSV.
diff --git a/ssl/internal.h b/ssl/internal.h
index 3d6b419..36883e5 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -2856,7 +2856,6 @@
 
   // version is the protocol version, or zero if the version has not yet been
   // set.
-  // TODO(davidben): This is redundant with |have_version|.
   uint16_t version = 0;
 
   // early_data_skipped is the amount of early data that has been skipped by the
@@ -2880,10 +2879,6 @@
   // messages when 0RTT is rejected.
   bool skip_early_data : 1;
 
-  // have_version is true if the connection's final version is known. Otherwise
-  // the version has not been negotiated yet.
-  bool have_version : 1;
-
   // v2_hello_done is true if the peer's V2ClientHello, if any, has been handled
   // and future messages should use the record layer.
   bool v2_hello_done : 1;
diff --git a/ssl/s3_lib.cc b/ssl/s3_lib.cc
index 8b822e2..472d1ab 100644
--- a/ssl/s3_lib.cc
+++ b/ssl/s3_lib.cc
@@ -165,7 +165,6 @@
 
 SSL3_STATE::SSL3_STATE()
     : skip_early_data(false),
-      have_version(false),
       v2_hello_done(false),
       is_v2_hello(false),
       has_message(false),
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 2e78599..2a80a05 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -425,7 +425,7 @@
     return false;
   }
 
-  if (ssl->s3->have_version &&
+  if (ssl->s3->version != 0 &&
       ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
     return false;
   }
@@ -1693,7 +1693,7 @@
 int SSL_get_extms_support(const SSL *ssl) {
   // TLS 1.3 does not require extended master secret and always reports as
   // supporting it.
-  if (!ssl->s3->have_version) {
+  if (ssl->s3->version == 0) {
     return 0;
   }
   if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
@@ -1868,7 +1868,7 @@
 }
 
 int SSL_get_secure_renegotiation_support(const SSL *ssl) {
-  if (!ssl->s3->have_version) {
+  if (ssl->s3->version == 0) {
     return 0;
   }
   return ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
diff --git a/ssl/ssl_versions.cc b/ssl/ssl_versions.cc
index 2f71978..aaa1a9b 100644
--- a/ssl/ssl_versions.cc
+++ b/ssl/ssl_versions.cc
@@ -258,7 +258,7 @@
   if (SSL_in_early_data(ssl) && !ssl->server) {
     return ssl->s3->hs->early_session->ssl_version;
   }
-  if (ssl->s3->have_version) {
+  if (ssl->s3->version != 0) {
     return ssl->s3->version;
   }
   // The TLS versions has not yet been negotiated. Historically, we would return
@@ -267,7 +267,7 @@
 }
 
 uint16_t ssl_protocol_version(const SSL *ssl) {
-  assert(ssl->s3->have_version);
+  assert(ssl->s3->version != 0);
   uint16_t version;
   if (!ssl_protocol_version_from_wire(&version, ssl->s3->version)) {
     // |ssl->s3->version| will always be set to a valid version.
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc
index 82d1600..44075ab 100644
--- a/ssl/t1_enc.cc
+++ b/ssl/t1_enc.cc
@@ -334,7 +334,7 @@
                                const uint8_t *context, size_t context_len,
                                int use_context) {
   // In TLS 1.3, the exporter may be used whenever the secret has been derived.
-  if (ssl->s3->have_version && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+  if (ssl->s3->version != 0 && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
     if (ssl->s3->exporter_secret_len == 0) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
       return 0;
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc
index 644be6a..766013f 100644
--- a/ssl/tls13_client.cc
+++ b/ssl/tls13_client.cc
@@ -183,7 +183,7 @@
 
 static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  assert(ssl->s3->have_version);
+  assert(ssl->s3->version != 0);
   SSLMessage msg;
   if (!ssl->method->get_message(ssl, &msg)) {
     return ssl_hs_read_message;
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc
index 5040862..6e2bdd4 100644
--- a/ssl/tls_record.cc
+++ b/ssl/tls_record.cc
@@ -232,7 +232,7 @@
 
   *out_consumed = in.size() - CBS_len(&cbs);
 
-  if (ssl->s3->have_version &&
+  if (ssl->s3->version != 0 &&
       ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
       SSL_in_init(ssl) &&
       type == SSL3_RT_CHANGE_CIPHER_SPEC &&
@@ -551,7 +551,7 @@
     // without specifying how to handle it. JDK11 misuses it to signal
     // full-duplex connection close after the handshake. As a workaround, skip
     // user_canceled as in TLS 1.2. This matches NSS and OpenSSL.
-    if (ssl->s3->have_version &&
+    if (ssl->s3->version != 0 &&
         ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
         alert_descr != SSL_AD_USER_CANCELLED) {
       *out_alert = SSL_AD_DECODE_ERROR;