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
This commit is contained in:
csoler 2014-03-20 23:01:00 +00:00
parent 9926517df9
commit d3bbd88abc
5 changed files with 391 additions and 323 deletions

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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::map<RsGxsId,
// uint32_t token=0 ;
// RsTokReqOptions opts;
// opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
//
// std::cerr << "Requesting GXS key to encrypt." << std::endl;
//
// RsGenExchange::getTokenService()->requestGroupInfo(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<RsMsgItem*>(_serialiser->deserialise(&decrypted_data[offset],&item_size)) ;
RsMsgItem *item = dynamic_cast<RsMsgItem*>(_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 ;
}

View file

@ -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<MsgInfoSummary> &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<MsgInfoSummary> &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<RsMsgItem *> &getMsgList();
//std::list<RsMsgItem *> &getMsgOutList();
//std::list<RsMsgItem *> &getMsgList();
//std::list<RsMsgItem *> &getMsgOutList();
int tick();
int status();
int tick();
int status();
/*** Overloaded from p3Config ****/
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool& cleanup, std::list<RsItem*>&);
virtual bool loadList(std::list<RsItem*>& load);
virtual void saveDone();
/*** Overloaded from p3Config ****/
/*** Overloaded from p3Config ****/
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool& cleanup, std::list<RsItem*>&);
virtual bool loadList(std::list<RsItem*>& load);
virtual void saveDone();
/*** Overloaded from p3Config ****/
/*** Overloaded from pqiMonitor ***/
virtual void statusChange(const std::list<pqipeer> &plist);
int checkOutgoingMessages();
/*** Overloaded from pqiMonitor ***/
/*** Overloaded from pqiMonitor ***/
virtual void statusChange(const std::list<pqipeer> &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<DistantOfflineMessengingInvite>& 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<GRouterKeyId,DistantMessengingInvite> _messenging_invites ;
std::map<GRouterKeyId,DistantMessengingInvite> _messenging_invites ;
// This contains the ongoing tunnel handling contacts.
// The map is indexed by the hash
std::map<GRouterKeyId,DistantMessengingContact> _messenging_contacts ;
std::map<GRouterKeyId,DistantMessengingContact> _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<uint32_t, RsMsgItem *> imsg;
std::map<uint32_t, RsMsgItem *> imsg;
/* ones that haven't made it out yet! */
std::map<uint32_t, RsMsgItem *> msgOutgoing;
std::map<uint32_t, RsMsgItem *> msgOutgoing;
std::map<RsPeerId, RsMsgItem *> _pendingPartialMessages ;
std::map<RsPeerId, RsMsgItem *> _pendingPartialMessages ;
/* maps for tags types and msg tags */
/* maps for tags types and msg tags */
std::map<uint32_t, RsMsgTagType*> mTags;
std::map<uint32_t, RsMsgTags*> mMsgTags;
std::map<uint32_t, RsMsgTagType*> mTags;
std::map<uint32_t, RsMsgTags*> mMsgTags;
uint32_t mMsgUniqueId;
uint32_t mMsgUniqueId;
// used delete msgSrcIds after config save
std::map<uint32_t, RsMsgSrcId*> mSrcIds;
// used delete msgSrcIds after config save
std::map<uint32_t, RsMsgSrcId*> mSrcIds;
// save the parent of the messages in draft for replied and forwarded
std::map<uint32_t, RsMsgParentId*> mParentId;
// save the parent of the messages in draft for replied and forwarded
std::map<uint32_t, RsMsgParentId*> mParentId;
std::string config_dir;
std::string config_dir;
bool mDistantMessagingEnabled ;
bool mDistantMessagingEnabled ;
};
#endif // MESSAGE_SERVICE_HEADER