MCPcopy Create free account
hub / github.com/PurpleI2P/i2pd / SendSessionConfirmed

Method SendSessionConfirmed

libi2pd/SSU2Session.cpp:1119–1198  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1117 }
1118
1119 void SSU2Session::SendSessionConfirmed (const uint8_t * Y)
1120 {
1121 // we are Alice
1122 m_SentHandshakePacket.reset (new HandshakePacket);
1123 m_SentHandshakePacket->sendTime = i2p::util::GetMillisecondsSinceEpoch ();
1124
1125 uint8_t kh2[32];
1126 i2p::crypto::HKDF (m_NoiseState->m_CK, nullptr, 0, "SessionConfirmed", kh2, 32); // k_header_2 = HKDF(chainKey, ZEROLEN, "SessionConfirmed", 32)
1127 // fill packet
1128 Header& header = m_SentHandshakePacket->header;
1129 header.h.connID = m_DestConnID; // dest id
1130 header.h.packetNum = 0; // always zero
1131 header.h.type = eSSU2SessionConfirmed;
1132 memset (header.h.flags, 0, 3);
1133 header.h.flags[0] = 1; // frag, total fragments always 1
1134 // payload
1135 size_t maxPayloadSize = m_MaxPayloadSize - 48; // for part 2, 48 is part1
1136 uint8_t * payload = m_SentHandshakePacket->payload;
1137 size_t payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.CopyRouterInfoBuffer ());
1138 if (!payloadSize)
1139 {
1140 // split by two fragments
1141 maxPayloadSize += m_MaxPayloadSize;
1142 payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.CopyRouterInfoBuffer ());
1143 header.h.flags[0] = 0x02; // frag 0, total fragments 2
1144 // TODO: check if we need more fragments
1145 }
1146 if (payloadSize < maxPayloadSize)
1147 payloadSize += CreatePaddingBlock (payload + payloadSize, maxPayloadSize - payloadSize);
1148 // KDF for Session Confirmed part 1
1149 m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
1150 // Encrypt part 1
1151 uint8_t * part1 = m_SentHandshakePacket->headerX;
1152 m_NoiseState->Encrypt (i2p::context.GetSSU2StaticPublicKey (), part1, 32);
1153 m_NoiseState->MixHash (part1, 48); // h = SHA256(h || ciphertext);
1154 // KDF for Session Confirmed part 2
1155 uint8_t sharedSecret[32];
1156 i2p::context.GetSSU2StaticKeys ().Agree (Y, sharedSecret);
1157 m_NoiseState->MixKey (sharedSecret);
1158 // Encrypt part2
1159 m_NoiseState->Encrypt (payload, payload, payloadSize);
1160 payloadSize += 16;
1161 m_NoiseState->MixHash (payload, payloadSize); // h = SHA256(h || ciphertext);
1162 m_SentHandshakePacket->payloadSize = payloadSize;
1163 if (header.h.flags[0] > 1)
1164 {
1165 if (payloadSize > m_MaxPayloadSize - 48)
1166 {
1167 payloadSize = m_MaxPayloadSize - 48 - (m_Server.GetRng ()() % 16);
1168 if (m_SentHandshakePacket->payloadSize - payloadSize < 24)
1169 payloadSize -= 24;
1170 }
1171 else
1172 header.h.flags[0] = 1;
1173 }
1174 // Encrypt header
1175 header.ll[0] ^= CreateHeaderMask (m_Address->i, payload + (payloadSize - 24));
1176 header.ll[1] ^= CreateHeaderMask (kh2, payload + (payloadSize - 12));

Callers

nothing calls this directly

Calls 10

HKDFFunction · 0.85
CreateHeaderMaskFunction · 0.85
CopyRouterInfoBufferMethod · 0.80
MixHashMethod · 0.80
AgreeMethod · 0.80
MixKeyMethod · 0.80
EncryptMethod · 0.45
SendMethod · 0.45

Tested by

no test coverage detected