diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/d1_both.c | 178 |
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 | |||
| 1425 | int 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 | ||
| 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 | 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 | |||
| 1517 | int | ||
| 1518 | dtls1_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 | ||
