| 1637 | } |
| 1638 | |
| 1639 | bool SSU2Session::ProcessHolePunch (uint8_t * buf, size_t len) |
| 1640 | { |
| 1641 | // we are Alice |
| 1642 | LogPrint (eLogDebug, "SSU2: HolePunch"); |
| 1643 | Header header; |
| 1644 | memcpy (header.buf, buf, 16); |
| 1645 | header.ll[0] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 24)); |
| 1646 | header.ll[1] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 12)); |
| 1647 | if (header.h.type != eSSU2HolePunch) |
| 1648 | { |
| 1649 | LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2HolePunch); |
| 1650 | return false; |
| 1651 | } |
| 1652 | if (len < 48) |
| 1653 | { |
| 1654 | LogPrint (eLogWarning, "SSU2: HolePunch message too short ", len); |
| 1655 | return false; |
| 1656 | } |
| 1657 | uint8_t nonce[12] = {0}; |
| 1658 | uint64_t headerX[2]; // sourceConnID, token |
| 1659 | m_Server.ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
| 1660 | m_DestConnID = headerX[0]; |
| 1661 | // decrypt and handle payload |
| 1662 | uint8_t * payload = buf + 32; |
| 1663 | CreateNonce (be32toh (header.h.packetNum), nonce); |
| 1664 | uint8_t h[32]; |
| 1665 | memcpy (h, header.buf, 16); |
| 1666 | memcpy (h + 16, &headerX, 16); |
| 1667 | if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len - 48, h, 32, |
| 1668 | i2p::context.GetSSU2IntroKey (), nonce, payload, len - 48, false)) |
| 1669 | { |
| 1670 | LogPrint (eLogWarning, "SSU2: HolePunch AEAD verification failed "); |
| 1671 | return false; |
| 1672 | } |
| 1673 | HandlePayload (payload, len - 48); |
| 1674 | m_IsDataReceived = false; |
| 1675 | // connect to Charlie |
| 1676 | ConnectAfterIntroduction (); |
| 1677 | |
| 1678 | return true; |
| 1679 | } |
| 1680 | |
| 1681 | bool SSU2Session::ProcessPeerTest (uint8_t * buf, size_t len) |
| 1682 | { |
no test coverage detected