PR: 2658 · openssl/openssl@4817504

3 min read Original article ↗

@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)

10841084

return code;

10851085

}

108610861087-

if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */

1087+

#ifndef OPENSSL_NO_HEARTBEATS

1088+

if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */

1089+

#else

1090+

if (!SSL_in_init(s)) /* done, no need to send a retransmit */

1091+

#endif

10881092

{

10891093

BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);

10901094

return code;

@@ -1438,3 +1442,149 @@ int dtls1_shutdown(SSL *s)

14381442

#endif

14391443

return ret;

14401444

}

1445+1446+

#ifndef OPENSSL_NO_HEARTBEATS

1447+

int

1448+

dtls1_process_heartbeat(SSL *s)

1449+

{

1450+

unsigned char *p = &s->s3->rrec.data[0], *pl;

1451+

unsigned short hbtype;

1452+

unsigned int payload;

1453+

unsigned int padding = 16; /* Use minimum padding */

1454+1455+

/* Read type and payload length first */

1456+

hbtype = *p++;

1457+

n2s(p, payload);

1458+

pl = p;

1459+1460+

if (s->msg_callback)

1461+

s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,

1462+

&s->s3->rrec.data[0], s->s3->rrec.length,

1463+

s, s->msg_callback_arg);

1464+1465+

if (hbtype == TLS1_HB_REQUEST)

1466+

{

1467+

unsigned char *buffer, *bp;

1468+

int r;

1469+1470+

/* Allocate memory for the response, size is 1 byte

1471+

* message type, plus 2 bytes payload length, plus

1472+

* payload, plus padding

1473+

*/

1474+

buffer = OPENSSL_malloc(1 + 2 + payload + padding);

1475+

bp = buffer;

1476+1477+

/* Enter response type, length and copy payload */

1478+

*bp++ = TLS1_HB_RESPONSE;

1479+

s2n(payload, bp);

1480+

memcpy(bp, pl, payload);

1481+

/* Random padding */

1482+

RAND_pseudo_bytes(p, padding);

1483+1484+

r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);

1485+1486+

if (r >= 0 && s->msg_callback)

1487+

s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,

1488+

buffer, 3 + payload + padding,

1489+

s, s->msg_callback_arg);

1490+1491+

OPENSSL_free(buffer);

1492+1493+

if (r < 0)

1494+

return r;

1495+

}

1496+

else if (hbtype == TLS1_HB_RESPONSE)

1497+

{

1498+

unsigned int seq;

1499+1500+

/* We only send sequence numbers (2 bytes unsigned int),

1501+

* and 16 random bytes, so we just try to read the

1502+

* sequence number */

1503+

n2s(pl, seq);

1504+1505+

if (payload == 18 && seq == s->tlsext_hb_seq)

1506+

{

1507+

dtls1_stop_timer(s);

1508+

s->tlsext_hb_seq++;

1509+

s->tlsext_hb_pending = 0;

1510+

}

1511+

}

1512+1513+

return 0;

1514+

}

1515+1516+

int

1517+

dtls1_heartbeat(SSL *s)

1518+

{

1519+

unsigned char *buf, *p;

1520+

int ret;

1521+

unsigned int payload = 18; /* Sequence number + random bytes */

1522+

unsigned int padding = 16; /* Use minimum padding */

1523+1524+

/* Only send if peer supports and accepts HB requests... */

1525+

if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||

1526+

s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)

1527+

{

1528+

SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);

1529+

return -1;

1530+

}

1531+1532+

/* ...and there is none in flight yet... */

1533+

if (s->tlsext_hb_pending)

1534+

{

1535+

SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);

1536+

return -1;

1537+

}

1538+1539+

/* ...and no handshake in progress. */

1540+

if (SSL_in_init(s) || s->in_handshake)

1541+

{

1542+

SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);

1543+

return -1;

1544+

}

1545+1546+

/* Check if padding is too long, payload and padding

1547+

* must not exceed 2^14 - 3 = 16381 bytes in total.

1548+

*/

1549+

OPENSSL_assert(payload + padding <= 16381);

1550+1551+

/* Create HeartBeat message, we just use a sequence number

1552+

* as payload to distuingish different messages and add

1553+

* some random stuff.

1554+

* - Message Type, 1 byte

1555+

* - Payload Length, 2 bytes (unsigned int)

1556+

* - Payload, the sequence number (2 bytes uint)

1557+

* - Payload, random bytes (16 bytes uint)

1558+

* - Padding

1559+

*/

1560+

buf = OPENSSL_malloc(1 + 2 + payload + padding);

1561+

p = buf;

1562+

/* Message Type */

1563+

*p++ = TLS1_HB_REQUEST;

1564+

/* Payload length (18 bytes here) */

1565+

s2n(payload, p);

1566+

/* Sequence number */

1567+

s2n(s->tlsext_hb_seq, p);

1568+

/* 16 random bytes */

1569+

RAND_pseudo_bytes(p, 16);

1570+

p += 16;

1571+

/* Random padding */

1572+

RAND_pseudo_bytes(p, padding);

1573+1574+

ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);

1575+

if (ret >= 0)

1576+

{

1577+

if (s->msg_callback)

1578+

s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,

1579+

buf, 3 + payload + padding,

1580+

s, s->msg_callback_arg);

1581+1582+

dtls1_start_timer(s);

1583+

s->tlsext_hb_pending = 1;

1584+

}

1585+1586+

OPENSSL_free(buf);

1587+1588+

return ret;

1589+

}

1590+

#endif