| 710 | } |
| 711 | |
| 712 | bool SSU2Session::SendSessionRequest (uint64_t token) |
| 713 | { |
| 714 | // we are Alice |
| 715 | #if OPENSSL_PQ |
| 716 | if (m_Server.GetVersion () > 2) // we support post quantum in config |
| 717 | SetVersion (m_Address->v); |
| 718 | #endif |
| 719 | m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); |
| 720 | m_SentHandshakePacket.reset (new HandshakePacket); |
| 721 | auto ts = i2p::util::GetMillisecondsSinceEpoch (); |
| 722 | m_SentHandshakePacket->sendTime = ts; |
| 723 | |
| 724 | Header& header = m_SentHandshakePacket->header; |
| 725 | uint8_t * headerX = m_SentHandshakePacket->headerX, |
| 726 | * payload = m_SentHandshakePacket->payload; |
| 727 | // fill packet |
| 728 | header.h.connID = m_DestConnID; // dest id |
| 729 | RAND_bytes (header.buf + 8, 4); // random packet num |
| 730 | header.h.type = eSSU2SessionRequest; |
| 731 | header.h.flags[0] = m_Version; // ver |
| 732 | header.h.flags[1] = (uint8_t)i2p::context.GetNetID (); // netID |
| 733 | header.h.flags[2] = 0; // flag |
| 734 | memcpy (headerX, &m_SourceConnID, 8); // source id |
| 735 | memcpy (headerX + 8, &token, 8); // token |
| 736 | memcpy (headerX + 16, m_EphemeralKeys->GetPublicKey (), 32); // X |
| 737 | // payload |
| 738 | size_t payloadSize = 0, offset = 0; |
| 739 | #if OPENSSL_PQ |
| 740 | if (m_Version > 2) |
| 741 | { |
| 742 | i2p::data::CryptoKeyType cryptoType = (i2p::data::CryptoKeyType)(m_Version + 2); |
| 743 | m_PQKeys = i2p::crypto::CreateMLKEMKeys (cryptoType); |
| 744 | m_PQKeys->GenerateKeys (); |
| 745 | offset = m_PQKeys->GetKeyLen () + 16; |
| 746 | payloadSize += offset; |
| 747 | } |
| 748 | #endif |
| 749 | payload[payloadSize] = eSSU2BlkDateTime; |
| 750 | htobe16buf (payload + payloadSize + 1, 4); |
| 751 | htobe32buf (payload + payloadSize + 3, (ts + 500)/1000); |
| 752 | payloadSize += 7; |
| 753 | if (GetRouterStatus () == eRouterStatusFirewalled && m_Address->IsIntroducer ()) |
| 754 | { |
| 755 | if (!m_Server.IsMaxNumIntroducers (m_RemoteEndpoint.address ().is_v4 ()) || |
| 756 | m_Server.GetRng ()() & 0x01) // request tag with probability 1/2 if we have enough introducers |
| 757 | { |
| 758 | // relay tag request |
| 759 | payload[payloadSize] = eSSU2BlkRelayTagRequest; |
| 760 | memset (payload + payloadSize + 1, 0, 2); // size = 0 |
| 761 | payloadSize += 3; |
| 762 | } |
| 763 | } |
| 764 | if (payloadSize <= m_MaxPayloadSize - 48) |
| 765 | payloadSize += CreatePaddingBlock (payload + payloadSize, std::min (m_MaxPayloadSize - payloadSize - 48, (size_t)32)); |
| 766 | else |
| 767 | { |
| 768 | LogPrint (eLogError, "SSU2: SessionRequest max payload size is too small ", m_MaxPayloadSize); |
| 769 | return false; |
nothing calls this directly
no test coverage detected