Dual DTLS version methods.

Add new methods DTLS_*_method() which support both DTLS 1.0 and DTLS 1.2 and
pick the highest version the peer supports during negotiation.

As with SSL/TLS options can change this behaviour specifically
SSL_OP_NO_DTLSv1 and SSL_OP_NO_DTLSv1_2.
(cherry picked from commit c6913eeb76)

Conflicts:

	CHANGES
This commit is contained in:
Dr. Stephen Henson
2013-04-06 15:50:12 +01:00
parent b60b9e7afe
commit 65a87d3cc3
11 changed files with 146 additions and 11 deletions

View File

@@ -968,8 +968,9 @@ int ssl3_get_client_hello(SSL *s)
s->client_version=(((int)p[0])<<8)|(int)p[1];
p+=2;
if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
(s->version != DTLS1_VERSION && s->client_version < s->version))
if ((SSL_IS_DTLS(s) && s->client_version > s->version
&& s->method->version != DTLS_ANY_VERSION) ||
(!SSL_IS_DTLS(s) && s->client_version < s->version))
{
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
@@ -1087,6 +1088,30 @@ int ssl3_get_client_hello(SSL *s)
}
p += cookie_len;
if (s->method->version == DTLS_ANY_VERSION)
{
/* Select version to use */
if (s->client_version <= DTLS1_2_VERSION &&
!(s->options & SSL_OP_NO_DTLSv1_2))
{
s->version = DTLS1_2_VERSION;
s->method = DTLSv1_2_server_method();
}
else if (s->client_version <= DTLS1_VERSION &&
!(s->options & SSL_OP_NO_DTLSv1))
{
s->version = DTLS1_VERSION;
s->method = DTLSv1_server_method();
}
else
{
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
s->version = s->client_version;
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
s->session->ssl_version = s->version;
}
}
n2s(p,i);