diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index d1479da0..479c2062 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -314,7 +314,13 @@ namespace i2p { router.GetElGamalEncryption ()->Encrypt ((uint8_t *)&clearText, sizeof(clearText), record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)router.GetIdentHash (), 16); - } + } + + void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, const uint8_t * clearText, uint8_t * record) + { + router.GetElGamalEncryption ()->Encrypt (clearText, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)router.GetIdentHash (), 16); + } bool HandleBuildRequestRecords (int num, uint8_t * records, I2NPBuildRequestRecordClearText& clearText) { diff --git a/I2NPProtocol.h b/I2NPProtocol.h index f9bb438f..f7932f01 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -43,6 +43,21 @@ namespace i2p // TunnelBuild const size_t TUNNEL_BUILD_RECORD_SIZE = 528; + + //BuildRequestRecordClearText + const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; + const size_t BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET = BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; + const size_t BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET + 32; + const size_t BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4; + const size_t BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32; + const size_t BUILD_REQUEST_RECORD_IV_KEY_OFFSET = BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32; + const size_t BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32; + const size_t BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32; + const size_t BUILD_REQUEST_RECORD_FLAG_OFFSET = BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16; + const size_t BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = BUILD_REQUEST_RECORD_FLAG_OFFSET + 1; + const size_t BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; + const size_t BUILD_REQUEST_RECORD_PADDING_OFFSET = BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; + const size_t BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 222; // BuildRequestRecordEncrypted const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0; @@ -214,6 +229,7 @@ namespace tunnel bool isGateway, bool isEndpoint); void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, const I2NPBuildRequestRecordClearText& clearText, uint8_t * record); + void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, const uint8_t * clearText, uint8_t * record); bool HandleBuildRequestRecords (int num, uint8_t * records, I2NPBuildRequestRecordClearText& clearText); void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); diff --git a/Tunnel.cpp b/Tunnel.cpp index 20b7ec12..6f604122 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -48,16 +48,9 @@ namespace tunnel while (hop) { int idx = recordIndicies[i]; - EncryptBuildRequestRecord (*hop->router, - CreateBuildRequestRecord (hop->router->GetIdentHash (), - hop->tunnelID, - hop->nextRouter->GetIdentHash (), - hop->nextTunnelID, - hop->layerKey, hop->ivKey, - hop->replyKey, hop->replyIV, - hop->next ? rnd.GenerateWord32 () : replyMsgID, // we set replyMsgID for last hop only - hop->isGateway, hop->isEndpoint), - records + idx*TUNNEL_BUILD_RECORD_SIZE); + uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + hop->CreateBuildRequestRecord (clearText, hop->next ? rnd.GenerateWord32 () : replyMsgID); // we set replyMsgID for last hop only + EncryptBuildRequestRecord (*hop->router, clearText, records + idx*TUNNEL_BUILD_RECORD_SIZE); hop->recordIndex = idx; i++; hop = hop->next; diff --git a/TunnelConfig.h b/TunnelConfig.h index e7910ce1..8351f546 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -8,6 +8,7 @@ #include "aes.h" #include "RouterInfo.h" #include "RouterContext.h" +#include "Timestamp.h" namespace i2p { @@ -82,6 +83,25 @@ namespace tunnel isGateway = false; } } + + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID) + { + htobe32buf (record + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + memcpy (record + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, router->GetIdentHash (), 32); + htobe32buf (record + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (record + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextRouter->GetIdentHash (), 32); + memcpy (record + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (record + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (record + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (record + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + uint8_t flag = 0; + if (isGateway) flag |= 0x80; + if (isEndpoint) flag |= 0x40; + record[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + htobe32buf (record + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); + htobe32buf (record + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + // TODO: fill padding + } }; class TunnelConfig