diff --git a/src/streams/SymmetricCipherStream.cpp b/src/streams/SymmetricCipherStream.cpp index 643aa0339..ece2642b5 100644 --- a/src/streams/SymmetricCipherStream.cpp +++ b/src/streams/SymmetricCipherStream.cpp @@ -24,7 +24,7 @@ SymmetricCipherStream::SymmetricCipherStream(QIODevice* baseDevice, SymmetricCip , m_bufferPos(0) , m_bufferFilling(false) , m_error(false) - , m_isInitalized(false) + , m_isInitialized(false) , m_dataWritten(false) { } @@ -36,12 +36,12 @@ SymmetricCipherStream::~SymmetricCipherStream() bool SymmetricCipherStream::init(const QByteArray& key, const QByteArray& iv) { - m_isInitalized = m_cipher->init(key, iv); - if (!m_isInitalized) { + m_isInitialized = m_cipher->init(key, iv); + if (!m_isInitialized) { setErrorString(m_cipher->errorString()); } - - return m_isInitalized; + m_streamCipher = m_cipher->blockSize() == 1; + return m_isInitialized; } void SymmetricCipherStream::resetInternalState() @@ -56,11 +56,8 @@ void SymmetricCipherStream::resetInternalState() bool SymmetricCipherStream::open(QIODevice::OpenMode mode) { - if (!m_isInitalized) { - return false; - } + return m_isInitialized && LayeredStream::open(mode); - return LayeredStream::open(mode); } bool SymmetricCipherStream::reset() @@ -127,11 +124,11 @@ bool SymmetricCipherStream::readBlock() QByteArray newData; if (m_bufferFilling) { - newData.resize(m_cipher->blockSize() - m_buffer.size()); + newData.resize(blockSize() - m_buffer.size()); } else { m_buffer.clear(); - newData.resize(m_cipher->blockSize()); + newData.resize(blockSize()); } int readResult = m_baseDevice->read(newData.data(), newData.size()); @@ -140,12 +137,11 @@ bool SymmetricCipherStream::readBlock() m_error = true; setErrorString(m_baseDevice->errorString()); return false; - } - else { + } else { m_buffer.append(newData.left(readResult)); } - if (m_buffer.size() != m_cipher->blockSize()) { + if (!m_streamCipher && m_buffer.size() != blockSize()) { m_bufferFilling = true; return false; } @@ -159,26 +155,28 @@ bool SymmetricCipherStream::readBlock() m_bufferFilling = false; if (m_baseDevice->atEnd()) { - // PKCS7 padding - quint8 padLength = m_buffer.at(m_buffer.size() - 1); + if (!m_streamCipher) { + // PKCS7 padding + quint8 padLength = m_buffer.at(m_buffer.size() - 1); - if (padLength == m_cipher->blockSize()) { - Q_ASSERT(m_buffer == QByteArray(m_cipher->blockSize(), m_cipher->blockSize())); - // full block with just padding: discard - m_buffer.clear(); - return false; - } - else if (padLength > m_cipher->blockSize()) { - // invalid padding - m_error = true; - setErrorString("Invalid padding."); - return false; - } - else { - Q_ASSERT(m_buffer.right(padLength) == QByteArray(padLength, padLength)); - // resize buffer to strip padding - m_buffer.resize(m_cipher->blockSize() - padLength); - return true; + if (padLength == blockSize()) { + Q_ASSERT(m_buffer == QByteArray(blockSize(), blockSize())); + // full block with just padding: discard + m_buffer.clear(); + return false; + } else if (padLength > blockSize()) { + // invalid padding + m_error = true; + setErrorString("Invalid padding."); + return false; + } else { + Q_ASSERT(m_buffer.right(padLength) == QByteArray(padLength, padLength)); + // resize buffer to strip padding + m_buffer.resize(blockSize() - padLength); + return true; + } + } else { + return m_buffer.size() > 0; } } else { @@ -200,14 +198,14 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize) qint64 offset = 0; while (bytesRemaining > 0) { - int bytesToCopy = qMin(bytesRemaining, static_cast(m_cipher->blockSize() - m_buffer.size())); + int bytesToCopy = qMin(bytesRemaining, static_cast(blockSize() - m_buffer.size())); m_buffer.append(data + offset, bytesToCopy); offset += bytesToCopy; bytesRemaining -= bytesToCopy; - if (m_buffer.size() == m_cipher->blockSize()) { + if (m_buffer.size() == blockSize()) { if (!writeBlock(false)) { if (m_error) { return -1; @@ -224,11 +222,11 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize) bool SymmetricCipherStream::writeBlock(bool lastBlock) { - Q_ASSERT(lastBlock || (m_buffer.size() == m_cipher->blockSize())); + Q_ASSERT(m_streamCipher || lastBlock || (m_buffer.size() == blockSize())); - if (lastBlock) { + if (lastBlock && !m_streamCipher) { // PKCS7 padding - int padLen = m_cipher->blockSize() - m_buffer.size(); + int padLen = blockSize() - m_buffer.size(); for (int i = 0; i < padLen; i++) { m_buffer.append(static_cast(padLen)); } @@ -250,3 +248,11 @@ bool SymmetricCipherStream::writeBlock(bool lastBlock) return true; } } + +int SymmetricCipherStream::blockSize() const { + if (m_streamCipher) { + return 1024; + } else { + return m_cipher->blockSize(); + } +} diff --git a/src/streams/SymmetricCipherStream.h b/src/streams/SymmetricCipherStream.h index b6228e1b8..b68dba01f 100644 --- a/src/streams/SymmetricCipherStream.h +++ b/src/streams/SymmetricCipherStream.h @@ -45,14 +45,16 @@ private: void resetInternalState(); bool readBlock(); bool writeBlock(bool lastBlock); + int blockSize() const; const QScopedPointer m_cipher; QByteArray m_buffer; int m_bufferPos; bool m_bufferFilling; bool m_error; - bool m_isInitalized; + bool m_isInitialized; bool m_dataWritten; + bool m_streamCipher; }; #endif // KEEPASSX_SYMMETRICCIPHERSTREAM_H