QByteArray EncryptioNgSimliteDecryptor::decrypt(const QByteArray &data, bool *ok) { if (ok) *ok = false; if (!Valid) return data; //check if the message has at least the length of the shortest possible encrypted message if (data.length() < 192) return data; //decode the message from the Base64 encoding QCA::Base64 decoder(QCA::Decode); QCA::SecureArray decodedMessage = decoder.stringToArray(data); if (!decoder.ok()) return data; //extract the Blowfish key (first 128 characters) QCA::SecureArray encryptedBlowfishKey(decodedMessage.toByteArray().left(128)); //and the encrypted message (the rest) QCA::SecureArray encryptedMessage(decodedMessage.toByteArray().mid(128)); QCA::SymmetricKey blowfishKey; if (!DecodingKey.decrypt(encryptedBlowfishKey, &blowfishKey, QCA::EME_PKCS1_OAEP)) return data; //recreate the initialization vector (should be the same as the one used for ciphering) char ivec[8] = {0, 0, 0, 0, 0, 0, 0, 0}; QCA::InitializationVector iv(QByteArray(ivec, 8)); //now that we have the symmetric Blowfish key, we can decrypt the message; //create a 128 bit Blowfish cipher object using Cipher Block Chaining (CBC) mode, //with default padding and for decoding QCA::Cipher cipher(QString("blowfish"), QCA::Cipher::CBC, QCA::Cipher::DefaultPadding, QCA::Decode, blowfishKey, iv); //decipher the message (put the message into the decoding cipher object) QCA::SecureArray plainText = cipher.process(encryptedMessage); if (!cipher.ok()) return data; //check whether the decrypted data length is at least the size of the header - //if not, then we have an invalid message if (plainText.size() < (int)sizeof(sim_message_header)) return data; //extract the header from the decrypted data and check if the magic number is //correct sim_message_header head; memcpy(&head, plainText.data(), sizeof(sim_message_header)); if (head.magicFirstPart != SIM_MAGIC_V1_1 || head.magicSecondPart != SIM_MAGIC_V1_2) return data; if (ok) *ok = true; //the message has been decrypted! :D //put it into the input/output byte array return cp2unicode(&plainText.data()[sizeof(sim_message_header)]).toUtf8(); }
void GaduSearchService::handleEventPubdir50SearchReply(struct gg_event *e) { gg_pubdir50_t res = e->event.pubdir50; ContactList results; int count = gg_pubdir50_count(res); kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "found %d results\n", count); for (int i = 0; i < count; i++) { Contact result; GaduContactAccountData *gcad = new GaduContactAccountData(result, Protocol->account(), gg_pubdir50_get(res, i, GG_PUBDIR50_UIN)); result.addAccountData(gcad); result.setFirstName(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_FIRSTNAME))); result.setLastName(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_LASTNAME))); result.setNickName(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_NICKNAME))); result.setBirthYear(QString::fromAscii(gg_pubdir50_get(res, i, GG_PUBDIR50_BIRTHYEAR)).toUShort()); result.setCity(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_CITY))); result.setFamilyName(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYNAME))); result.setFamilyCity(cp2unicode(gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYCITY))); result.setGender((ContactData::ContactGender)QString::fromAscii(gg_pubdir50_get(res, i, GG_PUBDIR50_GENDER)).toUShort()); // TODO: 0.6.6 // result.setStatus(gg_pubdir50_get(res, 0, GG_PUBDIR50_STATUS)); results.append(result); } From = gg_pubdir50_next(res); emit newResults(results); }
void GaduContactListService::handleEventUserlistGetReply(struct gg_event *e) { char *content = e->event.userlist.reply; if (!content) { kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "error!\n"); emit contactListImported(false, ContactList()); return; } if (content[0] != 0) ImportReply += cp2unicode(content); if (e->event.userlist.type == GG_USERLIST_GET_MORE_REPLY) { kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "next portion\n"); return; } kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "\n%s\n", unicode2latin(ImportReply).data()); emit contactListImported(true, GaduListHelper::stringToContactList(Protocol->account(), ImportReply)); }