From cb97ce6f728e051f2fb2b69690fa53a01e339663 Mon Sep 17 00:00:00 2001 From: csoler <csoler@users.sourceforge.net> Date: Wed, 18 Nov 2015 23:56:35 -0500 Subject: [PATCH] half-way through GxsTunnel service --- libretroshare/src/gxstunnel/p3gxstunnel.cc | 173 +++++--- libretroshare/src/gxstunnel/p3gxstunnel.h | 3 +- .../src/gxstunnel/rsgxstunnelitems.h | 385 +++--------------- libretroshare/src/serialiser/rsserviceids.h | 39 +- 4 files changed, 191 insertions(+), 409 deletions(-) diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index a62e8e5b2..b43aa7ff8 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -51,6 +51,13 @@ static const uint32_t RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED = 0x0000 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE = 0x0001 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE = 0x0002 ; +static const uint32_t RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00 ; +static const uint32_t RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x01 ; +static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ; + +static const uint32_t GXS_TUNNEL_HMAC_SIZE = SHA_DIGEST_LENGTH ; +static const uint32_t GXS_TUNNEL_IV_SIZE = 8 ; + void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr) { mTurtle = tr ; @@ -93,7 +100,7 @@ void p3GxsTunnelService::flush() } if(it->second.last_keep_alive_sent + GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) { - RsChatStatusItem *cs = new RsChatStatusItem ; + RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; #warning should we send that unencrypted?? cs->status_string.clear() ; @@ -112,21 +119,26 @@ void p3GxsTunnelService::flush() } } -bool p3GxsTunnelService::handleRecvItem(RsChatItem *item) +bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item) { if(item == NULL) return false ; switch(item->PacketSubType()) { - case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ; - return true ; + case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ; + return true ; - case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: - { - // Keep alive packets should not be forwarded to the GUI. It's just for keeping the tunnel up. - - return true ; +#warning need to implement tunnel data handling here + case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: + return true ; + +#warning need to implement tunnel data ACK handling here + case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: + return true ; + + case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(dynamic_cast<RsGxsTunnelStatusItem*>(item)) ; + return true ; } default: @@ -135,7 +147,9 @@ bool p3GxsTunnelService::handleRecvItem(RsChatItem *item) return false ; } -bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item) + +#warning is this function still used?? +bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item) { { RS_STACK_MUTEX(mGxsTunnelMtx) ; @@ -147,7 +161,7 @@ bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item) } #ifdef CHAT_DEBUG - std::cerr << "p3ChatService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl; + std::cerr << "p3GxsTunnelService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl; #endif sendTurtleData(item) ; return true; @@ -161,7 +175,7 @@ void p3GxsTunnelService::handleRecvStatusItem(RsGxsTunnelStatusItem *cs) // nothing more to do, because the decryption routing will update the last_contact time when decrypting. if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE) - std::cerr << "GxsTunnelService::handleRecvChatStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << std::endl; + std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << std::endl; } bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/) @@ -192,64 +206,64 @@ bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeer void p3GxsTunnelService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) { #ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService:: received new virtual peer " << virtual_peer_id << " for hash " << hash << ", dir=" << dir << std::endl; + std::cerr << "GxsTunnelService:: received new virtual peer " << virtual_peer_id << " for hash " << hash << ", dir=" << dir << std::endl; #endif - RsGxsId own_gxs_id ; + RsGxsId own_gxs_id ; - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ + { + RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - GxsTunnelDHInfo& dhinfo( _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ) ; - dhinfo.gxs_id.clear() ; + GxsTunnelDHInfo& dhinfo( _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ) ; + dhinfo.gxs_id.clear() ; - if(dhinfo.dh != NULL) - DH_free(dhinfo.dh) ; + if(dhinfo.dh != NULL) + DH_free(dhinfo.dh) ; - dhinfo.dh = NULL ; - dhinfo.direction = dir ; - dhinfo.hash = hash ; - dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ; + dhinfo.dh = NULL ; + dhinfo.direction = dir ; + dhinfo.hash = hash ; + dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ; - if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) - { - // check that a tunnel is not already working for this hash. If so, give up. + if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) + { + // check that a tunnel is not already working for this hash. If so, give up. - own_gxs_id = gxsIdFromHash(hash) ; - } - else // client side - { - RsGxsId to_gxs_id = gxsIdFromHash(hash) ; - std::map<RsGxsId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(to_gxs_id) ; + own_gxs_id = gxsIdFromHash(hash) ; + } + else // client side + { + RsGxsId to_gxs_id = gxsIdFromHash(hash) ; + std::map<RsGxsId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(to_gxs_id) ; - if(it == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) no pre-registered peer for hash " << hash << " on client side. This is a bug." << std::endl; - return ; - } + if(it == _gxs_tunnel_contacts.end()) + { + std::cerr << "(EE) no pre-registered peer for hash " << hash << " on client side. This is a bug." << std::endl; + return ; + } - if(it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) - { - std::cerr << " virtual peer is for a distant chat session that is already openned and alive. Giving it up." << std::endl; - return ; - } + if(it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) + { + std::cerr << " virtual peer is for a distant chat session that is already openned and alive. Giving it up." << std::endl; + return ; + } - own_gxs_id = it->second.own_gxs_id ; - } + own_gxs_id = it->second.own_gxs_id ; + } #ifdef DEBUG_GXS_TUNNEL - std::cerr << " Creating new virtual peer ID entry and empty DH session key." << std::endl; + std::cerr << " Creating new virtual peer ID entry and empty DH session key." << std::endl; #endif - } + } #ifdef DEBUG_GXS_TUNNEL - std::cerr << " Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl; + std::cerr << " Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl; #endif - // Start a new DH session for this tunnel - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ + // Start a new DH session for this tunnel + RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - locked_restartDHSession(virtual_peer_id,own_gxs_id) ; + locked_restartDHSession(virtual_peer_id,own_gxs_id) ; } void p3GxsTunnelService::locked_restartDHSession(const RsPeerId& virtual_peer_id,const RsGxsId& own_gxs_id) @@ -350,8 +364,6 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl; return ; } -#warning use flags here!! -#warning add a MAC to make sure the data is not forged if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags { #ifdef DEBUG_GXS_TUNNEL @@ -392,6 +404,7 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons } } +// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel. bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) { @@ -409,7 +422,9 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t { RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - uint32_t decrypted_size = RsAES::get_buffer_size(data_size-8); + uint32_t encrypted_size = data_size - GXS_TUNNEL_IV_SIZE - GXS_TUNNEL_HMAC_SIZE; + uint32_t decrypted_size = RsAES::get_buffer_size(encrypted_size); + uint8_t *encrypted_data = (uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE+GXS_TUNNEL_HMAC_SIZE; uint8_t *decrypted_data = new uint8_t[decrypted_size]; uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; @@ -434,11 +449,27 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t #ifdef DEBUG_GXS_TUNNEL std::cerr << " Using IV: " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl; - std::cerr << " key : " << Bin2Hex(aes_key,16) << ; std::cerr << std::endl; + std::cerr << " key : " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) << ; std::cerr << std::endl; + std::cerr << " hmac : " << Bin2Hex((uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE,GXS_TUNNEL_HMAC_SIZE) << ; std::cerr << std::endl; std::cerr << " data : " << Bin2Hex((uint8_t*)data_bytes,data_size) << ; std::cerr << std::endl; #endif + // first, check the HMAC + + unsigned char *hm = HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,NULL,NULL) ; + + if(memcmp(hm,&data_bytes[GXS_TUNNEL_IV_SIZE],GXS_TUNNEL_HMAC_SIZE)) + { + std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << Bin2Hex(md,GXS_TUNNEL_HMAC_SIZE) << std::endl; + std::cerr << "(EE) resetting new DH session." << std::endl; - if(!RsAES::aes_decrypt_8_16((uint8_t*)data_bytes+8,data_size-8,aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size)) + delete[] decrypted_data ; + + locked_restartDHSession(virtual_peer_id,it2->second.own_gxs_id) ; + + return false ; + } + + if(!RsAES::aes_decrypt_8_16(encrypted_data,encrypted_size, aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size)) { std::cerr << "(EE) packet decryption failed." << std::endl; std::cerr << "(EE) resetting new DH session." << std::endl; @@ -750,7 +781,9 @@ bool GxsTunnelService::locked_initDHSessionKey(DH *& dh) return true ; } -void p3GxsTunnelService::sendTurtleData(RsChatItem *item) +// Encrypts and sends the item. + +void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item) { #ifdef DEBUG_GXS_TUNNEL std::cerr << "GxsTunnelService::sendTurtleData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl; @@ -767,6 +800,7 @@ void p3GxsTunnelService::sendTurtleData(RsChatItem *item) gitem->data_size = rssize + 8 ; gitem->data_bytes = malloc(rssize+8) ; + // by convention, we use a IV of 0 for unencrypted data. memset(gitem->data_bytes,0,8) ; if(!item->serialise(&((uint8_t*)gitem->data_bytes)[8],rssize)) @@ -842,10 +876,6 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)]; uint32_t encrypted_size = RsAES::get_buffer_size(rssize); -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl; - std::cerr << " Using Key: " << Bin2Hex(aes_key,16) ; std::cerr << std::endl; -#endif if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size)) { std::cerr << "(EE) packet encryption failed." << std::endl; @@ -857,18 +887,27 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs // RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ; - gitem->data_size = encrypted_size + 8 ; + gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_HMAC_SIZE ; gitem->data_bytes = malloc(gitem->data_size) ; - memcpy(gitem->data_bytes ,&IV,8) ; - memcpy(& (((uint8_t*)gitem->data_bytes)[8]),encrypted_data,encrypted_size) ; + memcpy(& (((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ; + unsigned int md_len = GXS_TUNNEL_HMAC_SIZE ; + HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_IV_SIZE]),&md_len) ; + + memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_HMAC_SIZE+GXS_TUNNEL_IV_SIZE]),encrypted_data,encrypted_size) ; + delete[] encrypted_data ; +#ifdef DEBUG_GXS_TUNNEL + std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl; + std::cerr << " Using Key: " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl; + std::cerr << " hmac: " << Bin2Hex(gitem->data_bytes,GXS_TUNNEL_HMAC_SIZE) ; +#endif #ifdef DEBUG_GXS_TUNNEL std::cerr << "GxsTunnelService::sendTurtleData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl; std::cerr << " gitem->data_size = " << gitem->data_size << std::endl; - std::cerr << " data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ; + std::cerr << " serialised data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ; std::cerr << std::endl; #endif @@ -946,11 +985,11 @@ void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id #warning check that this code should go. #ifdef TO_BE_REMOVED // spawn a status item so as to open the chat window. - RsChatMsgItem *item = new RsChatMsgItem; + RsGxsTunnelMsgItem *item = new RsGxsTunnelMsgItem; item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ; item->chatFlags = RS_CHAT_FLAG_PRIVATE ; item->PeerId(RsPeerId(to_gxs_id)) ; - handleRecvChatMsgItem(item) ; + handleRecvGxsTunnelMsgItem(item) ; #endif } diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.h b/libretroshare/src/gxstunnel/p3gxstunnel.h index c08c57690..a26ef6019 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.h +++ b/libretroshare/src/gxstunnel/p3gxstunnel.h @@ -27,6 +27,7 @@ #include <turtle/turtleclientservice.h> #include <retroshare/rsgxstunnel.h> +#include <gxstunnel/rsgxstunnelitems.h> class RsGixs ; @@ -120,7 +121,7 @@ private: bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ; bool locked_initDHSessionKey(DH *&dh); - GxsTunnelPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle + TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle // Comunication with Turtle service diff --git a/libretroshare/src/gxstunnel/rsgxstunnelitems.h b/libretroshare/src/gxstunnel/rsgxstunnelitems.h index 34c960d95..f2f4c0ef5 100644 --- a/libretroshare/src/gxstunnel/rsgxstunnelitems.h +++ b/libretroshare/src/gxstunnel/rsgxstunnelitems.h @@ -25,7 +25,6 @@ #pragma once -#include "openssl/bn.h" #include "retroshare/rstypes.h" #include "serialiser/rstlvkeys.h" #include "serialiser/rsserviceids.h" @@ -35,60 +34,26 @@ #include "serialiser/rstlvfileitem.h" /* chat Flags */ -const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001; -const uint32_t RS_CHAT_FLAG_REQUESTS_AVATAR = 0x0002; -const uint32_t RS_CHAT_FLAG_CONTAINS_AVATAR = 0x0004; -const uint32_t RS_CHAT_FLAG_AVATAR_AVAILABLE = 0x0008; -const uint32_t RS_CHAT_FLAG_CUSTOM_STATE = 0x0010; // used for transmitting peer status string -const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020; -const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040; -const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080; -const uint32_t RS_CHAT_FLAG_PARTIAL_MESSAGE = 0x0100; -const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200; -const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400; -const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800; -const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000; +const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400; +const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800; +const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000; -const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001; +const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ; +const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ; +const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ; +const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ; -const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_ACCEPT = 0x08 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; // will be deprecated when only signed messages are accepted (02/2015) -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_deprecated = 0x0F ; // to be removed -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012) -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated3 = 0x12 ; -const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ; -const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG = 0x17 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT = 0x18 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x19 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1A ; +typedef uint64_t GxsTunnelDHSessionId ; -typedef uint64_t ChatLobbyId ; -typedef uint64_t ChatLobbyMsgId ; -typedef std::string ChatLobbyNickName ; -typedef uint64_t DistantChatDHSessionId ; - -class RsChatItem: public RsItem +class RsGxsTunnelItem: public RsItem { public: - RsChatItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_CHAT,chat_subtype) + RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype) { setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ; } - virtual ~RsChatItem() {} + virtual ~RsGxsTunnelItem() {} virtual void clear() {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ; @@ -96,305 +61,80 @@ class RsChatItem: public RsItem virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor }; -/*! - * For sending chat msgs - * @see p3ChatService - */ -class RsChatMsgItem: public RsChatItem -{ -public: - RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {} - RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {} +// /*! +// * For sending distant communication data. The item is not encrypted after being serialised, but the data it. +// * The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and +// * sent as data in a RsGxsTunnelDataItem. +// * +// * @see p3GxsTunnelService +// */ +// class RsGxsTunnelDataItem: public RsGxsTunnelItem +// { +// public: +// RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) {} +// RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) {} +// +// virtual ~RsGxsTunnelDataItem() {} +// virtual void clear() {} +// virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); +// +// virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? +// virtual uint32_t serial_size() ; // deserialise is handled using a constructor +// +// uint32_t sendTime; +// uint32_t flags; // mainly NEEDS_HACK? +// unsigned char *data ; // encrypted data +// uint32_t data_size ; // encrypted data size +// unsigned char IV[IV_LENGTH] ; // IV for the encrypted data +// unsigned char encrypted_data_mac[SHA_DIGEST_LENGTH] ; // mac of the encrypted data, in order to avoid +// }; - RsChatMsgItem(void *data,uint32_t size,uint8_t subtype = RS_PKT_SUBTYPE_DEFAULT) ; // deserialization +// Used to send status of connection. This can be closing orders, flushing orders, etc. +// These items are always sent encrypted. - virtual ~RsChatMsgItem() {} - virtual void clear() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor - - uint32_t chatFlags; - uint32_t sendTime; - std::string message; - - /* not serialised */ - uint32_t recvTime; -}; - -// This class contains the info to bounce an object throughout a lobby, while -// maintaining cache info to avoid duplicates. -// -class RsChatLobbyBouncingObject -{ -public: - ChatLobbyId lobby_id ; - ChatLobbyMsgId msg_id ; - ChatLobbyNickName nick ; // Nickname of sender - - RsTlvKeySignature signature ; - - virtual RsChatLobbyBouncingObject *duplicate() const = 0 ; - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - // returns the size in bytes of the data chunk to sign. - - virtual uint32_t signed_serial_size() =0; - virtual bool serialise_signed_part(void *data,uint32_t& size) = 0; - -protected: - // The functions below handle the serialisation of data that is specific to the bouncing object level. - // They are called by serial_size() and serialise() from children, but should not overload the serial_size() and - // serialise() methods, otherwise the wrong method will be called when serialising from this top level class. - - uint32_t serialized_size(bool include_signature) ; - bool serialise_to_memory(void *data,uint32_t tlvsize,uint32_t& offset,bool include_signature) ; - bool deserialise_from_memory(void *data,uint32_t rssize,uint32_t& offset) ; -}; - -class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject -{ -public: - RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG) {} - - RsChatLobbyMsgItem(void *data,uint32_t size) ; // deserialization /// TODO!!! - - virtual ~RsChatLobbyMsgItem() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; } - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor - - virtual uint32_t signed_serial_size() ; - virtual bool serialise_signed_part(void *data,uint32_t& size) ;// Isn't it better that items can serialize themselves ? - - ChatLobbyMsgId parent_msg_id ; // Used for threaded chat. -}; - -class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject -{ - public: - RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {} - RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!! - - virtual ~RsChatLobbyEventItem() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; } - // - virtual bool serialise(void *data,uint32_t& size) ; - virtual uint32_t serial_size() ; - - virtual uint32_t signed_serial_size() ; - virtual bool serialise_signed_part(void *data,uint32_t& size) ; - - // members. - // - uint8_t event_type ; // used for defining the type of event. - std::string string1; // used for any string - uint32_t sendTime; // used to check for old looping messages -}; - -class RsChatLobbyListRequestItem: public RsChatItem +class RsGxsTunnelStatusItem: public RsGxsTunnelItem { public: - RsChatLobbyListRequestItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST) {} - RsChatLobbyListRequestItem(void *data,uint32_t size) ; - virtual ~RsChatLobbyListRequestItem() {} + RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) {} + RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization - virtual bool serialise(void *data,uint32_t& size) ; - virtual uint32_t serial_size() ; - - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); -}; - -struct VisibleChatLobbyInfo -{ - ChatLobbyId id ; - std::string name ; - std::string topic ; - uint32_t count ; - ChatLobbyFlags flags ; -}; - -class RsChatLobbyListItem: public RsChatItem -{ - public: - RsChatLobbyListItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST) {} - RsChatLobbyListItem(void *data,uint32_t size) ; - virtual ~RsChatLobbyListItem() {} - - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - virtual bool serialise(void *data,uint32_t& size) ; - virtual uint32_t serial_size() ; - - std::vector<VisibleChatLobbyInfo> lobbies ; -}; - -class RsChatLobbyUnsubscribeItem: public RsChatItem -{ - public: - RsChatLobbyUnsubscribeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE) {} - RsChatLobbyUnsubscribeItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsChatLobbyUnsubscribeItem() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - uint64_t lobby_id ; - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor -}; - -class RsChatLobbyConnectChallengeItem: public RsChatItem -{ - public: - RsChatLobbyConnectChallengeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE) {} - RsChatLobbyConnectChallengeItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsChatLobbyConnectChallengeItem() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - uint64_t challenge_code ; - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor -}; - -class RsChatLobbyInviteItem: public RsChatItem -{ - public: - RsChatLobbyInviteItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE) {} - RsChatLobbyInviteItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsChatLobbyInviteItem() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - ChatLobbyId lobby_id ; - std::string lobby_name ; - std::string lobby_topic ; - ChatLobbyFlags lobby_flags ; - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor -}; - -/*! - * For saving incoming and outgoing chat msgs - * @see p3ChatService - */ -class RsPrivateChatMsgConfigItem: public RsChatItem -{ - public: - RsPrivateChatMsgConfigItem() :RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG) {} - RsPrivateChatMsgConfigItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsPrivateChatMsgConfigItem() {} - virtual void clear() {} + virtual ~RsGxsTunnelStatusItem() {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor + virtual uint32_t serial_size() ; // deserialise is handled using a constructor - /* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */ - void set(RsChatMsgItem *ci, const RsPeerId &peerId, uint32_t confFlags); - /* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */ - void get(RsChatMsgItem *ci); - - RsPeerId configPeerId; - uint32_t chatFlags; - uint32_t configFlags; - uint32_t sendTime; - std::string message; - uint32_t recvTime; -}; -class RsPrivateChatDistantInviteConfigItem: public RsChatItem -{ - public: - RsPrivateChatDistantInviteConfigItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG) {} - RsPrivateChatDistantInviteConfigItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsPrivateChatDistantInviteConfigItem() {} - virtual void clear() {} - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor - - unsigned char aes_key[16] ; - RsFileHash hash ; - std::string encrypted_radix64_string ; - RsPgpId destination_pgp_id ; - uint32_t time_of_validity ; - uint32_t last_hit_time ; uint32_t flags ; }; -class RsChatLobbyConfigItem: public RsChatItem -{ -public: - RsChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG) { lobby_Id = 0; } - RsChatLobbyConfigItem(void *data,uint32_t size) ; // deserialization - virtual ~RsChatLobbyConfigItem() {} +// Used to confirm reception of an encrypted item. - virtual void clear() { lobby_Id = 0; } - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor - - uint64_t lobby_Id; - uint32_t flags ; -}; - -// This class contains activity info for the sending peer: active, idle, typing, etc. -// -class RsChatStatusItem: public RsChatItem +class RsGxsTunnelDataAckItem: public RsGxsTunnelItem { public: - RsChatStatusItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_STATUS) {} - RsChatStatusItem(void *data,uint32_t size) ; // deserialization + RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK) {} + RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization - virtual ~RsChatStatusItem() {} + virtual ~RsGxsTunnelDataAckItem() {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor + virtual uint32_t serial_size() ; // deserialise is handled using a constructor - uint32_t flags ; - std::string status_string; + Sha1CheckSum data_hash ; }; -// This class contains avatar images in Qt format. -// -class RsChatAvatarItem: public RsChatItem -{ - public: - RsChatAvatarItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_AVATAR) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_AVATAR_ITEM) ;} - RsChatAvatarItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsChatAvatarItem() ; - virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() ; // deserialise is handled using a constructor - - uint32_t image_size ; // size of data in bytes - unsigned char *image_data ; // image -}; // This class contains the public Diffie-Hellman parameters to be sent // when performing a DH agreement over a distant chat tunnel. // -class RsChatDHPublicKeyItem: public RsChatItem +class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem { public: - RsChatDHPublicKeyItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;} - RsChatDHPublicKeyItem(void *data,uint32_t size) ; // deserialization + RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} + RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization - virtual ~RsChatDHPublicKeyItem() { BN_free(public_key) ; } + virtual ~RsGxsTunnelDHPublicKeyItem() { BN_free(public_key) ; } virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? @@ -408,22 +148,23 @@ class RsChatDHPublicKeyItem: public RsChatItem RsTlvSecurityKey gxs_key ; // public key of the signer private: - RsChatDHPublicKeyItem(const RsChatDHPublicKeyItem&) : RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} // make the object non copy-able - const RsChatDHPublicKeyItem& operator=(const RsChatDHPublicKeyItem&) { return *this ;} + // make the object non copy-able + RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {} + const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { return *this ;} }; -class RsChatSerialiser: public RsSerialType +class RsGxsTunnelSerialiser: public RsSerialType { public: - RsChatSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT) {} + RsGxsTunnelSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TUNNEL) {} virtual uint32_t size (RsItem *item) { - return static_cast<RsChatItem *>(item)->serial_size() ; + return static_cast<RsGxsTunnelItem *>(item)->serial_size() ; } virtual bool serialise(RsItem *item, void *data, uint32_t *size) { - return static_cast<RsChatItem *>(item)->serialise(data,*size) ; + return static_cast<RsGxsTunnelItem *>(item)->serialise(data,*size) ; } virtual RsItem *deserialise (void *data, uint32_t *size) ; }; diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index 3460008a8..b7d7b2fa1 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -38,32 +38,33 @@ */ /* These are Cache Only */ -const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001; +const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001; /* These are Services only */ -const uint16_t RS_SERVICE_TYPE_DISC = 0x0011; -const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012; -const uint16_t RS_SERVICE_TYPE_MSG = 0x0013; -const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014; -const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015; -const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016; -const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017; -const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018; +const uint16_t RS_SERVICE_TYPE_DISC = 0x0011; +const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012; +const uint16_t RS_SERVICE_TYPE_MSG = 0x0013; +const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014; +const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015; +const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016; +const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017; +const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018; -const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020; +const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020; /* Bandwidth Control */ -const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021; -// New Mail Service (replace old Msg Service) -const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022; -const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023; -const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024; -const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025; +const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021; +// New Mail Service (replace old Msg Service) +const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022; +const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023; +const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024; +const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025; const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026; -const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027; +const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027; +const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028; // Non essential services. -const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101; -const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102; +const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101; +const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102; /* New Cache Services */ /* Rs Network Exchange Service */