diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2012-02-09 15:41:44 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2012-02-09 15:41:44 +0000 |
commit | fc6800d19f4a0ca852c07128952d4c347d2d7065 (patch) | |
tree | e02ba23553b8a930e042885a11b6630975c3109b /ssl/s3_clnt.c | |
parent | d06f047b04dbdcd151efc620bf91253f0d70117e (diff) |
Modify client hello version when renegotiating to enhance interop with
some servers.
Diffstat (limited to 'ssl/s3_clnt.c')
-rw-r--r-- | ssl/s3_clnt.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index ff1cff23d0..4511a914a4 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -689,9 +689,43 @@ int ssl3_client_hello(SSL *s) /* Do the message type and length last */ d=p= &(buf[4]); + /* version indicates the negotiated version: for example from + * an SSLv2/v3 compatible client hello). The client_version + * field is the maximum version we permit and it is also + * used in RSA encrypted premaster secrets. Some servers can + * choke if we initially report a higher version then + * renegotiate to a lower one in the premaster secret. This + * didn't happen with TLS 1.0 as most servers supported it + * but it can with TLS 1.1 or later if the server only supports + * 1.0. + * + * Possible scenario with previous logic: + * 1. Client hello indicates TLS 1.2 + * 2. Server hello says TLS 1.0 + * 3. RSA encrypted premaster secret uses 1.2. + * 4. Handhaked proceeds using TLS 1.0. + * 5. Server sends hello request to renegotiate. + * 6. Client hello indicates TLS v1.0 as we now + * know that is maximum server supports. + * 7. Server chokes on RSA encrypted premaster secret + * containing version 1.0. + * + * For interoperability it should be OK to always use the + * maximum version we support in client hello and then rely + * on the checking of version to ensure the servers isn't + * being inconsistent: for example initially negotiating with + * TLS 1.0 and renegotiating with TLS 1.2. We do this by using + * client_version in client hello and not resetting it to + * the negotiated version. + */ +#if 0 *(p++)=s->version>>8; *(p++)=s->version&0xff; s->client_version=s->version; +#else + *(p++)=s->client_version>>8; + *(p++)=s->client_version&0xff; +#endif /* Random stuff */ memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); |