diff options
author | Felix Geyer <debfx@fobos.de> | 2010-09-16 20:20:46 +0400 |
---|---|---|
committer | Felix Geyer <debfx@fobos.de> | 2010-09-16 20:20:46 +0400 |
commit | c2bdfab158da4be7d422a768a3d481cbbd814370 (patch) | |
tree | 77f792e6e8e322a4e149aacac9ed6caeaefce074 /src | |
parent | 49d64d81626adf3bdc427d9bcdf7dab486ac916a (diff) |
Implement writing to the SymmetricCipherStream.
Diffstat (limited to 'src')
-rw-r--r-- | src/streams/SymmetricCipherStream.cpp | 87 | ||||
-rw-r--r-- | src/streams/SymmetricCipherStream.h | 4 |
2 files changed, 77 insertions, 14 deletions
diff --git a/src/streams/SymmetricCipherStream.cpp b/src/streams/SymmetricCipherStream.cpp index 483abefc3..30963bd7a 100644 --- a/src/streams/SymmetricCipherStream.cpp +++ b/src/streams/SymmetricCipherStream.cpp @@ -21,7 +21,8 @@ SymmetricCipherStream::SymmetricCipherStream(QIODevice* baseDevice, SymmetricCip SymmetricCipher::Direction direction, const QByteArray& key, const QByteArray& iv) : LayeredStream(baseDevice) , m_bufferPos(0) - , m_eof(false) + , m_bufferFilling(false) + , m_error(false) { m_cipher = new SymmetricCipher(algo, mode, direction, key, iv); } @@ -30,22 +31,30 @@ bool SymmetricCipherStream::reset() { m_buffer.clear(); m_bufferPos = 0; + m_bufferFilling = false; + m_error = false; m_cipher->reset(); return true; } -qint64 SymmetricCipherStream::readData(char* data, qint64 maxSize) +void SymmetricCipherStream::close() { - // TODO m_eof is probably wrong and should be removed - if (m_eof) { - return 0; + if (isWritable()) { + writeBlock(); } + LayeredStream::close(); +} + +qint64 SymmetricCipherStream::readData(char* data, qint64 maxSize) +{ + Q_ASSERT(maxSize >= 0); + qint64 bytesRemaining = maxSize; qint64 offset = 0; while (bytesRemaining > 0) { - if (m_bufferPos == m_buffer.size()) { + if ((m_bufferPos == m_buffer.size()) || m_bufferFilling) { if (!readBlock()) { return maxSize - bytesRemaining; } @@ -65,28 +74,80 @@ qint64 SymmetricCipherStream::readData(char* data, qint64 maxSize) bool SymmetricCipherStream::readBlock() { - m_buffer = m_baseDevice->read(m_cipher->blockSize()); + if (m_bufferFilling) { + m_buffer.append(m_baseDevice->read(m_cipher->blockSize() - m_buffer.size())); + } + else { + m_buffer = m_baseDevice->read(m_cipher->blockSize()); + } if (m_buffer.size() != m_cipher->blockSize()) { - m_eof = true; - // TODO check if m_buffer.size()!=0 + m_bufferFilling = true; return false; } else { m_cipher->processInPlace(m_buffer); m_bufferPos = 0; + m_bufferFilling = false; return true; } } qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize) { - // TODO implement - return 0; + Q_ASSERT(maxSize >= 0); + + if (m_error) { + return 0; + } + + qint64 bytesRemaining = maxSize; + qint64 offset = 0; + + while (bytesRemaining > 0) { + int bytesToCopy = qMin(bytesRemaining, static_cast<qint64>(m_cipher->blockSize() - m_buffer.size())); + + m_buffer.append(data + offset, bytesToCopy); + + offset += bytesToCopy; + bytesRemaining -= bytesToCopy; + + if (m_buffer.size() == m_cipher->blockSize()) { + if (!writeBlock()) { + if (m_error) { + return -1; + } + else { + return maxSize - bytesRemaining; + } + } + } + } + + return maxSize; } bool SymmetricCipherStream::writeBlock() { - // TODO implement - return false; + if (m_buffer.isEmpty()) { + return true; + } + else if (m_buffer.size() != m_cipher->blockSize()) { + int padLen = m_cipher->blockSize() - m_buffer.size(); + for (int i=m_buffer.size(); i<m_cipher->blockSize(); i++) { + m_buffer.append(static_cast<char>(padLen)); + } + } + + m_cipher->processInPlace(m_buffer); + + if (m_baseDevice->write(m_buffer) != m_buffer.size()) { + m_error = true; + // TODO copy error string + return false; + } + else { + m_buffer.clear(); + return true; + } } diff --git a/src/streams/SymmetricCipherStream.h b/src/streams/SymmetricCipherStream.h index 1891f91c8..90bfc7257 100644 --- a/src/streams/SymmetricCipherStream.h +++ b/src/streams/SymmetricCipherStream.h @@ -31,6 +31,7 @@ public: SymmetricCipherStream(QIODevice* baseDevice, SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode, SymmetricCipher::Direction direction, const QByteArray& key, const QByteArray& iv); bool reset(); + void close(); protected: qint64 readData(char* data, qint64 maxSize); @@ -43,7 +44,8 @@ private: SymmetricCipher* m_cipher; QByteArray m_buffer; int m_bufferPos; - bool m_eof; + bool m_bufferFilling; + bool m_error; }; #endif // KEEPASSX_SYMMETRICCIPHERSTREAM_H |