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();
}
示例#2
0
bool EncryptedStore::openRead(const QString& name)
{
    Q_D(KOdfStore);
    if (bad())
        return false;

    const KArchiveEntry* fileArchiveEntry = m_pZip->directory()->entry(name);
    if (!fileArchiveEntry) {
        return false;
    }
    if (fileArchiveEntry->isDirectory()) {
        kWarning(30002) << name << " is a directory!";
        return false;
    }
    const KZipFileEntry* fileZipEntry = static_cast<const KZipFileEntry*>(fileArchiveEntry);

    delete d->stream;
    d->stream = fileZipEntry->createDevice();
    d->size = fileZipEntry->size();
    if (m_encryptionData.contains(name)) {
        // This file is encrypted, do some decryption first
        if (m_bPasswordDeclined) {
            // The user has already declined to give a password
            // Open the file as empty
            d->stream->close();
            delete d->stream;
            d->stream = new QBuffer();
            d->stream->open(QIODevice::ReadOnly);
            d->size = 0;
            return true;
        }
        QCA::SecureArray encryptedFile(d->stream->readAll());
        if (encryptedFile.size() != d->size) {
            // Read error detected
            d->stream->close();
            delete d->stream;
            d->stream = NULL;
            kWarning(30002) << "read error";
            return false;
        }
        d->stream->close();
        delete d->stream;
        d->stream = NULL;
        KoEncryptedStore_EncryptionData encData = m_encryptionData.value(name);
        QCA::SecureArray decrypted;

        // If we don't have a password yet, try and find one
        if (m_password.isEmpty()) {
            findPasswordInKWallet();
        }

        while (true) {
            QByteArray pass;
            QCA::SecureArray password;
            bool keepPass = false;
            // I already have a password! Let's test it. If it's not good, we can dump it, anyway.
            if (!m_password.isEmpty()) {
                password = m_password;
                m_password = QCA::SecureArray();
            } else {
                if (!m_filename.isNull())
                    keepPass = false;
                QPointer<KPasswordDialog> dlg = new KPasswordDialog(d->window , 
				keepPass ? KPasswordDialog::ShowKeepPassword : static_cast<KPasswordDialog::KPasswordDialogFlags>(0));
                dlg->setPrompt(i18n("Please enter the password to open this file."));
                if (! dlg->exec()) {
                    m_bPasswordDeclined = true;
                    d->stream = new QBuffer();
                    d->stream->open(QIODevice::ReadOnly);
                    d->size = 0;
		    delete dlg;
                    return true;
                }
		if (dlg) {
                    password = QCA::SecureArray(dlg->password().toUtf8());
                    if (keepPass)
                        keepPass = dlg->keepPassword();
                    if (password.isEmpty()) {
		        delete dlg;
                        continue;
                    }
		}
		delete dlg;
            }

            decrypted = decryptFile(encryptedFile, encData, password);
            if (decrypted.isEmpty()) {
                kError(30002) << "empty decrypted file" << endl;
                return false;
            }

            if (!encData.checksum.isEmpty()) {
                QCA::SecureArray checksum;
                if (encData.checksumShort && decrypted.size() > 1024) {
                    // TODO: Eww!!!! I don't want to convert via insecure arrays to get the first 1K characters of a secure array <- fix QCA?
                    checksum = QCA::Hash("sha1").hash(QCA::SecureArray(decrypted.toByteArray().left(1024)));
                } else {
                    checksum = QCA::Hash("sha1").hash(decrypted);
                }
                if (checksum != encData.checksum) {
                    continue;
                }
            }

            // The password passed all possible tests, so let's accept it
            m_password = password;
            m_bPasswordUsed = true;

            if (keepPass) {
                savePasswordInKWallet();
            }

            break;
        }

        QByteArray *resultArray = new QByteArray(decrypted.toByteArray());
        QIODevice *resultDevice = KFilterDev::device(new QBuffer(resultArray, NULL), "application/x-gzip");
        if (!resultDevice) {
            delete resultArray;
            return false;
        }
        static_cast<KFilterDev*>(resultDevice)->setSkipHeaders();
        d->stream = resultDevice;
        d->size = encData.filesize;
    }
    d->stream->open(QIODevice::ReadOnly);

    return true;
}
示例#3
0
	if (s != SECSuccess) {
	    qDebug() << "DigestBegin failed";
	    return;
	}
    }

    void update(const QCA::MemoryRegion &a)
    {
	PK11_DigestOp(m_context, (const unsigned char*)a.data(), a.size());
    }

    QCA::MemoryRegion final()
    {
	unsigned int len = 0;
	QCA::SecureArray a( 64 );
	PK11_DigestFinal(m_context, (unsigned char*)a.data(), &len, a.size());
	a.resize(len);
	return a;
    }

private:
    PK11SlotInfo *m_slot;
    int m_status;
    PK11Context *m_context;
    SECOidTag m_hashAlgo;
};


//-----------------------------------------------------------
class nssHmacContext : public QCA::MACContext
{
示例#4
0
void
HatchetSipPlugin::webSocketConnected()
{
    tLog() << Q_FUNC_INFO << "WebSocket connected";

    if ( m_token.isEmpty() || !m_account->credentials().contains( "username" ) )
    {
        tLog() << Q_FUNC_INFO << "access token or username is empty, aborting";
        disconnectPlugin();
        return;
    }

    hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Connected );
    m_sipState = AcquiringVersion;

    m_uuid = QUuid::createUuid().toString();
    QCA::SecureArray sa( m_uuid.toLatin1() );
    QCA::SecureArray result = m_publicKey->encrypt( sa, QCA::EME_PKCS1_OAEP );

    tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "uuid:" << m_uuid << ", size of uuid:" << m_uuid.size() << ", size of sa:" << sa.size() << ", size of result:" << result.size();

    QVariantMap nonceVerMap;
    nonceVerMap[ "version" ] = VERSION;
    nonceVerMap[ "nonce" ] = QString( result.toByteArray().toBase64() );
    sendBytes( nonceVerMap );
}