Loading CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,9 @@ Changes between 1.0.0f and 1.0.1 [xx XXX xxxx] *) Add support for TLS/DTLS heartbeats. [Robin Seggelmann <seggelmann@fh-muenster.de>] *) Improved PRNG seeding for VOS. [Paul Green <Paul.Green@stratus.com>] Loading apps/s_cb.c +20 −0 Original line number Diff line number Diff line Loading @@ -603,6 +603,26 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * } } } #ifndef OPENSSL_NO_HEARTBEATS if (content_type == 24) /* Heartbeat */ { str_details1 = ", Heartbeat"; if (len > 0) { switch (((const unsigned char*)buf)[0]) { case 1: str_details1 = ", HeartbeatRequest"; break; case 2: str_details1 = ", HeartbeatResponse"; break; } } } #endif } BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2); Loading apps/s_client.c +8 −0 Original line number Diff line number Diff line Loading @@ -1862,6 +1862,14 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 SSL_renegotiate(con); cbuf_len=0; } #ifndef OPENSSL_NO_HEARTBEATS else if ((!c_ign_eof) && (cbuf[0] == 'B')) { BIO_printf(bio_err,"HEARTBEATING\n"); SSL_heartbeat(con); cbuf_len=0; } #endif else { cbuf_len=i; Loading apps/s_server.c +10 −0 Original line number Diff line number Diff line Loading @@ -2222,6 +2222,16 @@ static int sv_body(char *hostname, int s, 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'))) { Loading ssl/d1_both.c +151 −1 Original line number Diff line number Diff line Loading @@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code) return code; } #ifndef OPENSSL_NO_HEARTBEATS if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */ #else if (!SSL_in_init(s)) /* done, no need to send a retransmit */ #endif { BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); return code; Loading Loading @@ -1438,3 +1442,149 @@ int dtls1_shutdown(SSL *s) #endif return ret; } #ifndef OPENSSL_NO_HEARTBEATS int dtls1_process_heartbeat(SSL *s) { unsigned char *p = &s->s3->rrec.data[0], *pl; unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ /* Read type and payload length first */ hbtype = *p++; n2s(p, payload); pl = p; if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; int r; /* Allocate memory for the response, size is 1 byte * message type, plus 2 bytes payload length, plus * payload, plus padding */ buffer = OPENSSL_malloc(1 + 2 + payload + padding); bp = buffer; /* Enter response type, length and copy payload */ *bp++ = TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); /* Random padding */ RAND_pseudo_bytes(p, padding); r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); if (r >= 0 && s->msg_callback) s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding, s, s->msg_callback_arg); OPENSSL_free(buffer); if (r < 0) return r; } else if (hbtype == TLS1_HB_RESPONSE) { unsigned int seq; /* We only send sequence numbers (2 bytes unsigned int), * and 16 random bytes, so we just try to read the * sequence number */ n2s(pl, seq); if (payload == 18 && seq == s->tlsext_hb_seq) { dtls1_stop_timer(s); s->tlsext_hb_seq++; s->tlsext_hb_pending = 0; } } return 0; } int dtls1_heartbeat(SSL *s) { unsigned char *buf, *p; int ret; unsigned int payload = 18; /* Sequence number + random bytes */ unsigned int padding = 16; /* Use minimum padding */ /* Only send if peer supports and accepts HB requests... */ if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); return -1; } /* ...and there is none in flight yet... */ if (s->tlsext_hb_pending) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING); return -1; } /* ...and no handshake in progress. */ if (SSL_in_init(s) || s->in_handshake) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE); return -1; } /* Check if padding is too long, payload and padding * must not exceed 2^14 - 3 = 16381 bytes in total. */ OPENSSL_assert(payload + padding <= 16381); /* Create HeartBeat message, we just use a sequence number * as payload to distuingish different messages and add * some random stuff. * - Message Type, 1 byte * - Payload Length, 2 bytes (unsigned int) * - Payload, the sequence number (2 bytes uint) * - Payload, random bytes (16 bytes uint) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; /* Payload length (18 bytes here) */ s2n(payload, p); /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ RAND_pseudo_bytes(p, 16); p += 16; /* Random padding */ RAND_pseudo_bytes(p, padding); ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); if (ret >= 0) { if (s->msg_callback) s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding, s, s->msg_callback_arg); dtls1_start_timer(s); s->tlsext_hb_pending = 1; } OPENSSL_free(buf); return ret; } #endif Loading
CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,9 @@ Changes between 1.0.0f and 1.0.1 [xx XXX xxxx] *) Add support for TLS/DTLS heartbeats. [Robin Seggelmann <seggelmann@fh-muenster.de>] *) Improved PRNG seeding for VOS. [Paul Green <Paul.Green@stratus.com>] Loading
apps/s_cb.c +20 −0 Original line number Diff line number Diff line Loading @@ -603,6 +603,26 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * } } } #ifndef OPENSSL_NO_HEARTBEATS if (content_type == 24) /* Heartbeat */ { str_details1 = ", Heartbeat"; if (len > 0) { switch (((const unsigned char*)buf)[0]) { case 1: str_details1 = ", HeartbeatRequest"; break; case 2: str_details1 = ", HeartbeatResponse"; break; } } } #endif } BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2); Loading
apps/s_client.c +8 −0 Original line number Diff line number Diff line Loading @@ -1862,6 +1862,14 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240 SSL_renegotiate(con); cbuf_len=0; } #ifndef OPENSSL_NO_HEARTBEATS else if ((!c_ign_eof) && (cbuf[0] == 'B')) { BIO_printf(bio_err,"HEARTBEATING\n"); SSL_heartbeat(con); cbuf_len=0; } #endif else { cbuf_len=i; Loading
apps/s_server.c +10 −0 Original line number Diff line number Diff line Loading @@ -2222,6 +2222,16 @@ static int sv_body(char *hostname, int s, 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'))) { Loading
ssl/d1_both.c +151 −1 Original line number Diff line number Diff line Loading @@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code) return code; } #ifndef OPENSSL_NO_HEARTBEATS if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */ #else if (!SSL_in_init(s)) /* done, no need to send a retransmit */ #endif { BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); return code; Loading Loading @@ -1438,3 +1442,149 @@ int dtls1_shutdown(SSL *s) #endif return ret; } #ifndef OPENSSL_NO_HEARTBEATS int dtls1_process_heartbeat(SSL *s) { unsigned char *p = &s->s3->rrec.data[0], *pl; unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ /* Read type and payload length first */ hbtype = *p++; n2s(p, payload); pl = p; if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; int r; /* Allocate memory for the response, size is 1 byte * message type, plus 2 bytes payload length, plus * payload, plus padding */ buffer = OPENSSL_malloc(1 + 2 + payload + padding); bp = buffer; /* Enter response type, length and copy payload */ *bp++ = TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); /* Random padding */ RAND_pseudo_bytes(p, padding); r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); if (r >= 0 && s->msg_callback) s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding, s, s->msg_callback_arg); OPENSSL_free(buffer); if (r < 0) return r; } else if (hbtype == TLS1_HB_RESPONSE) { unsigned int seq; /* We only send sequence numbers (2 bytes unsigned int), * and 16 random bytes, so we just try to read the * sequence number */ n2s(pl, seq); if (payload == 18 && seq == s->tlsext_hb_seq) { dtls1_stop_timer(s); s->tlsext_hb_seq++; s->tlsext_hb_pending = 0; } } return 0; } int dtls1_heartbeat(SSL *s) { unsigned char *buf, *p; int ret; unsigned int payload = 18; /* Sequence number + random bytes */ unsigned int padding = 16; /* Use minimum padding */ /* Only send if peer supports and accepts HB requests... */ if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); return -1; } /* ...and there is none in flight yet... */ if (s->tlsext_hb_pending) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING); return -1; } /* ...and no handshake in progress. */ if (SSL_in_init(s) || s->in_handshake) { SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE); return -1; } /* Check if padding is too long, payload and padding * must not exceed 2^14 - 3 = 16381 bytes in total. */ OPENSSL_assert(payload + padding <= 16381); /* Create HeartBeat message, we just use a sequence number * as payload to distuingish different messages and add * some random stuff. * - Message Type, 1 byte * - Payload Length, 2 bytes (unsigned int) * - Payload, the sequence number (2 bytes uint) * - Payload, random bytes (16 bytes uint) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; /* Payload length (18 bytes here) */ s2n(payload, p); /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ RAND_pseudo_bytes(p, 16); p += 16; /* Random padding */ RAND_pseudo_bytes(p, padding); ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); if (ret >= 0) { if (s->msg_callback) s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding, s, s->msg_callback_arg); dtls1_start_timer(s); s->tlsext_hb_pending = 1; } OPENSSL_free(buf); return ret; } #endif