aboutsummaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2009-12-07 13:31:02 +0000
committerDr. Stephen Henson <steve@openssl.org>2009-12-07 13:31:02 +0000
commit637f374ad49d5f6d4f81d87d7cdd226428aa470c (patch)
tree2f471a88015ddb5c1e0b3b8b36717db006b0361e /ssl
parent7e4cae1d2f555cbe9226b377aff4b56c9f7ddd4d (diff)
downloadopenssl-637f374ad49d5f6d4f81d87d7cdd226428aa470c.tar.gz
Initial experimental TLSv1.1 support
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s23_clnt.c21
-rw-r--r--ssl/s23_srvr.c22
-rw-r--r--ssl/s3_pkt.c29
-rw-r--r--ssl/ssl.h6
-rw-r--r--ssl/ssl_lib.c6
-rw-r--r--ssl/ssl_locl.h7
-rw-r--r--ssl/ssl_sess.c5
-rw-r--r--ssl/ssl_txt.c2
-rw-r--r--ssl/t1_clnt.c14
-rw-r--r--ssl/t1_enc.c29
-rw-r--r--ssl/t1_lib.c2
-rw-r--r--ssl/t1_meth.c15
-rw-r--r--ssl/t1_srvr.c14
-rw-r--r--ssl/tls1.h4
14 files changed, 145 insertions, 31 deletions
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 53e080ee8e..bacf97c265 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -284,7 +284,11 @@ static int ssl23_client_hello(SSL *s)
if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
ssl2_compat = 0;
- if (!(s->options & SSL_OP_NO_TLSv1))
+ if (!(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ version = TLS1_1_VERSION;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1))
{
version = TLS1_VERSION;
}
@@ -332,7 +336,12 @@ static int ssl23_client_hello(SSL *s)
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
return -1;
- if (version == TLS1_VERSION)
+ if (version == TLS1_1_VERSION)
+ {
+ version_major = TLS1_1_VERSION_MAJOR;
+ version_minor = TLS1_1_VERSION_MINOR;
+ }
+ else if (version == TLS1_VERSION)
{
version_major = TLS1_VERSION_MAJOR;
version_minor = TLS1_VERSION_MINOR;
@@ -611,7 +620,7 @@ static int ssl23_get_server_hello(SSL *s)
#endif
}
else if (p[1] == SSL3_VERSION_MAJOR &&
- (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) &&
+ (p[2] >= SSL3_VERSION_MINOR && p[2] <= TLS1_1_VERSION_MINOR) &&
((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
(p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
{
@@ -629,6 +638,12 @@ static int ssl23_get_server_hello(SSL *s)
s->version=TLS1_VERSION;
s->method=TLSv1_client_method();
}
+ else if ((p[2] == TLS1_1_VERSION_MINOR) &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ s->method=TLSv1_1_client_method();
+ }
else
{
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 773c0e38d8..03efdf74c1 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -128,6 +128,8 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
return(SSLv3_server_method());
else if (ver == TLS1_VERSION)
return(TLSv1_server_method());
+ else if (ver == TLS1_1_VERSION)
+ return(TLSv1_1_server_method());
else
return(NULL);
}
@@ -283,7 +285,13 @@ int ssl23_get_client_hello(SSL *s)
/* SSLv3/TLSv1 */
if (p[4] >= TLS1_VERSION_MINOR)
{
- if (!(s->options & SSL_OP_NO_TLSv1))
+ if (p[4] >= TLS1_1_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ s->state=SSL23_ST_SR_CLNT_HELLO_B;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1))
{
s->version=TLS1_VERSION;
/* type=2; */ /* done later to survive restarts */
@@ -343,7 +351,13 @@ int ssl23_get_client_hello(SSL *s)
v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
{
- if (!(s->options & SSL_OP_NO_TLSv1))
+ if (v[1] >= TLS1_1_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_1))
+ {
+ s->version=TLS1_1_VERSION;
+ type=3;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1))
{
s->version=TLS1_VERSION;
type=3;
@@ -566,7 +580,9 @@ int ssl23_get_client_hello(SSL *s)
s->s3->rbuf.offset=0;
}
- if (s->version == TLS1_VERSION)
+ if (s->version == TLS1_1_VERSION)
+ s->method = TLSv1_1_server_method();
+ else if (s->version == TLS1_VERSION)
s->method = TLSv1_server_method();
else
s->method = SSLv3_server_method();
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index febc2860e1..d795199ead 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -115,6 +115,7 @@
#include "ssl_locl.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
+#include <openssl/rand.h>
static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned int len, int create_empty_fragment);
@@ -629,6 +630,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned char *p,*plen;
int i,mac_size,clear=0;
int prefix_len=0;
+ int eivlen;
long align=0;
SSL3_RECORD *wr;
SSL3_BUFFER *wb=&(s->s3->wbuf);
@@ -738,9 +740,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
/* field where we are to write out packet length */
plen=p;
p+=2;
+ /* Explicit IV length, block ciphers and TLS version 1.1 or later */
+ if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
+ {
+ eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+ if (eivlen <= 1)
+ eivlen = 0;
+ }
+ else
+ eivlen = 0;
/* lets setup the record stuff. */
- wr->data=p;
+ wr->data=p + eivlen;
wr->length=(int)len;
wr->input=(unsigned char *)buf;
@@ -768,11 +779,19 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
if (mac_size != 0)
{
- if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+ if (s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
goto err;
wr->length+=mac_size;
- wr->input=p;
- wr->data=p;
+ }
+
+ wr->input=p;
+ wr->data=p;
+
+ if (eivlen)
+ {
+ if (RAND_pseudo_bytes(p, eivlen) <= 0)
+ goto err;
+ wr->length += eivlen;
}
/* ssl3_enc can only have an error on read */
@@ -1262,7 +1281,7 @@ start:
default:
#ifndef OPENSSL_NO_TLS
/* TLS just ignores unknown message types */
- if (s->version == TLS1_VERSION)
+ if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION)
{
rr->length = 0;
goto start;
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 1d82a6df62..e3cb2a1a02 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -298,6 +298,7 @@ extern "C" {
#define SSL_TXT_SSLV2 "SSLv2"
#define SSL_TXT_SSLV3 "SSLv3"
#define SSL_TXT_TLSV1 "TLSv1"
+#define SSL_TXT_TLSV1_1 "TLSv1.1"
#define SSL_TXT_EXP "EXP"
#define SSL_TXT_EXPORT "EXPORT"
@@ -569,6 +570,7 @@ typedef struct ssl_session_st
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_1 0x00040000L
/* The next flag deliberately changes the ciphertest, this is a check
* for the PKCS#1 attack */
@@ -1630,6 +1632,10 @@ const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
+const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */
+
const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b3b356d5ab..04b6bfcb1c 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2380,8 +2380,10 @@ SSL_METHOD *ssl_bad_method(int ver)
const char *SSL_get_version(const SSL *s)
{
- if (s->version == TLS1_VERSION)
- return("TLSv1");
+ if (s->version == TLS1_1_VERSION)
+ return("TLSv1.1");
+ else if (s->version == SSL3_VERSION)
+ return("SSLv3");
else if (s->version == SSL3_VERSION)
return("SSLv3");
else if (s->version == SSL2_VERSION)
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index c7c93ac61d..226d407023 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -591,11 +591,12 @@ extern SSL3_ENC_METHOD TLSv1_enc_data;
extern SSL3_ENC_METHOD SSLv3_enc_data;
extern SSL3_ENC_METHOD DTLSv1_enc_data;
-#define IMPLEMENT_tls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
+#define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
+ s_get_meth) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
- TLS1_VERSION, \
+ version, \
tls1_new, \
tls1_clear, \
tls1_free, \
@@ -669,7 +670,7 @@ const SSL_METHOD *func_name(void) \
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
- TLS1_VERSION, \
+ TLS1_1_VERSION, \
tls1_new, \
tls1_clear, \
tls1_free, \
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index bebbfa099d..348410e5c3 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -300,6 +300,11 @@ int ssl_get_new_session(SSL *s, int session)
ss->ssl_version=TLS1_VERSION;
ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
}
+ else if (s->version == TLS1_1_VERSION)
+ {
+ ss->ssl_version=TLS1_1_VERSION;
+ ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+ }
else if (s->version == DTLS1_BAD_VER)
{
ss->ssl_version=DTLS1_BAD_VER;
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index 3122440e26..cab712b9a8 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -115,6 +115,8 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
s="SSLv2";
else if (x->ssl_version == SSL3_VERSION)
s="SSLv3";
+ else if (x->ssl_version == TLS1_1_VERSION)
+ s="TLSv1.1";
else if (x->ssl_version == TLS1_VERSION)
s="TLSv1";
else if (x->ssl_version == DTLS1_VERSION)
diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c
index c87af17712..b06bada6f2 100644
--- a/ssl/t1_clnt.c
+++ b/ssl/t1_clnt.c
@@ -66,13 +66,19 @@
static const SSL_METHOD *tls1_get_client_method(int ver);
static const SSL_METHOD *tls1_get_client_method(int ver)
{
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_client_method();
if (ver == TLS1_VERSION)
- return(TLSv1_client_method());
- else
- return(NULL);
+ return TLSv1_client_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_client_method,
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method,
+ ssl_undefined_function,
+ ssl3_connect,
+ tls1_get_client_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method,
ssl_undefined_function,
ssl3_connect,
tls1_get_client_method)
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index d9cb059d0c..028f6493d1 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -143,6 +143,7 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/md5.h>
+#include <openssl/rand.h>
#ifdef KSSL_DEBUG
#include <openssl/des.h>
#endif
@@ -617,7 +618,27 @@ int tls1_enc(SSL *s, int send)
if (s->enc_write_ctx == NULL)
enc=NULL;
else
+ {
+ int ivlen;
enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+ /* For TLSv1.1 and later explicit IV */
+ if (s->version >= TLS1_1_VERSION)
+ ivlen = EVP_CIPHER_iv_length(enc);
+ else
+ ivlen = 0;
+ if (ivlen > 1)
+ {
+ if ( rec->data != rec->input)
+ /* we can't write into the input stream:
+ * Can this ever happen?? (steve)
+ */
+ fprintf(stderr,
+ "%s:%d: rec->data != rec->input\n",
+ __FILE__, __LINE__);
+ else if (RAND_bytes(rec->input, ivlen) <= 0)
+ return -1;
+ }
+ }
}
else
{
@@ -746,7 +767,13 @@ int tls1_enc(SSL *s, int send)
return -1;
}
}
- rec->length-=i;
+ rec->length -=i;
+ if (s->version >= TLS1_1_VERSION)
+ {
+ rec->data += bs; /* skip the explicit IV */
+ rec->input += bs;
+ rec->length -= bs;
+ }
}
}
return(1);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 43c651f47b..ebf9c4fdae 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -166,7 +166,7 @@ void tls1_free(SSL *s)
void tls1_clear(SSL *s)
{
ssl3_clear(s);
- s->version=TLS1_VERSION;
+ s->version = s->method->version;
}
#ifndef OPENSSL_NO_EC
diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c
index 6ce7c0bbf5..3257636425 100644
--- a/ssl/t1_meth.c
+++ b/ssl/t1_meth.c
@@ -60,16 +60,21 @@
#include <openssl/objects.h>
#include "ssl_locl.h"
-static const SSL_METHOD *tls1_get_method(int ver);
static const SSL_METHOD *tls1_get_method(int ver)
{
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_method();
if (ver == TLS1_VERSION)
- return(TLSv1_method());
- else
- return(NULL);
+ return TLSv1_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_method,
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
+ ssl3_accept,
+ ssl3_connect,
+ tls1_get_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
ssl3_accept,
ssl3_connect,
tls1_get_method)
diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c
index 42525e9e89..274a3d6738 100644
--- a/ssl/t1_srvr.c
+++ b/ssl/t1_srvr.c
@@ -67,13 +67,19 @@
static const SSL_METHOD *tls1_get_server_method(int ver);
static const SSL_METHOD *tls1_get_server_method(int ver)
{
+ if (ver == TLS1_1_VERSION)
+ return TLSv1_1_server_method();
if (ver == TLS1_VERSION)
- return(TLSv1_server_method());
- else
- return(NULL);
+ return TLSv1_server_method();
+ return NULL;
}
-IMPLEMENT_tls1_meth_func(TLSv1_server_method,
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ tls1_get_server_method)
+
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
ssl3_accept,
ssl_undefined_function,
tls1_get_server_method)
diff --git a/ssl/tls1.h b/ssl/tls1.h
index b3cc8f098b..b32b713ca8 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -159,6 +159,10 @@ extern "C" {
#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0
+#define TLS1_1_VERSION 0x0302
+#define TLS1_1_VERSION_MAJOR 0x03
+#define TLS1_1_VERSION_MINOR 0x02
+
#define TLS1_VERSION 0x0301
#define TLS1_VERSION_MAJOR 0x03
#define TLS1_VERSION_MINOR 0x01