@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)
10841084 return code ;
10851085 }
10861086
1087- 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
0 commit comments