Moving TLS 1.3 version negotiation into extension.

Change-Id: I73f9fd64b46f26978b897409d817b34ec9d93afd
Reviewed-on: https://boringssl-review.googlesource.com/11080
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
This commit is contained in:
Steven Valdez
2016-09-27 20:12:22 +00:00
committed by CQ bot account: commit-bot@chromium.org
parent 2fb2ffb660
commit fdd10998e1
14 changed files with 341 additions and 122 deletions
+1 -1
View File
@@ -562,7 +562,7 @@ OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
#define DTLS1_VERSION 0xfeff
#define DTLS1_2_VERSION 0xfefd
#define TLS1_3_DRAFT_VERSION 14
#define TLS1_3_DRAFT_VERSION 0x7f0e
/* SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to
* |version|. If |version| is zero, the default minimum version is used. It
+1 -8
View File
@@ -209,16 +209,9 @@ extern "C" {
#define TLSEXT_TYPE_key_share 40
#define TLSEXT_TYPE_pre_shared_key 41
#define TLSEXT_TYPE_early_data 42
#define TLSEXT_TYPE_supported_versions 43
#define TLSEXT_TYPE_cookie 44
/* TLSEXT_TYPE_draft_version is the extension used to advertise the TLS 1.3
* draft implemented.
*
* See
* https://github.com/tlswg/tls13-spec/wiki/Implementations#version-negotiation
*/
#define TLSEXT_TYPE_draft_version 0xff02
/* ExtensionType value from RFC5746 */
#define TLSEXT_TYPE_renegotiate 0xff01
+4
View File
@@ -731,6 +731,10 @@ static int ssl3_send_client_hello(SSL *ssl) {
* key exchange, the ClientHello version is checked in the premaster secret.
* Some servers fail when this value changes. */
ssl->client_version = ssl->version;
if (max_version >= TLS1_3_VERSION) {
ssl->client_version = ssl->method->version_to_wire(TLS1_2_VERSION);
}
}
/* If the configured session has expired or was created at a disabled
+68 -26
View File
@@ -564,38 +564,75 @@ static int negotiate_version(
return 0;
}
/* 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;
/* Check supported_versions extension if it is present. */
CBS supported_versions;
if (ssl_early_callback_get_extension(client_hello, &supported_versions,
TLSEXT_TYPE_supported_versions)) {
CBS versions;
if (!CBS_get_u8_length_prefixed(&supported_versions, &versions) ||
CBS_len(&supported_versions) != 0 ||
CBS_len(&versions) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
int found_version = 0;
while (CBS_len(&versions) != 0) {
uint16_t ext_version;
if (!CBS_get_u16(&versions, &ext_version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
if (!ssl->method->version_from_wire(&ext_version, ext_version)) {
continue;
}
if (min_version <= ext_version &&
ext_version <= max_version) {
version = ext_version;
found_version = 1;
break;
}
}
if (!found_version) {
goto unsupported_protocol;
}
} 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;
/* Process ClientHello.version instead. Note that versions beyond (D)TLS 1.2
* do not use this mechanism. */
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 {
goto unsupported_protocol;
}
} 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;
} else {
goto unsupported_protocol;
}
}
}
/* Apply our minimum and maximum version. */
if (version > max_version) {
version = max_version;
}
/* Apply our minimum and maximum version. */
if (version > max_version) {
version = max_version;
}
if (version < min_version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
*out_alert = SSL_AD_PROTOCOL_VERSION;
return 0;
if (version < min_version) {
goto unsupported_protocol;
}
}
/* Handle FALLBACK_SCSV. */
@@ -617,6 +654,11 @@ static int negotiate_version(
ssl->s3->have_version = 1;
return 1;
unsupported_protocol:
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
*out_alert = SSL_AD_PROTOCOL_VERSION;
return 0;
}
static int ssl3_get_client_hello(SSL *ssl) {
-6
View File
@@ -543,12 +543,6 @@ static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
/* Only support SSLv3/TLS and DTLS. */
if ((ssl_version >> 8) != SSL3_VERSION_MAJOR &&
(ssl_version >> 8) != (DTLS1_VERSION >> 8)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
goto err;
}
ret->ssl_version = ssl_version;
CBS cipher;
+19 -3
View File
@@ -951,6 +951,10 @@ static int set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
return 1;
}
if (version == TLS1_3_VERSION) {
version = TLS1_3_DRAFT_VERSION;
}
return method->version_from_wire(out, version);
}
@@ -965,6 +969,10 @@ static int set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
return 1;
}
if (version == TLS1_3_VERSION) {
version = TLS1_3_DRAFT_VERSION;
}
return method->version_from_wire(out, version);
}
@@ -2109,7 +2117,8 @@ void ssl_update_cache(SSL *ssl, int mode) {
static const char *ssl_get_version(int version) {
switch (version) {
case TLS1_3_VERSION:
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
case TLS1_3_DRAFT_VERSION:
return "TLSv1.3";
case TLS1_2_VERSION:
@@ -2271,7 +2280,14 @@ int SSL_get_shutdown(const SSL *ssl) {
return ret;
}
int SSL_version(const SSL *ssl) { return ssl->version; }
int SSL_version(const SSL *ssl) {
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
if (ssl->version == TLS1_3_DRAFT_VERSION) {
return TLS1_3_VERSION;
}
return ssl->version;
}
SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
@@ -2962,7 +2978,7 @@ void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type,
version = 0;
break;
default:
version = ssl->version;
version = SSL_version(ssl);
}
ssl->msg_callback(is_write, version, content_type, buf, len, ssl,
+43 -29
View File
@@ -1966,27 +1966,6 @@ static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
return ext_ec_point_add_extension(ssl, out);
}
/* Draft Version Extension */
static int ext_draft_version_add_clienthello(SSL *ssl, CBB *out) {
uint16_t min_version, max_version;
if (!ssl_get_version_range(ssl, &min_version, &max_version) ||
max_version < TLS1_3_VERSION) {
return 1;
}
CBB contents;
if (!CBB_add_u16(out, TLSEXT_TYPE_draft_version) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16(&contents, TLS1_3_DRAFT_VERSION)) {
return 0;
}
return CBB_flush(out);
}
/* Pre Shared Key
*
* https://tools.ietf.org/html/draft-ietf-tls-tls13-14 */
@@ -2279,6 +2258,41 @@ int ssl_ext_key_share_add_serverhello(SSL *ssl, CBB *out) {
}
/* Supported Versions
*
* https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.1 */
static int ext_supported_versions_add_clienthello(SSL *ssl, CBB *out) {
uint16_t min_version, max_version;
if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
return 0;
}
if (max_version <= TLS1_2_VERSION) {
return 1;
}
CBB contents, versions;
if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u8_length_prefixed(&contents, &versions)) {
return 0;
}
for (uint16_t version = max_version; version >= min_version; version--) {
if (!CBB_add_u16(&versions, ssl->method->version_to_wire(version))) {
return 0;
}
}
if (!CBB_flush(out)) {
return 0;
}
return 1;
}
/* Negotiated Groups
*
* https://tools.ietf.org/html/rfc4492#section-5.1.2
@@ -2475,14 +2489,6 @@ static const struct tls_extension kExtensions[] = {
ext_ec_point_parse_clienthello,
ext_ec_point_add_serverhello,
},
{
TLSEXT_TYPE_draft_version,
NULL,
ext_draft_version_add_clienthello,
forbid_parse_serverhello,
ignore_parse_clienthello,
dont_add_serverhello,
},
{
TLSEXT_TYPE_key_share,
NULL,
@@ -2499,6 +2505,14 @@ static const struct tls_extension kExtensions[] = {
ignore_parse_clienthello,
dont_add_serverhello,
},
{
TLSEXT_TYPE_supported_versions,
NULL,
ext_supported_versions_add_clienthello,
forbid_parse_serverhello,
ignore_parse_clienthello,
dont_add_serverhello,
},
/* The final extension must be non-empty. WebSphere Application Server 7.0 is
* intolerant to the last extension being zero-length. See
* https://crbug.com/363583. */
+15 -22
View File
@@ -26,9 +26,8 @@ const (
VersionTLS13 = 0x0304
)
// The draft version of TLS 1.3 that is implemented here and sent in the draft
// indicator extension.
const tls13DraftVersion = 14
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
const tls13DraftVersion = 0x7f0e
const (
maxPlaintext = 16384 // maximum plaintext payload length
@@ -93,11 +92,11 @@ const (
extensionKeyShare uint16 = 40 // draft-ietf-tls-tls13-13
extensionPreSharedKey uint16 = 41 // draft-ietf-tls-tls13-13
extensionEarlyData uint16 = 42 // draft-ietf-tls-tls13-13
extensionSupportedVersions uint16 = 43 // draft-ietf-tls-tls13-16
extensionCookie uint16 = 44 // draft-ietf-tls-tls13-13
extensionCustom uint16 = 1234 // not IANA assigned
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionTLS13Draft uint16 = 0xff02
extensionChannelID uint16 = 30032 // not IANA assigned
)
@@ -601,6 +600,14 @@ type ProtocolBugs struct {
// specified value in the ClientHello version field.
SendClientVersion uint16
// OmitSupportedVersions, if true, causes the client to omit the
// supported versions extension.
OmitSupportedVersions bool
// SendSupportedVersions, if non-empty, causes the client to send a
// supported versions extension with the values from array.
SendSupportedVersions []uint16
// NegotiateVersion, if non-zero, causes the server to negotiate the
// specifed TLS version rather than the version supported by either
// peer.
@@ -1188,24 +1195,10 @@ func (c *Config) defaultCurves() map[CurveID]bool {
return defaultCurves
}
// mutualVersion returns the protocol version to use given the advertised
// version of the peer.
func (c *Config) mutualVersion(vers uint16, isDTLS bool) (uint16, bool) {
// There is no such thing as DTLS 1.1.
if isDTLS && vers == VersionTLS11 {
vers = VersionTLS10
}
minVersion := c.minVersion(isDTLS)
maxVersion := c.maxVersion(isDTLS)
if vers < minVersion {
return 0, false
}
if vers > maxVersion {
vers = maxVersion
}
return vers, true
// isSupportedVersion returns true if the specified protocol version is
// acceptable.
func (c *Config) isSupportedVersion(vers uint16, isDTLS bool) bool {
return c.minVersion(isDTLS) <= vers && vers <= c.maxVersion(isDTLS)
}
// getCertificateForName returns the best certificate for the given name,
+6 -2
View File
@@ -33,8 +33,10 @@ func versionToWire(vers uint16, isDTLS bool) uint16 {
}
} else {
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13:
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers
case VersionTLS13:
return tls13DraftVersion
}
}
@@ -51,8 +53,10 @@ func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) {
}
} else {
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13:
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers, true
case tls13DraftVersion:
return VersionTLS13, true
}
}
+19 -4
View File
@@ -57,6 +57,7 @@ func (c *Conn) clientHandshake() error {
return errors.New("tls: NextProtos values too large")
}
minVersion := c.config.minVersion(c.isDTLS)
maxVersion := c.config.maxVersion(c.isDTLS)
hello := &clientHelloMsg{
isDTLS: c.isDTLS,
@@ -74,7 +75,7 @@ func (c *Conn) clientHandshake() error {
duplicateExtension: c.config.Bugs.DuplicateExtension,
channelIDSupported: c.config.ChannelID != nil,
npnLast: c.config.Bugs.SwapNPNAndALPN,
extendedMasterSecret: c.config.maxVersion(c.isDTLS) >= VersionTLS10,
extendedMasterSecret: maxVersion >= VersionTLS10,
srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
customExtension: c.config.Bugs.CustomExtension,
@@ -235,8 +236,8 @@ NextCipherSuite:
}
}
versOk := candidateSession.vers >= c.config.minVersion(c.isDTLS) &&
candidateSession.vers <= c.config.maxVersion(c.isDTLS)
versOk := candidateSession.vers >= minVersion &&
candidateSession.vers <= maxVersion
if ticketOk && versOk && cipherSuiteOk {
session = candidateSession
}
@@ -285,6 +286,19 @@ NextCipherSuite:
}
}
if maxVersion == VersionTLS13 && !c.config.Bugs.OmitSupportedVersions {
if hello.vers >= VersionTLS13 {
hello.vers = VersionTLS12
}
for version := maxVersion; version >= minVersion; version-- {
hello.supportedVersions = append(hello.supportedVersions, versionToWire(version, c.isDTLS))
}
}
if len(c.config.Bugs.SendSupportedVersions) > 0 {
hello.supportedVersions = c.config.Bugs.SendSupportedVersions
}
if c.config.Bugs.SendClientVersion != 0 {
hello.vers = c.config.Bugs.SendClientVersion
}
@@ -366,12 +380,13 @@ NextCipherSuite:
serverVersion, ok := wireToVersion(serverWireVersion, c.isDTLS)
if ok {
c.vers, ok = c.config.mutualVersion(serverVersion, c.isDTLS)
ok = c.config.isSupportedVersion(serverVersion, c.isDTLS)
}
if !ok {
c.sendAlert(alertProtocolVersion)
return fmt.Errorf("tls: server selected unsupported protocol version %x", c.vers)
}
c.vers = serverVersion
c.haveVers = true
helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
+26 -5
View File
@@ -149,6 +149,7 @@ type clientHelloMsg struct {
ticketSupported bool
sessionTicket []uint8
signatureAlgorithms []signatureAlgorithm
supportedVersions []uint16
secureRenegotiation []byte
alpnProtocols []string
duplicateExtension bool
@@ -190,6 +191,7 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.ticketSupported == m1.ticketSupported &&
bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
eqUint16s(m.supportedVersions, m1.supportedVersions) &&
bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
(m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
@@ -340,6 +342,14 @@ func (m *clientHelloMsg) marshal() []byte {
signatureAlgorithms.addU16(uint16(sigAlg))
}
}
if len(m.supportedVersions) > 0 {
extensions.addU16(extensionSupportedVersions)
supportedVersionsExtension := extensions.addU16LengthPrefixed()
supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
for _, version := range m.supportedVersions {
supportedVersions.addU16(uint16(version))
}
}
if m.secureRenegotiation != nil {
extensions.addU16(extensionRenegotiationInfo)
secureRenegoExt := extensions.addU16LengthPrefixed()
@@ -400,11 +410,6 @@ func (m *clientHelloMsg) marshal() []byte {
customExt := extensions.addU16LengthPrefixed()
customExt.addBytes([]byte(m.customExtension))
}
if m.vers == VersionTLS13 {
extensions.addU16(extensionTLS13Draft)
extValue := extensions.addU16LengthPrefixed()
extValue.addU16(tls13DraftVersion)
}
if extensions.len() == 0 {
hello.discardChild()
@@ -477,6 +482,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
m.ticketSupported = false
m.sessionTicket = nil
m.signatureAlgorithms = nil
m.supportedVersions = nil
m.alpnProtocols = nil
m.extendedMasterSecret = false
m.customExtension = ""
@@ -645,6 +651,21 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
d = d[2:]
}
case extensionSupportedVersions:
if length < 1+2 {
return false
}
l := int(data[0])
if l != length-1 || l%2 == 1 || l < 2 {
return false
}
n := l / 2
d := data[1:]
m.supportedVersions = make([]uint16, n)
for i := range m.supportedVersions {
m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
d = d[2:]
}
case extensionRenegotiationInfo:
if length < 1 || length != int(data[0])+1 {
return false
+30 -7
View File
@@ -204,7 +204,10 @@ func (hs *serverHandshakeState) readClientHello() error {
return fmt.Errorf("tls: client offered different version on renego")
}
}
c.clientVersion = hs.clientHello.vers
// Convert the ClientHello wire version to a protocol version.
var clientVersion uint16
if c.isDTLS {
if hs.clientHello.vers <= 0xfefd {
@@ -213,9 +216,7 @@ func (hs *serverHandshakeState) readClientHello() error {
clientVersion = VersionTLS10
}
} else {
if hs.clientHello.vers >= VersionTLS13 {
clientVersion = VersionTLS13
} else if hs.clientHello.vers >= VersionTLS12 {
if hs.clientHello.vers >= VersionTLS12 {
clientVersion = VersionTLS12
} else if hs.clientHello.vers >= VersionTLS11 {
clientVersion = VersionTLS11
@@ -230,12 +231,34 @@ func (hs *serverHandshakeState) readClientHello() error {
c.vers = config.Bugs.NegotiateVersion
} else if c.haveVers && config.Bugs.NegotiateVersionOnRenego != 0 {
c.vers = config.Bugs.NegotiateVersionOnRenego
} else {
c.vers, ok = config.mutualVersion(clientVersion, c.isDTLS)
if !ok {
} else if len(hs.clientHello.supportedVersions) > 0 {
// Use the versions extension if supplied.
var foundVersion bool
for _, extVersion := range hs.clientHello.supportedVersions {
extVersion, ok = wireToVersion(extVersion, c.isDTLS)
if !ok {
continue
}
if config.isSupportedVersion(extVersion, c.isDTLS) {
c.vers = extVersion
foundVersion = true
break
}
}
if !foundVersion {
c.sendAlert(alertProtocolVersion)
return errors.New("tls: client did not offer any supported protocol versions")
}
} else {
// Otherwise, use the legacy ClientHello version.
version := clientVersion
if maxVersion := config.maxVersion(c.isDTLS); version > maxVersion {
version = maxVersion
}
if version == 0 || !config.isSupportedVersion(version, c.isDTLS) {
return fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
}
c.vers = version
}
c.haveVers = true
@@ -500,7 +523,7 @@ Curves:
ResendHelloRetryRequest:
// Send HelloRetryRequest.
helloRetryRequestMsg := helloRetryRequestMsg{
vers: c.vers,
vers: versionToWire(c.vers, c.isDTLS),
cipherSuite: hs.hello.cipherSuite,
selectedGroup: selectedCurve,
}
+104 -7
View File
@@ -4084,6 +4084,7 @@ func addVersionNegotiationTests() {
flags = append(flags, vers.flag)
}
// Test configuring the runner's maximum version.
for _, runnerVers := range tlsVersions {
protocols := []protocol{tls}
if runnerVers.hasDTLS && shimVers.hasDTLS {
@@ -4171,34 +4172,117 @@ func addVersionNegotiationTests() {
}
}
// Test the version extension at all versions.
for _, vers := range tlsVersions {
protocols := []protocol{tls}
if vers.hasDTLS {
protocols = append(protocols, dtls)
}
for _, protocol := range protocols {
suffix := vers.name
if protocol == dtls {
suffix += "-DTLS"
}
wireVersion := versionToWire(vers.version, protocol == dtls)
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "VersionNegotiationExtension-" + suffix,
config: Config{
Bugs: ProtocolBugs{
SendSupportedVersions: []uint16{0x1111, wireVersion, 0x2222},
},
},
expectedVersion: vers.version,
})
}
}
// If all versions are unknown, negotiation fails.
testCases = append(testCases, testCase{
testType: serverTest,
name: "NoSupportedVersions",
config: Config{
Bugs: ProtocolBugs{
SendSupportedVersions: []uint16{0x1111},
},
},
shouldFail: true,
expectedError: ":UNSUPPORTED_PROTOCOL:",
})
testCases = append(testCases, testCase{
protocol: dtls,
testType: serverTest,
name: "NoSupportedVersions-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendSupportedVersions: []uint16{0x1111},
},
},
shouldFail: true,
expectedError: ":UNSUPPORTED_PROTOCOL:",
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ClientHelloVersionTooHigh",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendClientVersion: 0x0304,
OmitSupportedVersions: true,
},
},
expectedVersion: VersionTLS12,
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ConflictingVersionNegotiation",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendClientVersion: 0x0304,
SendSupportedVersions: []uint16{0x0303},
},
},
expectedVersion: VersionTLS12,
})
// Test for version tolerance.
testCases = append(testCases, testCase{
testType: serverTest,
name: "MinorVersionTolerance",
config: Config{
Bugs: ProtocolBugs{
SendClientVersion: 0x03ff,
SendClientVersion: 0x03ff,
OmitSupportedVersions: true,
},
},
expectedVersion: VersionTLS13,
expectedVersion: VersionTLS12,
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "MajorVersionTolerance",
config: Config{
Bugs: ProtocolBugs{
SendClientVersion: 0x0400,
SendClientVersion: 0x0400,
OmitSupportedVersions: true,
},
},
expectedVersion: VersionTLS13,
expectedVersion: VersionTLS12,
})
testCases = append(testCases, testCase{
protocol: dtls,
testType: serverTest,
name: "MinorVersionTolerance-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendClientVersion: 0xfe00,
SendClientVersion: 0xfe00,
OmitSupportedVersions: true,
},
},
expectedVersion: VersionTLS12,
@@ -4209,7 +4293,8 @@ func addVersionNegotiationTests() {
name: "MajorVersionTolerance-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendClientVersion: 0xfdff,
SendClientVersion: 0xfdff,
OmitSupportedVersions: true,
},
},
expectedVersion: VersionTLS12,
@@ -4221,7 +4306,8 @@ func addVersionNegotiationTests() {
name: "VersionTooLow",
config: Config{
Bugs: ProtocolBugs{
SendClientVersion: 0x0200,
SendClientVersion: 0x0200,
OmitSupportedVersions: true,
},
},
shouldFail: true,
@@ -4317,12 +4403,20 @@ func addMinimumVersionTests() {
}
}
// Test the client enforces minimum
// versions. Use the NegotiateVersion bug to
// ensure the server does not decline to select
// a version first. This may occur if the
// versions extension is used.
testCases = append(testCases, testCase{
protocol: protocol,
testType: clientTest,
name: "MinimumVersion-Client-" + suffix,
config: Config{
MaxVersion: runnerVers.version,
Bugs: ProtocolBugs{
NegotiateVersion: runnerVers.version,
},
},
flags: flags,
expectedVersion: expectedVersion,
@@ -4336,6 +4430,9 @@ func addMinimumVersionTests() {
name: "MinimumVersion-Client2-" + suffix,
config: Config{
MaxVersion: runnerVers.version,
Bugs: ProtocolBugs{
NegotiateVersion: runnerVers.version,
},
},
flags: []string{"-min-version", shimVersFlag},
expectedVersion: expectedVersion,
+5 -2
View File
@@ -71,9 +71,11 @@ static int ssl3_version_from_wire(uint16_t *out_version,
case TLS1_VERSION:
case TLS1_1_VERSION:
case TLS1_2_VERSION:
case TLS1_3_VERSION:
*out_version = wire_version;
return 1;
case TLS1_3_DRAFT_VERSION:
*out_version = TLS1_3_VERSION;
return 1;
}
return 0;
@@ -85,8 +87,9 @@ static uint16_t ssl3_version_to_wire(uint16_t version) {
case TLS1_VERSION:
case TLS1_1_VERSION:
case TLS1_2_VERSION:
case TLS1_3_VERSION:
return version;
case TLS1_3_VERSION:
return TLS1_3_DRAFT_VERSION;
}
/* It is an error to use this function with an invalid version. */