Пример #1
0
MemoryReadStream *blowfishEBC(SeekableReadStream &input, const std::vector<byte> &key, Mode mode) {
	BlowfishContext ctx;

	blowfishSetKey(ctx, &key[0], key.size());

	size_t inputSize = input.size() - input.pos();

	// Round up to the next multiple of the block size
	const size_t outputSize = ((inputSize + kBlockSize - 1) / kBlockSize) * kBlockSize;

	ScopedArray<byte> output(new byte[outputSize]);

	byte buffer[kBlockSize];
	byte *data = output.get();
	while (inputSize > 0) {
		const size_t toRead = MIN<size_t>(inputSize, kBlockSize);

		if (input.read(buffer, toRead) != toRead)
			throw Exception(kReadError);

		std::memset(buffer + toRead, 0, kBlockSize - toRead);

		blowfishECB(ctx, mode, buffer, data);

		data      += toRead;
		inputSize -= toRead;
	}

	return new MemoryReadStream(output.release(), outputSize, true);
}
Пример #2
0
bool Cipher::encrypt(QByteArray& cipherText)
{
    if (cipherText.left(3) == "+p ")  // don't encode if...?
        cipherText = cipherText.mid(3);
    else {
        if (m_cbc)  // encode in ecb or cbc decide how to determine later
        {
            QByteArray temp = blowfishCBC(cipherText, true);

            if (temp == cipherText) {
                // kDebug("CBC Encoding Failed");
                return false;
            }

            cipherText = "+OK *" + temp;
        }
        else {
            QByteArray temp = blowfishECB(cipherText, true);

            if (temp == cipherText) {
                // kDebug("ECB Encoding Failed");
                return false;
            }

            cipherText = "+OK " + temp;
        }
    }
    return true;
}
Пример #3
0
QByteArray Cipher::decryptTopic(QByteArray cipherText)
{
    if (cipherText.mid(0, 4) == "+OK ")  // FiSH style topic
        cipherText = cipherText.mid(4);
    else if (cipherText.left(5) == "«m«")
        cipherText = cipherText.mid(5, cipherText.length() - 10);
    else
        return cipherText;

    QByteArray temp;
    // TODO currently no backwards sanity checks for topic, it seems to use different standards
    // if somebody figures them out they can enable it and add "ERROR_NONECB/CBC" warnings
    if (m_cbc)
        temp = blowfishCBC(cipherText.mid(1), false);
    else
        temp = blowfishECB(cipherText, false);

    if (temp == cipherText) {
        return cipherText;
    }
    else
        cipherText = temp;

    if (cipherText.mid(0, 2) == "@@")
        cipherText = cipherText.mid(2);

    return cipherText;
}
Пример #4
0
QByteArray Cipher::decrypt(QByteArray cipherText)
{
    QByteArray pfx = "";
    bool error = false;  // used to flag non cbc, seems like good practice not to parse w/o regard for set encryption type

    // if we get cbc
    if (cipherText.mid(0, 5) == "+OK *") {
        // if we have cbc
        if (m_cbc)
            cipherText = cipherText.mid(5);
        // if we don't
        else {
            cipherText = cipherText.mid(5);
            pfx = "ERROR_NONECB: ";
            error = true;
        }
    }
    // if we get ecb
    else if (cipherText.mid(0, 4) == "+OK " || cipherText.mid(0, 5) == "mcps ") {
        // if we had cbc
        if (m_cbc) {
            cipherText = (cipherText.mid(0, 4) == "+OK ") ? cipherText.mid(4) : cipherText.mid(5);
            pfx = "ERROR_NONCBC: ";
            error = true;
        }
        // if we don't
        else {
            if (cipherText.mid(0, 4) == "+OK ")
                cipherText = cipherText.mid(4);
            else
                cipherText = cipherText.mid(5);
        }
    }
    // all other cases we fail
    else
        return cipherText;

    QByteArray temp;
    // (if cbc and no error we parse cbc) || (if ecb and error we parse cbc)
    if ((m_cbc && !error) || (!m_cbc && error)) {
        temp = blowfishCBC(cipherText, false);

        if (temp == cipherText) {
            // kDebug("Decryption from CBC Failed");
            return cipherText + ' ' + '\n';
        }
        else
            cipherText = temp;
    }
    else {
        temp = blowfishECB(cipherText, false);

        if (temp == cipherText) {
            // kDebug("Decryption from ECB Failed");
            return cipherText + ' ' + '\n';
        }
        else
            cipherText = temp;
    }
    // TODO FIXME the proper fix for this is to show encryption differently e.g. [nick] instead of <nick>
    // don't hate me for the mircryption reference there.
    if (cipherText.at(0) == 1)
        pfx = "\x0";
    cipherText = pfx + cipherText + ' ' + '\n';  // FIXME(??) why is there an added space here?
    return cipherText;
}