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