From 7409d7ad517650db332ae528915a570e4e0ab88b Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 29 Apr 2011 22:56:51 +0000 Subject: [PATCH] Initial incomplete TLS v1.2 support. New ciphersuites added, new version checking added, SHA256 PRF support added. At present only RSA key exchange ciphersuites work with TLS v1.2 as the new signature format is not yet implemented. --- CHANGES | 8 ++ apps/s_cb.c | 4 + apps/s_client.c | 7 +- apps/s_server.c | 6 ++ ssl/s23_clnt.c | 23 ++++- ssl/s23_meth.c | 2 + ssl/s23_srvr.c | 24 ++++- ssl/s3_enc.c | 2 +- ssl/s3_lib.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++ ssl/s3_pkt.c | 4 +- ssl/ssl.h | 16 +++- ssl/ssl3.h | 2 +- ssl/ssl_ciph.c | 26 ++++-- ssl/ssl_lib.c | 6 +- ssl/ssl_locl.h | 10 ++- ssl/ssl_sess.c | 5 ++ ssl/ssl_txt.c | 2 + ssl/t1_clnt.c | 7 ++ ssl/t1_enc.c | 14 +-- ssl/t1_meth.c | 7 ++ ssl/t1_srvr.c | 7 ++ ssl/tls1.h | 37 ++++++++ 22 files changed, 417 insertions(+), 30 deletions(-) diff --git a/CHANGES b/CHANGES index 30458ff152..5191ed6870 100644 --- a/CHANGES +++ b/CHANGES @@ -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; diff --git a/ssl/ssl.h b/ssl/ssl.h index c3c0a1bb34..c487407607 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -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, ssl3_connect, diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c index 274a3d6738..f1d1565769 100644 --- a/ssl/t1_srvr.c +++ b/ssl/t1_srvr.c @@ -67,6 +67,8 @@ static const SSL_METHOD *tls1_get_server_method(int ver); static const SSL_METHOD *tls1_get_server_method(int ver) { + if (ver == TLS1_2_VERSION) + return TLSv1_2_server_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_server_method(); if (ver == TLS1_VERSION) @@ -74,6 +76,11 @@ static const SSL_METHOD *tls1_get_server_method(int ver) return NULL; } +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, + ssl3_accept, + ssl_undefined_function, + tls1_get_server_method) + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, ssl3_accept, ssl_undefined_function, diff --git a/ssl/tls1.h b/ssl/tls1.h index 6f8bb8806b..3593701305 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -159,6 +159,10 @@ extern "C" { #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 +#define TLS1_2_VERSION 0x0303 +#define TLS1_2_VERSION_MAJOR 0x03 +#define TLS1_2_VERSION_MINOR 0x03 + #define TLS1_1_VERSION 0x0302 #define TLS1_1_VERSION_MAJOR 0x03 #define TLS1_1_VERSION_MINOR 0x02 @@ -201,6 +205,7 @@ extern "C" { #define TLSEXT_TYPE_ec_point_formats 11 /* ExtensionType value from RFC5054 */ #define TLSEXT_TYPE_srp 12 +#define TLSEXT_TYPE_signature_algorithms 13 #define TLSEXT_TYPE_session_ticket 35 /* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ #if 0 /* will have to be provided externally for now , @@ -335,6 +340,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 #define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + /* Camellia ciphersuites from RFC4132 */ #define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 #define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 @@ -343,6 +356,16 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 #define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ #define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 #define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 #define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 @@ -501,6 +524,20 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" #define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" +/* TLS v1.2 ciphersuites */ +#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" #define TLS_CT_RSA_SIGN 1 #define TLS_CT_DSS_SIGN 2 -- 2.40.0