diff options
-rw-r--r-- | CHANGES | 8 | ||||
-rw-r--r-- | apps/s_cb.c | 4 | ||||
-rw-r--r-- | apps/s_client.c | 7 | ||||
-rw-r--r-- | apps/s_server.c | 6 | ||||
-rw-r--r-- | ssl/s23_clnt.c | 23 | ||||
-rw-r--r-- | ssl/s23_meth.c | 2 | ||||
-rw-r--r-- | ssl/s23_srvr.c | 24 | ||||
-rw-r--r-- | ssl/s3_enc.c | 2 | ||||
-rw-r--r-- | ssl/s3_lib.c | 228 | ||||
-rw-r--r-- | ssl/s3_pkt.c | 4 | ||||
-rw-r--r-- | ssl/ssl.h | 16 | ||||
-rw-r--r-- | ssl/ssl3.h | 2 | ||||
-rw-r--r-- | ssl/ssl_ciph.c | 26 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 6 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 10 | ||||
-rw-r--r-- | ssl/ssl_sess.c | 5 | ||||
-rw-r--r-- | ssl/ssl_txt.c | 2 | ||||
-rw-r--r-- | ssl/t1_clnt.c | 7 | ||||
-rw-r--r-- | ssl/t1_enc.c | 14 | ||||
-rw-r--r-- | ssl/t1_meth.c | 7 | ||||
-rw-r--r-- | ssl/t1_srvr.c | 7 | ||||
-rw-r--r-- | ssl/tls1.h | 37 |
22 files changed, 417 insertions, 30 deletions
@@ -4,6 +4,14 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] + *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch + to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based + ciphersuites. At present only RSA key exchange ciphersuites work with + TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete + SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods + and version checking. + [Steve Henson] + *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled with this defined it will not be affected by any changes to ssl internal structures. Add several utility functions to allow openssl application diff --git a/apps/s_cb.c b/apps/s_cb.c index dd9de4663c..7755373d77 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -676,6 +676,10 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, extname = "renegotiate"; break; + case TLSEXT_TYPE_signature_algorithms: + extname = "signature algorithms"; + break; + #ifdef TLSEXT_TYPE_opaque_prf_input case TLSEXT_TYPE_opaque_prf_input: extname = "opaque PRF input"; diff --git a/apps/s_client.c b/apps/s_client.c index 8e0e8cb35d..faf7f39c1d 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -328,11 +328,12 @@ static void sc_usage(void) #endif BIO_printf(bio_err," -ssl2 - just use SSLv2\n"); BIO_printf(bio_err," -ssl3 - just use SSLv3\n"); + BIO_printf(bio_err," -tls1_2 - just use TLSv1.2\n"); BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n"); BIO_printf(bio_err," -tls1 - just use TLSv1\n"); BIO_printf(bio_err," -dtls1 - just use DTLSv1\n"); BIO_printf(bio_err," -mtu - set the link layer MTU\n"); - BIO_printf(bio_err," -no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); + BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n"); BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n"); BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); @@ -790,6 +791,8 @@ int MAIN(int argc, char **argv) meth=SSLv3_client_method(); #endif #ifndef OPENSSL_NO_TLS1 + else if (strcmp(*argv,"-tls1_2") == 0) + meth=TLSv1_2_client_method(); else if (strcmp(*argv,"-tls1_1") == 0) meth=TLSv1_1_client_method(); else if (strcmp(*argv,"-tls1") == 0) @@ -840,6 +843,8 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; CAfile= *(++argv); } + else if (strcmp(*argv,"-no_tls1_2") == 0) + off|=SSL_OP_NO_TLSv1_2; else if (strcmp(*argv,"-no_tls1_1") == 0) off|=SSL_OP_NO_TLSv1_1; else if (strcmp(*argv,"-no_tls1") == 0) diff --git a/apps/s_server.c b/apps/s_server.c index 9233384028..de481f7794 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -503,6 +503,7 @@ static void sv_usage(void) #endif BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); + BIO_printf(bio_err," -tls1_2 - Just talk TLSv1.2\n"); BIO_printf(bio_err," -tls1_1 - Just talk TLSv1.1\n"); BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n"); @@ -513,6 +514,7 @@ static void sv_usage(void) BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n"); BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n"); BIO_printf(bio_err," -no_tls1_1 - Just disable TLSv1.1\n"); + BIO_printf(bio_err," -no_tls1_2 - Just disable TLSv1.2\n"); #ifndef OPENSSL_NO_DH BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n"); #endif @@ -1226,6 +1228,8 @@ int MAIN(int argc, char *argv[]) { off|=SSL_OP_NO_SSLv2; } else if (strcmp(*argv,"-no_ssl3") == 0) { off|=SSL_OP_NO_SSLv3; } + else if (strcmp(*argv,"-no_tls1_2") == 0) + { off|=SSL_OP_NO_TLSv1_2; } else if (strcmp(*argv,"-no_tls1_1") == 0) { off|=SSL_OP_NO_TLSv1_1; } else if (strcmp(*argv,"-no_tls1") == 0) @@ -1245,6 +1249,8 @@ int MAIN(int argc, char *argv[]) { meth=SSLv3_server_method(); } #endif #ifndef OPENSSL_NO_TLS1 + else if (strcmp(*argv,"-tls1_2") == 0) + { meth=TLSv1_2_server_method(); } else if (strcmp(*argv,"-tls1_1") == 0) { meth=TLSv1_1_server_method(); } else if (strcmp(*argv,"-tls1") == 0) diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 47f9389817..f49a95ba99 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -131,6 +131,8 @@ static const SSL_METHOD *ssl23_get_client_method(int ver) return(TLSv1_client_method()); else if (ver == TLS1_1_VERSION) return(TLSv1_1_client_method()); + else if (ver == TLS1_2_VERSION) + return(TLSv1_2_client_method()); else return(NULL); } @@ -286,7 +288,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_1)) + if (!(s->options & SSL_OP_NO_TLSv1_2)) + { + version = TLS1_2_VERSION; + } + else if (!(s->options & SSL_OP_NO_TLSv1_1)) { version = TLS1_1_VERSION; } @@ -335,7 +341,12 @@ static int ssl23_client_hello(SSL *s) if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) return -1; - if (version == TLS1_1_VERSION) + if (version == TLS1_2_VERSION) + { + version_major = TLS1_2_VERSION_MAJOR; + version_minor = TLS1_2_VERSION_MINOR; + } + else if (version == TLS1_1_VERSION) { version_major = TLS1_1_VERSION_MAJOR; version_minor = TLS1_1_VERSION_MINOR; @@ -619,7 +630,7 @@ static int ssl23_get_server_hello(SSL *s) #endif } else if (p[1] == SSL3_VERSION_MAJOR && - p[2] <= TLS1_1_VERSION_MINOR && + p[2] <= TLS1_2_VERSION_MINOR && ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { @@ -643,6 +654,12 @@ static int ssl23_get_server_hello(SSL *s) s->version=TLS1_1_VERSION; s->method=TLSv1_1_client_method(); } + else if ((p[2] == TLS1_2_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_2)) + { + s->version=TLS1_2_VERSION; + s->method=TLSv1_2_client_method(); + } else { SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c index a2b4b224b1..40eae0f0be 100644 --- a/ssl/s23_meth.c +++ b/ssl/s23_meth.c @@ -78,6 +78,8 @@ static const SSL_METHOD *ssl23_get_method(int ver) return(TLSv1_method()); else if (ver == TLS1_1_VERSION) return(TLSv1_1_method()); + else if (ver == TLS1_2_VERSION) + return(TLSv1_2_method()); else #endif return(NULL); diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c index 390b99bf56..b21c57a117 100644 --- a/ssl/s23_srvr.c +++ b/ssl/s23_srvr.c @@ -130,6 +130,8 @@ static const SSL_METHOD *ssl23_get_server_method(int ver) return(TLSv1_server_method()); else if (ver == TLS1_1_VERSION) return(TLSv1_1_server_method()); + else if (ver == TLS1_2_VERSION) + return(TLSv1_2_server_method()); else return(NULL); } @@ -285,10 +287,17 @@ int ssl23_get_client_hello(SSL *s) /* SSLv3/TLSv1 */ if (p[4] >= TLS1_VERSION_MINOR) { - if (p[4] >= TLS1_1_VERSION_MINOR && + if (p[4] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) + { + s->version=TLS1_2_VERSION; + s->state=SSL23_ST_SR_CLNT_HELLO_B; + } + else if (p[4] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version=TLS1_1_VERSION; + /* type=2; */ /* done later to survive restarts */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_TLSv1)) @@ -358,7 +367,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 (v[1] >= TLS1_1_VERSION_MINOR && + if (v[1] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) + { + s->version=TLS1_2_VERSION; + type=3; + } + else if (v[1] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version=TLS1_1_VERSION; @@ -581,8 +596,9 @@ int ssl23_get_client_hello(SSL *s) s->s3->rbuf.left=0; s->s3->rbuf.offset=0; } - - if (s->version == TLS1_1_VERSION) + if (s->version == TLS1_2_VERSION) + s->method = TLSv1_2_server_method(); + else if (s->version == TLS1_1_VERSION) s->method = TLSv1_1_server_method(); else if (s->version == TLS1_VERSION) s->method = TLSv1_server_method(); diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 58386e1ba0..ac5ae40a7e 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -610,7 +610,7 @@ int ssl3_digest_cached_records(SSL *s) /* Loop through bitso of algorithm2 field and create MD_CTX-es */ for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) { - if ((mask & s->s3->tmp.new_cipher->algorithm2) && md) + if ((mask & ssl_get_algorithm2(s)) && md) { s->s3->handshake_dgst[i]=EVP_MD_CTX_create(); EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index f3d230b7e6..b147935dc9 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1071,6 +1071,103 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 256, }, + /* TLS v1.2 ciphersuites */ + /* Cipher 3B */ + { + 1, + TLS1_TXT_RSA_WITH_NULL_SHA256, + TLS1_CK_RSA_WITH_NULL_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA256, + SSL_SSLV3, + SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 0, + 0, + }, + + /* Cipher 3C */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_SHA256, + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3D */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_SHA256, + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher 3E */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, + TLS1_CK_DH_DSS_WITH_AES_128_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3F */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_AES_128_SHA256, + TLS1_CK_DH_RSA_WITH_AES_128_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 40 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + #ifndef OPENSSL_NO_CAMELLIA /* Camellia ciphersuites from RFC4132 (128-bit portion) */ @@ -1287,6 +1384,122 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 128, }, #endif + + /* TLS v1.2 ciphersuites */ + /* Cipher 67 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 68 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, + TLS1_CK_DH_DSS_WITH_AES_256_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher 69 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_AES_256_SHA256, + TLS1_CK_DH_RSA_WITH_AES_256_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6A */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6B */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6C */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_SHA256, + TLS1_CK_ADH_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 6D */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_SHA256, + TLS1_CK_ADH_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, + + /* GOST Ciphersuites */ + { 1, "GOST94-GOST89-GOST89", @@ -3024,6 +3237,9 @@ const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1]; c.id=id; cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); +#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES +if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); +#endif if (cp == NULL || cp->valid == 0) return NULL; else @@ -3558,3 +3774,15 @@ need to go to SSL_ST_ACCEPT. } return(ret); } +/* If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch + * to new SHA256 PRF and handshake macs + */ +long ssl_get_algorithm2(SSL *s) + { + long alg2 = s->s3->tmp.new_cipher->algorithm2; + if (s->version >= TLS1_2_VERSION && + alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; + } + diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 536d0949f9..f6e31e9c3d 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -1319,7 +1319,9 @@ start: { default: #ifndef OPENSSL_NO_TLS - /* TLS just ignores unknown message types */ + /* TLS up to v1.1 just ignores unknown message types: + * TLS v1.2 give an unexpected message alert. + */ if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) { rr->length = 0; @@ -296,11 +296,13 @@ extern "C" { #define SSL_TXT_SHA "SHA" /* same as "SHA1" */ #define SSL_TXT_GOST94 "GOST94" #define SSL_TXT_GOST89MAC "GOST89MAC" +#define SSL_TXT_SHA256 "SHA256" #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_TLSV1_2 "TLSv1.2" #define SSL_TXT_EXP "EXP" #define SSL_TXT_EXPORT "EXPORT" @@ -591,11 +593,16 @@ 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_2 0x08000000L +/* These next two were never actually used for anything since SSLeay + * zap so we have some more flags. + */ /* The next flag deliberately changes the ciphertest, this is a check * for the PKCS#1 attack */ -#define SSL_OP_PKCS1_CHECK_1 0x08000000L -#define SSL_OP_PKCS1_CHECK_2 0x10000000L +#define SSL_OP_PKCS1_CHECK_1 0x0 +#define SSL_OP_PKCS1_CHECK_2 0x0 + #define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L /* Make server add server-hello extension from early version of @@ -1835,6 +1842,11 @@ 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 *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + + 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/ssl3.h b/ssl/ssl3.h index ab63140ad2..ea0c8542db 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -476,7 +476,7 @@ typedef struct ssl3_state_st int finish_md_len; unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2]; int peer_finish_md_len; - + unsigned long message_size; int message_type; diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 84829e5e9a..132b848e4a 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -179,28 +179,29 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; #define SSL_MD_SHA1_IDX 1 #define SSL_MD_GOST94_IDX 2 #define SSL_MD_GOST89MAC_IDX 3 +#define SSL_MD_SHA256_IDX 4 /*Constant SSL_MAX_DIGEST equal to size of digests array should be * defined in the * ssl_locl.h */ #define SSL_MD_NUM_IDX SSL_MAX_DIGEST static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ - NULL,NULL,NULL,NULL + NULL,NULL,NULL,NULL,NULL }; /* PKEY_TYPE for GOST89MAC is known in advance, but, because * implementation is engine-provided, we'll fill it only if * corresponding EVP_PKEY_METHOD is found */ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={ - EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef + EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,EVP_PKEY_HMAC }; static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ - 0,0,0,0 + 0,0,0,0,0 }; static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={ SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA, - SSL_HANDSHAKE_MAC_GOST94,0 + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256 }; #define CIPHER_ADD 1 @@ -298,6 +299,7 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0}, {0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0}, {0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0}, + {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0}, /* protocol version aliases */ {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, @@ -406,6 +408,10 @@ void ssl_load_ciphers(void) ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32; } + ssl_digest_methods[SSL_MD_SHA256_IDX]= + EVP_get_digestbyname(SN_sha256); + ssl_mac_secret_size[SSL_MD_SHA256_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); } #ifndef OPENSSL_NO_COMP @@ -550,6 +556,9 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SHA1: i=SSL_MD_SHA1_IDX; break; + case SSL_SHA256: + i=SSL_MD_SHA256_IDX; + break; case SSL_GOST94: i = SSL_MD_GOST94_IDX; break; @@ -586,9 +595,11 @@ int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) { return 0; } - if (ssl_handshake_digest_flag[idx]==0) return 0; *mask = ssl_handshake_digest_flag[idx]; - *md = ssl_digest_methods[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; return 1; } @@ -1603,6 +1614,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_SHA1: mac="SHA1"; break; + case SSL_SHA256: + mac="SHA256"; + break; default: mac="unknown"; break; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 6f70bdfff2..e191cce624 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1834,6 +1834,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) * deployed might change this. */ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + /* Disable TLS v1.2 by default for now */ + ret->options |= SSL_OP_NO_TLSv1_2; return(ret); err: @@ -2572,7 +2574,9 @@ SSL_METHOD *ssl_bad_method(int ver) const char *SSL_get_version(const SSL *s) { - if (s->version == TLS1_1_VERSION) + if (s->version == TLS1_2_VERSION) + return("TLSv1.2"); + else if (s->version == TLS1_1_VERSION) return("TLSv1.1"); else if (s->version == TLS1_VERSION) return("TLSv1"); diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 444e6f5d09..3c02547987 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -170,7 +170,7 @@ # define OPENSSL_EXTERN OPENSSL_EXPORT #endif -#define PKCS1_CHECK +#undef PKCS1_CHECK #define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ l|=(((unsigned long)(*((c)++)))<< 8), \ @@ -327,6 +327,7 @@ #define SSL_SHA1 0x00000002L #define SSL_GOST94 0x00000004L #define SSL_GOST89MAC 0x00000008L +#define SSL_SHA256 0x00000010L /* Bits for algorithm_ssl (protocol version) */ #define SSL_SSLV2 0x00000001L @@ -339,15 +340,17 @@ #define SSL_HANDSHAKE_MAC_MD5 0x10 #define SSL_HANDSHAKE_MAC_SHA 0x20 #define SSL_HANDSHAKE_MAC_GOST94 0x40 +#define SSL_HANDSHAKE_MAC_SHA256 0x80 #define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) /* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX * make sure to update this constant too */ -#define SSL_MAX_DIGEST 4 +#define SSL_MAX_DIGEST 5 #define TLS1_PRF_DGST_SHIFT 8 #define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) @@ -671,7 +674,7 @@ const SSL_METHOD *func_name(void) \ const SSL_METHOD *func_name(void) \ { \ static const SSL_METHOD func_name##_data= { \ - TLS1_1_VERSION, \ + TLS1_2_VERSION, \ tls1_new, \ tls1_clear, \ tls1_free, \ @@ -1083,4 +1086,5 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, int maxlen); int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, int *al); +long ssl_get_algorithm2(SSL *s); #endif diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 3f0b19558d..cbb7e70352 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -308,6 +308,11 @@ int ssl_get_new_session(SSL *s, int session) ss->ssl_version=TLS1_1_VERSION; ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH; } + else if (s->version == TLS1_2_VERSION) + { + ss->ssl_version=TLS1_2_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 552ec2b058..6479d52c0c 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_2_VERSION) + s="TLSv1.2"; else if (x->ssl_version == TLS1_1_VERSION) s="TLSv1.1"; else if (x->ssl_version == TLS1_VERSION) diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c index b06bada6f2..578617ed84 100644 --- a/ssl/t1_clnt.c +++ b/ssl/t1_clnt.c @@ -66,6 +66,8 @@ static const SSL_METHOD *tls1_get_client_method(int ver); static const SSL_METHOD *tls1_get_client_method(int ver) { + if (ver == TLS1_2_VERSION) + return TLSv1_2_client_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_client_method(); if (ver == TLS1_VERSION) @@ -73,6 +75,11 @@ static const SSL_METHOD *tls1_get_client_method(int ver) return NULL; } +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, + ssl_undefined_function, + ssl3_connect, + tls1_get_client_method) + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, ssl_undefined_function, ssl3_connect, diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 8950700846..95a5b35c42 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -291,7 +291,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) { int ret; - ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + ret = tls1_PRF(ssl_get_algorithm2(s), TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE, @@ -494,7 +494,7 @@ printf("which = %04X\nmac key=",which); /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ - if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + if (!tls1_PRF(ssl_get_algorithm2(s), exp_label,exp_label_len, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, @@ -505,7 +505,7 @@ printf("which = %04X\nmac key=",which); if (k > 0) { - if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + if (!tls1_PRF(ssl_get_algorithm2(s), TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, @@ -879,7 +879,7 @@ int tls1_final_finish_mac(SSL *s, for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++) { - if (mask & s->s3->tmp.new_cipher->algorithm2) + if (mask & ssl_get_algorithm2(s)) { int hashsize = EVP_MD_size(md); if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) @@ -898,7 +898,7 @@ int tls1_final_finish_mac(SSL *s, } } - if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + if (!tls1_PRF(ssl_get_algorithm2(s), str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0, s->session->master_key,s->session->master_key_length, out,buf2,sizeof buf2)) @@ -1024,7 +1024,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, } #endif - tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + tls1_PRF(ssl_get_algorithm2(s), TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE, co, col, @@ -1096,7 +1096,7 @@ int SSL_tls1_key_exporter(SSL *s, unsigned char *label, int label_len, if (!tmp) return 0; - rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2, + rv = tls1_PRF(ssl_get_algorithm2(s), label, label_len, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c index 3257636425..53c807de28 100644 --- a/ssl/t1_meth.c +++ b/ssl/t1_meth.c @@ -62,6 +62,8 @@ static const SSL_METHOD *tls1_get_method(int ver) { + if (ver == TLS1_2_VERSION) + return TLSv1_2_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_method(); if (ver == TLS1_VERSION) @@ -69,6 +71,11 @@ static const SSL_METHOD *tls1_get_method(int ver) return NULL; } +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, + ssl3_accept, + ssl3_connect, + tls1_get_method) + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, ssl3_accept, ss |