diff options
author | George Hazan <george.hazan@gmail.com> | 2013-11-27 19:09:16 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2013-11-27 19:09:16 +0000 |
commit | cb80a37654ebc902769f87ffbadd38d161109333 (patch) | |
tree | 12b91f3d6920716b441c29aefa39dc858c264fe0 | |
parent | ab1971b510fb004fc23aa3a69565ce69d8d0743e (diff) |
- strong cyphering for passwords in db3x_mmap;
- unique signature for the new mmap profiles;
git-svn-id: http://svn.miranda-ng.org/main/trunk@6997 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r-- | include/m_crypto.h | 4 | ||||
-rw-r--r-- | plugins/Db3x_mmap/src/dbcrypt.cpp | 109 | ||||
-rw-r--r-- | plugins/Db3x_mmap/src/dbintf.cpp | 2 | ||||
-rw-r--r-- | plugins/Db3x_mmap/src/dbintf.h | 13 | ||||
-rw-r--r-- | plugins/Db3x_mmap/src/dbsettings.cpp | 196 | ||||
-rw-r--r-- | plugins/ExternalAPI/delphi/m_historypp.inc | 2 | ||||
-rw-r--r-- | src/core/stdcrypt/Rijndael.cpp | 10 | ||||
-rw-r--r-- | src/core/stdcrypt/commonheaders.h | 2 | ||||
-rw-r--r-- | src/core/stdcrypt/encrypt.cpp | 112 | ||||
-rw-r--r-- | src/core/stdcrypt/stdcrypt.h | 6 | ||||
-rw-r--r-- | src/core/stdcrypt/utils.cpp | 6 |
11 files changed, 294 insertions, 168 deletions
diff --git a/include/m_crypto.h b/include/m_crypto.h index 1634f7c93e..0d79e2f9ba 100644 --- a/include/m_crypto.h +++ b/include/m_crypto.h @@ -45,11 +45,11 @@ struct MICryptoEngine // result must be freed using mir_free or assigned to mir_ptr<BYTE>
STDMETHOD_(BYTE*, encodeString)(const char *src, size_t *cbResultLen) PURE;
- STDMETHOD_(BYTE*, encodeStringW)(const WCHAR* src, size_t *cbResultLen) PURE;
+ STDMETHOD_(BYTE*, encodeBuffer)(const void *src, size_t cbLen, size_t *cbResultLen) PURE;
// result must be freed using mir_free or assigned to ptrA/ptrT
STDMETHOD_(char*, decodeString)(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) PURE;
- STDMETHOD_(WCHAR*, decodeStringW)(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) PURE;
+ STDMETHOD_(void*, decodeBuffer)(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) PURE;
};
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/Db3x_mmap/src/dbcrypt.cpp b/plugins/Db3x_mmap/src/dbcrypt.cpp index b0054bacbf..79a3744462 100644 --- a/plugins/Db3x_mmap/src/dbcrypt.cpp +++ b/plugins/Db3x_mmap/src/dbcrypt.cpp @@ -23,7 +23,101 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "commonheaders.h"
-int CDb3Base::InitCrypt()
+/////////////////////////////////////////////////////////////////////////////////////////
+
+bool isEncrypted(LPCSTR szModule, LPCSTR szSetting);
+
+//VERY VERY VERY BASIC ENCRYPTION FUNCTION
+
+static void Encrypt(char *msg, BOOL up)
+{
+ int jump = (up) ? 5 : -5;
+ for (int i = 0; msg[i]; i++)
+ msg[i] = msg[i] + jump;
+}
+
+__forceinline void DecodeString(LPSTR buf)
+{
+ Encrypt(buf, FALSE);
+}
+
+struct VarDescr
+{
+ VarDescr(LPCSTR var, LPCSTR value) :
+ szVar(mir_strdup(var)),
+ szValue(mir_strdup(value))
+ {}
+
+ ptrA szVar, szValue;
+};
+
+struct SettingUgraderParam
+{
+ CDb3Mmap *db;
+ LPCSTR szModule;
+ HANDLE hContact;
+ OBJLIST<VarDescr>* pList;
+};
+
+int sttSettingUgrader(const char *szSetting, LPARAM lParam)
+{
+ SettingUgraderParam *param = (SettingUgraderParam*)lParam;
+ if (isEncrypted(param->szModule, szSetting)) {
+ DBVARIANT dbv = { DBVT_UTF8 };
+ DBCONTACTGETSETTING dbcgs = { param->szModule, szSetting, &dbv };
+ if (!param->db->GetContactSettingStr(param->hContact, &dbcgs)) {
+ if (dbv.type == DBVT_UTF8) {
+ DecodeString(dbv.pszVal);
+ param->pList->insert(new VarDescr(szSetting, dbv.pszVal));
+ }
+ param->db->FreeVariant(&dbv);
+ }
+ }
+ return 0;
+}
+
+void sttContactEnum(HANDLE hContact, const char *szModule, CDb3Mmap *db)
+{
+ OBJLIST<VarDescr> arSettings(1);
+ SettingUgraderParam param = { db, szModule, hContact, &arSettings };
+
+ DBCONTACTENUMSETTINGS dbces = { 0 };
+ dbces.pfnEnumProc = sttSettingUgrader;
+ dbces.szModule = szModule;
+ dbces.lParam = (LPARAM)¶m;
+ db->EnumContactSettings(NULL, &dbces);
+
+ for (int i = 0; i < arSettings.getCount(); i++) {
+ VarDescr &p = arSettings[i];
+
+ size_t len;
+ BYTE *pResult = db->m_crypto->encodeString(p.szValue, &len);
+ if (pResult != NULL) {
+ DBCONTACTWRITESETTING dbcws = { szModule, p.szVar };
+ dbcws.value.type = DBVT_ENCRYPTED;
+ dbcws.value.pbVal = pResult;
+ dbcws.value.cpbVal = (WORD)len;
+ db->WriteContactSetting(hContact, &dbcws);
+
+ mir_free(pResult);
+ }
+ }
+}
+
+int sttModuleEnum(const char *szModule, DWORD, LPARAM lParam)
+{
+ CDb3Mmap *db = (CDb3Mmap*)lParam;
+ sttContactEnum(NULL, szModule, db);
+
+ for (HANDLE hContact = db->FindFirstContact(); hContact; hContact = db->FindNextContact(hContact))
+ sttContactEnum(hContact, szModule, db);
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CDb3Mmap::InitCrypt()
{
CRYPTO_PROVIDER *pProvider;
@@ -78,8 +172,19 @@ LBL_SetNewKey: if (dbv.cpbVal != (WORD)iKeyLength)
goto LBL_SetNewKey;
- m_crypto->setKey(dbv.pbVal, iKeyLength);
+ if (!m_crypto->setKey(dbv.pbVal, iKeyLength))
+ goto LBL_SetNewKey;
+
FreeVariant(&dbv);
}
+
+ if (memcmp(&m_dbHeader.signature, &dbSignature, sizeof(m_dbHeader.signature))) {
+ EnumModuleNames(sttModuleEnum, this);
+
+ // upgrade signature
+ memcpy(&m_dbHeader.signature, &dbSignature, sizeof(dbSignature));
+ DBWrite(0, &dbSignature, sizeof(dbSignature));
+ }
+
return 0;
}
diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp index f0d351a16e..398bd0c618 100644 --- a/plugins/Db3x_mmap/src/dbintf.cpp +++ b/plugins/Db3x_mmap/src/dbintf.cpp @@ -89,7 +89,7 @@ CDb3Base::~CDb3Base() if (!m_bReadOnly) {
DWORD bytesWritten;
SetFilePointer(m_hDbFile, 0, NULL, FILE_BEGIN);
- WriteFile(m_hDbFile, &dbSignatureIM, sizeof(dbSignatureIM), &bytesWritten, NULL);
+ WriteFile(m_hDbFile, &dbSignatureIM, 1, &bytesWritten, NULL);
}
CloseHandle(m_hDbFile);
diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h index e5178bf1b1..7f0455c6f9 100644 --- a/plugins/Db3x_mmap/src/dbintf.h +++ b/plugins/Db3x_mmap/src/dbintf.h @@ -50,6 +50,8 @@ DBHeader #define WSOFS_END 0xFFFFFFFF
#define WS_ERROR 0xFFFFFFFF
+#define DBVT_ENCRYPTED 250
+
struct DBSignature {
char name[15];
BYTE eof;
@@ -151,7 +153,7 @@ struct CDb3Base : public MIDatabase, public MIDatabaseChecker, public MZeroedObj __forceinline HANDLE getFile() const { return m_hDbFile; }
-protected:
+public:
STDMETHODIMP_(void) SetCacheSafetyMode(BOOL);
STDMETHODIMP_(LONG) GetContactCount(void);
@@ -202,9 +204,7 @@ protected: virtual void DBFill(DWORD ofs, int bytes) = 0;
virtual void DBFlush(int setting) = 0;
virtual int InitCache(void) = 0;
-
-protected:
- int InitCrypt(void);
+ virtual int InitCrypt(void) { return 0; }
public: // Check functions
int WorkInitialChecks(int);
@@ -221,8 +221,6 @@ protected: DWORD m_ChunkSize;
bool m_safetyMode, m_bReadOnly, m_bEncrypted;
- MICryptoEngine *m_crypto;
-
////////////////////////////////////////////////////////////////////////////
// database stuff
public:
@@ -231,6 +229,8 @@ public: PBYTE m_pDbCache;
HANDLE m_hMap;
+ MICryptoEngine *m_crypto;
+
protected:
DWORD m_dwFileSize;
HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent;
@@ -305,6 +305,7 @@ protected: virtual void DBFill(DWORD ofs, int bytes);
virtual void DBFlush(int setting);
virtual int InitCache(void);
+ virtual int InitCrypt(void);
protected:
PBYTE m_pNull;
diff --git a/plugins/Db3x_mmap/src/dbsettings.cpp b/plugins/Db3x_mmap/src/dbsettings.cpp index eafc619f0c..cd7d8799a4 100644 --- a/plugins/Db3x_mmap/src/dbsettings.cpp +++ b/plugins/Db3x_mmap/src/dbsettings.cpp @@ -35,9 +35,9 @@ DWORD __forceinline GetSettingValueLength(PBYTE pSetting) #define NeedBytes(n) if (bytesRemaining<(n)) pBlob = (PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining)
#define MoveAlong(n) {int x = n; pBlob += (x); ofsBlobPtr += (x); bytesRemaining -= (x);}
-#define VLT(n) ((n == DBVT_UTF8)?DBVT_ASCIIZ:n)
+#define VLT(n) ((n == DBVT_UTF8 || n == DBVT_ENCRYPTED)?DBVT_ASCIIZ:n)
-static bool isEncrypted(LPCSTR szModule, LPCSTR szSetting)
+bool isEncrypted(LPCSTR szModule, LPCSTR szSetting)
{
if (!_strnicmp(szSetting, "password", 8)) return true;
if (!strcmp(szSetting, "NLProxyAuthPassword")) return true;
@@ -52,25 +52,6 @@ static bool isEncrypted(LPCSTR szModule, LPCSTR szSetting) return false;
}
-//VERY VERY VERY BASIC ENCRYPTION FUNCTION
-
-static void Encrypt(char *msg, BOOL up)
-{
- int jump = (up) ? 5 : -5;
- for (int i = 0; msg[i]; i++)
- msg[i] = msg[i] + jump;
-}
-
-__forceinline void EncodeString(LPSTR buf)
-{
- Encrypt(buf, TRUE);
-}
-
-__forceinline void DecodeString(LPSTR buf)
-{
- Encrypt(buf, FALSE);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcgs, int isStatic)
@@ -123,8 +104,6 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcg dbcgs->pValue->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal)+1);
strcpy(dbcgs->pValue->pszVal,pCachedValue->pszVal);
}
- if (bIsEncrypted)
- DecodeString(dbcgs->pValue->pszVal);
}
else memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT ));
@@ -146,7 +125,7 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcg DWORD ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc, ofsContact, ofsModuleName);
if (ofsSettingsGroup) {
int bytesRemaining;
- bool bEncrypted = false;
+ unsigned varLen;
DWORD ofsBlobPtr = ofsSettingsGroup + offsetof(DBContactSettings, blob);
PBYTE pBlob = DBRead(ofsBlobPtr, sizeof(DBContactSettings), &bytesRemaining);
while (pBlob[0]) {
@@ -157,8 +136,8 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcg if (isStatic && (pBlob[0] & DBVTF_VARIABLELENGTH) && VLT(dbcgs->pValue->type) != VLT(pBlob[0]))
return 1;
- dbcgs->pValue->type = pBlob[0];
- switch (pBlob[0]) {
+ BYTE iType = dbcgs->pValue->type = pBlob[0];
+ switch (iType) {
case DBVT_DELETED: /* this setting is deleted */
dbcgs->pValue->type = DBVT_DELETED;
return 2;
@@ -166,41 +145,73 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcg case DBVT_BYTE: dbcgs->pValue->bVal = pBlob[1]; break;
case DBVT_WORD: MoveMemory(&(dbcgs->pValue->wVal), (PWORD)(pBlob + 1), 2); break;
case DBVT_DWORD: MoveMemory(&(dbcgs->pValue->dVal), (PDWORD)(pBlob + 1), 4); break;
+
case DBVT_UTF8:
case DBVT_ASCIIZ:
- bEncrypted = m_bEncrypted || isEncrypted(dbcgs->szModule, dbcgs->szSetting);
- NeedBytes(3 + *(PWORD)(pBlob + 1));
+ varLen = *(PWORD)(pBlob + 1);
+ NeedBytes(int(3 + varLen));
if (isStatic) {
dbcgs->pValue->cchVal--;
- if (*(PWORD)(pBlob + 1) < dbcgs->pValue->cchVal)
- dbcgs->pValue->cchVal = *(PWORD)(pBlob + 1);
+ if (varLen < dbcgs->pValue->cchVal)
+ dbcgs->pValue->cchVal = varLen;
MoveMemory(dbcgs->pValue->pszVal, pBlob + 3, dbcgs->pValue->cchVal); // decode
dbcgs->pValue->pszVal[dbcgs->pValue->cchVal] = 0;
- dbcgs->pValue->cchVal = *(PWORD)(pBlob + 1);
+ dbcgs->pValue->cchVal = varLen;
}
else {
- dbcgs->pValue->pszVal = (char*)mir_alloc(1 + *(PWORD)(pBlob + 1));
- MoveMemory(dbcgs->pValue->pszVal, pBlob + 3, *(PWORD)(pBlob + 1));
- dbcgs->pValue->pszVal[*(PWORD)(pBlob + 1)] = 0;
+ dbcgs->pValue->pszVal = (char*)mir_alloc(1 + varLen);
+ MoveMemory(dbcgs->pValue->pszVal, pBlob + 3, varLen);
+ dbcgs->pValue->pszVal[varLen] = 0;
}
break;
+
case DBVT_BLOB:
- NeedBytes(3 + *(PWORD)(pBlob + 1));
+ varLen = *(PWORD)(pBlob + 1);
+ NeedBytes(int(3 + varLen));
if (isStatic) {
- if (*(PWORD)(pBlob + 1) < dbcgs->pValue->cpbVal)
- dbcgs->pValue->cpbVal = *(PWORD)(pBlob + 1);
- MoveMemory(dbcgs->pValue->pbVal, pBlob + 3, dbcgs->pValue->cpbVal); // decode
+ if (varLen < dbcgs->pValue->cpbVal)
+ dbcgs->pValue->cpbVal = varLen;
+ MoveMemory(dbcgs->pValue->pbVal, pBlob + 3, dbcgs->pValue->cpbVal);
+ }
+ else {
+ dbcgs->pValue->pbVal = (BYTE *)mir_alloc(varLen);
+ MoveMemory(dbcgs->pValue->pbVal, pBlob + 3, varLen);
}
+ dbcgs->pValue->cpbVal = varLen;
+ break;
+
+ case DBVT_ENCRYPTED:
+ if (m_crypto == NULL)
+ return 1;
else {
- dbcgs->pValue->pbVal = (BYTE *)mir_alloc(*(PWORD)(pBlob + 1));
- MoveMemory(dbcgs->pValue->pbVal, pBlob + 3, *(PWORD)(pBlob + 1)); // decode
+ varLen = *(PWORD)(pBlob + 1);
+ NeedBytes(int(3 + varLen));
+ size_t realLen;
+ ptrA decoded(m_crypto->decodeString(pBlob + 3, varLen, &realLen));
+ if (decoded == NULL)
+ return 1;
+
+ varLen = (WORD)realLen;
+ dbcgs->pValue->type = DBVT_UTF8;
+ if (isStatic) {
+ dbcgs->pValue->cchVal--;
+ if (varLen < dbcgs->pValue->cchVal)
+ dbcgs->pValue->cchVal = varLen;
+ MoveMemory(dbcgs->pValue->pszVal, decoded, dbcgs->pValue->cchVal);
+ dbcgs->pValue->pszVal[dbcgs->pValue->cchVal] = 0;
+ dbcgs->pValue->cchVal = varLen;
+ }
+ else {
+ dbcgs->pValue->pszVal = (char*)mir_alloc(1 + varLen);
+ MoveMemory(dbcgs->pValue->pszVal, decoded, varLen);
+ dbcgs->pValue->pszVal[varLen] = 0;
+ }
}
- dbcgs->pValue->cpbVal = *(PWORD)(pBlob + 1);
break;
}
/**** add to cache **********************/
- if (dbcgs->pValue->type != DBVT_BLOB && !bEncrypted) {
+ if (iType != DBVT_BLOB && iType != DBVT_ENCRYPTED) {
DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(hContact, szCachedSettingName, 1);
if (pCachedValue != NULL) {
m_cache->SetCachedVariant(dbcgs->pValue, pCachedValue);
@@ -208,10 +219,6 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact, DBCONTACTGETSETTING *dbcg }
}
- // don't cache decrypted values
- if (dbcgs->pValue->type == DBVT_UTF8 || dbcgs->pValue->type == DBVT_ASCIIZ)
- if (bEncrypted)
- DecodeString(dbcgs->pValue->pszVal);
return 0;
}
NeedBytes(1);
@@ -403,23 +410,33 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT else return 1;
}
- if (tmp.value.type != DBVT_BYTE && tmp.value.type != DBVT_WORD && tmp.value.type != DBVT_DWORD && tmp.value.type != DBVT_ASCIIZ && tmp.value.type != DBVT_UTF8 && tmp.value.type != DBVT_BLOB)
- return 1;
- if ((!tmp.szModule) || (!tmp.szSetting) || ((tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8) && tmp.value.pszVal == NULL) || (tmp.value.type == DBVT_BLOB && tmp.value.pbVal == NULL))
+ if (tmp.szModule == NULL || tmp.szSetting == NULL)
return 1;
- // the db can not tolerate strings/blobs longer than 0xFFFF since the format writes 2 lengths
+ mir_ptr<BYTE> pEncoded(NULL);
bool bIsEncrypted = false;
switch (tmp.value.type) {
- case DBVT_ASCIIZ: case DBVT_BLOB: case DBVT_UTF8:
- size_t len = (tmp.value.type != DBVT_BLOB) ? strlen(tmp.value.pszVal) : tmp.value.cpbVal;
- if (len >= 0xFFFF) {
-#ifdef _DEBUG
- OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n");
-#endif
- return 1;
- }
+ case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD:
+ break;
+ case DBVT_ASCIIZ: case DBVT_UTF8:
+ if (tmp.value.pszVal == NULL) return 1;
+ tmp.value.cchVal = (WORD)strlen(tmp.value.pszVal);
bIsEncrypted = m_bEncrypted || isEncrypted(dbcws->szModule, dbcws->szSetting);
+ if (bIsEncrypted) {
+ size_t len;
+ BYTE *pResult = m_crypto->encodeString(tmp.value.pszVal, &len);
+ if (pResult != NULL) {
+ pEncoded = tmp.value.pbVal = pResult;
+ tmp.value.cpbVal = (WORD)len;
+ tmp.value.type = DBVT_ENCRYPTED;
+ }
+ }
+ break;
+ case DBVT_BLOB: case DBVT_ENCRYPTED:
+ if (tmp.value.pbVal == NULL) return 1;
+ break;
+ default:
+ return 1;
}
mir_cslockfull lck(m_csDbAccess);
@@ -427,7 +444,7 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT char *szCachedSettingName = m_cache->GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen);
log3("set [%08p] %s (%p)", hContact, szCachedSettingName, szCachedSettingName);
- if (tmp.value.type != DBVT_BLOB && !bIsEncrypted) {
+ if (tmp.value.type != DBVT_BLOB && tmp.value.type != DBVT_ENCRYPTED && !bIsEncrypted) {
DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(hContact, szCachedSettingName, 1);
if (pCachedValue != NULL) {
bool bIsIdentical = false;
@@ -467,13 +484,16 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT DBContactSettings dbcs;
DWORD ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc, ofsContact, ofsModuleName);
if (ofsSettingsGroup == 0) { //module group didn't exist - make it
- if (tmp.value.type & DBVTF_VARIABLELENGTH) {
- if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8)
- bytesRequired = (int)strlen(tmp.value.pszVal) + 2;
- else if (tmp.value.type == DBVT_BLOB)
- bytesRequired = tmp.value.cpbVal + 2;
+ switch (tmp.value.type) {
+ case DBVT_ASCIIZ: case DBVT_UTF8:
+ bytesRequired = tmp.value.cchVal + 2;
+ break;
+ case DBVT_BLOB: case DBVT_ENCRYPTED:
+ bytesRequired = tmp.value.cpbVal + 2;
+ break;
+ default:
+ bytesRequired = tmp.value.type;
}
- else bytesRequired = tmp.value.type;
bytesRequired += 2 + settingNameLen;
bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY - (bytesRequired % DB_SETTINGS_RESIZE_GRANULARITY)) % DB_SETTINGS_RESIZE_GRANULARITY;
ofsSettingsGroup = CreateNewSpace(bytesRequired + offsetof(DBContactSettings, blob));
@@ -507,7 +527,10 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT MoveAlong(1 + settingNameLen);
//if different type or variable length and length is different
NeedBytes(3);
- if (pBlob[0] != tmp.value.type || ((pBlob[0] == DBVT_ASCIIZ || pBlob[0] == DBVT_UTF8) && *(PWORD)(pBlob + 1) != strlen(tmp.value.pszVal)) || (pBlob[0] == DBVT_BLOB && *(PWORD)(pBlob + 1) != tmp.value.cpbVal)) {
+ if (pBlob[0] != tmp.value.type ||
+ ((pBlob[0] == DBVT_ASCIIZ || pBlob[0] == DBVT_UTF8) && *(PWORD)(pBlob + 1) != tmp.value.cchVal) ||
+ ((pBlob[0] == DBVT_BLOB || pBlob[0] == DBVT_ENCRYPTED) && *(PWORD)(pBlob + 1) != tmp.value.cpbVal))
+ {
//bin it
NeedBytes(3);
int nameLen = 1 + settingNameLen;
@@ -533,13 +556,12 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT case DBVT_WORD: DBWrite(ofsBlobPtr, &tmp.value.wVal, 2); break;
case DBVT_DWORD: DBWrite(ofsBlobPtr, &tmp.value.dVal, 4); break;
case DBVT_BLOB:
- DBWrite(ofsBlobPtr + 2, tmp.value.pbVal, tmp.value.cpbVal); // encode
+ case DBVT_ENCRYPTED:
+ DBWrite(ofsBlobPtr + 2, tmp.value.pbVal, tmp.value.cpbVal);
break;
case DBVT_UTF8:
case DBVT_ASCIIZ:
- if (bIsEncrypted)
- EncodeString(tmp.value.pszVal);
- DBWrite(ofsBlobPtr + 2, tmp.value.pszVal, (int)strlen(tmp.value.pszVal)); // encode
+ DBWrite(ofsBlobPtr + 2, tmp.value.pszVal, tmp.value.cchVal);
break;
}
//quit
@@ -554,13 +576,17 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT //cannot do a simple replace, add setting to end of list
//pBlob already points to end of list
//see if it fits
- if (tmp.value.type & DBVTF_VARIABLELENGTH) {
- if (tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8)
- bytesRequired = (int)strlen(tmp.value.pszVal) + 2;
- else if (tmp.value.type == DBVT_BLOB)
- bytesRequired = tmp.value.cpbVal + 2;
+ switch (tmp.value.type) {
+ case DBVT_ASCIIZ: case DBVT_UTF8:
+ bytesRequired = tmp.value.cchVal + 2;
+ break;
+ case DBVT_BLOB: case DBVT_ENCRYPTED:
+ bytesRequired = tmp.value.cpbVal + 2;
+ break;
+ default:
+ bytesRequired = tmp.value.type;
}
- else bytesRequired = tmp.value.type;
+
bytesRequired += 2 + settingNameLen;
bytesRequired += ofsBlobPtr + 1 - (ofsSettingsGroup + offsetof(DBContactSettings, blob));
@@ -612,19 +638,17 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT case DBVT_BYTE: DBWrite(ofsBlobPtr, &tmp.value.bVal, 1); MoveAlong(1); break;
case DBVT_WORD: DBWrite(ofsBlobPtr, &tmp.value.wVal, 2); MoveAlong(2); break;
case DBVT_DWORD: DBWrite(ofsBlobPtr, &tmp.value.dVal, 4); MoveAlong(4); break;
- case DBVT_BLOB:
+
+ case DBVT_BLOB: case DBVT_ENCRYPTED:
DBWrite(ofsBlobPtr, &tmp.value.cpbVal, 2);
- DBWrite(ofsBlobPtr + 2, tmp.value.pbVal, tmp.value.cpbVal); // encode
+ DBWrite(ofsBlobPtr + 2, tmp.value.pbVal, tmp.value.cpbVal);
MoveAlong(2 + tmp.value.cpbVal);
break;
- case DBVT_UTF8:
- case DBVT_ASCIIZ:
- int len = (int)strlen(tmp.value.pszVal);
- if (bIsEncrypted)
- EncodeString(tmp.value.pszVal);
- DBWrite(ofsBlobPtr, &len, 2);
- DBWrite(ofsBlobPtr + 2, tmp.value.pszVal, len); // encode
- MoveAlong(2 + len);
+
+ case DBVT_UTF8: case DBVT_ASCIIZ:
+ DBWrite(ofsBlobPtr, &tmp.value.cchVal, 2);
+ DBWrite(ofsBlobPtr + 2, tmp.value.pszVal, tmp.value.cchVal);
+ MoveAlong(2 + tmp.value.cchVal);
break;
}
diff --git a/plugins/ExternalAPI/delphi/m_historypp.inc b/plugins/ExternalAPI/delphi/m_historypp.inc index a0ff7e82d7..19fed89f4e 100644 --- a/plugins/ExternalAPI/delphi/m_historypp.inc +++ b/plugins/ExternalAPI/delphi/m_historypp.inc @@ -149,7 +149,7 @@ type cbSize : DWord;
hContact : THandle;
hDBEvent : THandle;
- pPassword: PAnsiChar;
+ junkie: PAnsiChar;
end;
POpenEventParams = ^TOpenEventParams;
diff --git a/src/core/stdcrypt/Rijndael.cpp b/src/core/stdcrypt/Rijndael.cpp index fd9cf84d83..95cc317099 100644 --- a/src/core/stdcrypt/Rijndael.cpp +++ b/src/core/stdcrypt/Rijndael.cpp @@ -963,8 +963,14 @@ int CRijndael::MakeKey(BYTE const* key, char const* chain, int keylength, int bl m_keylength = keylength;
m_blockSize = blockSize;
//Initialize the chain
- memcpy(m_chain0, chain, m_blockSize);
- memcpy(m_chain, chain, m_blockSize);
+ size_t len = strlen(chain);
+ if (len >= m_blockSize)
+ memcpy(m_chain0, chain, m_blockSize);
+ else {
+ memcpy(m_chain0, chain, len);
+ memset(m_chain0 + len, 0, m_blockSize - len);
+ }
+ memcpy(m_chain, m_chain0, m_blockSize);
//Calculate Number of Rounds
switch (m_keylength) {
case 16:
diff --git a/src/core/stdcrypt/commonheaders.h b/src/core/stdcrypt/commonheaders.h index 37168497d8..07daa68ac1 100644 --- a/src/core/stdcrypt/commonheaders.h +++ b/src/core/stdcrypt/commonheaders.h @@ -78,4 +78,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern HINSTANCE hInst;
bool getRandomBytes(BYTE *buf, size_t bufLen);
-void slow_hash(const void *buf, size_t bufLen, BYTE tmpHash[32]);
+void slow_hash(const void *buf, size_t bufLen, BYTE *tmpHash);
diff --git a/src/core/stdcrypt/encrypt.cpp b/src/core/stdcrypt/encrypt.cpp index 00e52935d8..5be76f1c54 100644 --- a/src/core/stdcrypt/encrypt.cpp +++ b/src/core/stdcrypt/encrypt.cpp @@ -67,24 +67,20 @@ bool CStdCrypt::getKey(BYTE *pKey, size_t cbKeyLen) bool CStdCrypt::setKey(const BYTE *pKey, size_t cbKeyLen)
{
- ExternalKey tmp = { 0 };
-
// full external key. decode & check password
- if (cbKeyLen == sizeof(tmp)) {
- BYTE tmpHash[32];
- slow_hash(m_password, m_password.GetLength(), tmpHash);
-
- CRijndael tmpAes;
- tmpAes.MakeKey(tmpHash, tmpAes.sm_chain0, KEY_LENGTH, BLOCK_SIZE);
- tmpAes.Decrypt(pKey, &tmp, sizeof(tmp));
- if (tmp.m_crc32 != crc32(0xAbbaDead, (LPCBYTE)m_password.GetString(), m_password.GetLength()))
- return false;
- }
- // new key. simply copy it
- else if (cbKeyLen == KEY_LENGTH) {
- memcpy(&tmp.m_key, pKey, KEY_LENGTH);
- }
- else return false;
+ if (cbKeyLen != sizeof(ExternalKey))
+ return false;
+
+ BYTE tmpHash[32];
+ slow_hash(m_password, m_password.GetLength(), tmpHash);
+
+ CRijndael tmpAes;
+ tmpAes.MakeKey(tmpHash, tmpAes.sm_chain0, KEY_LENGTH, BLOCK_SIZE);
+
+ ExternalKey tmp = { 0 };
+ tmpAes.Decrypt(pKey, &tmp, sizeof(tmp));
+ if (tmp.m_crc32 != crc32(0xAbbaDead, (LPCBYTE)m_password.GetString(), m_password.GetLength()))
+ return false;
memcpy(m_key, &tmp.m_key, KEY_LENGTH);
m_aes.MakeKey(m_key, m_password, KEY_LENGTH, BLOCK_SIZE);
@@ -97,7 +93,9 @@ bool CStdCrypt::generateKey(void) if (!getRandomBytes(tmp, sizeof(tmp)))
return false;
- return setKey(tmp, sizeof(tmp));
+ memcpy(m_key, tmp, KEY_LENGTH);
+ m_aes.MakeKey(m_key, m_password, KEY_LENGTH, BLOCK_SIZE);
+ return m_valid = true;
}
void CStdCrypt::purgeKey(void)
@@ -115,37 +113,34 @@ void CStdCrypt::setPassword(const char *pszPassword) // result must be freed using mir_free or assigned to mir_ptr<BYTE>
BYTE* CStdCrypt::encodeString(const char *src, size_t *cbResultLen)
{
- if (cbResultLen)
- *cbResultLen = 0;
-
- if (!m_valid || src == NULL || *src == 0)
- return NULL;
-
- size_t cbLen = strlen(src);
- cbLen += BLOCK_SIZE - (cbLen % BLOCK_SIZE);
- BYTE *result = (BYTE*)mir_alloc(cbLen);
- if (m_aes.Encrypt(src, LPSTR(result), cbLen)) {
- mir_free(result);
+ if (!m_valid || src == NULL) {
+ if (cbResultLen)
+ *cbResultLen = 0;
return NULL;
}
- if (cbResultLen)
- *cbResultLen = cbLen;
- return result;
+ return encodeBuffer(src, strlen(src)+1, cbResultLen);
}
-BYTE* CStdCrypt::encodeStringW(const WCHAR *src, size_t *cbResultLen)
+BYTE* CStdCrypt::encodeBuffer(const void *src, size_t cbLen, size_t *cbResultLen)
{
if (cbResultLen)
*cbResultLen = 0;
- if (!m_valid || src == NULL || *src == 0)
+ if (!m_valid || src == NULL || cbLen >= 0xFFFE)
return NULL;
- size_t cbLen = wcslen(src) * sizeof(WCHAR);
- cbLen += BLOCK_SIZE - (cbLen % BLOCK_SIZE);
+ BYTE *tmpBuf = (BYTE*)_alloca(cbLen + 2);
+ *(PWORD)tmpBuf = (WORD)cbLen;
+ memcpy(tmpBuf + 2, src, cbLen);
+ cbLen += 2;
+ size_t rest = cbLen % BLOCK_SIZE;
+ if (rest)
+ cbLen += BLOCK_SIZE - rest;
+
BYTE *result = (BYTE*)mir_alloc(cbLen);
- if (m_aes.Encrypt(LPCSTR(src), LPSTR(result), cbLen)) {
+ m_aes.ResetChain();
+ if (m_aes.Encrypt(tmpBuf, LPSTR(result), cbLen)) {
mir_free(result);
return NULL;
}
@@ -157,29 +152,21 @@ BYTE* CStdCrypt::encodeStringW(const WCHAR *src, size_t *cbResultLen) char* CStdCrypt::decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen)
{
- if (cbResultLen)
- *cbResultLen = 0;
-
- if (!m_valid || pBuf == NULL || (bufLen % BLOCK_SIZE) != 0)
- return NULL;
-
- char *result = (char*)mir_alloc(bufLen+1);
- if (m_aes.Decrypt(LPCSTR(pBuf), result, bufLen)) {
- mir_free(result);
- return NULL;
+ size_t resLen;
+ char *result = (char*)decodeBuffer(pBuf, bufLen, &resLen);
+ if (result) {
+ if (result[resLen-1] != 0) { // smth went wrong
+ mir_free(result);
+ return NULL;
+ }
}
- result[bufLen] = 0;
- for (int i = (int)bufLen-1; i >= 0; i--)
- if (result[i] == 0)
- bufLen--;
-
if (cbResultLen)
- *cbResultLen = bufLen;
+ *cbResultLen = resLen;
return result;
}
-WCHAR* CStdCrypt::decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen)
+void* CStdCrypt::decodeBuffer(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen)
{
if (cbResultLen)
*cbResultLen = 0;
@@ -187,20 +174,23 @@ WCHAR* CStdCrypt::decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResul if (!m_valid || pBuf == NULL || (bufLen % BLOCK_SIZE) != 0)
return NULL;
- WCHAR *result = (WCHAR*)mir_alloc(bufLen + sizeof(WCHAR));
- if (m_aes.Decrypt(LPCSTR(pBuf), LPSTR(result), bufLen)) {
+ char *result = (char*)mir_alloc(bufLen + 1);
+ m_aes.ResetChain();
+ if (m_aes.Decrypt(LPCSTR(pBuf), result, bufLen)) {
mir_free(result);
return NULL;
}
- bufLen /= sizeof(WCHAR);
result[bufLen] = 0;
- for (int i = (int)bufLen - 1; i >= 0; i--)
- if (result[i] == 0)
- bufLen--;
+ WORD cbLen = *(PWORD)result;
+ if (cbLen > bufLen) {
+ mir_free(result);
+ return NULL;
+ }
+ memmove(result, result + 2, cbLen);
if (cbResultLen)
- *cbResultLen = bufLen;
+ *cbResultLen = cbLen;
return result;
}
diff --git a/src/core/stdcrypt/stdcrypt.h b/src/core/stdcrypt/stdcrypt.h index c9a3a72315..6129cabcc8 100644 --- a/src/core/stdcrypt/stdcrypt.h +++ b/src/core/stdcrypt/stdcrypt.h @@ -49,9 +49,9 @@ struct CStdCrypt : public MICryptoEngine, public MZeroedObject // result must be freed using mir_free or assigned to mir_ptr<BYTE>
STDMETHODIMP_(BYTE*) encodeString(const char *src, size_t *cbResultLen);
- STDMETHODIMP_(BYTE*) encodeStringW(const WCHAR* src, size_t *cbResultLen);
+ STDMETHODIMP_(BYTE*) encodeBuffer(const void *src, size_t cbLen, size_t *cbResultLen);
// result must be freed using mir_free or assigned to ptrA/ptrT
- STDMETHODIMP_(char*) decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen);
- STDMETHODIMP_(WCHAR*) decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen);
+ STDMETHODIMP_(char*) decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen);
+ STDMETHODIMP_(void*) decodeBuffer(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen);
};
diff --git a/src/core/stdcrypt/utils.cpp b/src/core/stdcrypt/utils.cpp index 3ef8b7bdf7..99b2d3c8db 100644 --- a/src/core/stdcrypt/utils.cpp +++ b/src/core/stdcrypt/utils.cpp @@ -342,7 +342,7 @@ static void sha256_final(SHA256_CONTEXT *hd, BYTE tmpHash[32]) #undef X
}
-static void make_sha256(const void *buf, size_t bufLen, BYTE tmpHash[32])
+static void make_sha256(const void *buf, size_t bufLen, BYTE *tmpHash)
{
SHA256_CONTEXT tmp;
sha256_init(&tmp);
@@ -350,10 +350,10 @@ static void make_sha256(const void *buf, size_t bufLen, BYTE tmpHash[32]) sha256_final(&tmp, tmpHash);
}
-void slow_hash(const void *buf, size_t bufLen, BYTE tmpHash[32])
+void slow_hash(const void *buf, size_t bufLen, BYTE* tmpHash)
{
make_sha256(buf, bufLen, tmpHash);
for (int i = 0; i < 50000; i++)
- make_sha256(tmpHash, sizeof(tmpHash), tmpHash);
+ make_sha256(tmpHash, 32, tmpHash);
}
|