summaryrefslogtreecommitdiff
path: root/src/lib/libssl/d1_both.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/d1_both.c')
-rw-r--r--src/lib/libssl/d1_both.c178
1 files changed, 175 insertions, 3 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index 9f898d6997..de8bab873f 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -227,14 +227,14 @@ int dtls1_do_write(SSL *s, int type)
227 unsigned int len, frag_off, mac_size, blocksize; 227 unsigned int len, frag_off, mac_size, blocksize;
228 228
229 /* AHA! Figure out the MTU, and stick to the right size */ 229 /* AHA! Figure out the MTU, and stick to the right size */
230 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) 230 if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
231 { 231 {
232 s->d1->mtu = 232 s->d1->mtu =
233 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 233 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
234 234
235 /* I've seen the kernel return bogus numbers when it doesn't know 235 /* I've seen the kernel return bogus numbers when it doesn't know
236 * (initial write), so just make sure we have a reasonable number */ 236 * (initial write), so just make sure we have a reasonable number */
237 if ( s->d1->mtu < dtls1_min_mtu()) 237 if (s->d1->mtu < dtls1_min_mtu())
238 { 238 {
239 s->d1->mtu = 0; 239 s->d1->mtu = 0;
240 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); 240 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)
1084 return code; 1084 return code;
1085 } 1085 }
1086 1086
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
1088 { 1092 {
1089 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); 1093 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
1090 return code; 1094 return code;
@@ -1417,3 +1421,171 @@ dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
1417 1421
1418 ccs_hdr->type = *(data++); 1422 ccs_hdr->type = *(data++);
1419 } 1423 }
1424
1425int dtls1_shutdown(SSL *s)
1426 {
1427 int ret;
1428#ifndef OPENSSL_NO_SCTP
1429 if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
1430 !(s->shutdown & SSL_SENT_SHUTDOWN))
1431 {
1432 ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
1433 if (ret < 0) return -1;
1434
1435 if (ret == 0)
1436 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, NULL);
1437 }
1438#endif
1439 ret = ssl3_shutdown(s);
1440#ifndef OPENSSL_NO_SCTP
1441 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
1442#endif
1443 return ret;
1444 }
1445
1446#ifndef OPENSSL_NO_HEARTBEATS
1447int
1448dtls1_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 bp += payload;
1482 /* Random padding */
1483 RAND_pseudo_bytes(bp, padding);
1484
1485 r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
1486
1487 if (r >= 0 && s->msg_callback)
1488 s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1489 buffer, 3 + payload + padding,
1490 s, s->msg_callback_arg);
1491
1492 OPENSSL_free(buffer);
1493
1494 if (r < 0)
1495 return r;
1496 }
1497 else if (hbtype == TLS1_HB_RESPONSE)
1498 {
1499 unsigned int seq;
1500
1501 /* We only send sequence numbers (2 bytes unsigned int),
1502 * and 16 random bytes, so we just try to read the
1503 * sequence number */
1504 n2s(pl, seq);
1505
1506 if (payload == 18 && seq == s->tlsext_hb_seq)
1507 {
1508 dtls1_stop_timer(s);
1509 s->tlsext_hb_seq++;
1510 s->tlsext_hb_pending = 0;
1511 }
1512 }
1513
1514 return 0;
1515 }
1516
1517int
1518dtls1_heartbeat(SSL *s)
1519 {
1520 unsigned char *buf, *p;
1521 int ret;
1522 unsigned int payload = 18; /* Sequence number + random bytes */
1523 unsigned int padding = 16; /* Use minimum padding */
1524
1525 /* Only send if peer supports and accepts HB requests... */
1526 if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
1527 s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
1528 {
1529 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
1530 return -1;
1531 }
1532
1533 /* ...and there is none in flight yet... */
1534 if (s->tlsext_hb_pending)
1535 {
1536 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
1537 return -1;
1538 }
1539
1540 /* ...and no handshake in progress. */
1541 if (SSL_in_init(s) || s->in_handshake)
1542 {
1543 SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
1544 return -1;
1545 }
1546
1547 /* Check if padding is too long, payload and padding
1548 * must not exceed 2^14 - 3 = 16381 bytes in total.
1549 */
1550 OPENSSL_assert(payload + padding <= 16381);
1551
1552 /* Create HeartBeat message, we just use a sequence number
1553 * as payload to distuingish different messages and add
1554 * some random stuff.
1555 * - Message Type, 1 byte
1556 * - Payload Length, 2 bytes (unsigned int)
1557 * - Payload, the sequence number (2 bytes uint)
1558 * - Payload, random bytes (16 bytes uint)
1559 * - Padding
1560 */
1561 buf = OPENSSL_malloc(1 + 2 + payload + padding);
1562 p = buf;
1563 /* Message Type */
1564 *p++ = TLS1_HB_REQUEST;
1565 /* Payload length (18 bytes here) */
1566 s2n(payload, p);
1567 /* Sequence number */
1568 s2n(s->tlsext_hb_seq, p);
1569 /* 16 random bytes */
1570 RAND_pseudo_bytes(p, 16);
1571 p += 16;
1572 /* Random padding */
1573 RAND_pseudo_bytes(p, padding);
1574
1575 ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
1576 if (ret >= 0)
1577 {
1578 if (s->msg_callback)
1579 s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1580 buf, 3 + payload + padding,
1581 s, s->msg_callback_arg);
1582
1583 dtls1_start_timer(s);
1584 s->tlsext_hb_pending = 1;
1585 }
1586
1587 OPENSSL_free(buf);
1588
1589 return ret;
1590 }
1591#endif