summaryrefslogtreecommitdiff
path: root/crypto/openssl/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssl/ssl')
-rw-r--r--crypto/openssl/ssl/Makefile112
-rw-r--r--crypto/openssl/ssl/d1_both.c174
-rw-r--r--crypto/openssl/ssl/d1_clnt.c69
-rw-r--r--crypto/openssl/ssl/d1_enc.c3
-rw-r--r--crypto/openssl/ssl/d1_lib.c48
-rw-r--r--crypto/openssl/ssl/d1_pkt.c9
-rw-r--r--crypto/openssl/ssl/d1_srvr.c76
-rw-r--r--crypto/openssl/ssl/dtls1.h8
-rw-r--r--crypto/openssl/ssl/heartbeat_test.c466
-rw-r--r--crypto/openssl/ssl/kssl.c72
-rw-r--r--crypto/openssl/ssl/kssl.h9
-rw-r--r--crypto/openssl/ssl/s23_clnt.c29
-rw-r--r--crypto/openssl/ssl/s23_lib.c7
-rw-r--r--crypto/openssl/ssl/s23_srvr.c1
-rw-r--r--crypto/openssl/ssl/s2_enc.c12
-rw-r--r--crypto/openssl/ssl/s2_lib.c2
-rw-r--r--crypto/openssl/ssl/s2_pkt.c9
-rw-r--r--crypto/openssl/ssl/s2_srvr.c22
-rw-r--r--crypto/openssl/ssl/s3_both.c3
-rw-r--r--crypto/openssl/ssl/s3_cbc.c65
-rw-r--r--crypto/openssl/ssl/s3_clnt.c155
-rw-r--r--crypto/openssl/ssl/s3_enc.c15
-rw-r--r--crypto/openssl/ssl/s3_lib.c79
-rw-r--r--crypto/openssl/ssl/s3_meth.c5
-rw-r--r--crypto/openssl/ssl/s3_pkt.c67
-rw-r--r--crypto/openssl/ssl/s3_srvr.c267
-rw-r--r--crypto/openssl/ssl/srtp.h8
-rw-r--r--crypto/openssl/ssl/ssl.h44
-rw-r--r--crypto/openssl/ssl/ssl3.h24
-rw-r--r--crypto/openssl/ssl/ssl_asn1.c4
-rw-r--r--crypto/openssl/ssl/ssl_cert.c29
-rw-r--r--crypto/openssl/ssl/ssl_ciph.c52
-rw-r--r--crypto/openssl/ssl/ssl_err.c2
-rw-r--r--crypto/openssl/ssl/ssl_lib.c36
-rw-r--r--crypto/openssl/ssl/ssl_locl.h30
-rw-r--r--crypto/openssl/ssl/ssl_sess.c16
-rw-r--r--crypto/openssl/ssl/ssl_stat.c5
-rw-r--r--crypto/openssl/ssl/ssl_utst.c73
-rw-r--r--crypto/openssl/ssl/ssltest.c75
-rw-r--r--crypto/openssl/ssl/t1_enc.c90
-rw-r--r--crypto/openssl/ssl/t1_lib.c233
-rw-r--r--crypto/openssl/ssl/tls1.h6
42 files changed, 1777 insertions, 734 deletions
diff --git a/crypto/openssl/ssl/Makefile b/crypto/openssl/ssl/Makefile
index debe07405bf8..8dd390e67f99 100644
--- a/crypto/openssl/ssl/Makefile
+++ b/crypto/openssl/ssl/Makefile
@@ -15,7 +15,7 @@ KRB5_INCLUDES=
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile README ssl-lib.com install.com
-TEST=ssltest.c
+TEST=ssltest.c heartbeat_test.c
APPS=
LIB=$(TOP)/libssl.a
@@ -30,7 +30,7 @@ LIBSRC= \
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
ssl_ciph.c ssl_stat.c ssl_rsa.c \
ssl_asn1.c ssl_txt.c ssl_algs.c \
- bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
+ bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c ssl_utst.c
LIBOBJ= \
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \
@@ -41,7 +41,7 @@ LIBOBJ= \
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
ssl_ciph.o ssl_stat.o ssl_rsa.o \
ssl_asn1.o ssl_txt.o ssl_algs.o \
- bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
+ bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o ssl_utst.o
SRC= $(LIBSRC)
@@ -547,26 +547,27 @@ s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
-s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
-s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_cbc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
-s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_cbc.o: ../include/openssl/sha.h ../include/openssl/srtp.h
-s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
+s3_cbc.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
+s3_cbc.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+s3_cbc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+s3_cbc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s3_cbc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s3_cbc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s3_cbc.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_cbc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s3_cbc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_cbc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_cbc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_cbc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_cbc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_cbc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_cbc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s3_cbc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_cbc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_cbc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_cbc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_cbc.c
+s3_cbc.o: ssl_locl.h
s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -671,28 +672,29 @@ s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c ssl_locl.h
-s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
-s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
-s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
+s3_srvr.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
+s3_srvr.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s3_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_srvr.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s3_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s3_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s3_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s3_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
+s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_srvr.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_srvr.o: s3_srvr.c ssl_locl.h
ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -915,6 +917,26 @@ ssl_txt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
ssl_txt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
ssl_txt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
ssl_txt.o: ssl_txt.c
+ssl_utst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+ssl_utst.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_utst.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_utst.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_utst.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_utst.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_utst.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_utst.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_utst.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_utst.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_utst.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_utst.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_utst.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_utst.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_utst.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+ssl_utst.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_utst.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_utst.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_utst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_utst.o: ssl_utst.c
t1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
t1_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
t1_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c
index bf40ccbeabc5..1b9d64bf6027 100644
--- a/crypto/openssl/ssl/d1_both.c
+++ b/crypto/openssl/ssl/d1_both.c
@@ -156,9 +156,8 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
/* XDTLS: figure out the right values */
-static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
+static const unsigned int g_probable_mtu[] = {1500, 512, 256};
-static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s,
@@ -211,8 +210,7 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
return frag;
}
-static void
-dtls1_hm_fragment_free(hm_fragment *frag)
+void dtls1_hm_fragment_free(hm_fragment *frag)
{
if (frag->msg_header.is_ccs)
@@ -225,53 +223,50 @@ dtls1_hm_fragment_free(hm_fragment *frag)
OPENSSL_free(frag);
}
-/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
-int dtls1_do_write(SSL *s, int type)
- {
- int ret;
- int curr_mtu;
- unsigned int len, frag_off, mac_size, blocksize;
+static int dtls1_query_mtu(SSL *s)
+{
+ if(s->d1->link_mtu)
+ {
+ s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+ s->d1->link_mtu = 0;
+ }
/* AHA! Figure out the MTU, and stick to the right size */
- if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+ if (s->d1->mtu < dtls1_min_mtu(s))
{
- s->d1->mtu =
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
-
- /* I've seen the kernel return bogus numbers when it doesn't know
- * (initial write), so just make sure we have a reasonable number */
- if (s->d1->mtu < dtls1_min_mtu())
+ if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
- s->d1->mtu = 0;
- s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
- s->d1->mtu, NULL);
+ s->d1->mtu =
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+ /* I've seen the kernel return bogus numbers when it doesn't know
+ * (initial write), so just make sure we have a reasonable number */
+ if (s->d1->mtu < dtls1_min_mtu(s))
+ {
+ /* Set to min mtu */
+ s->d1->mtu = dtls1_min_mtu(s);
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
+ s->d1->mtu, NULL);
+ }
}
+ else
+ return 0;
}
-#if 0
- mtu = s->d1->mtu;
-
- fprintf(stderr, "using MTU = %d\n", mtu);
-
- mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
-
- curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
+ return 1;
+}
- if ( curr_mtu > 0)
- mtu = curr_mtu;
- else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
- return ret;
+/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
+int dtls1_do_write(SSL *s, int type)
+ {
+ int ret;
+ unsigned int curr_mtu;
+ int retry = 1;
+ unsigned int len, frag_off, mac_size, blocksize, used_len;
- if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
- {
- ret = BIO_flush(SSL_get_wbio(s));
- if ( ret <= 0)
- return ret;
- mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
- }
-#endif
+ if(!dtls1_query_mtu(s))
+ return -1;
- OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */
+ OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something reasonable now */
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
OPENSSL_assert(s->init_num ==
@@ -289,10 +284,15 @@ int dtls1_do_write(SSL *s, int type)
blocksize = 0;
frag_off = 0;
- while( s->init_num)
+ /* s->init_num shouldn't ever be < 0...but just in case */
+ while(s->init_num > 0)
{
- curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
- DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
+ used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH
+ + mac_size + blocksize;
+ if(s->d1->mtu > used_len)
+ curr_mtu = s->d1->mtu - used_len;
+ else
+ curr_mtu = 0;
if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
{
@@ -300,15 +300,27 @@ int dtls1_do_write(SSL *s, int type)
ret = BIO_flush(SSL_get_wbio(s));
if ( ret <= 0)
return ret;
- curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
- mac_size - blocksize;
+ used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
+ if(s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH)
+ {
+ curr_mtu = s->d1->mtu - used_len;
+ }
+ else
+ {
+ /* Shouldn't happen */
+ return -1;
+ }
}
- if ( s->init_num > curr_mtu)
+ /* We just checked that s->init_num > 0 so this cast should be safe */
+ if (((unsigned int)s->init_num) > curr_mtu)
len = curr_mtu;
else
len = s->init_num;
+ /* Shouldn't ever happen */
+ if(len > INT_MAX)
+ len = INT_MAX;
/* XDTLS: this function is too long. split out the CCS part */
if ( type == SSL3_RT_HANDSHAKE)
@@ -319,17 +331,29 @@ int dtls1_do_write(SSL *s, int type)
s->init_off -= DTLS1_HM_HEADER_LENGTH;
s->init_num += DTLS1_HM_HEADER_LENGTH;
- /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
- if ( len <= DTLS1_HM_HEADER_LENGTH)
- len += DTLS1_HM_HEADER_LENGTH;
+ /* We just checked that s->init_num > 0 so this cast should be safe */
+ if (((unsigned int)s->init_num) > curr_mtu)
+ len = curr_mtu;
+ else
+ len = s->init_num;
}
+ /* Shouldn't ever happen */
+ if(len > INT_MAX)
+ len = INT_MAX;
+
+ if ( len < DTLS1_HM_HEADER_LENGTH )
+ {
+ /*
+ * len is so small that we really can't do anything sensible
+ * so fail
+ */
+ return -1;
+ }
dtls1_fix_message_header(s, frag_off,
len - DTLS1_HM_HEADER_LENGTH);
dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
-
- OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
}
ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
@@ -342,12 +366,23 @@ int dtls1_do_write(SSL *s, int type)
* is fine and wait for an alert to handle the
* retransmit
*/
- if ( BIO_ctrl(SSL_get_wbio(s),
+ if ( retry && BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
- s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
- BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+ {
+ if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+ {
+ if(!dtls1_query_mtu(s))
+ return -1;
+ /* Have one more go */
+ retry = 0;
+ }
+ else
+ return -1;
+ }
else
+ {
return(-1);
+ }
}
else
{
@@ -684,8 +719,8 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st* msg_hdr, int *ok)
item = pitem_new(seq64be, frag);
if (item == NULL)
{
- goto err;
i = -1;
+ goto err;
}
item = pqueue_insert(s->d1->buffered_messages, item);
@@ -1193,6 +1228,8 @@ dtls1_buffer_message(SSL *s, int is_ccs)
OPENSSL_assert(s->init_off == 0);
frag = dtls1_hm_fragment_new(s->init_num, 0);
+ if (!frag)
+ return 0;
memcpy(frag->fragment, s->init_buf->data, s->init_num);
@@ -1409,28 +1446,20 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
return p;
}
-unsigned int
-dtls1_min_mtu(void)
+unsigned int
+dtls1_link_min_mtu(void)
{
return (g_probable_mtu[(sizeof(g_probable_mtu) /
sizeof(g_probable_mtu[0])) - 1]);
}
-static unsigned int
-dtls1_guess_mtu(unsigned int curr_mtu)
+unsigned int
+dtls1_min_mtu(SSL *s)
{
- unsigned int i;
-
- if ( curr_mtu == 0 )
- return g_probable_mtu[0] ;
-
- for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
- if ( curr_mtu > g_probable_mtu[i])
- return g_probable_mtu[i];
-
- return curr_mtu;
+ return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
}
+
void
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
{
@@ -1489,6 +1518,9 @@ dtls1_process_heartbeat(SSL *s)
/* Read type and payload length first */
if (1 + 2 + 16 > s->s3->rrec.length)
return 0; /* silently discard */
+ if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
+
hbtype = *p++;
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c
index 6493796ad13b..9045fb9902f5 100644
--- a/crypto/openssl/ssl/d1_clnt.c
+++ b/crypto/openssl/ssl/d1_clnt.c
@@ -249,6 +249,9 @@ int dtls1_connect(SSL *s)
memset(s->s3->client_random,0,sizeof(s->s3->client_random));
s->d1->send_cookie = 0;
s->hit = 0;
+ s->d1->change_cipher_spec_ok = 0;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
break;
#ifndef OPENSSL_NO_SCTP
@@ -370,20 +373,6 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
-#ifndef OPENSSL_NO_TLSEXT
- ret=ssl3_check_finished(s);
- if (ret <= 0) goto end;
- if (ret == 2)
- {
- s->hit = 1;
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_CR_SESSION_TICKET_A;
- else
- s->state=SSL3_ST_CR_FINISHED_A;
- s->init_num=0;
- break;
- }
-#endif
/* Check if it is anon DH or PSK */
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
!(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -506,7 +495,6 @@ int dtls1_connect(SSL *s)
else
#endif
s->state=SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec=0;
}
s->init_num=0;
@@ -527,7 +515,6 @@ int dtls1_connect(SSL *s)
#endif
s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0;
- s->s3->change_cipher_spec=0;
break;
case SSL3_ST_CW_CHANGE_A:
@@ -538,13 +525,6 @@ int dtls1_connect(SSL *s)
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
if (ret <= 0) goto end;
-#ifndef OPENSSL_NO_SCTP
- /* Change to new shared key of SCTP-Auth,
- * will be ignored if no SCTP used.
- */
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
-#endif
-
s->state=SSL3_ST_CW_FINISHED_A;
s->init_num=0;
@@ -571,6 +551,16 @@ int dtls1_connect(SSL *s)
goto end;
}
+#ifndef OPENSSL_NO_SCTP
+ if (s->hit)
+ {
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+ }
+#endif
+
dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
break;
@@ -613,6 +603,13 @@ int dtls1_connect(SSL *s)
}
else
{
+#ifndef OPENSSL_NO_SCTP
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+
#ifndef OPENSSL_NO_TLSEXT
/* Allow NewSessionTicket if ticket expected */
if (s->tlsext_ticket_expected)
@@ -773,7 +770,7 @@ int dtls1_client_hello(SSL *s)
unsigned char *buf;
unsigned char *p,*d;
unsigned int i,j;
- unsigned long Time,l;
+ unsigned long l;
SSL_COMP *comp;
buf=(unsigned char *)s->init_buf->data;
@@ -798,13 +795,11 @@ int dtls1_client_hello(SSL *s)
/* if client_random is initialized, reuse it, we are
* required to use same upon reply to HelloVerify */
- for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
+ for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++)
+ ;
if (i==sizeof(s->s3->client_random))
- {
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
- }
+ ssl_fill_hello_random(s, 0, p,
+ sizeof(s->s3->client_random));
/* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
@@ -868,12 +863,18 @@ int dtls1_client_hello(SSL *s)
*(p++)=0; /* Add the NULL method */
#ifndef OPENSSL_NO_TLSEXT
+ /* TLS extensions*/
+ if (ssl_prepare_clienthello_tlsext(s) <= 0)
+ {
+ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+ goto err;
+ }
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
{
SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
goto err;
}
-#endif
+#endif
l=(p-d);
d=buf;
@@ -1716,6 +1717,12 @@ int dtls1_send_client_certificate(SSL *s)
s->state=SSL3_ST_CW_CERT_D;
l=dtls1_output_cert_chain(s,
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+ if (!l)
+ {
+ SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+ return 0;
+ }
s->init_num=(int)l;
s->init_off=0;
diff --git a/crypto/openssl/ssl/d1_enc.c b/crypto/openssl/ssl/d1_enc.c
index 712c4647f24c..3da2b4c8c2a7 100644
--- a/crypto/openssl/ssl/d1_enc.c
+++ b/crypto/openssl/ssl/d1_enc.c
@@ -241,7 +241,8 @@ int dtls1_enc(SSL *s, int send)
return 0;
}
- EVP_Cipher(ds,rec->data,rec->input,l);
+ if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
+ return -1;
#ifdef KSSL_DEBUG
{
diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c
index 43d3d9ee4b29..14337b31a4e9 100644
--- a/crypto/openssl/ssl/d1_lib.c
+++ b/crypto/openssl/ssl/d1_lib.c
@@ -113,6 +113,9 @@ int dtls1_new(SSL *s)
d1->cookie_len = sizeof(s->d1->cookie);
}
+ d1->link_mtu = 0;
+ d1->mtu = 0;
+
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
{
@@ -161,24 +164,25 @@ static void dtls1_clear_queues(SSL *s)
while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
{
frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ dtls1_hm_fragment_free(frag);
pitem_free(item);
}
while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
{
frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ dtls1_hm_fragment_free(frag);
pitem_free(item);
}
while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
{
- frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ rdata = (DTLS1_RECORD_DATA *) item->data;
+ if (rdata->rbuf.buf)
+ {
+ OPENSSL_free(rdata->rbuf.buf);
+ }
+ OPENSSL_free(item->data);
pitem_free(item);
}
}
@@ -196,6 +200,7 @@ void dtls1_free(SSL *s)
pqueue_free(s->d1->buffered_app_data.q);
OPENSSL_free(s->d1);
+ s->d1 = NULL;
}
void dtls1_clear(SSL *s)
@@ -206,6 +211,7 @@ void dtls1_clear(SSL *s)
pqueue sent_messages;
pqueue buffered_app_data;
unsigned int mtu;
+ unsigned int link_mtu;
if (s->d1)
{
@@ -215,6 +221,7 @@ void dtls1_clear(SSL *s)
sent_messages = s->d1->sent_messages;
buffered_app_data = s->d1->buffered_app_data.q;
mtu = s->d1->mtu;
+ link_mtu = s->d1->link_mtu;
dtls1_clear_queues(s);
@@ -228,6 +235,7 @@ void dtls1_clear(SSL *s)
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
{
s->d1->mtu = mtu;
+ s->d1->link_mtu = link_mtu;
}
s->d1->unprocessed_rcds.q = unprocessed_rcds;
@@ -272,7 +280,22 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
/* Just one protocol version is supported so far;
* fail closed if the version is not as expected. */
return s->version == DTLS_MAX_VERSION;
-
+ case DTLS_CTRL_SET_LINK_MTU:
+ if (larg < (long)dtls1_link_min_mtu())
+ return 0;
+ s->d1->link_mtu = larg;
+ return 1;
+ case DTLS_CTRL_GET_LINK_MIN_MTU:
+ return (long)dtls1_link_min_mtu();
+ case SSL_CTRL_SET_MTU:
+ /*
+ * We may not have a BIO set yet so can't call dtls1_min_mtu()
+ * We'll have to make do with dtls1_link_min_mtu() and max overhead
+ */
+ if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
+ return 0;
+ s->d1->mtu = larg;
+ return larg;
default:
ret = ssl3_ctrl(s, cmd, larg, parg);
break;
@@ -411,12 +434,17 @@ void dtls1_stop_timer(SSL *s)
int dtls1_check_timeout_num(SSL *s)
{
+ unsigned int mtu;
+
s->d1->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
- if (s->d1->timeout.num_alerts > 2)
+ if (s->d1->timeout.num_alerts > 2
+ && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
- s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ if(mtu < s->d1->mtu)
+ s->d1->mtu = mtu;
}
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c
index 2a07d966a1fe..0059fe2f152d 100644
--- a/crypto/openssl/ssl/d1_pkt.c
+++ b/crypto/openssl/ssl/d1_pkt.c
@@ -855,6 +855,12 @@ start:
}
}
+ if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE)
+ {
+ rr->length = 0;
+ goto start;
+ }
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1063,6 +1069,7 @@ start:
!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
!s->s3->renegotiate)
{
+ s->d1->handshake_read_seq++;
s->new_session = 1;
ssl3_renegotiate(s);
if (ssl3_renegotiate_check(s))
@@ -1623,7 +1630,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
wr->length += bs;
}
- s->method->ssl3_enc->enc(s,1);
+ if(s->method->ssl3_enc->enc(s,1) < 1) goto err;
/* record length after mac and block padding */
/* if (type == SSL3_RT_APPLICATION_DATA ||
diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c
index d1a11ad9edbd..da4c21e06a1c 100644
--- a/crypto/openssl/ssl/d1_srvr.c
+++ b/crypto/openssl/ssl/d1_srvr.c
@@ -233,6 +233,7 @@ int dtls1_accept(SSL *s)
}
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{
+ BUF_MEM_free(buf);
ret= -1;
goto end;
}
@@ -246,6 +247,9 @@ int dtls1_accept(SSL *s)
}
s->init_num=0;
+ s->d1->change_cipher_spec_ok = 0;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE)
{
@@ -276,10 +280,11 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_HELLO_REQ_B:
s->shutdown=0;
+ dtls1_clear_record_buffer(s);
dtls1_start_timer(s);
ret=dtls1_send_hello_request(s);
if (ret <= 0) goto end;
- s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
+ s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
s->state=SSL3_ST_SW_FLUSH;
s->init_num=0;
@@ -588,10 +593,11 @@ int dtls1_accept(SSL *s)
s->state = SSL3_ST_SR_CLNT_HELLO_C;
}
else {
- /* could be sent for a DH cert, even if we
- * have not asked for it :-) */
- ret=ssl3_get_client_certificate(s);
- if (ret <= 0) goto end;
+ if (s->s3->tmp.cert_request)
+ {
+ ret=ssl3_get_client_certificate(s);
+ if (ret <= 0) goto end;
+ }
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
@@ -647,8 +653,14 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
-
- s->d1->change_cipher_spec_ok = 1;
+ /*
+ * This *should* be the first time we enable CCS, but be
+ * extra careful about surrounding code changes. We need
+ * to set this here because we don't know if we're
+ * expecting a CertificateVerify or not.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->d1->change_cipher_spec_ok = 1;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -664,7 +676,18 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- s->d1->change_cipher_spec_ok = 1;
+ /*
+ * Enable CCS for resumed handshakes.
+ * In a full handshake, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, so change_cipher_spec_ok was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in d1_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->d1->change_cipher_spec_ok = 1;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
@@ -712,10 +735,13 @@ int dtls1_accept(SSL *s)
if (ret <= 0) goto end;
#ifndef OPENSSL_NO_SCTP
- /* Change to new shared key of SCTP-Auth,
- * will be ignored if no SCTP used.
- */
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+ if (!s->hit)
+ {
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+ }
#endif
s->state=SSL3_ST_SW_FINISHED_A;
@@ -740,7 +766,16 @@ int dtls1_accept(SSL *s)
if (ret <= 0) goto end;
s->state=SSL3_ST_SW_FLUSH;
if (s->hit)
+ {
s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+ }
else
{
s->s3->tmp.next_state=SSL_ST_OK;
@@ -903,15 +938,13 @@ int dtls1_send_server_hello(SSL *s)
unsigned char *p,*d;
int i;
unsigned int sl;
- unsigned long l,Time;
+ unsigned long l;
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
{
buf=(unsigned char *)s->init_buf->data;
p=s->s3->server_random;
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
+ ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE);
/* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
@@ -960,6 +993,11 @@ int dtls1_send_server_hello(SSL *s)
#endif
#ifndef OPENSSL_NO_TLSEXT
+ if (ssl_prepare_serverhello_tlsext(s) <= 0)
+ {
+ SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
+ return -1;
+ }
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
{
SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
@@ -1336,6 +1374,7 @@ int dtls1_send_server_key_exchange(SSL *s)
(unsigned char *)encodedPoint,
encodedlen);
OPENSSL_free(encodedPoint);
+ encodedPoint = NULL;
p += encodedlen;
}
#endif
@@ -1577,6 +1616,11 @@ int dtls1_send_server_certificate(SSL *s)
}
l=dtls1_output_cert_chain(s,x);
+ if (!l)
+ {
+ SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+ return(0);
+ }
s->state=SSL3_ST_SW_CERT_B;
s->init_num=(int)l;
s->init_off=0;
diff --git a/crypto/openssl/ssl/dtls1.h b/crypto/openssl/ssl/dtls1.h
index 192c5deff98a..338575268f9e 100644
--- a/crypto/openssl/ssl/dtls1.h
+++ b/crypto/openssl/ssl/dtls1.h
@@ -117,6 +117,9 @@ extern "C" {
#define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP"
#endif
+/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
+#define DTLS1_MAX_MTU_OVERHEAD 48
+
typedef struct dtls1_bitmap_st
{
unsigned long map; /* track 32 packets on 32-bit systems
@@ -231,6 +234,7 @@ typedef struct dtls1_state_st
/* Is set when listening for new connections with dtls1_listen() */
unsigned int listen;
+ unsigned int link_mtu; /* max on-the-wire DTLS packet size */
unsigned int mtu; /* max DTLS packet size */
struct hm_header_st w_msg_hdr;
@@ -252,6 +256,10 @@ typedef struct dtls1_state_st
unsigned int handshake_fragment_len;
unsigned int retransmitting;
+ /*
+ * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+ * Cleared after the message has been processed.
+ */
unsigned int change_cipher_spec_ok;
#ifndef OPENSSL_NO_SCTP
diff --git a/crypto/openssl/ssl/heartbeat_test.c b/crypto/openssl/ssl/heartbeat_test.c
new file mode 100644
index 000000000000..de9d39761ef8
--- /dev/null
+++ b/crypto/openssl/ssl/heartbeat_test.c
@@ -0,0 +1,466 @@
+/* test/heartbeat_test.c */
+/*
+ * Unit test for TLS heartbeats.
+ *
+ * Acts as a regression test against the Heartbleed bug (CVE-2014-0160).
+ *
+ * Author: Mike Bland (mbland@acm.org, http://mike-bland.com/)
+ * Date: 2014-04-12
+ * License: Creative Commons Attribution 4.0 International (CC By 4.0)
+ * http://creativecommons.org/licenses/by/4.0/deed.en_US
+ *
+ * OUTPUT
+ * ------
+ * The program returns zero on success. It will print a message with a count
+ * of the number of failed tests and return nonzero if any tests fail.
+ *
+ * It will print the contents of the request and response buffers for each
+ * failing test. In a "fixed" version, all the tests should pass and there
+ * should be no output.
+ *
+ * In a "bleeding" version, you'll see:
+ *
+ * test_dtls1_heartbleed failed:
+ * expected payload len: 0
+ * received: 1024
+ * sent 26 characters
+ * "HEARTBLEED "
+ * received 1024 characters
+ * "HEARTBLEED \xde\xad\xbe\xef..."
+ * ** test_dtls1_heartbleed failed **
+ *
+ * The contents of the returned buffer in the failing test will depend on the
+ * contents of memory on your machine.
+ *
+ * MORE INFORMATION
+ * ----------------
+ * http://mike-bland.com/2014/04/12/heartbleed.html
+ * http://mike-bland.com/tags/heartbleed.html
+ */
+
+#define OPENSSL_UNIT_TEST
+
+#include "../test/testutil.h"
+
+#include "../ssl/ssl_locl.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_HEARTBEATS) && !defined(OPENSSL_NO_UNIT_TEST)
+
+/* As per https://tools.ietf.org/html/rfc6520#section-4 */
+#define MIN_PADDING_SIZE 16
+
+/* Maximum number of payload characters to print as test output */
+#define MAX_PRINTABLE_CHARACTERS 1024
+
+typedef struct heartbeat_test_fixture
+ {
+ SSL_CTX *ctx;
+ SSL *s;
+ const char* test_case_name;
+ int (*process_heartbeat)(SSL* s);
+ unsigned char* payload;
+ int sent_payload_len;
+ int expected_return_value;
+ int return_payload_offset;
+ int expected_payload_len;
+ const char* expected_return_payload;
+ } HEARTBEAT_TEST_FIXTURE;
+
+static HEARTBEAT_TEST_FIXTURE set_up(const char* const test_case_name,
+ const SSL_METHOD* meth)
+ {
+ HEARTBEAT_TEST_FIXTURE fixture;
+ int setup_ok = 1;
+ memset(&fixture, 0, sizeof(fixture));
+ fixture.test_case_name = test_case_name;
+
+ fixture.ctx = SSL_CTX_new(meth);
+ if (!fixture.ctx)
+ {
+ fprintf(stderr, "Failed to allocate SSL_CTX for test: %s\n",
+ test_case_name);
+ setup_ok = 0;
+ goto fail;
+ }
+
+ fixture.s = SSL_new(fixture.ctx);
+ if (!fixture.s)
+ {
+ fprintf(stderr, "Failed to allocate SSL for test: %s\n", test_case_name);
+ setup_ok = 0;
+ goto fail;
+ }
+
+ if (!ssl_init_wbio_buffer(fixture.s, 1))
+ {
+ fprintf(stderr, "Failed to set up wbio buffer for test: %s\n",
+ test_case_name);
+ setup_ok = 0;
+ goto fail;
+ }
+
+ if (!ssl3_setup_buffers(fixture.s))
+ {
+ fprintf(stderr, "Failed to setup buffers for test: %s\n",
+ test_case_name);
+ setup_ok = 0;
+ goto fail;
+ }
+
+ /* Clear the memory for the return buffer, since this isn't automatically
+ * zeroed in opt mode and will cause spurious test failures that will change
+ * with each execution.
+ */
+ memset(fixture.s->s3->wbuf.buf, 0, fixture.s->s3->wbuf.len);
+
+ fail:
+ if (!setup_ok)
+ {
+ ERR_print_errors_fp(stderr);
+ exit(EXIT_FAILURE);
+ }
+ return fixture;
+ }
+
+static HEARTBEAT_TEST_FIXTURE set_up_dtls(const char* const test_case_name)
+ {
+ HEARTBEAT_TEST_FIXTURE fixture = set_up(test_case_name,
+ DTLSv1_server_method());
+ fixture.process_heartbeat = dtls1_process_heartbeat;
+
+ /* As per dtls1_get_record(), skipping the following from the beginning of
+ * the returned heartbeat message:
+ * type-1 byte; version-2 bytes; sequence number-8 bytes; length-2 bytes
+ *
+ * And then skipping the 1-byte type encoded by process_heartbeat for
+ * a total of 14 bytes, at which point we can grab the length and the
+ * payload we seek.
+ */
+ fixture.return_payload_offset = 14;
+ return fixture;
+ }
+
+/* Needed by ssl3_write_bytes() */
+static int dummy_handshake(SSL* s)
+ {
+ return 1;
+ }
+
+static HEARTBEAT_TEST_FIXTURE set_up_tls(const char* const test_case_name)
+ {
+ HEARTBEAT_TEST_FIXTURE fixture = set_up(test_case_name,
+ TLSv1_server_method());
+ fixture.process_heartbeat = tls1_process_heartbeat;
+ fixture.s->handshake_func = dummy_handshake;
+
+ /* As per do_ssl3_write(), skipping the following from the beginning of
+ * the returned heartbeat message:
+ * type-1 byte; version-2 bytes; length-2 bytes
+ *
+ * And then skipping the 1-byte type encoded by process_heartbeat for
+ * a total of 6 bytes, at which point we can grab the length and the payload
+ * we seek.
+ */
+ fixture.return_payload_offset = 6;
+ return fixture;
+ }
+
+static void tear_down(HEARTBEAT_TEST_FIXTURE fixture)
+ {
+ ERR_print_errors_fp(stderr);
+ SSL_free(fixture.s);
+ SSL_CTX_free(fixture.ctx);
+ }
+
+static void print_payload(const char* const prefix,
+ const unsigned char *payload, const int n)
+ {
+ const int end = n < MAX_PRINTABLE_CHARACTERS ? n
+ : MAX_PRINTABLE_CHARACTERS;
+ int i = 0;
+
+ printf("%s %d character%s", prefix, n, n == 1 ? "" : "s");
+ if (end != n) printf(" (first %d shown)", end);
+ printf("\n \"");
+
+ for (; i != end; ++i)
+ {
+ const unsigned char c = payload[i];
+ if (isprint(c)) fputc(c, stdout);
+ else printf("\\x%02x", c);
+ }
+ printf("\"\n");
+ }
+
+static int execute_heartbeat(HEARTBEAT_TEST_FIXTURE fixture)
+ {
+ int result = 0;
+ SSL* s = fixture.s;
+ unsigned char *payload = fixture.payload;
+ unsigned char sent_buf[MAX_PRINTABLE_CHARACTERS + 1];
+ int return_value;
+ unsigned const char *p;
+ int actual_payload_len;
+
+ s->s3->rrec.data = payload;
+ s->s3->rrec.length = strlen((const char*)payload);
+ *payload++ = TLS1_HB_REQUEST;
+ s2n(fixture.sent_payload_len, payload);
+
+ /* Make a local copy of the request, since it gets overwritten at some
+ * point */
+ memcpy((char *)sent_buf, (const char*)payload, sizeof(sent_buf));
+
+ return_value = fixture.process_heartbeat(s);
+
+ if (return_value != fixture.expected_return_value)
+ {
+ printf("%s failed: expected return value %d, received %d\n",
+ fixture.test_case_name, fixture.expected_return_value,
+ return_value);
+ result = 1;
+ }
+
+ /* If there is any byte alignment, it will be stored in wbuf.offset. */
+ p = &(s->s3->wbuf.buf[
+ fixture.return_payload_offset + s->s3->wbuf.offset]);
+ actual_payload_len = 0;
+ n2s(p, actual_payload_len);
+
+ if (actual_payload_len != fixture.expected_payload_len)
+ {
+ printf("%s failed:\n expected payload len: %d\n received: %d\n",
+ fixture.test_case_name, fixture.expected_payload_len,
+ actual_payload_len);
+ print_payload("sent", sent_buf, strlen((const char*)sent_buf));
+ print_payload("received", p, actual_payload_len);
+ result = 1;
+ }
+ else
+ {
+ char* actual_payload = BUF_strndup((const char*)p, actual_payload_len);
+ if (strcmp(actual_payload, fixture.expected_return_payload) != 0)
+ {
+ printf("%s failed:\n expected payload: \"%s\"\n received: \"%s\"\n",
+ fixture.test_case_name, fixture.expected_return_payload,
+ actual_payload);
+ result = 1;
+ }
+ OPENSSL_free(actual_payload);
+ }
+
+ if (result != 0)
+ {
+ printf("** %s failed **\n--------\n", fixture.test_case_name);
+ }
+ return result;
+ }
+
+static int honest_payload_size(unsigned char payload_buf[])
+ {
+ /* Omit three-byte pad at the beginning for type and payload length */
+ return strlen((const char*)&payload_buf[3]) - MIN_PADDING_SIZE;
+ }
+
+#define SETUP_HEARTBEAT_TEST_FIXTURE(type)\
+ SETUP_TEST_FIXTURE(HEARTBEAT_TEST_FIXTURE, set_up_##type)
+
+#define EXECUTE_HEARTBEAT_TEST()\
+ EXECUTE_TEST(execute_heartbeat, tear_down)
+
+static int test_dtls1_not_bleeding()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(dtls);
+ /* Three-byte pad at the beginning for type and payload length */
+ unsigned char payload_buf[] = " Not bleeding, sixteen spaces of padding"
+ " ";
+ const int payload_buf_len = honest_payload_size(payload_buf);
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = payload_buf_len;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = payload_buf_len;
+ fixture.expected_return_payload = "Not bleeding, sixteen spaces of padding";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_dtls1_not_bleeding_empty_payload()
+ {
+ int payload_buf_len;
+
+ SETUP_HEARTBEAT_TEST_FIXTURE(dtls);
+ /* Three-byte pad at the beginning for type and payload length, plus a NUL
+ * at the end */
+ unsigned char payload_buf[4 + MIN_PADDING_SIZE];
+ memset(payload_buf, ' ', sizeof(payload_buf));
+ payload_buf[sizeof(payload_buf) - 1] = '\0';
+ payload_buf_len = honest_payload_size(payload_buf);
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = payload_buf_len;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = payload_buf_len;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_dtls1_heartbleed()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(dtls);
+ /* Three-byte pad at the beginning for type and payload length */
+ unsigned char payload_buf[] = " HEARTBLEED ";
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = MAX_PRINTABLE_CHARACTERS;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = 0;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_dtls1_heartbleed_empty_payload()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(dtls);
+ /* Excluding the NUL at the end, one byte short of type + payload length +
+ * minimum padding */
+ unsigned char payload_buf[MIN_PADDING_SIZE + 3];
+ memset(payload_buf, ' ', sizeof(payload_buf));
+ payload_buf[sizeof(payload_buf) - 1] = '\0';
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = MAX_PRINTABLE_CHARACTERS;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = 0;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_dtls1_heartbleed_excessive_plaintext_length()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(dtls);
+ /* Excluding the NUL at the end, one byte in excess of maximum allowed
+ * heartbeat message length */
+ unsigned char payload_buf[SSL3_RT_MAX_PLAIN_LENGTH + 2];
+ memset(payload_buf, ' ', sizeof(payload_buf));
+ payload_buf[sizeof(payload_buf) - 1] = '\0';
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = honest_payload_size(payload_buf);
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = 0;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_tls1_not_bleeding()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(tls);
+ /* Three-byte pad at the beginning for type and payload length */
+ unsigned char payload_buf[] = " Not bleeding, sixteen spaces of padding"
+ " ";
+ const int payload_buf_len = honest_payload_size(payload_buf);
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = payload_buf_len;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = payload_buf_len;
+ fixture.expected_return_payload = "Not bleeding, sixteen spaces of padding";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_tls1_not_bleeding_empty_payload()
+ {
+ int payload_buf_len;
+
+ SETUP_HEARTBEAT_TEST_FIXTURE(tls);
+ /* Three-byte pad at the beginning for type and payload length, plus a NUL
+ * at the end */
+ unsigned char payload_buf[4 + MIN_PADDING_SIZE];
+ memset(payload_buf, ' ', sizeof(payload_buf));
+ payload_buf[sizeof(payload_buf) - 1] = '\0';
+ payload_buf_len = honest_payload_size(payload_buf);
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = payload_buf_len;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = payload_buf_len;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_tls1_heartbleed()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(tls);
+ /* Three-byte pad at the beginning for type and payload length */
+ unsigned char payload_buf[] = " HEARTBLEED ";
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = MAX_PRINTABLE_CHARACTERS;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = 0;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+static int test_tls1_heartbleed_empty_payload()
+ {
+ SETUP_HEARTBEAT_TEST_FIXTURE(tls);
+ /* Excluding the NUL at the end, one byte short of type + payload length +
+ * minimum padding */
+ unsigned char payload_buf[MIN_PADDING_SIZE + 3];
+ memset(payload_buf, ' ', sizeof(payload_buf));
+ payload_buf[sizeof(payload_buf) - 1] = '\0';
+
+ fixture.payload = &payload_buf[0];
+ fixture.sent_payload_len = MAX_PRINTABLE_CHARACTERS;
+ fixture.expected_return_value = 0;
+ fixture.expected_payload_len = 0;
+ fixture.expected_return_payload = "";
+ EXECUTE_HEARTBEAT_TEST();
+ }
+
+#undef EXECUTE_HEARTBEAT_TEST
+#undef SETUP_HEARTBEAT_TEST_FIXTURE
+
+int main(int argc, char *argv[])
+ {
+ int num_failed;
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ num_failed = test_dtls1_not_bleeding() +
+ test_dtls1_not_bleeding_empty_payload() +
+ test_dtls1_heartbleed() +
+ test_dtls1_heartbleed_empty_payload() +
+ /* The following test causes an assertion failure at
+ * ssl/d1_pkt.c:dtls1_write_bytes() in versions prior to 1.0.1g: */
+ (OPENSSL_VERSION_NUMBER >= 0x1000107fL ?
+ test_dtls1_heartbleed_excessive_plaintext_length() : 0) +
+ test_tls1_not_bleeding() +
+ test_tls1_not_bleeding_empty_payload() +
+ test_tls1_heartbleed() +
+ test_tls1_heartbleed_empty_payload() +
+ 0;
+
+ ERR_print_errors_fp(stderr);
+
+ if (num_failed != 0)
+ {
+ printf("%d test%s failed\n", num_failed, num_failed != 1 ? "s" : "");
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+ }
+
+#else /* OPENSSL_NO_HEARTBEATS*/
+
+int main(int argc, char *argv[])
+ {
+ return EXIT_SUCCESS;
+ }
+#endif /* OPENSSL_NO_HEARTBEATS */
diff --git a/crypto/openssl/ssl/kssl.c b/crypto/openssl/ssl/kssl.c
index fd7c67bb1fcb..950a0c56f1a9 100644
--- a/crypto/openssl/ssl/kssl.c
+++ b/crypto/openssl/ssl/kssl.c
@@ -954,15 +954,15 @@ print_krb5_data(char *label, krb5_data *kdata)
{
int i;
- printf("%s[%d] ", label, kdata->length);
+ fprintf(stderr,"%s[%d] ", label, kdata->length);
for (i=0; i < (int)kdata->length; i++)
{
if (0 && isprint((int) kdata->data[i]))
- printf( "%c ", kdata->data[i]);
+ fprintf(stderr, "%c ", kdata->data[i]);
else
- printf( "%02x ", (unsigned char) kdata->data[i]);
+ fprintf(stderr, "%02x ", (unsigned char) kdata->data[i]);
}
- printf("\n");
+ fprintf(stderr,"\n");
}
@@ -973,20 +973,20 @@ print_krb5_authdata(char *label, krb5_authdata **adata)
{
if (adata == NULL)
{
- printf("%s, authdata==0\n", label);
+ fprintf(stderr,"%s, authdata==0\n", label);
return;
}
- printf("%s [%p]\n", label, (void *)adata);
+ fprintf(stderr,"%s [%p]\n", label, (void *)adata);
#if 0
{
int i;
- printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
+ fprintf(stderr,"%s[at%d:%d] ", label, adata->ad_type, adata->length);
for (i=0; i < adata->length; i++)
{
- printf((isprint(adata->contents[i]))? "%c ": "%02x",
+ fprintf(stderr,(isprint(adata->contents[i]))? "%c ": "%02x",
adata->contents[i]);
}
- printf("\n");
+ fprintf(stderr,"\n");
}
#endif
}
@@ -1001,24 +1001,24 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
if (keyblk == NULL)
{
- printf("%s, keyblk==0\n", label);
+ fprintf(stderr,"%s, keyblk==0\n", label);
return;
}
#ifdef KRB5_HEIMDAL
- printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype,
+ fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->keytype,
keyblk->keyvalue->length);
for (i=0; i < (int)keyblk->keyvalue->length; i++)
{
- printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
+ fprintf(stderr,"%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
}
- printf("\n");
+ fprintf(stderr,"\n");
#else
- printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
+ fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
for (i=0; i < (int)keyblk->length; i++)
{
- printf("%02x",keyblk->contents[i]);
+ fprintf(stderr,"%02x",keyblk->contents[i]);
}
- printf("\n");
+ fprintf(stderr,"\n");
#endif
}
@@ -1031,17 +1031,17 @@ print_krb5_princ(char *label, krb5_principal_data *princ)
{
int i, ui, uj;
- printf("%s principal Realm: ", label);
+ fprintf(stderr,"%s principal Realm: ", label);
if (princ == NULL) return;
for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.data[ui]);
- printf(" (nametype %d) has %d strings:\n", princ->type,princ->length);
+ fprintf(stderr," (nametype %d) has %d strings:\n", princ->type,princ->length);
for (i=0; i < (int)princ->length; i++)
{
- printf("\t%d [%d]: ", i, princ->data[i].length);
+ fprintf(stderr,"\t%d [%d]: ", i, princ->data[i].length);
for (uj=0; uj < (int)princ->data[i].length; uj++) {
putchar(princ->data[i].data[uj]);
}
- printf("\n");
+ fprintf(stderr,"\n");
}
return;
}
@@ -1332,7 +1332,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
}
#ifdef KSSL_DEBUG
- printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
+ fprintf(stderr,"in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
#endif /* KSSL_DEBUG */
if (!krb5context && (krb5rc = krb5_init_context(&krb5context)))
@@ -1481,18 +1481,18 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
#ifdef KSSL_DEBUG
{
int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs;
- printf("Decrypted ticket fields:\n");
- printf("\tflags: %X, transit-type: %X",
+ fprintf(stderr,"Decrypted ticket fields:\n");
+ fprintf(stderr,"\tflags: %X, transit-type: %X",
krb5ticket->enc_part2->flags,
krb5ticket->enc_part2->transited.tr_type);
print_krb5_data("\ttransit-data: ",
&(krb5ticket->enc_part2->transited.tr_contents));
- printf("\tcaddrs: %p, authdata: %p\n",
+ fprintf(stderr,"\tcaddrs: %p, authdata: %p\n",
krb5ticket->enc_part2->caddrs,
krb5ticket->enc_part2->authorization_data);
if (paddr)
{
- printf("\tcaddrs:\n");
+ fprintf(stderr,"\tcaddrs:\n");
for (i=0; paddr[i] != NULL; i++)
{
krb5_data d;
@@ -1501,7 +1501,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
print_krb5_data("\t\tIP: ", &d);
}
}
- printf("\tstart/auth/end times: %d / %d / %d\n",
+ fprintf(stderr,"\tstart/auth/end times: %d / %d / %d\n",
krb5ticket->enc_part2->times.starttime,
krb5ticket->enc_part2->times.authtime,
krb5ticket->enc_part2->times.endtime);
@@ -1976,7 +1976,7 @@ krb5_error_code kssl_validate_times( krb5_timestamp atime,
if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED;
#ifdef KSSL_DEBUG
- printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n",
+ fprintf(stderr,"kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n",
start, atime, now, skew, ttimes->endtime);
#endif /* KSSL_DEBUG */
@@ -2027,10 +2027,10 @@ krb5_error_code kssl_check_authent(
#ifdef KSSL_DEBUG
{
unsigned int ui;
- printf("kssl_check_authent: authenticator[%d]:\n",authentp->length);
+ fprintf(stderr,"kssl_check_authent: authenticator[%d]:\n",authentp->length);
p = authentp->data;
- for (ui=0; ui < authentp->length; ui++) printf("%02x ",p[ui]);
- printf("\n");
+ for (ui=0; ui < authentp->length; ui++) fprintf(stderr,"%02x ",p[ui]);
+ fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -2095,9 +2095,9 @@ krb5_error_code kssl_check_authent(
#ifdef KSSL_DEBUG
{
int padl;
- printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
- for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
- printf("\n");
+ fprintf(stderr,"kssl_check_authent: decrypted authenticator[%d] =\n", outl);
+ for (padl=0; padl < outl; padl++) fprintf(stderr,"%02x ",unenc_authent[padl]);
+ fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -2132,10 +2132,10 @@ krb5_error_code kssl_check_authent(
}
#ifdef KSSL_DEBUG
- printf("kssl_check_authent: returns %d for client time ", *atimep);
+ fprintf(stderr,"kssl_check_authent: returns %d for client time ", *atimep);
if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
- printf("%.*s\n", auth->ctime->length, auth->ctime->data);
- else printf("NULL\n");
+ fprintf(stderr,"%.*s\n", auth->ctime->length, auth->ctime->data);
+ else fprintf(stderr,"NULL\n");
#endif /* KSSL_DEBUG */
err:
diff --git a/crypto/openssl/ssl/kssl.h b/crypto/openssl/ssl/kssl.h
index 8242fd5eeb65..e4df84307313 100644
--- a/crypto/openssl/ssl/kssl.h
+++ b/crypto/openssl/ssl/kssl.h
@@ -70,6 +70,15 @@
#include <stdio.h>
#include <ctype.h>
#include <krb5.h>
+#ifdef OPENSSL_SYS_WIN32
+/* These can sometimes get redefined indirectly by krb5 header files
+ * after they get undefed in ossl_typ.h
+ */
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/crypto/openssl/ssl/s23_clnt.c b/crypto/openssl/ssl/s23_clnt.c
index 617f70e76006..86ab3de1c123 100644
--- a/crypto/openssl/ssl/s23_clnt.c
+++ b/crypto/openssl/ssl/s23_clnt.c
@@ -271,12 +271,35 @@ static int ssl23_no_ssl2_ciphers(SSL *s)
return 1;
}
+/* Fill a ClientRandom or ServerRandom field of length len. Returns <= 0
+ * on failure, 1 on success. */
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
+ {
+ int send_time = 0;
+
+ if (len < 4)
+ return 0;
+ if (server)
+ send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
+ else
+ send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
+ if (send_time)
+ {
+ unsigned long Time = (unsigned long)time(NULL);
+ unsigned char *p = result;
+ l2n(Time, p);
+ return RAND_pseudo_bytes(p, len-4);
+ }
+ else
+ return RAND_pseudo_bytes(result, len);
+ }
+
static int ssl23_client_hello(SSL *s)
{
unsigned char *buf;
unsigned char *p,*d;
int i,ch_len;
- unsigned long Time,l;
+ unsigned long l;
int ssl2_compat;
int version = 0, version_major, version_minor;
#ifndef OPENSSL_NO_COMP
@@ -357,9 +380,7 @@ static int ssl23_client_hello(SSL *s)
#endif
p=s->s3->client_random;
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+ if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
return -1;
if (version == TLS1_2_VERSION)
diff --git a/crypto/openssl/ssl/s23_lib.c b/crypto/openssl/ssl/s23_lib.c
index 3bf728318a4c..f3c29d1dde61 100644
--- a/crypto/openssl/ssl/s23_lib.c
+++ b/crypto/openssl/ssl/s23_lib.c
@@ -107,6 +107,13 @@ int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
long l;
/* We can write SSLv2 and SSLv3 ciphers */
+ /* but no ECC ciphers */
+ if (c->algorithm_mkey == SSL_kECDHr ||
+ c->algorithm_mkey == SSL_kECDHe ||
+ c->algorithm_mkey == SSL_kEECDH ||
+ c->algorithm_auth == SSL_aECDH ||
+ c->algorithm_auth == SSL_aECDSA)
+ return 0;
if (p != NULL)
{
l=c->id;
diff --git a/crypto/openssl/ssl/s23_srvr.c b/crypto/openssl/ssl/s23_srvr.c
index de909b180851..3178815ec99b 100644
--- a/crypto/openssl/ssl/s23_srvr.c
+++ b/crypto/openssl/ssl/s23_srvr.c
@@ -192,6 +192,7 @@ int ssl23_accept(SSL *s)
}
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{
+ BUF_MEM_free(buf);
ret= -1;
goto end;
}
diff --git a/crypto/openssl/ssl/s2_enc.c b/crypto/openssl/ssl/s2_enc.c
index ff3395f459e7..a35968f63a7f 100644
--- a/crypto/openssl/ssl/s2_enc.c
+++ b/crypto/openssl/ssl/s2_enc.c
@@ -117,8 +117,9 @@ err:
/* read/writes from s->s2->mac_data using length for encrypt and
* decrypt. It sets s->s2->padding and s->[rw]length
- * if we are encrypting */
-void ssl2_enc(SSL *s, int send)
+ * if we are encrypting
+ * Returns 0 on error and 1 on success */
+int ssl2_enc(SSL *s, int send)
{
EVP_CIPHER_CTX *ds;
unsigned long l;
@@ -136,7 +137,7 @@ void ssl2_enc(SSL *s, int send)
}
/* check for NULL cipher */
- if (ds == NULL) return;
+ if (ds == NULL) return 1;
bs=ds->cipher->block_size;
@@ -145,7 +146,10 @@ void ssl2_enc(SSL *s, int send)
if (bs == 8)
l=(l+7)/8*8;
- EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
+ if(EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l) < 1)
+ return 0;
+
+ return 1;
}
void ssl2_mac(SSL *s, unsigned char *md, int send)
diff --git a/crypto/openssl/ssl/s2_lib.c b/crypto/openssl/ssl/s2_lib.c
index 8c9b642882eb..c63be3052b28 100644
--- a/crypto/openssl/ssl/s2_lib.c
+++ b/crypto/openssl/ssl/s2_lib.c
@@ -250,7 +250,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[]={
SSL_SSLV2,
SSL_NOT_EXP|SSL_HIGH,
0,
- 168,
+ 112,
168,
},
diff --git a/crypto/openssl/ssl/s2_pkt.c b/crypto/openssl/ssl/s2_pkt.c
index 8bb6ab8baa33..acd61dc546af 100644
--- a/crypto/openssl/ssl/s2_pkt.c
+++ b/crypto/openssl/ssl/s2_pkt.c
@@ -265,7 +265,11 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
if ((!s->s2->clear_text) &&
(s->s2->rlength >= (unsigned int)mac_size))
{
- ssl2_enc(s,0);
+ if(!ssl2_enc(s,0))
+ {
+ SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_DECRYPTION_FAILED);
+ return(-1);
+ }
s->s2->ract_data_length-=mac_size;
ssl2_mac(s,mac,0);
s->s2->ract_data_length-=s->s2->padding;
@@ -616,7 +620,8 @@ static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
s->s2->wact_data_length=len+p;
ssl2_mac(s,s->s2->mac_data,1);
s->s2->wlength+=p+mac_size;
- ssl2_enc(s,1);
+ if(ssl2_enc(s,1) < 1)
+ return -1;
}
/* package up the header */
diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c
index 2cba426bb7ef..59ced3f3052f 100644
--- a/crypto/openssl/ssl/s2_srvr.c
+++ b/crypto/openssl/ssl/s2_srvr.c
@@ -188,13 +188,21 @@ int ssl2_accept(SSL *s)
s->version=SSL2_VERSION;
s->type=SSL_ST_ACCEPT;
- buf=s->init_buf;
- if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
- { ret= -1; goto end; }
- if (!BUF_MEM_grow(buf,(int)
- SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
- { ret= -1; goto end; }
- s->init_buf=buf;
+ if(s->init_buf == NULL)
+ {
+ if ((buf=BUF_MEM_new()) == NULL)
+ {
+ ret= -1;
+ goto end;
+ }
+ if (!BUF_MEM_grow(buf,(int) SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+ {
+ BUF_MEM_free(buf);
+ ret= -1;
+ goto end;
+ }
+ s->init_buf=buf;
+ }
s->init_num=0;
s->ctx->stats.sess_accept++;
s->handshake_func=ssl2_accept;
diff --git a/crypto/openssl/ssl/s3_both.c b/crypto/openssl/ssl/s3_both.c
index ae0ee27c41aa..3581fbf4ff42 100644
--- a/crypto/openssl/ssl/s3_both.c
+++ b/crypto/openssl/ssl/s3_both.c
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
i=s->method->ssl3_enc->final_finish_mac(s,
sender,slen,s->s3->tmp.finish_md);
+ if (i == 0)
+ return 0;
s->s3->tmp.finish_md_len = i;
memcpy(p, s->s3->tmp.finish_md, i);
p+=i;
@@ -437,6 +439,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
goto f_err;
}
*ok=1;
+ s->state = stn;
s->init_msg = s->init_buf->data + 4;
s->init_num = (int)s->s3->tmp.message_size;
return s->init_num;
diff --git a/crypto/openssl/ssl/s3_cbc.c b/crypto/openssl/ssl/s3_cbc.c
index 443a31e74627..11f13adbf7c2 100644
--- a/crypto/openssl/ssl/s3_cbc.c
+++ b/crypto/openssl/ssl/s3_cbc.c
@@ -53,6 +53,7 @@
*
*/
+#include "../crypto/constant_time_locl.h"
#include "ssl_locl.h"
#include <openssl/md5.h>
@@ -67,37 +68,6 @@
* supported by TLS.) */
#define MAX_HASH_BLOCK_SIZE 128
-/* Some utility functions are needed:
- *
- * These macros return the given value with the MSB copied to all the other
- * bits. They use the fact that arithmetic shift shifts-in the sign bit.
- * However, this is not ensured by the C standard so you may need to replace
- * them with something else on odd CPUs. */
-#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
-#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
-
-/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
-static unsigned constant_time_lt(unsigned a, unsigned b)
- {
- a -= b;
- return DUPLICATE_MSB_TO_ALL(a);
- }
-
-/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
-static unsigned constant_time_ge(unsigned a, unsigned b)
- {
- a -= b;
- return DUPLICATE_MSB_TO_ALL(~a);
- }
-
-/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char constant_time_eq_8(unsigned a, unsigned b)
- {
- unsigned c = a ^ b;
- c--;
- return DUPLICATE_MSB_TO_ALL_8(c);
- }
-
/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
* record in |rec| by updating |rec->length| in constant time.
*
@@ -126,8 +96,8 @@ int ssl3_cbc_remove_padding(const SSL* s,
padding_length = good & (padding_length+1);
rec->length -= padding_length;
rec->type |= padding_length<<8; /* kludge: pass padding length */
- return (int)((good & 1) | (~good & -1));
-}
+ return constant_time_select_int(good, 1, -1);
+ }
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
* record in |rec| in constant time and returns 1 if the padding is valid and
@@ -208,7 +178,7 @@ int tls1_cbc_remove_padding(const SSL* s,
for (i = 0; i < to_check; i++)
{
- unsigned char mask = constant_time_ge(padding_length, i);
+ unsigned char mask = constant_time_ge_8(padding_length, i);
unsigned char b = rec->data[rec->length-1-i];
/* The final |padding_length+1| bytes should all have the value
* |padding_length|. Therefore the XOR should be zero. */
@@ -216,20 +186,14 @@ int tls1_cbc_remove_padding(const SSL* s,
}
/* If any of the final |padding_length+1| bytes had the wrong value,
- * one or more of the lower eight bits of |good| will be cleared. We
- * AND the bottom 8 bits together and duplicate the result to all the
- * bits. */
- good &= good >> 4;
- good &= good >> 2;
- good &= good >> 1;
- good <<= sizeof(good)*8-1;
- good = DUPLICATE_MSB_TO_ALL(good);
-
+ * one or more of the lower eight bits of |good| will be cleared.
+ */
+ good = constant_time_eq(0xff, good & 0xff);
padding_length = good & (padding_length+1);
rec->length -= padding_length;
rec->type |= padding_length<<8; /* kludge: pass padding length */
- return (int)((good & 1) | (~good & -1));
+ return constant_time_select_int(good, 1, -1);
}
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
@@ -296,8 +260,8 @@ void ssl3_cbc_copy_mac(unsigned char* out,
memset(rotated_mac, 0, md_size);
for (i = scan_start, j = 0; i < orig_len; i++)
{
- unsigned char mac_started = constant_time_ge(i, mac_start);
- unsigned char mac_ended = constant_time_ge(i, mac_end);
+ unsigned char mac_started = constant_time_ge_8(i, mac_start);
+ unsigned char mac_ended = constant_time_ge_8(i, mac_end);
unsigned char b = rec->data[i];
rotated_mac[j++] |= b & mac_started & ~mac_ended;
j &= constant_time_lt(j,md_size);
@@ -683,12 +647,12 @@ void ssl3_cbc_digest_record(
b = data[k-header_length];
k++;
- is_past_c = is_block_a & constant_time_ge(j, c);
- is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
+ is_past_c = is_block_a & constant_time_ge_8(j, c);
+ is_past_cp1 = is_block_a & constant_time_ge_8(j, c+1);
/* If this is the block containing the end of the
* application data, and we are at the offset for the
* 0x80 value, then overwrite b with 0x80. */
- b = (b&~is_past_c) | (0x80&is_past_c);
+ b = constant_time_select_8(is_past_c, 0x80, b);
/* If this the the block containing the end of the
* application data and we're past the 0x80 value then
* just write zero. */
@@ -704,7 +668,8 @@ void ssl3_cbc_digest_record(
if (j >= md_block_size - md_length_size)
{
/* If this is index_b, write a length byte. */
- b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
+ b = constant_time_select_8(
+ is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
}
block[j] = b;
}
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 741347ccfc4d..7692716988ac 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -167,9 +167,9 @@
#include <openssl/engine.h>
#endif
-static const SSL_METHOD *ssl3_get_client_method(int ver);
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
+#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_client_method(int ver)
{
if (ver == SSL3_VERSION)
@@ -182,6 +182,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method)
+#endif
int ssl3_connect(SSL *s)
{
@@ -272,6 +273,9 @@ int ssl3_connect(SSL *s)
s->state=SSL3_ST_CW_CLNT_HELLO_A;
s->ctx->stats.sess_connect++;
s->init_num=0;
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
@@ -312,23 +316,9 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
-#ifndef OPENSSL_NO_TLSEXT
- ret=ssl3_check_finished(s);
- if (ret <= 0) goto end;
- if (ret == 2)
- {
- s->hit = 1;
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_CR_SESSION_TICKET_A;
- else
- s->state=SSL3_ST_CR_FINISHED_A;
- s->init_num=0;
- break;
- }
-#endif
- /* Check if it is anon DH/ECDH */
+ /* Check if it is anon DH/ECDH, SRP auth */
/* or PSK */
- if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+ if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) &&
!(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
ret=ssl3_get_server_certificate(s);
@@ -433,12 +423,10 @@ int ssl3_connect(SSL *s)
else
{
s->state=SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec=0;
}
if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
{
s->state=SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec=0;
}
s->init_num=0;
@@ -450,7 +438,6 @@ int ssl3_connect(SSL *s)
if (ret <= 0) goto end;
s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0;
- s->s3->change_cipher_spec=0;
break;
case SSL3_ST_CW_CHANGE_A:
@@ -558,7 +545,6 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
-
s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
@@ -656,7 +642,7 @@ int ssl3_client_hello(SSL *s)
unsigned char *buf;
unsigned char *p,*d;
int i;
- unsigned long Time,l;
+ unsigned long l;
#ifndef OPENSSL_NO_COMP
int j;
SSL_COMP *comp;
@@ -668,11 +654,7 @@ int ssl3_client_hello(SSL *s)
SSL_SESSION *sess = s->session;
if ((sess == NULL) ||
(sess->ssl_version != s->version) ||
-#ifdef OPENSSL_NO_TLSEXT
!sess->session_id_length ||
-#else
- (!sess->session_id_length && !sess->tlsext_tick) ||
-#endif
(sess->not_resumable))
{
if (!ssl_get_new_session(s,0))
@@ -681,9 +663,8 @@ int ssl3_client_hello(SSL *s)
/* else use the pre-loaded session */
p=s->s3->client_random;
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+
+ if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
goto err;
/* Do the message type and length last */
@@ -879,6 +860,8 @@ int ssl3_get_server_hello(SSL *s)
memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
+ s->hit = 0;
+
/* get the session-id */
j= *(p++);
@@ -902,11 +885,12 @@ int ssl3_get_server_hello(SSL *s)
{
s->session->cipher = pref_cipher ?
pref_cipher : ssl_get_cipher_by_char(s, p+j);
+ s->hit = 1;
}
}
#endif /* OPENSSL_NO_TLSEXT */
- if (j != 0 && j == s->session->session_id_length
+ if (!s->hit && j != 0 && j == s->session->session_id_length
&& memcmp(p,s->session->session_id,j) == 0)
{
if(s->sid_ctx_length != s->session->sid_ctx_length
@@ -917,14 +901,13 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1;
}
- else /* a miss or crap from the other end */
+ /* a miss or crap from the other end */
+ if (!s->hit)
{
/* If we were trying for session-id reuse, make a new
* SSL_SESSION so we don't stuff up other people */
- s->hit=0;
if (s->session->session_id_length > 0)
{
if (!ssl_get_new_session(s,0))
@@ -1202,9 +1185,9 @@ int ssl3_get_server_certificate(SSL *s)
? 0 : 1;
#ifdef KSSL_DEBUG
- printf("pkey,x = %p, %p\n", pkey,x);
- printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
- printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
+ fprintf(stderr,"pkey,x = %p, %p\n", pkey,x);
+ fprintf(stderr,"ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
+ fprintf(stderr,"cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
#endif /* KSSL_DEBUG */
@@ -1918,6 +1901,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
{
int num;
+ unsigned int size;
j=0;
q=md_buf;
@@ -1930,9 +1914,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,param,param_len);
- EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
- q+=i;
- j+=i;
+ EVP_DigestFinal_ex(&md_ctx,q,&size);
+ q+=size;
+ j+=size;
}
i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
pkey->pkey.rsa);
@@ -1968,8 +1952,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
}
else
{
- if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
- /* aNULL or kPSK do not need public keys */
+ /* aNULL, aSRP or kPSK do not need public keys */
+ if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & SSL_kPSK))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
goto err;
@@ -2191,24 +2175,13 @@ int ssl3_get_new_session_ticket(SSL *s)
n=s->method->ssl_get_message(s,
SSL3_ST_CR_SESSION_TICKET_A,
SSL3_ST_CR_SESSION_TICKET_B,
- -1,
+ SSL3_MT_NEWSESSION_TICKET,
16384,
&ok);
if (!ok)
return((int)n);
- if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
- {
- s->s3->tmp.reuse_message=1;
- return(1);
- }
- if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
- {
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
- goto f_err;
- }
if (n < 6)
{
/* need at least ticket_lifetime_hint + ticket length */
@@ -2240,7 +2213,7 @@ int ssl3_get_new_session_ticket(SSL *s)
}
memcpy(s->session->tlsext_tick, p, ticklen);
s->session->tlsext_ticklen = ticklen;
- /* There are two ways to detect a resumed ticket sesion.
+ /* There are two ways to detect a resumed ticket session.
* One is to set an appropriate session ID and then the server
* must return a match in ServerHello. This allows the normal
* client session ID matching to work and we know much
@@ -2479,7 +2452,7 @@ int ssl3_send_client_key_exchange(SSL *s)
EVP_CIPHER_CTX_init(&ciph_ctx);
#ifdef KSSL_DEBUG
- printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
+ fprintf(stderr,"ssl3_send_client_key_exchange(%lx & %lx)\n",
alg_k, SSL_kKRB5);
#endif /* KSSL_DEBUG */
@@ -2495,9 +2468,9 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
#ifdef KSSL_DEBUG
{
- printf("kssl_cget_tkt rtn %d\n", krb5rc);
+ fprintf(stderr,"kssl_cget_tkt rtn %d\n", krb5rc);
if (krb5rc && kssl_err.text)
- printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
+ fprintf(stderr,"kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
}
#endif /* KSSL_DEBUG */
@@ -2978,7 +2951,11 @@ int ssl3_send_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
else if (alg_k & SSL_kPSK)
{
- char identity[PSK_MAX_IDENTITY_LEN];
+ /* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes
+ * to return a \0-terminated identity. The last byte
+ * is for us for simulating strnlen. */
+ char identity[PSK_MAX_IDENTITY_LEN + 2];
+ size_t identity_len;
unsigned char *t = NULL;
unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
unsigned int pre_ms_len = 0, psk_len = 0;
@@ -2992,8 +2969,9 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
}
+ memset(identity, 0, sizeof(identity));
psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
- identity, PSK_MAX_IDENTITY_LEN,
+ identity, sizeof(identity) - 1,
psk_or_pre_ms, sizeof(psk_or_pre_ms));
if (psk_len > PSK_MAX_PSK_LEN)
{
@@ -3007,7 +2985,14 @@ int ssl3_send_client_key_exchange(SSL *s)
SSL_R_PSK_IDENTITY_NOT_FOUND);
goto psk_err;
}
-
+ identity[PSK_MAX_IDENTITY_LEN + 1] = '\0';
+ identity_len = strlen(identity);
+ if (identity_len > PSK_MAX_IDENTITY_LEN)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto psk_err;
+ }
/* create PSK pre_master_secret */
pre_ms_len = 2+psk_len+2+psk_len;
t = psk_or_pre_ms;
@@ -3041,14 +3026,13 @@ int ssl3_send_client_key_exchange(SSL *s)
s->session->master_key_length =
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
- psk_or_pre_ms, pre_ms_len);
- n = strlen(identity);
- s2n(n, p);
- memcpy(p, identity, n);
- n+=2;
+ psk_or_pre_ms, pre_ms_len);
+ s2n(identity_len, p);
+ memcpy(p, identity, identity_len);
+ n = 2 + identity_len;
psk_err = 0;
psk_err:
- OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+ OPENSSL_cleanse(identity, sizeof(identity));
OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
if (psk_err != 0)
{
@@ -3315,6 +3299,12 @@ int ssl3_send_client_certificate(SSL *s)
s->state=SSL3_ST_CW_CERT_D;
l=ssl3_output_cert_chain(s,
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
+ if (!l)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+ return 0;
+ }
s->init_num=(int)l;
s->init_off=0;
}
@@ -3484,40 +3474,9 @@ int ssl3_send_next_proto(SSL *s)
}
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-}
+ }
#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
-/* Check to see if handshake is full or resumed. Usually this is just a
- * case of checking to see if a cache hit has occurred. In the case of
- * session tickets we have to check the next message to be sure.
- */
-
-#ifndef OPENSSL_NO_TLSEXT
-int ssl3_check_finished(SSL *s)
- {
- int ok;
- long n;
- /* If we have no ticket it cannot be a resumed session. */
- if (!s->session->tlsext_tick)
- return 1;
- /* this function is called when we really expect a Certificate
- * message, so permit appropriate message length */
- n=s->method->ssl_get_message(s,
- SSL3_ST_CR_CERT_A,
- SSL3_ST_CR_CERT_B,
- -1,
- s->max_cert_list,
- &ok);
- if (!ok) return((int)n);
- s->s3->tmp.reuse_message = 1;
- if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
- || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
- return 2;
-
- return 1;
- }
-#endif
-
int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
{
int i = 0;
diff --git a/crypto/openssl/ssl/s3_enc.c b/crypto/openssl/ssl/s3_enc.c
index 5cd3be3254d6..89c133e681ed 100644
--- a/crypto/openssl/ssl/s3_enc.c
+++ b/crypto/openssl/ssl/s3_enc.c
@@ -535,7 +535,8 @@ int ssl3_enc(SSL *s, int send)
/* otherwise, rec->length >= bs */
}
- EVP_Cipher(ds,rec->data,rec->input,l);
+ if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
+ return -1;
if (EVP_MD_CTX_md(s->read_hash) != NULL)
mac_size = EVP_MD_CTX_size(s->read_hash);
@@ -642,10 +643,18 @@ int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
int ssl3_final_finish_mac(SSL *s,
const char *sender, int len, unsigned char *p)
{
- int ret;
+ int ret, sha1len;
ret=ssl3_handshake_mac(s,NID_md5,sender,len,p);
+ if(ret == 0)
+ return 0;
+
p+=ret;
- ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
+
+ sha1len=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
+ if(sha1len == 0)
+ return 0;
+
+ ret+=sha1len;
return(ret);
}
static int ssl3_handshake_mac(SSL *s, int md_nid,
diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c
index fe1f654dcda5..e7cbef4814a5 100644
--- a/crypto/openssl/ssl/s3_lib.c
+++ b/crypto/openssl/ssl/s3_lib.c
@@ -328,7 +328,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -377,7 +377,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -425,7 +425,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -474,7 +474,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -522,7 +522,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -602,7 +602,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -687,7 +687,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -751,7 +751,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_SSLV3,
SSL_NOT_EXP|SSL_HIGH,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -1683,9 +1683,9 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -1699,7 +1699,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES128,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
128,
128,
@@ -1715,7 +1715,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_AES256,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP|SSL_HIGH,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
256,
256,
@@ -2062,7 +2062,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2142,7 +2142,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2222,7 +2222,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2302,7 +2302,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2382,7 +2382,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2432,7 +2432,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2448,7 +2448,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -2464,7 +2464,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
SSL_TLSV1,
SSL_NOT_EXP|SSL_HIGH,
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
- 168,
+ 112,
168,
},
@@ -3037,6 +3037,11 @@ void ssl3_clear(SSL *s)
s->s3->tmp.ecdh = NULL;
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+ s->s3->is_probably_safari = 0;
+#endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_TLSEXT */
rp = s->s3->rbuf.buf;
wp = s->s3->wbuf.buf;
@@ -3805,17 +3810,17 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
#endif
#ifdef CIPHER_DEBUG
- printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
+ fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
{
c=sk_SSL_CIPHER_value(srvr,i);
- printf("%p:%s\n",(void *)c,c->name);
+ fprintf(stderr, "%p:%s\n",(void *)c,c->name);
}
- printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
+ fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
{
c=sk_SSL_CIPHER_value(clnt,i);
- printf("%p:%s\n",(void *)c,c->name);
+ fprintf(stderr, "%p:%s\n",(void *)c,c->name);
}
#endif
@@ -3845,12 +3850,17 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
emask_k = cert->export_mask_k;
emask_a = cert->export_mask_a;
#ifndef OPENSSL_NO_SRP
- mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
- emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
+ if (s->srp_ctx.srp_Mask & SSL_kSRP)
+ {
+ mask_k |= SSL_kSRP;
+ emask_k |= SSL_kSRP;
+ mask_a |= SSL_aSRP;
+ emask_a |= SSL_aSRP;
+ }
#endif
-
+
#ifdef KSSL_DEBUG
-/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
+/* fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
#endif /* KSSL_DEBUG */
alg_k=c->algorithm_mkey;
@@ -3873,7 +3883,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{
ok = (alg_k & emask_k) && (alg_a & emask_a);
#ifdef CIPHER_DEBUG
- printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
+ fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
(void *)c,c->name);
#endif
}
@@ -3881,7 +3891,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{
ok = (alg_k & mask_k) && (alg_a & mask_a);
#ifdef CIPHER_DEBUG
- printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
+ fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
c->name);
#endif
}
@@ -3990,6 +4000,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
}
ok = ok && ec_ok;
}
+#ifndef OPENSSL_NO_ECDH
if (
/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
(alg_k & SSL_kEECDH)
@@ -4037,6 +4048,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
}
ok = ok && ec_ok;
}
+#endif /* OPENSSL_NO_ECDH */
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_NO_TLSEXT */
@@ -4044,6 +4056,13 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
ii=sk_SSL_CIPHER_find(allow,c);
if (ii >= 0)
{
+#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT)
+ if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) && s->s3->is_probably_safari)
+ {
+ if (!ret) ret=sk_SSL_CIPHER_value(allow,ii);
+ continue;
+ }
+#endif
ret=sk_SSL_CIPHER_value(allow,ii);
break;
}
diff --git a/crypto/openssl/ssl/s3_meth.c b/crypto/openssl/ssl/s3_meth.c
index cdddb17b627d..4dec7033d6c9 100644
--- a/crypto/openssl/ssl/s3_meth.c
+++ b/crypto/openssl/ssl/s3_meth.c
@@ -60,7 +60,7 @@
#include <openssl/objects.h>
#include "ssl_locl.h"
-static const SSL_METHOD *ssl3_get_method(int ver);
+#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_method(int ver)
{
if (ver == SSL3_VERSION)
@@ -73,5 +73,4 @@ IMPLEMENT_ssl3_meth_func(SSLv3_method,
ssl3_accept,
ssl3_connect,
ssl3_get_method)
-
-
+#endif
diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c
index 811a047f9f27..1ec9e6ea46da 100644
--- a/crypto/openssl/ssl/s3_pkt.c
+++ b/crypto/openssl/ssl/s3_pkt.c
@@ -110,6 +110,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include <errno.h>
#define USE_SOCKETS
#include "ssl_locl.h"
@@ -274,6 +275,12 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
return(n);
}
+/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
+ * be processed per call to ssl3_get_record. Without this limit an attacker
+ * could send empty records at a faster rate than we can process and cause
+ * ssl3_get_record to loop forever. */
+#define MAX_EMPTY_RECORDS 32
+
/* Call this to get a new input record.
* It will return <= 0 if more data is needed, normally due to an error
* or non-blocking IO.
@@ -294,6 +301,7 @@ static int ssl3_get_record(SSL *s)
short version;
unsigned mac_size, orig_len;
size_t extra;
+ unsigned empty_record_count = 0;
rr= &(s->s3->rrec);
sess=s->session;
@@ -337,7 +345,7 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
if (version != s->version)
{
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- if ((s->version & 0xFF00) == (version & 0xFF00))
+ if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash)
/* Send back error using their minor version number :-) */
s->version = (unsigned short)version;
al=SSL_AD_PROTOCOL_VERSION;
@@ -524,7 +532,17 @@ printf("\n");
s->packet_length=0;
/* just read a 0 length packet */
- if (rr->length == 0) goto again;
+ if (rr->length == 0)
+ {
+ empty_record_count++;
+ if (empty_record_count > MAX_EMPTY_RECORDS)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_RECORD_TOO_SMALL);
+ goto f_err;
+ }
+ goto again;
+ }
#if 0
fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
@@ -582,10 +600,11 @@ int ssl3_do_compress(SSL *ssl)
int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
{
const unsigned char *buf=buf_;
- unsigned int tot,n,nw;
- int i;
+ unsigned int n,nw;
+ int i,tot;
s->rwstate=SSL_NOTHING;
+ OPENSSL_assert(s->s3->wnum <= INT_MAX);
tot=s->s3->wnum;
s->s3->wnum=0;
@@ -600,6 +619,22 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
}
}
+ /* ensure that if we end up with a smaller value of data to write
+ * out than the the original len from a write which didn't complete
+ * for non-blocking I/O and also somehow ended up avoiding
+ * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as
+ * it must never be possible to end up with (len-tot) as a large
+ * number that will then promptly send beyond the end of the users
+ * buffer ... so we trap and report the error in a way the user
+ * will notice
+ */
+ if (len < tot)
+ {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_BAD_LENGTH);
+ return(-1);
+ }
+
+
n=(len-tot);
for (;;)
{
@@ -643,9 +678,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
SSL3_BUFFER *wb=&(s->s3->wbuf);
SSL_SESSION *sess;
- if (wb->buf == NULL)
- if (!ssl3_setup_write_buffer(s))
- return -1;
/* first check if there is a SSL3_BUFFER still being written
* out. This will happen with non blocking IO */
@@ -659,12 +691,12 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
if (i <= 0)
return(i);
/* if it went, fall through and send more stuff */
- /* we may have released our buffer, so get it again */
- if (wb->buf == NULL)
- if (!ssl3_setup_write_buffer(s))
- return -1;
}
+ if (wb->buf == NULL)
+ if (!ssl3_setup_write_buffer(s))
+ return -1;
+
if (len == 0 && !create_empty_fragment)
return 0;
@@ -826,8 +858,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
wr->length += eivlen;
}
- /* ssl3_enc can only have an error on read */
- s->method->ssl3_enc->enc(s,1);
+ if(s->method->ssl3_enc->enc(s,1)<1) goto err;
/* record length after mac and block padding */
s2n(wr->length,plen);
@@ -955,7 +986,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (!ssl3_setup_read_buffer(s))
return(-1);
- if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||
+ if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) ||
(peek && (type != SSL3_RT_APPLICATION_DATA)))
{
SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
@@ -1474,8 +1505,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
slen=s->method->ssl3_enc->client_finished_label_len;
}
- s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+ i = s->method->ssl3_enc->final_finish_mac(s,
sender,slen,s->s3->tmp.peer_finish_md);
+ if (i == 0)
+ {
+ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ s->s3->tmp.peer_finish_md_len = i;
return(1);
}
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index 5cb1a4b17cb5..fadca74ec269 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -154,6 +154,7 @@
#include <stdio.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
+#include "../crypto/constant_time_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
@@ -169,6 +170,7 @@
#endif
#include <openssl/md5.h>
+#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_server_method(int ver);
static const SSL_METHOD *ssl3_get_server_method(int ver)
@@ -179,6 +181,12 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
return(NULL);
}
+IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ ssl3_get_server_method)
+#endif
+
#ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{
@@ -205,11 +213,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
}
#endif
-IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
- ssl3_accept,
- ssl_undefined_function,
- ssl3_get_server_method)
-
int ssl3_accept(SSL *s)
{
BUF_MEM *buf;
@@ -283,6 +286,7 @@ int ssl3_accept(SSL *s)
}
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{
+ BUF_MEM_free(buf);
ret= -1;
goto end;
}
@@ -297,6 +301,9 @@ int ssl3_accept(SSL *s)
s->init_num=0;
s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE)
{
@@ -410,9 +417,8 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_CERT_B:
/* Check if it is anon DH or anon ECDH, */
/* normal PSK or KRB5 or SRP */
- if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
- && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
- && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+ if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP))
+ && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
ret=ssl3_send_server_certificate(s);
if (ret <= 0) goto end;
@@ -506,7 +512,9 @@ int ssl3_accept(SSL *s)
* (against the specs, but s3_clnt.c accepts this for SSL 3) */
!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
/* never request cert in Kerberos ciphersuites */
- (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
+ /* don't request certificate for SRP auth */
+ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
/* With normal PSK Certificates and
* Certificate Requests are omitted */
|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -663,8 +671,14 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
-
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ /*
+ * This *should* be the first time we enable CCS, but be
+ * extra careful about surrounding code changes. We need
+ * to set this here because we don't know if we're
+ * expecting a CertificateVerify or not.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -683,6 +697,19 @@ int ssl3_accept(SSL *s)
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
case SSL3_ST_SR_NEXT_PROTO_A:
case SSL3_ST_SR_NEXT_PROTO_B:
+ /*
+ * Enable CCS for resumed handshakes with NPN.
+ * In a full handshake with NPN, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in s3_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
+
ret=ssl3_get_next_proto(s);
if (ret <= 0) goto end;
s->init_num = 0;
@@ -692,7 +719,18 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ /*
+ * Enable CCS for resumed handshakes without NPN.
+ * In a full handshake, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in s3_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
@@ -764,7 +802,6 @@ int ssl3_accept(SSL *s)
#else
if (s->s3->next_proto_neg_seen)
{
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
}
else
@@ -954,7 +991,8 @@ int ssl3_get_client_hello(SSL *s)
(s->version != DTLS1_VERSION && 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)
+ if ((s->client_version>>8) == SSL3_VERSION_MAJOR &&
+ !s->enc_write_ctx && !s->write_hash)
{
/* similar to ssl3_get_record, send alert using remote version number */
s->version = s->client_version;
@@ -1005,7 +1043,16 @@ int ssl3_get_client_hello(SSL *s)
else
{
i=ssl_get_prev_session(s, p, j, d + n);
- if (i == 1)
+ /*
+ * Only resume if the session's version matches the negotiated
+ * version.
+ * RFC 5246 does not provide much useful advice on resumption
+ * with a different protocol version. It doesn't forbid it but
+ * the sanity of such behaviour would be questionable.
+ * In practice, clients do not accept a version mismatch and
+ * will abort the handshake with an error.
+ */
+ if (i == 1 && s->version == s->session->ssl_version)
{ /* previous session */
s->hit=1;
}
@@ -1100,14 +1147,15 @@ int ssl3_get_client_hello(SSL *s)
id=s->session->cipher->id;
#ifdef CIPHER_DEBUG
- printf("client sent %d ciphers\n",sk_num(ciphers));
+ fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers));
#endif
for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
{
c=sk_SSL_CIPHER_value(ciphers,i);
#ifdef CIPHER_DEBUG
- printf("client [%2d of %2d]:%s\n",
- i,sk_num(ciphers),SSL_CIPHER_get_name(c));
+ fprintf(stderr,"client [%2d of %2d]:%s\n",
+ i,sk_SSL_CIPHER_num(ciphers),
+ SSL_CIPHER_get_name(c));
#endif
if (c->id == id)
{
@@ -1189,12 +1237,9 @@ int ssl3_get_client_hello(SSL *s)
* server_random before calling tls_session_secret_cb in order to allow
* SessionTicket processing to use it in key derivation. */
{
- unsigned long Time;
unsigned char *pos;
- Time=(unsigned long)time(NULL); /* Time */
pos=s->s3->server_random;
- l2n(Time,pos);
- if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+ if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0)
{
al=SSL_AD_INTERNAL_ERROR;
goto f_err;
@@ -1431,19 +1476,13 @@ int ssl3_send_server_hello(SSL *s)
unsigned char *p,*d;
int i,sl;
unsigned long l;
-#ifdef OPENSSL_NO_TLSEXT
- unsigned long Time;
-#endif
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
{
buf=(unsigned char *)s->init_buf->data;
#ifdef OPENSSL_NO_TLSEXT
p=s->s3->server_random;
- /* Generate server_random if it was not needed previously */
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+ if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
return -1;
#endif
/* Do the message type and length last */
@@ -1834,7 +1873,7 @@ int ssl3_send_server_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
}
- for (i=0; r[i] != NULL && i<4; i++)
+ for (i=0; i < 4 && r[i] != NULL; i++)
{
nr[i]=BN_num_bytes(r[i]);
#ifndef OPENSSL_NO_SRP
@@ -1845,7 +1884,7 @@ int ssl3_send_server_key_exchange(SSL *s)
n+=2+nr[i];
}
- if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+ if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP))
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
@@ -1870,7 +1909,7 @@ int ssl3_send_server_key_exchange(SSL *s)
d=(unsigned char *)s->init_buf->data;
p= &(d[4]);
- for (i=0; r[i] != NULL && i<4; i++)
+ for (i=0; i < 4 && r[i] != NULL; i++)
{
#ifndef OPENSSL_NO_SRP
if ((i == 2) && (type & SSL_kSRP))
@@ -2101,6 +2140,11 @@ int ssl3_send_certificate_request(SSL *s)
s->init_num=n+4;
s->init_off=0;
#ifdef NETSCAPE_HANG_BUG
+ if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+ goto err;
+ }
p=(unsigned char *)s->init_buf->data + s->init_num;
/* do the header */
@@ -2160,6 +2204,11 @@ int ssl3_get_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
+ unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+ int decrypt_len;
+ unsigned char decrypt_good, version_good;
+ size_t j;
+
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
@@ -2197,8 +2246,9 @@ int ssl3_get_client_key_exchange(SSL *s)
{
if (!(s->options & SSL_OP_TLS_D5_BUG))
{
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
- goto err;
+ goto f_err;
}
else
p-=2;
@@ -2207,59 +2257,84 @@ int ssl3_get_client_key_exchange(SSL *s)
n=i;
}
- i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
-
- al = -1;
-
- if (i != SSL_MAX_MASTER_KEY_LENGTH)
+ /*
+ * Reject overly short RSA ciphertext because we want to be sure
+ * that the buffer size makes it safe to iterate over the entire
+ * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
+ * actual expected size is larger due to RSA padding, but the
+ * bound is sufficient to be safe.
+ */
+ if (n < SSL_MAX_MASTER_KEY_LENGTH)
{
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
+ al = SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+ goto f_err;
}
- if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
- {
- /* The premaster secret must contain the same version number as the
- * ClientHello to detect version rollback attacks (strangely, the
- * protocol does not offer such protection for DH ciphersuites).
- * However, buggy clients exist that send the negotiated protocol
- * version instead if the server does not support the requested
- * protocol version.
- * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
- if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
- (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
-
- /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
- * (http://eprint.iacr.org/2003/052/) exploits the version
- * number check as a "bad version oracle" -- an alert would
- * reveal that the plaintext corresponding to some ciphertext
- * made up by the adversary is properly formatted except
- * that the version number is wrong. To avoid such attacks,
- * we should treat this just like any other decryption error. */
- }
- }
+ /* We must not leak whether a decryption failure occurs because
+ * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
+ * RFC 2246, section 7.4.7.1). The code follows that advice of
+ * the TLS RFC and generates a random premaster secret for the
+ * case that the decrypt fails. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
- if (al != -1)
+ /* should be RAND_bytes, but we cannot work around a failure. */
+ if (RAND_pseudo_bytes(rand_premaster_secret,
+ sizeof(rand_premaster_secret)) <= 0)
+ goto err;
+ decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+ ERR_clear_error();
+
+ /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
+ * decrypt_good will be 0xff if so and zero otherwise. */
+ decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
+
+ /* If the version in the decrypted pre-master secret is correct
+ * then version_good will be 0xff, otherwise it'll be zero.
+ * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+ * (http://eprint.iacr.org/2003/052/) exploits the version
+ * number check as a "bad version oracle". Thus version checks
+ * are done in constant time and are treated like any other
+ * decryption error. */
+ version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
+ version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
+
+ /* The premaster secret must contain the same version number as
+ * the ClientHello to detect version rollback attacks
+ * (strangely, the protocol does not offer such protection for
+ * DH ciphersuites). However, buggy clients exist that send the
+ * negotiated protocol version instead if the server does not
+ * support the requested protocol version. If
+ * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+ if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
+ {
+ unsigned char workaround_good;
+ workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
+ workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
+ version_good |= workaround_good;
+ }
+
+ /* Both decryption and version must be good for decrypt_good
+ * to remain non-zero (0xff). */
+ decrypt_good &= version_good;
+
+ /*
+ * Now copy rand_premaster_secret over from p using
+ * decrypt_good_mask. If decryption failed, then p does not
+ * contain valid plaintext, however, a check above guarantees
+ * it is still sufficiently large to read from.
+ */
+ for (j = 0; j < sizeof(rand_premaster_secret); j++)
{
- /* Some decryption failure -- use random value instead as countermeasure
- * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
- * (see RFC 2246, section 7.4.7.1). */
- ERR_clear_error();
- i = SSL_MAX_MASTER_KEY_LENGTH;
- p[0] = s->client_version >> 8;
- p[1] = s->client_version & 0xff;
- if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
- goto err;
+ p[j] = constant_time_select_8(decrypt_good, p[j],
+ rand_premaster_secret[j]);
}
-
+
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
- p,i);
- OPENSSL_cleanse(p,i);
+ p,sizeof(rand_premaster_secret));
+ OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
}
else
#endif
@@ -2401,10 +2476,10 @@ int ssl3_get_client_key_exchange(SSL *s)
&kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
- printf("kssl_sget_tkt rtn %d [%d]\n",
+ fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
- printf("kssl_err text= %s\n", kssl_err.text);
+ fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason);
@@ -2418,10 +2493,10 @@ int ssl3_get_client_key_exchange(SSL *s)
&authtime, &kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
- printf("kssl_check_authent rtn %d [%d]\n",
+ fprintf(stderr,"kssl_check_authent rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
- printf("kssl_err text= %s\n", kssl_err.text);
+ fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason);
@@ -2824,6 +2899,8 @@ int ssl3_get_client_key_exchange(SSL *s)
unsigned char premaster_secret[32], *start;
size_t outlen=32, inlen;
unsigned long alg_a;
+ int Ttag, Tclass;
+ long Tlen;
/* Get our certificate private key*/
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2845,26 +2922,15 @@ int ssl3_get_client_key_exchange(SSL *s)
ERR_clear_error();
}
/* Decrypt session key */
- if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
- goto gerr;
- }
- if (p[1] == 0x81)
- {
- start = p+3;
- inlen = p[2];
- }
- else if (p[1] < 0x80)
- {
- start = p+2;
- inlen = p[1];
- }
- else
+ if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED ||
+ Ttag != V_ASN1_SEQUENCE ||
+ Tclass != V_ASN1_UNIVERSAL)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
goto gerr;
}
+ start = p;
+ inlen = Tlen;
if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0)
{
@@ -2928,7 +2994,7 @@ int ssl3_get_cert_verify(SSL *s)
SSL3_ST_SR_CERT_VRFY_A,
SSL3_ST_SR_CERT_VRFY_B,
-1,
- 516, /* Enough for 4096 bit RSA key with TLS v1.2 */
+ SSL3_RT_MAX_PLAIN_LENGTH,
&ok);
if (!ok) return((int)n);
@@ -3352,6 +3418,11 @@ int ssl3_send_server_certificate(SSL *s)
}
l=ssl3_output_cert_chain(s,x);
+ if (!l)
+ {
+ SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+ return(0);
+ }
s->state=SSL3_ST_SW_CERT_B;
s->init_num=(int)l;
s->init_off=0;
diff --git a/crypto/openssl/ssl/srtp.h b/crypto/openssl/ssl/srtp.h
index 1e9ed3a345a4..3edff417cbd5 100644
--- a/crypto/openssl/ssl/srtp.h
+++ b/crypto/openssl/ssl/srtp.h
@@ -1,4 +1,4 @@
-/* ssl/tls1.h */
+/* ssl/srtp.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -118,6 +118,8 @@
#ifndef HEADER_D1_SRTP_H
#define HEADER_D1_SRTP_H
+#include <openssl/ssl.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -130,12 +132,16 @@ extern "C" {
#define SRTP_NULL_SHA1_80 0x0005
#define SRTP_NULL_SHA1_32 0x0006
+#ifndef OPENSSL_NO_SRTP
+
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h
index 8332947a4e0d..2ba5923204d2 100644
--- a/crypto/openssl/ssl/ssl.h
+++ b/crypto/openssl/ssl/ssl.h
@@ -554,13 +554,18 @@ struct ssl_session_st
/* Allow initial connection to servers that don't support RI */
#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L
+#define SSL_OP_TLSEXT_PADDING 0x00000010L
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
-#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */
+#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L
#define SSL_OP_TLS_D5_BUG 0x00000100L
#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0
+
/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
* in OpenSSL 0.9.6d. Usually (depending on the application protocol)
* the workaround is not needed. Unfortunately some broken SSL/TLS
@@ -641,9 +646,20 @@ struct ssl_session_st
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+/* Send the current time in the Random fields of the ClientHello and
+ * ServerHello records for compatibility with hypothetical implementations
+ * that require it.
+ */
+#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
+#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
/* Send TLS_FALLBACK_SCSV in the ClientHello.
- * To be set by applications that reconnect with a downgraded protocol
- * version; see draft-ietf-tls-downgrade-scsv-00 for details. */
+ * To be set only by applications that reconnect with a downgraded protocol
+ * version; see draft-ietf-tls-downgrade-scsv-00 for details.
+ *
+ * DO NOT ENABLE THIS if your application attempts a normal handshake.
+ * Only use this in explicit fallback retries, following the guidance
+ * in draft-ietf-tls-downgrade-scsv-00.
+ */
#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
@@ -676,6 +692,10 @@ struct ssl_session_st
SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
#define SSL_set_mtu(ssl, mtu) \
SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+#define DTLS_set_link_mtu(ssl, mtu) \
+ SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
+#define DTLS_get_link_min_mtu(ssl) \
+ SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
#define SSL_get_secure_renegotiation_support(ssl) \
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
@@ -910,7 +930,7 @@ struct ssl_ctx_st
*/
unsigned int max_send_fragment;
-#ifndef OPENSSL_ENGINE
+#ifndef OPENSSL_NO_ENGINE
/* Engine to pass requests for client certs to
*/
ENGINE *client_cert_engine;
@@ -1615,6 +1635,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
#define SSL_CTRL_CHECK_PROTO_VERSION 119
+#define DTLS_CTRL_SET_LINK_MTU 120
+#define DTLS_CTRL_GET_LINK_MIN_MTU 121
#define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
@@ -1866,13 +1888,15 @@ const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
+#endif
-const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */
-const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS version */
+const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available SSL/TLS version */
+const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available SSL/TLS version */
const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
@@ -2051,6 +2075,10 @@ int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secre
void SSL_set_debug(SSL *s, int debug);
int SSL_cache_hit(SSL *s);
+#ifndef OPENSSL_NO_UNIT_TEST
+const struct openssl_ssl_test_functions *SSL_test_functions(void);
+#endif
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h
index 78883abef4b7..6fad054e03c5 100644
--- a/crypto/openssl/ssl/ssl3.h
+++ b/crypto/openssl/ssl/ssl3.h
@@ -393,7 +393,12 @@ typedef struct ssl3_buffer_st
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
-
+/*
+ * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+ * Cleared after the message has been processed.
+ */
+#define SSL3_FLAGS_CCS_OK 0x0080
+
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
* restart a handshake because of MS SGC and so prevents us
* from restarting the handshake in a loop. It's reset on a
@@ -404,7 +409,6 @@ typedef struct ssl3_buffer_st
* effected, but we can't prevent that.
*/
#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040
-#define SSL3_FLAGS_CCS_OK 0x0080
#ifndef OPENSSL_NO_SSL_INTERN
@@ -456,8 +460,11 @@ typedef struct ssl3_state_st
* and freed and MD_CTX-es for all required digests are stored in
* this array */
EVP_MD_CTX **handshake_dgst;
- /* this is set whenerver we see a change_cipher_spec message
- * come in when we are not looking for one */
+ /*
+ * Set whenever an expected ChangeCipherSpec message is processed.
+ * Unset when the peer's Finished message is received.
+ * Unexpected ChangeCipherSpec messages trigger a fatal alert.
+ */
int change_cipher_spec;
int warn_alert;
@@ -545,6 +552,15 @@ typedef struct ssl3_state_st
/* Set if we saw the Next Protocol Negotiation extension from our peer. */
int next_proto_neg_seen;
#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+ /* This is set to true if we believe that this is a version of Safari
+ * running on OS X 10.6 or newer. We wish to know this because Safari
+ * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */
+ char is_probably_safari;
+#endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_TLSEXT */
} SSL3_STATE;
#endif
diff --git a/crypto/openssl/ssl/ssl_asn1.c b/crypto/openssl/ssl/ssl_asn1.c
index 38540be1e538..477500371027 100644
--- a/crypto/openssl/ssl/ssl_asn1.c
+++ b/crypto/openssl/ssl/ssl_asn1.c
@@ -408,6 +408,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
if (os.length != 3)
{
c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+ c.line=__LINE__;
goto err;
}
id=0x02000000L|
@@ -420,6 +421,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
if (os.length != 2)
{
c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+ c.line=__LINE__;
goto err;
}
id=0x03000000L|
@@ -429,6 +431,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
else
{
c.error=SSL_R_UNKNOWN_SSL_VERSION;
+ c.line=__LINE__;
goto err;
}
@@ -521,6 +524,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
if (os.length > SSL_MAX_SID_CTX_LENGTH)
{
c.error=SSL_R_BAD_LENGTH;
+ c.line=__LINE__;
goto err;
}
else
diff --git a/crypto/openssl/ssl/ssl_cert.c b/crypto/openssl/ssl/ssl_cert.c
index 5123a89182e5..cef3ff46e4a3 100644
--- a/crypto/openssl/ssl/ssl_cert.c
+++ b/crypto/openssl/ssl/ssl_cert.c
@@ -286,35 +286,6 @@ CERT *ssl_cert_dup(CERT *cert)
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
CRYPTO_LOCK_EVP_PKEY);
-
- switch(i)
- {
- /* If there was anything special to do for
- * certain types of keys, we'd do it here.
- * (Nothing at the moment, I think.) */
-
- case SSL_PKEY_RSA_ENC:
- case SSL_PKEY_RSA_SIGN:
- /* We have an RSA key. */
- break;
-
- case SSL_PKEY_DSA_SIGN:
- /* We have a DSA key. */
- break;
-
- case SSL_PKEY_DH_RSA:
- case SSL_PKEY_DH_DSA:
- /* We have a DH key. */
- break;
-
- case SSL_PKEY_ECC:
- /* We have an ECC key */
- break;
-
- default:
- /* Can't happen. */
- SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
- }
}
}
diff --git a/crypto/openssl/ssl/ssl_ciph.c b/crypto/openssl/ssl/ssl_ciph.c
index 06da26acc587..b767361e79b8 100644
--- a/crypto/openssl/ssl/ssl_ciph.c
+++ b/crypto/openssl/ssl/ssl_ciph.c
@@ -563,7 +563,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
break;
}
- if ((i < 0) || (i > SSL_ENC_NUM_IDX))
+ if ((i < 0) || (i >= SSL_ENC_NUM_IDX))
*enc=NULL;
else
{
@@ -597,7 +597,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
i= -1;
break;
}
- if ((i < 0) || (i > SSL_MD_NUM_IDX))
+ if ((i < 0) || (i >= SSL_MD_NUM_IDX))
{
*md=NULL;
if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
@@ -814,7 +814,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
co_list[co_list_num].active = 0;
co_list_num++;
#ifdef KSSL_DEBUG
- printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
+ fprintf(stderr,"\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
#endif /* KSSL_DEBUG */
/*
if (!sk_push(ca_list,(char *)c)) goto err;
@@ -926,12 +926,12 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
int rule, int strength_bits,
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
{
- CIPHER_ORDER *head, *tail, *curr, *curr2, *last;
+ CIPHER_ORDER *head, *tail, *curr, *next, *last;
const SSL_CIPHER *cp;
int reverse = 0;
#ifdef CIPHER_DEBUG
- printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
+ fprintf(stderr, "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
#endif
@@ -943,21 +943,25 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
if (reverse)
{
- curr = tail;
+ next = tail;
last = head;
}
else
{
- curr = head;
+ next = head;
last = tail;
}
- curr2 = curr;
+ curr = NULL;
for (;;)
{
- if ((curr == NULL) || (curr == last)) break;
- curr = curr2;
- curr2 = reverse ? curr->prev : curr->next;
+ if (curr == last) break;
+
+ curr = next;
+
+ if (curr == NULL) break;
+
+ next = reverse ? curr->prev : curr->next;
cp = curr->cipher;
@@ -973,7 +977,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
else
{
#ifdef CIPHER_DEBUG
- printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
+ fprintf(stderr, "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
#endif
if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
@@ -993,7 +997,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
}
#ifdef CIPHER_DEBUG
- printf("Action = %d\n", rule);
+ fprintf(stderr, "Action = %d\n", rule);
#endif
/* add the cipher if it has not been added yet. */
@@ -1382,7 +1386,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
*/
num_of_ciphers = ssl_method->num_ciphers();
#ifdef KSSL_DEBUG
- printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
+ fprintf(stderr,"ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
#endif /* KSSL_DEBUG */
co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
if (co_list == NULL)
@@ -1509,7 +1513,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
{
sk_SSL_CIPHER_push(cipherstack, curr->cipher);
#ifdef CIPHER_DEBUG
- printf("<%s>\n",curr->cipher->name);
+ fprintf(stderr, "<%s>\n",curr->cipher->name);
#endif
}
}
@@ -1599,6 +1603,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_kSRP:
kx="SRP";
break;
+ case SSL_kGOST:
+ kx="GOST";
+ break;
default:
kx="unknown";
}
@@ -1632,6 +1639,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_aSRP:
au="SRP";
break;
+ case SSL_aGOST94:
+ au="GOST94";
+ break;
+ case SSL_aGOST01:
+ au="GOST01";
+ break;
default:
au="unknown";
break;
@@ -1679,6 +1692,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_SEED:
enc="SEED(128)";
break;
+ case SSL_eGOST2814789CNT:
+ enc="GOST89(256)";
+ break;
default:
enc="unknown";
break;
@@ -1701,6 +1717,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_AEAD:
mac="AEAD";
break;
+ case SSL_GOST89MAC:
+ mac="GOST89";
+ break;
+ case SSL_GOST94:
+ mac="GOST94";
+ break;
default:
mac="unknown";
break;
diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c
index d19b129ea86a..1b7eb47e15b9 100644
--- a/crypto/openssl/ssl/ssl_err.c
+++ b/crypto/openssl/ssl/ssl_err.c
@@ -544,7 +544,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
-{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbearts"},
+{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbeats"},
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) ,"heartbeat request already pending"},
{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),"tls illegal exporter label"},
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c
index e0a97cf7df5d..4a62b4a790db 100644
--- a/crypto/openssl/ssl/ssl_lib.c
+++ b/crypto/openssl/ssl/ssl_lib.c
@@ -383,13 +383,7 @@ SSL *SSL_new(SSL_CTX *ctx)
return(s);
err:
if (s != NULL)
- {
- if (s->cert != NULL)
- ssl_cert_free(s->cert);
- if (s->ctx != NULL)
- SSL_CTX_free(s->ctx); /* decrement reference count */
- OPENSSL_free(s);
- }
+ SSL_free(s);
SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
@@ -1080,19 +1074,6 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
l=s->max_cert_list;
s->max_cert_list=larg;
return(l);
- case SSL_CTRL_SET_MTU:
-#ifndef OPENSSL_NO_DTLS1
- if (larg < (long)dtls1_min_mtu())
- return 0;
-#endif
-
- if (SSL_version(s) == DTLS1_VERSION ||
- SSL_version(s) == DTLS1_BAD_VER)
- {
- s->d1->mtu = larg;
- return larg;
- }
- return 0;
case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
return 0;
@@ -1349,6 +1330,10 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
p=buf;
sk=s->session->ciphers;
+
+ if (sk_SSL_CIPHER_num(sk) == 0)
+ return NULL;
+
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
int n;
@@ -1503,6 +1488,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
+ p += n;
continue;
}
@@ -1834,7 +1820,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
ret->extra_certs=NULL;
- ret->comp_methods=SSL_COMP_get_compression_methods();
+ /* No compression for DTLS */
+ if (meth->version != DTLS1_VERSION)
+ ret->comp_methods=SSL_COMP_get_compression_methods();
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
@@ -2106,7 +2094,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
#ifdef CIPHER_DEBUG
- printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+ fprintf(stderr,"rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
#endif
@@ -2829,9 +2817,7 @@ void ssl_clear_cipher_ctx(SSL *s)
/* Fix this function so that it takes an optional type parameter */
X509 *SSL_get_certificate(const SSL *s)
{
- if (s->server)
- return(ssl_get_server_send_cert(s));
- else if (s->cert != NULL)
+ if (s->cert != NULL)
return(s->cert->key->x509);
else
return(NULL);
diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h
index 741797ea92f1..1b8fa8c4cbf6 100644
--- a/crypto/openssl/ssl/ssl_locl.h
+++ b/crypto/openssl/ssl/ssl_locl.h
@@ -810,6 +810,16 @@ const SSL_METHOD *func_name(void) \
return &func_name##_data; \
}
+struct openssl_ssl_test_functions
+ {
+ int (*p_ssl_init_wbio_buffer)(SSL *s, int push);
+ int (*p_ssl3_setup_buffers)(SSL *s);
+ int (*p_tls1_process_heartbeat)(SSL *s);
+ int (*p_dtls1_process_heartbeat)(SSL *s);
+ };
+
+#ifndef OPENSSL_UNIT_TEST
+
void ssl_clear_cipher_ctx(SSL *s);
int ssl_clear_bad_session(SSL *s);
CERT *ssl_cert_new(void);
@@ -850,10 +860,11 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
int ssl_verify_alarm_type(long type);
void ssl_load_ciphers(void);
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
int ssl2_enc_init(SSL *s, int client);
int ssl2_generate_key_material(SSL *s);
-void ssl2_enc(SSL *s,int send_data);
+int ssl2_enc(SSL *s,int send_data);
void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
@@ -986,7 +997,9 @@ void dtls1_stop_timer(SSL *s);
int dtls1_is_timer_expired(SSL *s);
void dtls1_double_timeout(SSL *s);
int dtls1_send_newsession_ticket(SSL *s);
-unsigned int dtls1_min_mtu(void);
+unsigned int dtls1_min_mtu(SSL *s);
+unsigned int dtls1_link_min_mtu(void);
+void dtls1_hm_fragment_free(hm_fragment *frag);
/* some client-only functions */
int ssl3_client_hello(SSL *s);
@@ -1003,7 +1016,6 @@ int ssl3_get_key_exchange(SSL *s);
int ssl3_get_server_certificate(SSL *s);
int ssl3_check_cert_and_algorithm(SSL *s);
#ifndef OPENSSL_NO_TLSEXT
-int ssl3_check_finished(SSL *s);
# ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_send_next_proto(SSL *s);
# endif
@@ -1095,8 +1107,8 @@ int tls1_ec_nid2curve_id(int nid);
#endif /* OPENSSL_NO_EC */
#ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
int ssl_prepare_clienthello_tlsext(SSL *s);
@@ -1176,4 +1188,12 @@ void tls_fips_digest_extra(
int srp_verify_server_param(SSL *s, int *al);
+#else
+
+#define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
+#define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers
+#define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat
+#define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat
+
+#endif
#endif
diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c
index ad40fadd02cc..235f92d824cd 100644
--- a/crypto/openssl/ssl/ssl_sess.c
+++ b/crypto/openssl/ssl/ssl_sess.c
@@ -335,7 +335,21 @@ int ssl_get_new_session(SSL *s, int session)
return(0);
}
#ifndef OPENSSL_NO_TLSEXT
- /* If RFC4507 ticket use empty session ID */
+ /*
+ * If RFC5077 ticket, use empty session ID (as server).
+ * Note that:
+ * (a) ssl_get_prev_session() does lookahead into the
+ * ClientHello extensions to find the session ticket.
+ * When ssl_get_prev_session() fails, s3_srvr.c calls
+ * ssl_get_new_session() in ssl3_get_client_hello().
+ * At that point, it has not yet parsed the extensions,
+ * however, because of the lookahead, it already knows
+ * whether a ticket is expected or not.
+ *
+ * (b) s3_clnt.c calls ssl_get_new_session() before parsing
+ * ServerHello extensions, and before recording the session
+ * ID received from the server, so this block is a noop.
+ */
if (s->tlsext_ticket_expected)
{
ss->session_id_length = 0;
diff --git a/crypto/openssl/ssl/ssl_stat.c b/crypto/openssl/ssl/ssl_stat.c
index 144b81e55fe4..c5a15ce54824 100644
--- a/crypto/openssl/ssl/ssl_stat.c
+++ b/crypto/openssl/ssl/ssl_stat.c
@@ -212,7 +212,6 @@ case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break;
case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break;
#endif
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
/* SSLv2/v3 compatibility states */
/* client */
case SSL23_ST_CW_CLNT_HELLO_A: str="SSLv2/v3 write client hello A"; break;
@@ -222,7 +221,6 @@ case SSL23_ST_CR_SRVR_HELLO_B: str="SSLv2/v3 read server hello B"; break;
/* server */
case SSL23_ST_SR_CLNT_HELLO_A: str="SSLv2/v3 read client hello A"; break;
case SSL23_ST_SR_CLNT_HELLO_B: str="SSLv2/v3 read client hello B"; break;
-#endif
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DTLS1 read hello verify request A"; break;
@@ -366,7 +364,6 @@ case SSL3_ST_SR_CERT_VRFY_A: str="3RCV_A"; break;
case SSL3_ST_SR_CERT_VRFY_B: str="3RCV_B"; break;
#endif
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
/* SSLv2/v3 compatibility states */
/* client */
case SSL23_ST_CW_CLNT_HELLO_A: str="23WCHA"; break;
@@ -376,7 +373,7 @@ case SSL23_ST_CR_SRVR_HELLO_B: str="23RSHA"; break;
/* server */
case SSL23_ST_SR_CLNT_HELLO_A: str="23RCHA"; break;
case SSL23_ST_SR_CLNT_HELLO_B: str="23RCHB"; break;
-#endif
+
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DRCHVA"; break;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DRCHVB"; break;
diff --git a/crypto/openssl/ssl/ssl_utst.c b/crypto/openssl/ssl/ssl_utst.c
new file mode 100644
index 000000000000..3679bc3c2309
--- /dev/null
+++ b/crypto/openssl/ssl/ssl_utst.c
@@ -0,0 +1,73 @@
+/* ssl_utst.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_UNIT_TEST
+
+
+static const struct openssl_ssl_test_functions ssl_test_functions =
+ {
+ ssl_init_wbio_buffer,
+ ssl3_setup_buffers,
+ tls1_process_heartbeat,
+ dtls1_process_heartbeat
+ };
+
+const struct openssl_ssl_test_functions *SSL_test_functions(void)
+ {
+ return &ssl_test_functions;
+ }
+
+#endif
diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c
index 316bbb0c9582..08889569f4ef 100644
--- a/crypto/openssl/ssl/ssltest.c
+++ b/crypto/openssl/ssl/ssltest.c
@@ -345,7 +345,7 @@ static void sv_usage(void)
#ifndef OPENSSL_NO_SSL2
fprintf(stderr," -ssl2 - use SSLv2\n");
#endif
-#ifndef OPENSSL_NO_SSL3
+#ifndef OPENSSL_NO_SSL3_METHOD
fprintf(stderr," -ssl3 - use SSLv3\n");
#endif
#ifndef OPENSSL_NO_TLS1
@@ -368,7 +368,9 @@ static void sv_usage(void)
" Use \"openssl ecparam -list_curves\" for all names\n" \
" (default is sect163r2).\n");
#endif
- fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
+ fprintf(stderr," -test_cipherlist - Verifies the order of the ssl cipher lists.\n"
+ " When this option is requested, the cipherlist\n"
+ " tests are run instead of handshake tests.\n");
}
static void print_details(SSL *c_ssl, const char *prefix)
@@ -549,6 +551,7 @@ int main(int argc, char *argv[])
#ifdef OPENSSL_FIPS
int fips_mode=0;
#endif
+ int no_protocol = 0;
verbose = 0;
debug = 0;
@@ -658,11 +661,26 @@ int main(int argc, char *argv[])
}
#endif
else if (strcmp(*argv,"-ssl2") == 0)
- ssl2=1;
+ {
+#ifdef OPENSSL_NO_SSL2
+ no_protocol = 1;
+#endif
+ ssl2 = 1;
+ }
else if (strcmp(*argv,"-tls1") == 0)
- tls1=1;
+ {
+#ifdef OPENSSL_NO_TLS1
+ no_protocol = 1;
+#endif
+ tls1 = 1;
+ }
else if (strcmp(*argv,"-ssl3") == 0)
- ssl3=1;
+ {
+#ifdef OPENSSL_NO_SSL3_METHOD
+ no_protocol = 1;
+#endif
+ ssl3 = 1;
+ }
else if (strncmp(*argv,"-num",4) == 0)
{
if (--argc < 1) goto bad;
@@ -781,15 +799,41 @@ bad:
goto end;
}
+ /*
+ * test_cipherlist prevails over protocol switch: we test the cipherlist
+ * for all enabled protocols.
+ */
if (test_cipherlist == 1)
{
/* ensure that the cipher list are correctly sorted and exit */
+ fprintf(stdout, "Testing cipherlist order only. Ignoring all "
+ "other options.\n");
if (do_test_cipherlist() == 0)
EXIT(1);
ret = 0;
goto end;
}
+ if (ssl2 + ssl3 + tls1 > 1)
+ {
+ fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should "
+ "be requested.\n");
+ EXIT(1);
+ }
+
+ /*
+ * Testing was requested for a compiled-out protocol (e.g. SSLv2).
+ * Ideally, we would error out, but the generic test wrapper can't know
+ * when to expect failure. So we do nothing and return success.
+ */
+ if (no_protocol)
+ {
+ fprintf(stderr, "Testing was requested for a disabled protocol. "
+ "Skipping tests.\n");
+ ret = 0;
+ goto end;
+ }
+
if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
{
fprintf(stderr, "This case cannot work. Use -f to perform "
@@ -868,24 +912,25 @@ bad:
}
#endif
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+/* At this point, ssl2/ssl3/tls1 is only set if the protocol is available.
+ * (Otherwise we exit early.)
+ * However the compiler doesn't know this, so we ifdef. */
+#ifndef OPENSSL_NO_SSL2
if (ssl2)
meth=SSLv2_method();
- else
- if (tls1)
- meth=TLSv1_method();
else
+#endif
+#ifndef OPENSSL_NO_SSL3
if (ssl3)
meth=SSLv3_method();
else
- meth=SSLv23_method();
-#else
-#ifdef OPENSSL_NO_SSL2
- meth=SSLv3_method();
-#else
- meth=SSLv2_method();
#endif
+#ifndef OPENSSL_NO_TLS1
+ if (tls1)
+ meth=TLSv1_method();
+ else
#endif
+ meth=SSLv23_method();
c_ctx=SSL_CTX_new(meth);
s_ctx=SSL_CTX_new(meth);
diff --git a/crypto/openssl/ssl/t1_enc.c b/crypto/openssl/ssl/t1_enc.c
index f7aa8426f184..1308c0344fea 100644
--- a/crypto/openssl/ssl/t1_enc.c
+++ b/crypto/openssl/ssl/t1_enc.c
@@ -303,15 +303,15 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
s->session->master_key,s->session->master_key_length,
km,tmp,num);
#ifdef KSSL_DEBUG
- printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+ fprintf(stderr,"tls1_generate_key_block() ==> %d byte master_key =\n\t",
s->session->master_key_length);
{
int i;
for (i=0; i < s->session->master_key_length; i++)
{
- printf("%02X", s->session->master_key[i]);
+ fprintf(stderr,"%02X", s->session->master_key[i]);
}
- printf("\n"); }
+ fprintf(stderr,"\n"); }
#endif /* KSSL_DEBUG */
return ret;
}
@@ -349,19 +349,19 @@ int tls1_change_cipher_state(SSL *s, int which)
#endif
#ifdef KSSL_DEBUG
- printf("tls1_change_cipher_state(which= %d) w/\n", which);
- printf("\talg= %ld/%ld, comp= %p\n",
+ fprintf(stderr,"tls1_change_cipher_state(which= %d) w/\n", which);
+ fprintf(stderr,"\talg= %ld/%ld, comp= %p\n",
s->s3->tmp.new_cipher->algorithm_mkey,
s->s3->tmp.new_cipher->algorithm_auth,
comp);
- printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
- printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+ fprintf(stderr,"\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+ fprintf(stderr,"\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
c->nid,c->block_size,c->key_len,c->iv_len);
- printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
+ fprintf(stderr,"\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
{
int i;
for (i=0; i<s->s3->tmp.key_block_length; i++)
- printf("%02x", s->s3->tmp.key_block[i]); printf("\n");
+ fprintf(stderr,"%02x", s->s3->tmp.key_block[i]); fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -540,11 +540,11 @@ printf("which = %04X\nmac key=",which);
#ifdef KSSL_DEBUG
{
int i;
- printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
- printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
- printf("\n");
- printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
- printf("\n");
+ fprintf(stderr,"EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
+ fprintf(stderr,"\tkey= "); for (i=0; i<c->key_len; i++) fprintf(stderr,"%02x", key[i]);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\t iv= "); for (i=0; i<c->iv_len; i++) fprintf(stderr,"%02x", iv[i]);
+ fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -591,7 +591,7 @@ int tls1_setup_key_block(SSL *s)
int ret=0;
#ifdef KSSL_DEBUG
- printf ("tls1_setup_key_block()\n");
+ fprintf(stderr,"tls1_setup_key_block()\n");
#endif /* KSSL_DEBUG */
if (s->s3->tmp.key_block_length != 0)
@@ -740,7 +740,7 @@ int tls1_enc(SSL *s, int send)
}
#ifdef KSSL_DEBUG
- printf("tls1_enc(%d)\n", send);
+ fprintf(stderr,"tls1_enc(%d)\n", send);
#endif /* KSSL_DEBUG */
if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
@@ -812,18 +812,18 @@ int tls1_enc(SSL *s, int send)
#ifdef KSSL_DEBUG
{
unsigned long ui;
- printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+ fprintf(stderr,"EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
ds,rec->data,rec->input,l);
- printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+ fprintf(stderr,"\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n",
ds->buf_len, ds->cipher->key_len,
DES_KEY_SZ, DES_SCHEDULE_SZ,
ds->cipher->iv_len);
- printf("\t\tIV: ");
- for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
- printf("\n");
- printf("\trec->input=");
- for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
- printf("\n");
+ fprintf(stderr,"\t\tIV: ");
+ for (i=0; i<ds->cipher->iv_len; i++) fprintf(stderr,"%02X", ds->iv[i]);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\trec->input=");
+ for (ui=0; ui<l; ui++) fprintf(stderr," %02x", rec->input[ui]);
+ fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -848,9 +848,9 @@ int tls1_enc(SSL *s, int send)
#ifdef KSSL_DEBUG
{
unsigned long i;
- printf("\trec->data=");
+ fprintf(stderr,"\trec->data=");
for (i=0; i<l; i++)
- printf(" %02x", rec->data[i]); printf("\n");
+ fprintf(stderr," %02x", rec->data[i]); fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
@@ -920,18 +920,19 @@ int tls1_final_finish_mac(SSL *s,
if (mask & ssl_get_algorithm2(s))
{
int hashsize = EVP_MD_size(md);
- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+ if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
{
/* internal error: 'buf' is too small for this cipersuite! */
err = 1;
}
else
{
- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
- EVP_DigestFinal_ex(&ctx,q,&i);
- if (i != (unsigned int)hashsize) /* can't really happen */
+ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+ !EVP_DigestFinal_ex(&ctx,q,&i) ||
+ (i != (unsigned int)hashsize))
err = 1;
- q+=i;
+ q+=hashsize;
}
}
}
@@ -985,7 +986,8 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
}
else
{
- EVP_MD_CTX_copy(&hmac,hash);
+ if (!EVP_MD_CTX_copy(&hmac,hash))
+ return -1;
mac_ctx = &hmac;
}
@@ -1046,14 +1048,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
if (!stream_mac)
EVP_MD_CTX_cleanup(&hmac);
#ifdef TLS_DEBUG
-printf("sec=");
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
-printf("seq=");
-{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("buf=");
-{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
-printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+fprintf(stderr,"seq=");
+{int z; for (z=0; z<8; z++) fprintf(stderr,"%02X ",seq[z]); fprintf(stderr,"\n"); }
+fprintf(stderr,"rec=");
+{unsigned int z; for (z=0; z<rec->length; z++) fprintf(stderr,"%02X ",rec->data[z]); fprintf(stderr,"\n"); }
#endif
if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
@@ -1066,7 +1064,7 @@ printf("rec=");
}
#ifdef TLS_DEBUG
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<md_size; z++) fprintf(stderr,"%02X ",md[z]); fprintf(stderr,"\n"); }
#endif
return(md_size);
}
@@ -1080,7 +1078,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
#ifdef KSSL_DEBUG
- printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+ fprintf(stderr,"tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
#endif /* KSSL_DEBUG */
#ifdef TLSEXT_TYPE_opaque_prf_input
@@ -1115,7 +1113,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
#endif
#ifdef KSSL_DEBUG
- printf ("tls1_generate_master_secret() complete\n");
+ fprintf(stderr,"tls1_generate_master_secret() complete\n");
#endif /* KSSL_DEBUG */
return(SSL3_MASTER_SECRET_SIZE);
}
@@ -1130,7 +1128,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
int rv;
#ifdef KSSL_DEBUG
- printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
+ fprintf(stderr,"tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", s, out, olen, label, llen, context, contextlen);
#endif /* KSSL_DEBUG */
buff = OPENSSL_malloc(olen);
@@ -1183,7 +1181,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
- rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ rv = tls1_PRF(ssl_get_algorithm2(s),
val, vallen,
NULL, 0,
NULL, 0,
@@ -1193,7 +1191,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
out,buff,olen);
#ifdef KSSL_DEBUG
- printf ("tls1_export_keying_material() complete\n");
+ fprintf(stderr,"tls1_export_keying_material() complete\n");
#endif /* KSSL_DEBUG */
goto ret;
err1:
diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c
index 90c1c42286ba..179b467d4508 100644
--- a/crypto/openssl/ssl/t1_lib.c
+++ b/crypto/openssl/ssl/t1_lib.c
@@ -204,28 +204,40 @@ static int nid_list[] =
static int pref_list[] =
{
+#ifndef OPENSSL_NO_EC2M
NID_sect571r1, /* sect571r1 (14) */
NID_sect571k1, /* sect571k1 (13) */
+#endif
NID_secp521r1, /* secp521r1 (25) */
+#ifndef OPENSSL_NO_EC2M
NID_sect409k1, /* sect409k1 (11) */
NID_sect409r1, /* sect409r1 (12) */
+#endif
NID_secp384r1, /* secp384r1 (24) */
+#ifndef OPENSSL_NO_EC2M
NID_sect283k1, /* sect283k1 (9) */
NID_sect283r1, /* sect283r1 (10) */
+#endif
NID_secp256k1, /* secp256k1 (22) */
NID_X9_62_prime256v1, /* secp256r1 (23) */
+#ifndef OPENSSL_NO_EC2M
NID_sect239k1, /* sect239k1 (8) */
NID_sect233k1, /* sect233k1 (6) */
NID_sect233r1, /* sect233r1 (7) */
+#endif
NID_secp224k1, /* secp224k1 (20) */
NID_secp224r1, /* secp224r1 (21) */
+#ifndef OPENSSL_NO_EC2M
NID_sect193r1, /* sect193r1 (4) */
NID_sect193r2, /* sect193r2 (5) */
+#endif
NID_secp192k1, /* secp192k1 (18) */
NID_X9_62_prime192v1, /* secp192r1 (19) */
+#ifndef OPENSSL_NO_EC2M
NID_sect163k1, /* sect163k1 (1) */
NID_sect163r1, /* sect163r1 (2) */
NID_sect163r2, /* sect163r2 (3) */
+#endif
NID_secp160k1, /* secp160k1 (15) */
NID_secp160r1, /* secp160r1 (16) */
NID_secp160r2, /* secp160r2 (17) */
@@ -233,7 +245,7 @@ static int pref_list[] =
int tls1_ec_curve_id2nid(int curve_id)
{
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ /* ECC curves from RFC 4492 */
if ((curve_id < 1) || ((unsigned int)curve_id >
sizeof(nid_list)/sizeof(nid_list[0])))
return 0;
@@ -242,7 +254,7 @@ int tls1_ec_curve_id2nid(int curve_id)
int tls1_ec_nid2curve_id(int nid)
{
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ /* ECC curves from RFC 4492 */
switch (nid)
{
case NID_sect163k1: /* sect163k1 (1) */
@@ -342,33 +354,26 @@ static unsigned char tls12_sigalgs[] = {
#ifndef OPENSSL_NO_SHA
tlsext_sigalg(TLSEXT_hash_sha1)
#endif
-#ifndef OPENSSL_NO_MD5
- tlsext_sigalg_rsa(TLSEXT_hash_md5)
-#endif
};
int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
{
size_t slen = sizeof(tls12_sigalgs);
-#ifdef OPENSSL_FIPS
- /* If FIPS mode don't include MD5 which is last */
- if (FIPS_mode())
- slen -= 2;
-#endif
if (p)
memcpy(p, tls12_sigalgs, slen);
return (int)slen;
}
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
{
int extdatalen=0;
- unsigned char *ret = p;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
/* don't add extensions for SSLv3 unless doing secure renegotiation */
if (s->client_version == SSL3_VERSION
&& !s->s3->send_connection_binding)
- return p;
+ return orig;
ret+=2;
@@ -417,7 +422,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
return NULL;
}
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
@@ -460,8 +465,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
#endif
#ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist != NULL &&
- s->version != DTLS1_VERSION)
+ if (s->tlsext_ecpointformatlist != NULL)
{
/* Add TLS extension ECPointFormats to the ClientHello message */
long lenmax;
@@ -480,8 +484,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
ret+=s->tlsext_ecpointformatlist_length;
}
- if (s->tlsext_ellipticcurvelist != NULL &&
- s->version != DTLS1_VERSION)
+ if (s->tlsext_ellipticcurvelist != NULL)
{
/* Add TLS extension EllipticCurves to the ClientHello message */
long lenmax;
@@ -497,11 +500,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
s2n(TLSEXT_TYPE_elliptic_curves,ret);
s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
- /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
- * elliptic_curve_list, but the examples use two bytes.
- * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
- * resolves this to two bytes.
- */
s2n(s->tlsext_ellipticcurvelist_length, ret);
memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
ret+=s->tlsext_ellipticcurvelist_length;
@@ -625,6 +623,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
#ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension */
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
s2n(TLSEXT_TYPE_heartbeat,ret);
s2n(1,ret);
/* Set mode:
@@ -656,7 +656,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
@@ -669,25 +669,55 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += el;
}
#endif
+ /* Add padding to workaround bugs in F5 terminators.
+ * See https://tools.ietf.org/html/draft-agl-tls-padding-03
+ *
+ * NB: because this code works out the length of all existing
+ * extensions it MUST always appear last.
+ */
+ if (s->options & SSL_OP_TLSEXT_PADDING)
+ {
+ int hlen = ret - (unsigned char *)s->init_buf->data;
+ /* The code in s23_clnt.c to build ClientHello messages
+ * includes the 5-byte record header in the buffer, while
+ * the code in s3_clnt.c does not.
+ */
+ if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+ hlen -= 5;
+ if (hlen > 0xff && hlen < 0x200)
+ {
+ hlen = 0x200 - hlen;
+ if (hlen >= 4)
+ hlen -= 4;
+ else
+ hlen = 0;
+
+ s2n(TLSEXT_TYPE_padding, ret);
+ s2n(hlen, ret);
+ memset(ret, 0, hlen);
+ ret += hlen;
+ }
+ }
- if ((extdatalen = ret-p-2)== 0)
- return p;
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
- s2n(extdatalen,p);
+ s2n(extdatalen, orig);
return ret;
}
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
{
int extdatalen=0;
- unsigned char *ret = p;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
#endif
/* don't add extensions for SSLv3, unless doing secure renegotiation */
if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
- return p;
+ return orig;
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
@@ -710,7 +740,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
return NULL;
}
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
@@ -725,8 +755,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist != NULL &&
- s->version != DTLS1_VERSION)
+ if (s->tlsext_ecpointformatlist != NULL)
{
/* Add TLS extension ECPointFormats to the ServerHello message */
long lenmax;
@@ -790,7 +819,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
@@ -823,6 +852,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
/* Add Heartbeat extension if we've received one */
if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
{
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
s2n(TLSEXT_TYPE_heartbeat,ret);
s2n(1,ret);
/* Set mode:
@@ -859,13 +890,96 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
- if ((extdatalen = ret-p-2)== 0)
- return p;
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
- s2n(extdatalen,p);
+ s2n(extdatalen, orig);
return ret;
}
+#ifndef OPENSSL_NO_EC
+/* ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |d|, of length |n|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ * SNI,
+ * elliptic_curves
+ * ec_point_formats
+ *
+ * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
+ * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
+ * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
+ * 10.8..10.8.3 (which don't work).
+ */
+static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsigned char *d, int n) {
+ unsigned short type, size;
+ static const unsigned char kSafariExtensionsBlock[] = {
+ 0x00, 0x0a, /* elliptic_curves extension */
+ 0x00, 0x08, /* 8 bytes */
+ 0x00, 0x06, /* 6 bytes of curve ids */
+ 0x00, 0x17, /* P-256 */
+ 0x00, 0x18, /* P-384 */
+ 0x00, 0x19, /* P-521 */
+
+ 0x00, 0x0b, /* ec_point_formats */
+ 0x00, 0x02, /* 2 bytes */
+ 0x01, /* 1 point format */
+ 0x00, /* uncompressed */
+ };
+
+ /* The following is only present in TLS 1.2 */
+ static const unsigned char kSafariTLS12ExtensionsBlock[] = {
+ 0x00, 0x0d, /* signature_algorithms */
+ 0x00, 0x0c, /* 12 bytes */
+ 0x00, 0x0a, /* 10 bytes */
+ 0x05, 0x01, /* SHA-384/RSA */
+ 0x04, 0x01, /* SHA-256/RSA */
+ 0x02, 0x01, /* SHA-1/RSA */
+ 0x04, 0x03, /* SHA-256/ECDSA */
+ 0x02, 0x03, /* SHA-1/ECDSA */
+ };
+
+ if (data >= (d+n-2))
+ return;
+ data += 2;
+
+ if (data > (d+n-4))
+ return;
+ n2s(data,type);
+ n2s(data,size);
+
+ if (type != TLSEXT_TYPE_server_name)
+ return;
+
+ if (data+size > d+n)
+ return;
+ data += size;
+
+ if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
+ {
+ const size_t len1 = sizeof(kSafariExtensionsBlock);
+ const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
+
+ if (data + len1 + len2 != d+n)
+ return;
+ if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
+ return;
+ if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
+ return;
+ }
+ else
+ {
+ const size_t len = sizeof(kSafariExtensionsBlock);
+
+ if (data + len != d+n)
+ return;
+ if (memcmp(data, kSafariExtensionsBlock, len) != 0)
+ return;
+ }
+
+ s->s3->is_probably_safari = 1;
+}
+#endif /* !OPENSSL_NO_EC */
+
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
{
unsigned short type;
@@ -886,6 +1000,21 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
#endif
+#ifndef OPENSSL_NO_EC
+ if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
+ ssl_check_for_safari(s, data, d, n);
+#endif /* !OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_SRP
+ if (s->srp_ctx.login != NULL)
+ {
+ OPENSSL_free(s->srp_ctx.login);
+ s->srp_ctx.login = NULL;
+ }
+#endif
+
+ s->srtp_profile = NULL;
+
if (data >= (d+n-2))
goto ri_check;
n2s(data,len);
@@ -1039,8 +1168,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
#endif
#ifndef OPENSSL_NO_EC
- else if (type == TLSEXT_TYPE_ec_point_formats &&
- s->version != DTLS1_VERSION)
+ else if (type == TLSEXT_TYPE_ec_point_formats)
{
unsigned char *sdata = data;
int ecpointformatlist_length = *(sdata++);
@@ -1074,15 +1202,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
fprintf(stderr,"\n");
#endif
}
- else if (type == TLSEXT_TYPE_elliptic_curves &&
- s->version != DTLS1_VERSION)
+ else if (type == TLSEXT_TYPE_elliptic_curves)
{
unsigned char *sdata = data;
int ellipticcurvelist_length = (*(sdata++) << 8);
ellipticcurvelist_length += (*(sdata++));
if (ellipticcurvelist_length != size - 2 ||
- ellipticcurvelist_length < 1)
+ ellipticcurvelist_length < 1 ||
+ /* Each NamedCurve is 2 bytes. */
+ ellipticcurvelist_length & 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
@@ -1181,7 +1310,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
}
else if (type == TLSEXT_TYPE_status_request &&
- s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
+ s->version != DTLS1_VERSION)
{
if (size < 5)
@@ -1396,6 +1525,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
#ifndef OPENSSL_NO_NEXTPROTONEG
s->s3->next_proto_neg_seen = 0;
#endif
+ s->tlsext_ticket_expected = 0;
#ifndef OPENSSL_NO_HEARTBEATS
s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
@@ -1435,8 +1565,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
#ifndef OPENSSL_NO_EC
- else if (type == TLSEXT_TYPE_ec_point_formats &&
- s->version != DTLS1_VERSION)
+ else if (type == TLSEXT_TYPE_ec_point_formats)
{
unsigned char *sdata = data;
int ecpointformatlist_length = *(sdata++);
@@ -1691,7 +1820,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
- /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+ /* we support all named elliptic curves in RFC 4492 */
if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
@@ -2255,7 +2384,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
}
EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
+ {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ OPENSSL_free(sdec);
return 2;
+ }
slen += mlen;
EVP_CIPHER_CTX_cleanup(&ctx);
p = sdec;
@@ -2371,14 +2504,6 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg)
{
switch(hash_alg)
{
-#ifndef OPENSSL_NO_MD5
- case TLSEXT_hash_md5:
-#ifdef OPENSSL_FIPS
- if (FIPS_mode())
- return NULL;
-#endif
- return EVP_md5();
-#endif
#ifndef OPENSSL_NO_SHA
case TLSEXT_hash_sha1:
return EVP_sha1();
diff --git a/crypto/openssl/ssl/tls1.h b/crypto/openssl/ssl/tls1.h
index 1b104795f40e..6ae887646253 100644
--- a/crypto/openssl/ssl/tls1.h
+++ b/crypto/openssl/ssl/tls1.h
@@ -233,6 +233,12 @@ extern "C" {
/* ExtensionType value from RFC5620 */
#define TLSEXT_TYPE_heartbeat 15
+/* ExtensionType value for TLS padding extension.
+ * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
+ * http://tools.ietf.org/html/draft-agl-tls-padding-03
+ */
+#define TLSEXT_TYPE_padding 21
+
/* ExtensionType value from RFC4507 */
#define TLSEXT_TYPE_session_ticket 35