From d3bbd88abc9aae94147d2a2e0f994244cc969e37 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 20 Mar 2014 23:01:00 +0000 Subject: [PATCH] encryption/decryption of distant messages. Moved initialisation of services after GXS components in rsinit.cc. Slightly changed prototype of GxsSecurity::{en,de}crypt() to be consistent with the other methods of that class git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-IdCleaning@7193 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 139 +++++---- libretroshare/src/gxs/gxssecurity.h | 4 +- libretroshare/src/rsserver/rsinit.cc | 115 ++++---- libretroshare/src/services/p3msgservice.cc | 328 ++++++++++++--------- libretroshare/src/services/p3msgservice.h | 128 ++++---- 5 files changed, 391 insertions(+), 323 deletions(-) diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index f32e9f150..8f2a5a414 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -204,101 +204,112 @@ std::string GxsSecurity::getBinDataSign(void *data, int len) -bool GxsSecurity::encrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey) +bool GxsSecurity::encrypt(void *& out, int & outlen, const void *in, int inlen, const RsTlvSecurityKey& key) { - - #ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::encrypt() " << std::endl; + std::cerr << "GxsSecurity::encrypt() " << std::endl; #endif - RSA *rsa_publish_pub = NULL; - EVP_PKEY *public_key = NULL; + RSA *rsa_publish_pub = RSAPublicKey_dup(extractPublicKey(key)) ; + EVP_PKEY *public_key = NULL; - RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); - rsa_publish_pub = RSAPublicKey_dup(rsa_publish); + //RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); + //rsa_publish_pub = RSAPublicKey_dup(rsa_publish); - if(rsa_publish_pub != NULL){ - public_key = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(public_key, rsa_publish_pub); - }else{ + if(rsa_publish_pub != NULL) + { + public_key = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(public_key, rsa_publish_pub); + }else{ #ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity(): Could not generate publish key " << grpId - << std::endl; + std::cerr << "GxsSecurity(): Could not generate publish key " << grpId + << std::endl; #endif - return false; - } + return false; + } - EVP_CIPHER_CTX ctx; - int eklen, net_ekl; - unsigned char *ek; - unsigned char iv[EVP_MAX_IV_LENGTH]; - EVP_CIPHER_CTX_init(&ctx); - int out_currOffset = 0; - int out_offset = 0; + EVP_CIPHER_CTX ctx; + int eklen, net_ekl; + unsigned char *ek; + unsigned char iv[EVP_MAX_IV_LENGTH]; + EVP_CIPHER_CTX_init(&ctx); + int out_currOffset = 0; + int out_offset = 0; - int max_evp_key_size = EVP_PKEY_size(public_key); - ek = (unsigned char*)malloc(max_evp_key_size); - const EVP_CIPHER *cipher = EVP_aes_128_cbc(); - int cipher_block_size = EVP_CIPHER_block_size(cipher); - int size_net_ekl = sizeof(net_ekl); + int max_evp_key_size = EVP_PKEY_size(public_key); + ek = (unsigned char*)malloc(max_evp_key_size); + const EVP_CIPHER *cipher = EVP_aes_128_cbc(); + int cipher_block_size = EVP_CIPHER_block_size(cipher); + int size_net_ekl = sizeof(net_ekl); - int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl; + int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl; - // intialize context and send store encrypted cipher in ek - if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false; + // intialize context and send store encrypted cipher in ek + if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false; - // now assign memory to out accounting for data, and cipher block size, key length, and key length val - out = new unsigned char[inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH]; + // now assign memory to out accounting for data, and cipher block size, key length, and key length val + out = new unsigned char[inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH]; - net_ekl = htonl(eklen); - memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl); - out_offset += size_net_ekl; + net_ekl = htonl(eklen); + memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl); + out_offset += size_net_ekl; - memcpy((unsigned char*)out + out_offset, ek, eklen); - out_offset += eklen; + memcpy((unsigned char*)out + out_offset, ek, eklen); + out_offset += eklen; - memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); - out_offset += EVP_MAX_IV_LENGTH; + memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); + out_offset += EVP_MAX_IV_LENGTH; - // now encrypt actual data - if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) return false; + // now encrypt actual data + if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) return false; - // move along to partial block space - out_offset += out_currOffset; + // move along to partial block space + out_offset += out_currOffset; - // add padding - if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) return false; + // add padding + if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) return false; - // move to end - out_offset += out_currOffset; + // move to end + out_offset += out_currOffset; - // make sure offset has not gone passed valid memory bounds - if(out_offset > max_outlen) return false; + // make sure offset has not gone passed valid memory bounds + if(out_offset > max_outlen) return false; - // free encrypted key data - free(ek); + // free encrypted key data + free(ek); - outlen = out_offset; - return true; - - delete[] ek; - -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::encrypt() finished with outlen : " << outlen << std::endl; -#endif - - return true; + outlen = out_offset; + return true; } -bool GxsSecurity::decrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey) +bool GxsSecurity::decrypt(void *& out, int & outlen, const void *in, int inlen, const RsTlvSecurityKey& key) { #ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::decrypt() " << std::endl; + std::cerr << "GxsSecurity::decrypt() " << std::endl; #endif + RSA *rsa_publish = RSAPublicKey_dup(extractPrivateKey(key)) ; + EVP_PKEY *privateKey = NULL; + + //RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); + //rsa_publish_pub = RSAPublicKey_dup(rsa_publish); + + if(rsa_publish != NULL) + { + privateKey = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(privateKey, rsa_publish); + } + else + { +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity(): Could not generate publish key " << grpId + << std::endl; +#endif + return false; + } + EVP_CIPHER_CTX ctx; int eklen = 0, net_ekl = 0; diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h index 4ebd122f4..990875aff 100644 --- a/libretroshare/src/gxs/gxssecurity.h +++ b/libretroshare/src/gxs/gxssecurity.h @@ -98,7 +98,7 @@ public: *@param in *@param inlen */ - static bool encrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey); + static bool encrypt(void *&out, int &outlen, const void *in, int inlen, const RsTlvSecurityKey& key) ; /** @@ -110,7 +110,7 @@ public: * @param inlen * @return false if encryption failed */ - static bool decrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey); + static bool decrypt(void *&out, int &outlen, const void *in, int inlen, const RsTlvSecurityKey& key) ; /*! * uses grp signature to check if group has been diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 3f7aafcd6..c8367ca48 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1293,63 +1293,6 @@ int RsServer::StartupRetroShare() // mPluginsManager->loadPlugins(programatically_inserted_plugins) ; - /* create Services */ - mDisc = new p3discovery2(mPeerMgr, mLinkMgr, mNetMgr); - mHeart = new p3heartbeat(mLinkMgr, pqih); - msgSrv = new p3MsgService(mLinkMgr); - chatSrv = new p3ChatService(mLinkMgr, mHistoryMgr); - mStatusSrv = new p3StatusService(mLinkMgr); - -#ifdef GROUTER - p3GRouter *gr = new p3GRouter(mLinkMgr) ; - rsGRouter = gr ; - pqih->addService(gr) ; -#endif - - p3turtle *tr = new p3turtle(mLinkMgr) ; - rsTurtle = tr ; - pqih -> addService(tr); - pqih -> addService(ftserver); - - rsDisc = mDisc; - rsMsgs = new p3Msgs(msgSrv, chatSrv); - - // connect components to turtle router. - - ftserver->connectToTurtleRouter(tr) ; - chatSrv->connectToTurtleRouter(tr) ; -#ifdef GROUTER - msgSrv->connectToGlobalRouter(gr) ; -#endif - pqih -> addService(mHeart); - pqih -> addService(mDisc); - pqih -> addService(msgSrv); - pqih -> addService(chatSrv); - pqih ->addService(mStatusSrv); - - - // set interfaces for plugins - // - RsPlugInInterfaces interfaces; - interfaces.mFiles = rsFiles; - interfaces.mPeers = rsPeers; - interfaces.mMsgs = rsMsgs; - interfaces.mTurtle = rsTurtle; - interfaces.mDisc = rsDisc; - interfaces.mDht = rsDht; - // don't exist no more. - //interfaces.mForums = mForums; - interfaces.mNotify = mNotify; - - mPluginsManager->setInterfaces(interfaces); - - // now add plugin objects inside the loop: - // - client services provided by plugins. - // - cache services provided by plugins. - // - mPluginsManager->registerClientServices(pqih) ; - mPluginsManager->registerCacheServices() ; - #ifdef RS_ENABLE_GXS // The idea is that if priorGxsDir is non @@ -1537,6 +1480,64 @@ int RsServer::StartupRetroShare() #endif // RS_ENABLE_GXS. + /* create Services */ + mDisc = new p3discovery2(mPeerMgr, mLinkMgr, mNetMgr); + mHeart = new p3heartbeat(mLinkMgr, pqih); + msgSrv = new p3MsgService(mLinkMgr,mGxsIdService); + chatSrv = new p3ChatService(mLinkMgr, mHistoryMgr); + mStatusSrv = new p3StatusService(mLinkMgr); + +#ifdef GROUTER + p3GRouter *gr = new p3GRouter(mLinkMgr) ; + rsGRouter = gr ; + pqih->addService(gr) ; +#endif + + p3turtle *tr = new p3turtle(mLinkMgr) ; + rsTurtle = tr ; + pqih -> addService(tr); + pqih -> addService(ftserver); + + rsDisc = mDisc; + rsMsgs = new p3Msgs(msgSrv, chatSrv); + + // connect components to turtle router. + + ftserver->connectToTurtleRouter(tr) ; + chatSrv->connectToTurtleRouter(tr) ; +#ifdef GROUTER + msgSrv->connectToGlobalRouter(gr) ; +#endif + pqih -> addService(mHeart); + pqih -> addService(mDisc); + pqih -> addService(msgSrv); + pqih -> addService(chatSrv); + pqih ->addService(mStatusSrv); + + + // set interfaces for plugins + // + RsPlugInInterfaces interfaces; + interfaces.mFiles = rsFiles; + interfaces.mPeers = rsPeers; + interfaces.mMsgs = rsMsgs; + interfaces.mTurtle = rsTurtle; + interfaces.mDisc = rsDisc; + interfaces.mDht = rsDht; + // don't exist no more. + //interfaces.mForums = mForums; + interfaces.mNotify = mNotify; + + mPluginsManager->setInterfaces(interfaces); + + // now add plugin objects inside the loop: + // - client services provided by plugins. + // - cache services provided by plugins. + // + mPluginsManager->registerClientServices(pqih) ; + mPluginsManager->registerCacheServices() ; + + #ifdef RS_RTT p3rtt *mRtt = new p3rtt(mLinkMgr); diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index f9bca9c5f..917d85f48 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -26,15 +26,20 @@ #include "retroshare/rsiface.h" #include "retroshare/rspeers.h" +#include "retroshare/rsidentity.h" #include "pqi/pqibin.h" #include "pqi/pqiarchive.h" #include "pqi/p3linkmgr.h" #include "pqi/authgpg.h" - -#include "services/p3msgservice.h" -#include "pgp/pgpkeyutil.h" #include "pqi/p3cfgmgr.h" + +#include "gxs/gxssecurity.h" + +#include "services/p3idservice.h" +#include "services/p3msgservice.h" + +#include "pgp/pgpkeyutil.h" #include "rsserver/p3face.h" #include "serialiser/rsconfigitems.h" #ifdef GROUTER @@ -78,9 +83,8 @@ static const uint8_t DISTANT_MSG_PROTOCOL_VERSION_02 = 0x48 ; */ -p3MsgService::p3MsgService(p3LinkMgr *lm) - :p3Service(RS_SERVICE_TYPE_MSG), p3Config(CONFIG_TYPE_MSGS), - mLinkMgr(lm), mMsgMtx("p3MsgService"), mMsgUniqueId(time(NULL)) +p3MsgService::p3MsgService(p3LinkMgr *lm,p3IdService *id_serv) + :p3Service(RS_SERVICE_TYPE_MSG), p3Config(CONFIG_TYPE_MSGS), mLinkMgr(lm), mIdService(id_serv), mMsgMtx("p3MsgService"), mMsgUniqueId(time(NULL)) { _serialiser = new RsMsgSerialiser(); addSerialType(_serialiser); @@ -1677,146 +1681,187 @@ RsMsgItem *p3MsgService::initMIRsMsg(const MessageInfo &info, const RsPeerId& to return msg; } +//void p3MsgService::handleResponse(uint32_t token,uint32_t req_type) +//{ +//} +// +//bool p3MsgService::hasRequestGxsIdKey(const RsGxsId& key_id) +//{ +// // Finite state machinery to get the GXS key. This is horrible. +// // +// +// std::maprequestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); +// +// uint32_t status ; +// while( (status = RsGenExchange::getTokenService()->requestStatus(token)) != GXS_REQUEST_V2_STATUS_COMPLETE) +// { +// std::cerr << " Waiting for answer..." << std::endl; +// usleep(500000) ; +// } +//} + bool p3MsgService::createDistantMessage(const RsGxsId& destination_gxs_id,const RsGxsId& source_gxs_id,RsMsgItem *item) { #ifdef DEBUG_DISTANT_MSG std::cerr << "Creating distant message for recipient " << item->PeerId() << ", encryption key=" << destination_gxs_id << " in place." << std::endl; #endif + unsigned char *data = NULL ; + void *encrypted_data = NULL ; - // 0 - append own id to the data. - // - uint32_t conservative_max_signature_size = 1000 ; - uint32_t message_size = _serialiser->size(item) ; - uint32_t total_data_size = 1+5+source_gxs_id.SIZE_IN_BYTES+5+message_size+conservative_max_signature_size ; - - unsigned char *data = (unsigned char *)malloc(total_data_size) ; - - // -1 - setup protocol version - // -#ifdef DEBUG_DISTANT_MSG - std::cerr << " adding protocol version TAG = " << std::hex << (int)DISTANT_MSG_PROTOCOL_VERSION_02 << std::dec << std::endl; -#endif - uint32_t offset = 0 ; - data[offset++] = DISTANT_MSG_PROTOCOL_VERSION_02 ; - -#ifdef DEBUG_DISTANT_MSG - std::cerr << " adding own key ID " << AuthGPG::getAuthGPG()->getGPGOwnId() << std::endl; -#endif - data[offset++] = DISTANT_MSG_TAG_IDENTITY ; - offset += PGPKeyParser::write_125Size(&data[offset],source_gxs_id.SIZE_IN_BYTES) ; - memcpy(&data[offset], source_gxs_id.toByteArray(), source_gxs_id.SIZE_IN_BYTES) ; - offset += source_gxs_id.SIZE_IN_BYTES ; - - // 1 - serialise the whole message item into a binary chunk. - // - -#ifdef DEBUG_DISTANT_MSG - std::cerr << " serialising item..." << std::endl; -#endif - data[offset++] = DISTANT_MSG_TAG_CLEAR_MSG ; - offset += PGPKeyParser::write_125Size(&data[offset],message_size) ; - - uint32_t remaining_size = total_data_size - offset ; - - if(!_serialiser->serialise(item,&data[offset],&remaining_size)) + try { - std::cerr << "(EE) p3MsgService::encryptMessage(): Serialization error." << std::endl; - free(data) ; - return false; - } - offset += message_size ; - - // 2 - now sign the data, if necessary, and put the signature up front - - uint32_t signature_length = 0 ; - unsigned char *signature_data = NULL ; - - if(item->msgFlags & RS_MSG_FLAGS_SIGNED) - { -#ifdef DEBUG_DISTANT_MSG - std::cerr << " Signing the message..." << std::endl; -#endif - signature_length = 2000 ; - signature_data = new unsigned char[signature_length] ; - - // do a proper signature here + // 0 - append own id to the data. // + uint32_t conservative_max_signature_size = 1000 ; + uint32_t message_size = _serialiser->size(item) ; + uint32_t total_data_size = 1+5+source_gxs_id.SIZE_IN_BYTES+5+message_size+conservative_max_signature_size ; + + data = (unsigned char *)malloc(total_data_size) ; + + // -1 - setup protocol version + // +#ifdef DEBUG_DISTANT_MSG + std::cerr << " adding protocol version TAG = " << std::hex << (int)DISTANT_MSG_PROTOCOL_VERSION_02 << std::dec << std::endl; +#endif + uint32_t offset = 0 ; + data[offset++] = DISTANT_MSG_PROTOCOL_VERSION_02 ; + +#ifdef DEBUG_DISTANT_MSG + std::cerr << " adding own key ID " << AuthGPG::getAuthGPG()->getGPGOwnId() << std::endl; +#endif + data[offset++] = DISTANT_MSG_TAG_IDENTITY ; + offset += PGPKeyParser::write_125Size(&data[offset],source_gxs_id.SIZE_IN_BYTES) ; + memcpy(&data[offset], source_gxs_id.toByteArray(), source_gxs_id.SIZE_IN_BYTES) ; + offset += source_gxs_id.SIZE_IN_BYTES ; + + // 1 - serialise the whole message item into a binary chunk. + // + +#ifdef DEBUG_DISTANT_MSG + std::cerr << " serialising item..." << std::endl; +#endif + data[offset++] = DISTANT_MSG_TAG_CLEAR_MSG ; + offset += PGPKeyParser::write_125Size(&data[offset],message_size) ; + + uint32_t remaining_size = total_data_size - offset ; + + if(!_serialiser->serialise(item,&data[offset],&remaining_size)) + throw std::runtime_error("Serialization error.") ; + + offset += message_size ; + + // 2 - now sign the data, if necessary, and put the signature up front + + uint32_t signature_length = 0 ; + unsigned char *signature_data = NULL ; + + if(false)//item->msgFlags & RS_MSG_FLAGS_SIGNED) + { +#ifdef DEBUG_DISTANT_MSG + std::cerr << " Signing the message..." << std::endl; +#endif + signature_length = 2000 ; + signature_data = new unsigned char[signature_length] ; + + // do a proper signature here + // #warning UNFINISHED CODE!!! -// if(!mGxsIface->signature(data,offset,signature_data,signature_length)) -// { -// free(data) ; -// std::cerr << "Signature failed!" << std::endl; -// return false; -// } + // if(!mGxsIface->signature(data,offset,signature_data,signature_length)) + // { + // free(data) ; + // std::cerr << "Signature failed!" << std::endl; + // return false; + // } #ifdef DEBUG_DISTANT_MSG - std::cerr << " After signature: signature size = " << signature_length << std::endl; + std::cerr << " After signature: signature size = " << signature_length << std::endl; #endif - } + } #ifdef DEBUG_DISTANT_MSG - std::cerr << " total decrypted size = " << offset + signature_length << std::endl; + std::cerr << " total decrypted size = " << offset + signature_length << std::endl; #endif - // 3 - append the signature to the serialized data. + // 3 - append the signature to the serialized data. - if(signature_length > 0) - { + if(signature_length > 0) + { #ifdef DEBUG_DISTANT_MSG - std::cerr << " Appending signature." << std::endl; + std::cerr << " Appending signature." << std::endl; #endif - memcpy(&data[offset],signature_data,signature_length) ; - offset += signature_length ; - } + memcpy(&data[offset],signature_data,signature_length) ; + offset += signature_length ; + } - // 2 - pgp-encrypt the whole chunk with the user-supplied public key. - // - uint32_t encrypted_size = offset + 1000 ; - unsigned char *encrypted_data = new unsigned char[encrypted_size] ; + // 2 - pgp-encrypt the whole chunk with the user-supplied public key. + // + int encrypted_size = offset + 1000 ; + encrypted_data = malloc(encrypted_size) ; #ifdef DEBUG_DISTANT_MSG - std::cerr << " Encrypting for Key ID " << pgp_id << std::endl; + std::cerr << " Encrypting for Key ID " << pgp_id << std::endl; #endif - // Do proper encryption here + // Do proper encryption here #warning UNFINISHED CODE!!! -// if(!mGxsIface->encrypt(data,offset,encrypted_data,encrypted_size,destination_gxs_id))) -// { + + RsTlvSecurityKey encryption_key ; + + if(!mIdService->getKey(destination_gxs_id,encryption_key)) + throw std::runtime_error("Cannot get encryption key for id " + destination_gxs_id.toStdString()) ; + + if(!GxsSecurity::encrypt(encrypted_data,encrypted_size,data,offset,encryption_key)) + throw std::runtime_error("Encryption failed!") ; + free(data) ; - delete[] encrypted_data ; - std::cerr << "Encryption failed!" << std::endl; - return false; - //} - //free(data) ; + data = NULL ; #ifdef DEBUG_DISTANT_MSG - std::cerr << " Decrypted size = " << offset << std::endl; - std::cerr << " Encrypted size = " << encrypted_size << std::endl; - std::cerr << " First bytes of encrypted data: " << std::hex << (int)encrypted_data[0] << " " << (int)encrypted_data[1] << " " << (int)encrypted_data[2] << std::dec << std::endl; - std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum(encrypted_data,encrypted_size).toStdString() << std::endl; + std::cerr << " Decrypted size = " << offset << std::endl; + std::cerr << " Encrypted size = " << encrypted_size << std::endl; + std::cerr << " First bytes of encrypted data: " << std::hex << (int)encrypted_data[0] << " " << (int)encrypted_data[1] << " " << (int)encrypted_data[2] << std::dec << std::endl; + std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum(encrypted_data,encrypted_size).toStdString() << std::endl; #endif - // Now turn the binary encrypted chunk into a readable radix string. - // + // Now turn the binary encrypted chunk into a readable radix string. + // #ifdef DEBUG_DISTANT_MSG - std::cerr << " Converting to radix64" << std::endl; + std::cerr << " Converting to radix64" << std::endl; #endif - std::string armoured_data ; - Radix64::encode((char *)encrypted_data,encrypted_size,armoured_data) ; - delete[] encrypted_data ; + std::string armoured_data ; + Radix64::encode((char *)encrypted_data,encrypted_size,armoured_data) ; - // wipe the item clean and replace the message by the encrypted data. + free(encrypted_data) ; + encrypted_data = NULL ; - item->message = armoured_data ; - item->subject = "" ; - item->rspeerid_msgcc.ids.clear() ; - item->rspeerid_msgbcc.ids.clear() ; - item->rspeerid_msgto.ids.clear() ; - item->rsgxsid_msgcc.ids.clear() ; - item->rsgxsid_msgbcc.ids.clear() ; - item->rsgxsid_msgto.ids.clear() ; - item->msgFlags |= RS_MSG_FLAGS_ENCRYPTED ; - item->attachment.TlvClear() ; + // wipe the item clean and replace the message by the encrypted data. + + item->message = armoured_data ; + item->subject = "" ; + item->rspeerid_msgcc.ids.clear() ; + item->rspeerid_msgbcc.ids.clear() ; + item->rspeerid_msgto.ids.clear() ; + item->rsgxsid_msgcc.ids.clear() ; + item->rsgxsid_msgbcc.ids.clear() ; + item->rsgxsid_msgto.ids.clear() ; + item->msgFlags |= RS_MSG_FLAGS_ENCRYPTED ; + item->attachment.TlvClear() ; #ifdef DEBUG_DISTANT_MSG - std::cerr << " Done" << std::endl; + std::cerr << " Done" << std::endl; #endif - return true ; + return true ; + } + catch(std::exception& e) + { + std::cerr << __PRETTY_FUNCTION__ << ": Error. reason: " << e.what() << std::endl; + + if(encrypted_data) free(encrypted_data) ; + if(data) free(data) ; + return false ; + } } std::string printNumber(uint32_t n,bool hex) @@ -1828,13 +1873,14 @@ std::string printNumber(uint32_t n,bool hex) } bool p3MsgService::decryptMessage(const std::string& mId) { - unsigned char *decrypted_data = NULL; + void *decrypted_data = NULL; char *encrypted_data = NULL; try { uint32_t msgId = atoi(mId.c_str()); std::string encrypted_string ; + RsGxsId destination_gxs_id ; #ifdef DEBUG_DISTANT_MSG std::cerr << "Decrypting message with Id " << mId << std::endl; @@ -1851,6 +1897,7 @@ bool p3MsgService::decryptMessage(const std::string& mId) } encrypted_string = mit->second->message ; + destination_gxs_id = RsGxsId(mit->second->PeerId()) ; } size_t encrypted_size ; @@ -1861,11 +1908,9 @@ bool p3MsgService::decryptMessage(const std::string& mId) std::cerr << " Message has been radix64 decoded." << std::endl; #endif - uint32_t decrypted_size = encrypted_size + 500 ; - unsigned char *decrypted_data = new unsigned char[decrypted_size] ; - #ifdef DEBUG_DISTANT_MSG std::cerr << " Calling decryption. Encrypted data size = " << encrypted_size << ", Allocated size = " << decrypted_size << std::endl; + std::cerr << " Destination GxsId : " << destination_gxs_id << std::endl; std::cerr << " First bytes of encrypted data: " << std::hex << (int)((unsigned char*)encrypted_data)[0] << " " << (int)((unsigned char*)encrypted_data)[1] << " " << (int)((unsigned char*)encrypted_data)[2] << std::dec << std::endl; std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum((uint8_t*)encrypted_data,encrypted_size).toStdString() << std::endl; #endif @@ -1873,17 +1918,26 @@ bool p3MsgService::decryptMessage(const std::string& mId) // TODO // #warning UNFINISHED CODE!!! -// if(!rsGxs->decrypt(encrypted_data,encrypted_size,decrypted_data,&decrypted_size)) -// throw std::runtime_error("decryption failed!") ; + int decrypted_size = 0 ; + decrypted_data = NULL ; + + RsTlvSecurityKey encryption_key ; + + if(!mIdService->getPrivateKey(destination_gxs_id,encryption_key)) + throw std::runtime_error("Cannot get private encryption key for id " + destination_gxs_id.toStdString()) ; + + if(!GxsSecurity::decrypt(decrypted_data,decrypted_size,(void*)encrypted_data,encrypted_size,encryption_key)) + throw std::runtime_error("Decryption failed!") ; + + uint8_t *decr_data = (uint8_t*)decrypted_data ; #ifdef DEBUG_DISTANT_MSG std::cerr << " Message has succesfully decrypted. Decrypted size = " << decrypted_size << std::endl; #endif - // 1 - get the sender's id uint32_t offset = 0 ; - unsigned char protocol_version = decrypted_data[offset++] ; + unsigned char protocol_version = decr_data[offset++] ; #ifdef DEBUG_DISTANT_MSG std::cerr << " Read protocol version number " << std::hex << (int)protocol_version << std::dec << std::endl; @@ -1894,19 +1948,19 @@ bool p3MsgService::decryptMessage(const std::string& mId) #ifdef DEBUG_DISTANT_MSG std::cerr << " Reading identity section " << std::endl; #endif - uint8_t ptag = decrypted_data[offset] ; + uint8_t ptag = decr_data[offset] ; if(ptag != DISTANT_MSG_TAG_IDENTITY) throw std::runtime_error("Bad ptag in encrypted msg packet "+printNumber(ptag,true)+" => packet is dropped.") ; - unsigned char *tmp_data = &decrypted_data[offset] ; + unsigned char *tmp_data = &decr_data[offset] ; uint32_t identity_size = PGPKeyParser::read_125Size(tmp_data) ; - offset += tmp_data - decrypted_data ; + offset += tmp_data - decr_data ; if(identity_size != RsGxsId::SIZE_IN_BYTES) throw std::runtime_error("Bad size in Identity section " + printNumber(identity_size,false) + " => packet is dropped.") ; - RsGxsId senders_id(&decrypted_data[offset]) ; + RsGxsId senders_id(&decr_data[offset]) ; offset += identity_size ; #ifdef DEBUG_DISTANT_MSG @@ -1914,19 +1968,19 @@ bool p3MsgService::decryptMessage(const std::string& mId) #endif // 2 - deserialize the item - ptag = decrypted_data[offset] ; + ptag = decr_data[offset] ; if(ptag != DISTANT_MSG_TAG_CLEAR_MSG) throw std::runtime_error("Bad ptag in encrypted msg packet " + printNumber(ptag,true) + " => packet is dropped.") ; - tmp_data = &decrypted_data[offset] ; + tmp_data = &decr_data[offset] ; uint32_t item_size = PGPKeyParser::read_125Size(tmp_data) ; - offset += tmp_data - decrypted_data ; + offset += tmp_data - decr_data ; #ifdef DEBUG_DISTANT_MSG std::cerr << " Deserializing..." << std::endl; #endif - RsMsgItem *item = dynamic_cast(_serialiser->deserialise(&decrypted_data[offset],&item_size)) ; + RsMsgItem *item = dynamic_cast(_serialiser->deserialise(&decr_data[offset],&item_size)) ; if(item == NULL) throw std::runtime_error("Decrypted message could not be deserialized.") ; @@ -1939,14 +1993,14 @@ bool p3MsgService::decryptMessage(const std::string& mId) if(offset < decrypted_size) { - uint8_t ptag = decrypted_data[offset++] ; + uint8_t ptag = decr_data[offset++] ; if(ptag != DISTANT_MSG_TAG_SIGNATURE) throw std::runtime_error("Bad ptag in signature packet " + printNumber(ptag,true) + " => packet is dropped.") ; - unsigned char *tmp_data = &decrypted_data[offset] ; + unsigned char *tmp_data = &decr_data[offset] ; uint32_t signature_size = PGPKeyParser::read_125Size(tmp_data) ; - offset += tmp_data - decrypted_data ; + offset += tmp_data - decr_data ; std::cerr << " Signature is present. Verifying it..." << std::endl; @@ -1965,8 +2019,8 @@ bool p3MsgService::decryptMessage(const std::string& mId) else throw std::runtime_error("Structural error in packet: sizes do not match. Dropping the message.") ; - delete[] decrypted_data ; - decrypted_data = NULL ; + free(decr_data) ; + decr_data = NULL ; // 4 - replace the item with the decrypted data, and update flags @@ -2035,8 +2089,8 @@ bool p3MsgService::decryptMessage(const std::string& mId) catch(std::exception& e) { std::cerr << "Decryption failed: " << e.what() << std::endl; - if(encrypted_data != NULL) delete[] encrypted_data ; - if(decrypted_data != NULL) delete[] decrypted_data ; + if(encrypted_data != NULL) free(encrypted_data) ; + if(decrypted_data != NULL) free(decrypted_data) ; return false ; } diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h index 30329e59f..e5baf1474 100644 --- a/libretroshare/src/services/p3msgservice.h +++ b/libretroshare/src/services/p3msgservice.h @@ -51,6 +51,7 @@ #include "turtle/turtleclientservice.h" class p3LinkMgr; +class p3IdService; // Temp tweak to test grouter class p3MsgService: public p3Service, public p3Config, public pqiMonitor @@ -59,57 +60,57 @@ class p3MsgService: public p3Service, public p3Config, public pqiMonitor #endif { public: - p3MsgService(p3LinkMgr *lm); + p3MsgService(p3LinkMgr *lm,p3IdService *id_service); - /* External Interface */ -bool getMessageSummaries(std::list &msgList); -bool getMessage(const std::string &mid, MessageInfo &msg); -void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox); + /* External Interface */ + bool getMessageSummaries(std::list &msgList); + bool getMessage(const std::string &mid, MessageInfo &msg); + void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox); -bool decryptMessage(const std::string& mid) ; -bool removeMsgId(const std::string &mid); -bool markMsgIdRead(const std::string &mid, bool bUnreadByUser); -bool setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mask); -bool getMsgParentId(const std::string &msgId, std::string &msgParentId); -// msgParentId == 0 --> remove -bool setMsgParentId(uint32_t msgId, uint32_t msgParentId); + bool decryptMessage(const std::string& mid) ; + bool removeMsgId(const std::string &mid); + bool markMsgIdRead(const std::string &mid, bool bUnreadByUser); + bool setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mask); + bool getMsgParentId(const std::string &msgId, std::string &msgParentId); + // msgParentId == 0 --> remove + bool setMsgParentId(uint32_t msgId, uint32_t msgParentId); -bool MessageSend(MessageInfo &info); -bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag); -bool MessageToDraft(MessageInfo &info, const std::string &msgParentId); -bool MessageToTrash(const std::string &mid, bool bTrash); + bool MessageSend(MessageInfo &info); + bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag); + bool MessageToDraft(MessageInfo &info, const std::string &msgParentId); + bool MessageToTrash(const std::string &mid, bool bTrash); -bool getMessageTagTypes(MsgTagType& tags); -bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); -bool removeMessageTagType(uint32_t tagId); + bool getMessageTagTypes(MsgTagType& tags); + bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); + bool removeMessageTagType(uint32_t tagId); -bool getMessageTag(const std::string &msgId, MsgTagInfo& info); -/* set == false && tagId == 0 --> remove all */ -bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); + bool getMessageTag(const std::string &msgId, MsgTagInfo& info); + /* set == false && tagId == 0 --> remove all */ + bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); -bool resetMessageStandardTagTypes(MsgTagType& tags); + bool resetMessageStandardTagTypes(MsgTagType& tags); -void loadWelcomeMsg(); /* startup message */ + void loadWelcomeMsg(); /* startup message */ -//std::list &getMsgList(); -//std::list &getMsgOutList(); + //std::list &getMsgList(); + //std::list &getMsgOutList(); -int tick(); -int status(); + int tick(); + int status(); - /*** Overloaded from p3Config ****/ -virtual RsSerialiser *setupSerialiser(); -virtual bool saveList(bool& cleanup, std::list&); -virtual bool loadList(std::list& load); -virtual void saveDone(); - /*** Overloaded from p3Config ****/ + /*** Overloaded from p3Config ****/ + virtual RsSerialiser *setupSerialiser(); + virtual bool saveList(bool& cleanup, std::list&); + virtual bool loadList(std::list& load); + virtual void saveDone(); + /*** Overloaded from p3Config ****/ - /*** Overloaded from pqiMonitor ***/ -virtual void statusChange(const std::list &plist); -int checkOutgoingMessages(); - /*** Overloaded from pqiMonitor ***/ + /*** Overloaded from pqiMonitor ***/ + virtual void statusChange(const std::list &plist); + int checkOutgoingMessages(); + /*** Overloaded from pqiMonitor ***/ - /*** overloaded from p3turtle ***/ + /*** overloaded from p3turtle ***/ #ifdef GROUTER virtual void connectToGlobalRouter(p3GRouter *) ; @@ -125,23 +126,23 @@ int checkOutgoingMessages(); uint32_t status ; bool pending_messages ; }; - bool createDistantOfflineMessengingInvite(time_t time_of_validity,DistantMsgPeerId &peer_id) ; + bool createDistantOfflineMessengingInvite(time_t time_of_validity,DistantMsgPeerId &peer_id) ; bool getDistantOfflineMessengingInvites(std::vector& invites) ; void enableDistantMessaging(bool b) ; bool distantMessagingEnabled() ; - bool getDistantMessagePeerId(const RsGxsId &gxs_id,DistantMsgPeerId &peer_id) ; + bool getDistantMessagePeerId(const RsGxsId &gxs_id,DistantMsgPeerId &peer_id) ; private: - void sendPrivateMsgItem(RsMsgItem *msgitem) ; + void sendPrivateMsgItem(RsMsgItem *msgitem) ; // This maps contains the current invitations to respond to. // The map is indexed by the hash - std::map _messenging_invites ; + std::map _messenging_invites ; // This contains the ongoing tunnel handling contacts. // The map is indexed by the hash - std::map _messenging_contacts ; + std::map _messenging_contacts ; // Overloaded from RsTurtleClientService @@ -150,12 +151,12 @@ int checkOutgoingMessages(); #endif // Utility functions - bool createDistantMessage(const RsGxsId& destination_gxs_id,const RsGxsId& source_gxs_id,RsMsgItem *msg) ; + bool createDistantMessage(const RsGxsId& destination_gxs_id,const RsGxsId& source_gxs_id,RsMsgItem *msg) ; bool locked_findHashForVirtualPeerId(const RsPeerId& pid,Sha1CheckSum& hash) ; void manageDistantPeers() ; #ifdef GROUTER - void sendGRouterData(const GRouterKeyId &key_id,RsMsgItem *) ; + void sendGRouterData(const GRouterKeyId &key_id,RsMsgItem *) ; #endif void handleIncomingItem(RsMsgItem *) ; @@ -180,36 +181,37 @@ int checkOutgoingMessages(); void initStandardTagTypes(); - p3LinkMgr *mLinkMgr; + p3LinkMgr *mLinkMgr; + p3IdService *mIdService ; - /* Mutex Required for stuff below */ + /* Mutex Required for stuff below */ - RsMutex mMsgMtx; - RsMsgSerialiser *_serialiser ; + RsMutex mMsgMtx; + RsMsgSerialiser *_serialiser ; /* stored list of messages */ - std::map imsg; + std::map imsg; /* ones that haven't made it out yet! */ - std::map msgOutgoing; + std::map msgOutgoing; - std::map _pendingPartialMessages ; + std::map _pendingPartialMessages ; - /* maps for tags types and msg tags */ + /* maps for tags types and msg tags */ - std::map mTags; - std::map mMsgTags; + std::map mTags; + std::map mMsgTags; - uint32_t mMsgUniqueId; + uint32_t mMsgUniqueId; - // used delete msgSrcIds after config save - std::map mSrcIds; + // used delete msgSrcIds after config save + std::map mSrcIds; - // save the parent of the messages in draft for replied and forwarded - std::map mParentId; + // save the parent of the messages in draft for replied and forwarded + std::map mParentId; - std::string config_dir; + std::string config_dir; - bool mDistantMessagingEnabled ; + bool mDistantMessagingEnabled ; }; #endif // MESSAGE_SERVICE_HEADER