Add a helper function to normalize the current version.

We have need to normalize other versions during version negotiation, but
almost all will be post-negotiation. Hopefully later this can be
replaced with a value explicitly stored on the object and we do away
with ssl->version.

Change-Id: I595db9163d0af2e7c083b9a09310179aaa9ac812
Reviewed-on: https://boringssl-review.googlesource.com/6841
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index a9f1508..ad76b8c 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1272,7 +1272,11 @@
  *
  * TODO(davidben): To normalize some DTLS-specific code, move away from using
  * the wire version except at API boundaries. */
-uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version);
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version);
+
+/* ssl3_protocol_version returns |ssl|'s protocol version. It is an error to
+ * call this function before the version is determined. */
+uint16_t ssl3_protocol_version(const SSL *ssl);
 
 uint32_t ssl_get_algorithm_prf(const SSL *ssl);
 int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 80c1b10..10eaac8 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -836,8 +836,7 @@
   /* If the cipher is disabled then we didn't sent it in the ClientHello, so if
    * the server selected it, it's an error. */
   if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
-      SSL_CIPHER_get_min_version(c) >
-          ssl3_version_from_wire(ssl, ssl->version)) {
+      SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
     al = SSL_AD_ILLEGAL_PARAMETER;
     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
     goto f_err;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 7de12a8..30fbfac 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -494,8 +494,7 @@
     ok = 1;
 
     /* Check the TLS version. */
-    if (SSL_CIPHER_get_min_version(c) >
-        ssl3_version_from_wire(ssl, ssl->version)) {
+    if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) {
       ok = 0;
     }
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 3e2b156..483e386 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2469,7 +2469,7 @@
   }
 }
 
-uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
+uint16_t ssl3_version_from_wire(const SSL *ssl, uint16_t wire_version) {
   if (!SSL_IS_DTLS(ssl)) {
     return wire_version;
   }
@@ -2490,6 +2490,11 @@
   return version;
 }
 
+uint16_t ssl3_protocol_version(const SSL *ssl) {
+  assert(ssl->s3->have_version);
+  return ssl3_version_from_wire(ssl, ssl->version);
+}
+
 int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
 
 int SSL_is_server(SSL *ssl) { return ssl->server; }
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index a40f4a4..25ff710 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -305,10 +305,10 @@
     iv = server_write_iv;
   }
 
-  SSL_AEAD_CTX *aead_ctx = SSL_AEAD_CTX_new(
-      is_read ? evp_aead_open : evp_aead_seal,
-      ssl3_version_from_wire(ssl, ssl->version), ssl->s3->tmp.new_cipher, key,
-      key_len, mac_secret, mac_secret_len, iv, iv_len);
+  SSL_AEAD_CTX *aead_ctx =
+      SSL_AEAD_CTX_new(is_read ? evp_aead_open : evp_aead_seal,
+                       ssl3_protocol_version(ssl), ssl->s3->tmp.new_cipher, key,
+                       key_len, mac_secret, mac_secret_len, iv, iv_len);
   if (aead_ctx == NULL) {
     return 0;
   }
@@ -345,7 +345,7 @@
   if (ssl->session->cipher == NULL ||
       !ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
                                ssl->session->cipher,
-                               ssl3_version_from_wire(ssl, ssl->version))) {
+                               ssl3_protocol_version(ssl))) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
     return 0;
   }