diff options
author | djm <> | 2012-10-13 21:23:50 +0000 |
---|---|---|
committer | djm <> | 2012-10-13 21:23:50 +0000 |
commit | e9d65189905c6e99c1062d65e26bf83eebb0a26a (patch) | |
tree | 10ebe51c3542099b0ab8325d8f322372375dc3b4 /src/lib/libssl/d1_both.c | |
parent | 59625e84c89bf82e1c6d20c55785b618eb56ea72 (diff) | |
parent | 228cae30b117c2493f69ad3c195341cd6ec8d430 (diff) | |
download | openbsd-e9d65189905c6e99c1062d65e26bf83eebb0a26a.tar.gz openbsd-e9d65189905c6e99c1062d65e26bf83eebb0a26a.tar.bz2 openbsd-e9d65189905c6e99c1062d65e26bf83eebb0a26a.zip |
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
Diffstat (limited to 'src/lib/libssl/d1_both.c')
-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 | ||