aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xConfigure7
-rw-r--r--apps/openssl.c3
-rw-r--r--apps/s_cb.c17
-rw-r--r--apps/s_client.c7
-rw-r--r--apps/s_server.c8
-rw-r--r--include/openssl/ssl.h13
-rw-r--r--include/openssl/ssl3.h1
-rw-r--r--include/openssl/tls1.h32
-rw-r--r--ssl/s3_lib.c7
-rw-r--r--ssl/ssl_err.c5
-rw-r--r--ssl/t1_trce.c3
-rwxr-xr-xutil/mkdef.pl2
12 files changed, 102 insertions, 3 deletions
diff --git a/Configure b/Configure
index ab935e4372..307b1d8ac4 100755
--- a/Configure
+++ b/Configure
@@ -367,6 +367,7 @@ my @disablables = (
"fuzz-libfuzzer",
"fuzz-afl",
"gost",
+ "heartbeats",
"hw(-.+)?",
"idea",
"makedepend",
@@ -434,6 +435,7 @@ our %disabled = ( # "what" => "comment"
"external-tests" => "default",
"fuzz-libfuzzer" => "default",
"fuzz-afl" => "default",
+ "heartbeats" => "default",
"md2" => "default",
"msan" => "default",
"rc5" => "default",
@@ -485,8 +487,8 @@ my @disable_cascades = (
"tls" => [ @tls ],
- # SRP requires TLSEXT
- "tlsext" => [ "srp" ],
+ # SRP and HEARTBEATS require TLSEXT
+ "tlsext" => [ "srp", "heartbeats" ],
"crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
@@ -504,6 +506,7 @@ my @disable_cascades = (
"stdio" => [ "apps", "capieng" ],
"apps" => [ "tests" ],
"comp" => [ "zlib" ],
+ sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
sub { !$disabled{"msan"} } => [ "asm" ],
);
diff --git a/apps/openssl.c b/apps/openssl.c
index a4159138e5..f6a8f9df55 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -628,6 +628,9 @@ static void list_disabled(void)
#ifdef OPENSSL_NO_GOST
BIO_puts(bio_out, "GOST\n");
#endif
+#ifdef OPENSSL_NO_HEARTBEATS
+ BIO_puts(bio_out, "HEARTBEATS\n");
+#endif
#ifdef OPENSSL_NO_IDEA
BIO_puts(bio_out, "IDEA\n");
#endif
diff --git a/apps/s_cb.c b/apps/s_cb.c
index a2e8cbc8e2..d5c308ee13 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -555,6 +555,22 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
case 23:
str_content_type = "ApplicationData";
break;
+#ifndef OPENSSL_NO_HEARTBEATS
+ case 24:
+ str_details1 = ", Heartbeat";
+
+ if (len > 0) {
+ switch (bp[0]) {
+ case 1:
+ str_details1 = ", HeartbeatRequest";
+ break;
+ case 2:
+ str_details1 = ", HeartbeatResponse";
+ break;
+ }
+ }
+ break;
+#endif
}
}
@@ -595,6 +611,7 @@ static STRINT_PAIR tlsext_types[] = {
{"SRP", TLSEXT_TYPE_srp},
{"signature algorithms", TLSEXT_TYPE_signature_algorithms},
{"use SRTP", TLSEXT_TYPE_use_srtp},
+ {"heartbeat", TLSEXT_TYPE_heartbeat},
{"session ticket", TLSEXT_TYPE_session_ticket},
{"renegotiation info", TLSEXT_TYPE_renegotiate},
{"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
diff --git a/apps/s_client.c b/apps/s_client.c
index 1bcfe8e3dc..cfd7cbd79d 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -2448,6 +2448,13 @@ int s_client_main(int argc, char **argv)
SSL_renegotiate(con);
cbuf_len = 0;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
+ BIO_printf(bio_err, "HEARTBEATING\n");
+ SSL_heartbeat(con);
+ cbuf_len = 0;
+ }
+#endif
else {
cbuf_len = i;
cbuf_off = 0;
diff --git a/apps/s_server.c b/apps/s_server.c
index 88cbf9f8c1..ee6631809c 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2226,6 +2226,14 @@ static int sv_body(int s, int stype, unsigned char *context)
*/
goto err;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+ BIO_printf(bio_err, "HEARTBEATING\n");
+ SSL_heartbeat(con);
+ i = 0;
+ continue;
+ }
+#endif
if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
SSL_renegotiate(con);
i = SSL_do_handshake(con);
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 6a6d0f6679..b61a992e16 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -509,6 +509,11 @@ unsigned long SSL_set_options(SSL *s, unsigned long op);
# define SSL_get_secure_renegotiation_support(ssl) \
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
+# ifndef OPENSSL_NO_HEARTBEATS
+# define SSL_heartbeat(ssl) \
+ SSL_ctrl((ssl),SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT,0,NULL)
+# endif
+
# define SSL_CTX_set_cert_flags(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL)
# define SSL_set_cert_flags(s,op) \
@@ -1090,6 +1095,11 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79
# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80
# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81
+# ifndef OPENSSL_NO_HEARTBEATS
+# define SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT 85
+# define SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING 86
+# define SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS 87
+# endif
# define DTLS_CTRL_GET_TIMEOUT 73
# define DTLS_CTRL_HANDLE_TIMEOUT 74
# define SSL_CTRL_GET_RI_SUPPORT 76
@@ -2075,6 +2085,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_DO_SSL3_WRITE 104
# define SSL_F_DTLS1_BUFFER_RECORD 247
# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 318
+# define SSL_F_DTLS1_HEARTBEAT 305
# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288
# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424
# define SSL_F_DTLS1_PROCESS_RECORD 257
@@ -2499,6 +2510,8 @@ int ERR_load_SSL_strings(void);
# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
+# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365
+# define SSL_R_TLS_HEARTBEAT_PENDING 366
# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367
# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
# define SSL_R_TOO_MANY_WARN_ALERTS 409
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 48b7fb5327..aca1922306 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -204,6 +204,7 @@ extern "C" {
# define SSL3_RT_ALERT 21
# define SSL3_RT_HANDSHAKE 22
# define SSL3_RT_APPLICATION_DATA 23
+# define DTLS1_RT_HEARTBEAT 24
/* Pseudo content types to indicate additional parameters */
# define TLS1_RT_CRYPTO 0x1000
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index e069806146..1fd5788936 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -146,6 +146,9 @@ extern "C" {
/* ExtensionType value from RFC5764 */
# define TLSEXT_TYPE_use_srtp 14
+/* ExtensionType value from RFC5620 */
+# define TLSEXT_TYPE_heartbeat 15
+
/* ExtensionType value from RFC7301 */
# define TLSEXT_TYPE_application_layer_protocol_negotiation 16
@@ -322,6 +325,35 @@ SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+# ifndef OPENSSL_NO_HEARTBEATS
+# define SSL_DTLSEXT_HB_ENABLED 0x01
+# define SSL_DTLSEXT_HB_DONT_SEND_REQUESTS 0x02
+# define SSL_DTLSEXT_HB_DONT_RECV_REQUESTS 0x04
+# define SSL_get_dtlsext_heartbeat_pending(ssl) \
+ SSL_ctrl((ssl),SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING,0,NULL)
+# define SSL_set_dtlsext_heartbeat_no_requests(ssl, arg) \
+ SSL_ctrl((ssl),SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT \
+ SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT
+# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING \
+ SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING
+# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS \
+ SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS
+# define SSL_TLSEXT_HB_ENABLED \
+ SSL_DTLSEXT_HB_ENABLED
+# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS \
+ SSL_DTLSEXT_HB_DONT_SEND_REQUESTS
+# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS \
+ SSL_DTLSEXT_HB_DONT_RECV_REQUESTS
+# define SSL_get_tlsext_heartbeat_pending(ssl) \
+ SSL_get_dtlsext_heartbeat_pending(ssl)
+# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
+ SSL_set_dtlsext_heartbeat_no_requests(ssl, arg)
+# endif
+# endif
+
/* PSK ciphersuites from 4279 */
# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A
# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 8aab778ba6..2439167307 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3047,6 +3047,13 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ret = 1;
break;
+#ifndef OPENSSL_NO_HEARTBEATS
+ case SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT:
+ case SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING:
+ case SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS:
+ break;
+#endif
+
case SSL_CTRL_CHAIN:
if (larg)
return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg);
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 95397661c1..6c438fe2fe 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -30,6 +30,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_DO_SSL3_WRITE), "do_ssl3_write"},
{ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "dtls1_buffer_record"},
{ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "dtls1_check_timeout_num"},
+ {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"},
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "dtls1_preprocess_fragment"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),
"dtls1_process_buffered_records"},
@@ -619,6 +620,10 @@ 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_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),
diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c
index e12a4a849b..2e94c65bdf 100644
--- a/ssl/t1_trce.c
+++ b/ssl/t1_trce.c
@@ -710,6 +710,9 @@ static int ssl_print_extension(BIO *bio, int indent, int server, int extype,
}
break;
+ case TLSEXT_TYPE_heartbeat:
+ return 0;
+
case TLSEXT_TYPE_session_ticket:
if (extlen != 0)
ssl_print_hex(bio, indent + 4, "ticket", ext, extlen);
diff --git a/util/mkdef.pl b/util/mkdef.pl
index 3b8c5c4778..c5884d3b92 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -101,7 +101,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
# RFC3779
"RFC3779",
# TLS
- "PSK", "SRP",
+ "PSK", "SRP", "HEARTBEATS",
# CMS
"CMS",
"OCSP",