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/dtls_method.c b/ssl/dtls_method.c
index e2e1726..9d791b5 100644
--- a/ssl/dtls_method.c
+++ b/ssl/dtls_method.c
@@ -65,31 +65,33 @@
 #include "internal.h"
 
 
-static uint16_t dtls1_version_from_wire(uint16_t wire_version) {
-  uint16_t tls_version = ~wire_version;
-  uint16_t version = tls_version + 0x0201;
-  /* If either component overflowed, clamp it so comparisons still work. */
-  if ((version >> 8) < (tls_version >> 8)) {
-    version = 0xff00 | (version & 0xff);
+static int dtls1_version_from_wire(uint16_t *out_version,
+                                   uint16_t wire_version) {
+  switch (wire_version) {
+    case DTLS1_VERSION:
+      /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
+      *out_version = TLS1_1_VERSION;
+      return 1;
+    case DTLS1_2_VERSION:
+      *out_version = TLS1_2_VERSION;
+      return 1;
   }
-  if ((version & 0xff) < (tls_version & 0xff)) {
-    version = (version & 0xff00) | 0xff;
-  }
-  /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
-  if (version == TLS1_VERSION) {
-    version = TLS1_1_VERSION;
-  }
-  return version;
+
+  return 0;
 }
 
 static uint16_t dtls1_version_to_wire(uint16_t version) {
-  assert(version >= TLS1_1_VERSION);
-
-  /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
-  if (version == TLS1_1_VERSION) {
-    return DTLS1_VERSION;
+  switch (version) {
+    case TLS1_1_VERSION:
+      /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
+      return DTLS1_VERSION;
+    case TLS1_2_VERSION:
+      return DTLS1_2_VERSION;
   }
-  return ~(version - 0x0201);
+
+  /* It is an error to use this function with an invalid version. */
+  assert(0);
+  return 0;
 }
 
 static int dtls1_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {