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) {