From a9580df150d799246eaecbf3c1fb5cecf9f8ab49 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 23 Jul 2012 13:49:28 +0000 Subject: SecureIM, SeenPlugin, SendSS, Sessions: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/SecureIM/src/crypt_dll.cpp | 236 +++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 plugins/SecureIM/src/crypt_dll.cpp (limited to 'plugins/SecureIM/src/crypt_dll.cpp') diff --git a/plugins/SecureIM/src/crypt_dll.cpp b/plugins/SecureIM/src/crypt_dll.cpp new file mode 100644 index 0000000000..6a97021886 --- /dev/null +++ b/plugins/SecureIM/src/crypt_dll.cpp @@ -0,0 +1,236 @@ +#include "commonheaders.h" + + +// generate KeyA pair and return public key +LPSTR InitKeyA(pUinKey ptr,int features) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("InitKeyA: %04x", features); +#endif + if ( !ptr->cntx ) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK"); + if(tmp) { + cpp_init_keyp(ptr->cntx,tmp); // make pre-shared key from password + mir_free(tmp); + } + + LPSTR pub_text = cpp_init_keya(ptr->cntx,features); // calculate public and private key & fill KeyA + + LPSTR keysig; + if(features&CPP_FEATURES_NEWPG) { + if(features&KEY_B_SIG) + keysig = (LPSTR)SIG_KEYB; + else + keysig = (LPSTR)SIG_KEYA; + } + else + if(isProtoSmallPackets(ptr->hContact)) + keysig = (LPSTR)SIG_KEY4; + else + keysig = (LPSTR)SIG_KEY3; + + int slen = (int)strlen(keysig); + int tlen = (int)strlen(pub_text); + + LPSTR keyToSend = (LPSTR) mir_alloc(slen+tlen+1); + + memcpy(keyToSend,keysig,slen); + memcpy(keyToSend+slen,pub_text,tlen+1); + + return keyToSend; +} + +// store KeyB into context +int InitKeyB(pUinKey ptr,LPCSTR key) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("InitKeyB: %s", key); +#endif + if (!ptr->cntx) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + if (!cpp_keyp(ptr->cntx)) { + char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK"); + if(tmp) { + cpp_init_keyp(ptr->cntx,tmp); // make pre-shared key from password + mir_free(tmp); + } + } + + cpp_init_keyb(ptr->cntx,key); + ptr->features = cpp_get_features(ptr->cntx); + + return cpp_get_error(ptr->cntx); +} + + +// store KeyX into context +void InitKeyX(pUinKey ptr,BYTE *key) { + + if (!ptr->cntx) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + cpp_set_keyx(ptr->cntx,key); +} + + +// calculate secret key +BOOL CalculateKeyX(pUinKey ptr,HANDLE hContact) { + + int agr = cpp_calc_keyx(ptr->cntx); + if ( agr ) { + // do this only if key exchanged is ok + // we use a 192bit key + int keysize = cpp_size_keyx(); + PBYTE buffer = (PBYTE) alloca(keysize); // buffer for hash + + // store key + cpp_get_keyx(ptr->cntx,buffer); + + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + + // store key in database + cws.szSetting = "offlineKey"; + cws.value.type = DBVT_BLOB; + cws.value.cpbVal = keysize; + cws.value.pbVal = buffer; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); + + // store timeout of key in database (2 days) + cws.szSetting = "offlineKeyTimeout"; + cws.value.type = DBVT_DWORD; + cws.value.dVal = gettime()+(60*60*24*DBGetContactSettingWord(0,szModuleName,"okt",2)); + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); + + // key exchange is finished + showPopUpEC(ptr->hContact); + } + else { + // agree value problem + showPopUp(sim002,hContact,g_hPOP[POP_PU_DIS],0); + } + return agr!=0; +} + + +// encrypt message +LPSTR encrypt(pUinKey ptr, LPCSTR szEncMsg) { + + LPSTR szSig = (LPSTR) (ptr->offlineKey?SIG_ENOF:SIG_ENON); + + int slen = (int)strlen(szSig); + int clen = (int)strlen(szEncMsg); + + LPSTR szMsg = (LPSTR) mir_alloc(clen+slen+1); + memcpy(szMsg, szSig, slen); + memcpy(szMsg+slen, szEncMsg, clen+1); + + return szMsg; +} + + +// encode message +LPSTR encodeMsg(pUinKey ptr, LPARAM lParam) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (LPSTR) pccsd->lParam; + + if ( pccsd->wParam & PREF_UTF ) + szNewMsg = encrypt(ptr,cpp_encodeU(ptr->cntx,szOldMsg)); + else + if ( pccsd->wParam & PREF_UNICODE ) + szNewMsg = encrypt(ptr,cpp_encodeW(ptr->cntx,(LPWSTR)(szOldMsg+strlen(szOldMsg)+1))); + else + szNewMsg = encrypt(ptr,cpp_encodeA(ptr->cntx,szOldMsg)); + +// pccsd->wParam &= ~(PREF_UNICODE|PREF_UTF); + pccsd->wParam &= ~PREF_UNICODE; + + return szNewMsg; +} + + +// decode message +LPSTR decodeMsg(pUinKey ptr, LPARAM lParam, LPSTR szEncMsg) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT *ppre = (PROTORECVEVENT *)pccsd->lParam; + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (ppre->flags&PREF_UTF)?cpp_decodeU(ptr->cntx,szEncMsg):cpp_decode(ptr->cntx,szEncMsg); + + if(szOldMsg == NULL) { + ptr->decoded=false; + switch(cpp_get_error(ptr->cntx)) { + case CPP_ERROR_BAD_LEN: + szNewMsg = mir_strdup(Translate(sim102)); + break; + case CPP_ERROR_BAD_CRC: + szNewMsg = mir_strdup(Translate(sim103)); + break; + default: { + ptr->decoded=true; + szNewMsg = mir_strdup(Translate(sim101)); + } + break; + } + ppre->flags &= ~(PREF_UNICODE|PREF_UTF); + pccsd->wParam &= ~(PREF_UNICODE|PREF_UTF); + } + else { + ptr->decoded=true; + if ( ppre->flags & PREF_UTF ) { // если протокол поддерживает utf8 - тогда отправляем в utf8 + int olen = (int)strlen(szOldMsg)+1; + szNewMsg = (LPSTR) mir_alloc(olen); + memcpy(szNewMsg,szOldMsg,olen); + } + else { + int olen = ((int)strlen(szOldMsg)+1)*(sizeof(WCHAR)+1); + szNewMsg = (LPSTR) mir_alloc(olen); + memcpy(szNewMsg,szOldMsg,olen); + ppre->flags |= PREF_UNICODE; + pccsd->wParam |= PREF_UNICODE; + } + } + ppre->szMessage = szNewMsg; + return szNewMsg; +} + + +BOOL LoadKeyPGP(pUinKey ptr) { + int mode = DBGetContactSettingByte(ptr->hContact,szModuleName,"pgp_mode",255); + if(mode==0) { + DBVARIANT dbv; + DBGetContactSetting(ptr->hContact,szModuleName,"pgp",&dbv); + BOOL r=(dbv.type==DBVT_BLOB); + if(r) pgp_set_keyid(ptr->cntx,(PVOID)dbv.pbVal); + DBFreeVariant(&dbv); + return r; + } + else + if(mode==1) { + LPSTR key = myDBGetStringDecode(ptr->hContact,szModuleName,"pgp"); + if ( key ) { + pgp_set_key(ptr->cntx,key); + mir_free(key); + return 1; + } + } + return 0; +} + + +BOOL LoadKeyGPG(pUinKey ptr) { + + LPSTR key = myDBGetString(ptr->hContact,szModuleName,"gpg"); + if ( key ) { + gpg_set_keyid(ptr->cntx,key); + mir_free(key); + return 2; + } + return 0; +} + +// EOF -- cgit v1.2.3