Don't return invalid versions in version_from_wire.

This is in preparation for using the supported_versions extension to
experiment with draft TLS 1.3 versions, since we don't wish to restore
the fallback. With versions begin opaque values, we will want
version_from_wire to reject unknown values, not attempt to preserve
order in some way.

This means ClientHello.version processing needs to be separate code.
That's just written out fully in negotiate_version now. It also means
SSL_set_{min,max}_version will notice invalid inputs which aligns us
better with upstream's versions of those APIs.

This CL doesn't replace ssl->version with an internal-representation
version, though follow work should do it once a couple of changes land
in consumers.

BUG=90

Change-Id: Id2f5e1fa72847c823ee7f082e9e69f55e51ce9da
Reviewed-on: https://boringssl-review.googlesource.com/11122
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 3790762..d57735a 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -564,12 +564,30 @@
     return 0;
   }
 
-  uint16_t client_version =
-      ssl->method->version_from_wire(client_hello->version);
-  ssl->client_version = client_hello->version;
+  /* For TLS versions which use ClientHello.version, convert it to a version we
+   * are aware of. */
+  uint16_t version = 0;
+  if (SSL_is_dtls(ssl)) {
+    if (client_hello->version <= DTLS1_2_VERSION) {
+      version = TLS1_2_VERSION;
+    } else if (client_hello->version <= DTLS1_VERSION) {
+      version = TLS1_1_VERSION;
+    }
+  } else {
+    if (client_hello->version >= TLS1_3_VERSION) {
+      version = TLS1_3_VERSION;
+    } else if (client_hello->version >= TLS1_2_VERSION) {
+      version = TLS1_2_VERSION;
+    } else if (client_hello->version >= TLS1_1_VERSION) {
+      version = TLS1_1_VERSION;
+    } else if (client_hello->version >= TLS1_VERSION) {
+      version = TLS1_VERSION;
+    } else if (client_hello->version >= SSL3_VERSION) {
+      version = SSL3_VERSION;
+    }
+  }
 
-  /* Select the version to use. */
-  uint16_t version = client_version;
+  /* Apply our minimum and maximum version. */
   if (version > max_version) {
     version = max_version;
   }
@@ -589,6 +607,7 @@
     return 0;
   }
 
+  ssl->client_version = client_hello->version;
   ssl->version = ssl->method->version_to_wire(version);
   ssl->s3->enc_method = ssl3_get_enc_method(version);
   assert(ssl->s3->enc_method != NULL);