Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Geyer <debfx@fobos.de>2010-09-18 19:19:42 +0400
committerFelix Geyer <debfx@fobos.de>2010-09-18 19:19:42 +0400
commit5da7d3fca6647c8a67c5d6a1d057ca0367bf9d4b (patch)
tree67a166e69ba159956356e40dc7b73851c8d94635 /src
parentc93ac9f6fc860389c7e1dcfd3c0167e507d3bfd9 (diff)
Implement writing in SymmetricCipherStream and add a unit test.
Diffstat (limited to 'src')
-rw-r--r--src/core/Endian.cpp66
-rw-r--r--src/core/Endian.h8
-rw-r--r--src/streams/HashedBlockStream.cpp104
-rw-r--r--src/streams/HashedBlockStream.h6
4 files changed, 178 insertions, 6 deletions
diff --git a/src/core/Endian.cpp b/src/core/Endian.cpp
index 8fca50f12..177c3a7fb 100644
--- a/src/core/Endian.cpp
+++ b/src/core/Endian.cpp
@@ -131,4 +131,70 @@ quint64 readUInt64(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok)
return readInt64(device, byteOrder, ok);
}
+QByteArray int16ToBytes(qint16 num, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba;
+ ba.resize(2);
+
+ if (byteOrder == QSysInfo::LittleEndian) {
+ qToLittleEndian<qint16>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+ else {
+ qToBigEndian<qint64>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+
+ return ba;
+}
+
+QByteArray int32ToBytes(qint32 num, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba;
+ ba.resize(4);
+
+ if (byteOrder == QSysInfo::LittleEndian) {
+ qToLittleEndian<qint32>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+ else {
+ qToBigEndian<qint32>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+
+ return ba;
+}
+
+QByteArray int64ToBytes(qint64 num, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba;
+ ba.resize(8);
+
+ if (byteOrder == QSysInfo::LittleEndian) {
+ qToLittleEndian<qint64>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+ else {
+ qToBigEndian<qint64>(num, reinterpret_cast<uchar*>(ba.data()));
+ }
+
+ return ba;
+}
+
+bool writeInt16(qint16 num, QIODevice* device, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba = int16ToBytes(num, byteOrder);
+ int bytesWritten = device->write(ba);
+ return (bytesWritten == ba.size());
+}
+
+bool writeInt32(qint32 num, QIODevice* device, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba = int32ToBytes(num, byteOrder);
+ int bytesWritten = device->write(ba);
+ return (bytesWritten == ba.size());
+}
+
+bool writeInt64(qint64 num, QIODevice* device, QSysInfo::Endian byteOrder)
+{
+ QByteArray ba = int64ToBytes(num, byteOrder);
+ int bytesWritten = device->write(ba);
+ return (bytesWritten == ba.size());
+}
+
} // namespace Endian
diff --git a/src/core/Endian.h b/src/core/Endian.h
index 8958cc400..023df6463 100644
--- a/src/core/Endian.h
+++ b/src/core/Endian.h
@@ -38,6 +38,14 @@ namespace Endian
quint32 readUInt32(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok);
qint64 readInt64(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok);
quint64 readUInt64(QIODevice* device, QSysInfo::Endian byteOrder, bool* ok);
+
+ QByteArray int16ToBytes(qint16 num, QSysInfo::Endian byteOrder);
+ QByteArray int32ToBytes(qint32 num, QSysInfo::Endian byteOrder);
+ QByteArray int64ToBytes(qint64 num, QSysInfo::Endian byteOrder);
+
+ bool writeInt16(qint16 num, QIODevice* device, QSysInfo::Endian byteOrder);
+ bool writeInt32(qint32 num, QIODevice* device, QSysInfo::Endian byteOrder);
+ bool writeInt64(qint64 num, QIODevice* device, QSysInfo::Endian byteOrder);
};
#endif // KEEPASSX_ENDIAN_H
diff --git a/src/streams/HashedBlockStream.cpp b/src/streams/HashedBlockStream.cpp
index a63dba2c4..c758fc4e9 100644
--- a/src/streams/HashedBlockStream.cpp
+++ b/src/streams/HashedBlockStream.cpp
@@ -19,6 +19,7 @@
#include <cstring>
+#include "core/Endian.h"
#include "crypto/CryptoHash.h"
const QSysInfo::Endian HashedBlockStream::BYTEORDER = QSysInfo::LittleEndian;
@@ -42,10 +43,41 @@ void HashedBlockStream::init()
m_bufferPos = 0;
m_blockIndex = 0;
m_eof = false;
+ m_error = false;
+}
+
+bool HashedBlockStream::reset()
+{
+ if (isWritable()) {
+ if (!m_buffer.isEmpty()) {
+ if (!writeHashedBlock()) {
+ return false;
+ }
+ }
+
+ // write empty final block
+ if (!writeHashedBlock()) {
+ return false;
+ }
+ }
+
+ init();
+ m_buffer.clear();
+
+ return true;
}
void HashedBlockStream::close()
{
+ if (isWritable()) {
+ if (!m_buffer.isEmpty()) {
+ writeHashedBlock();
+ }
+
+ // write empty final block
+ writeHashedBlock();
+ }
+
LayeredStream::close();
}
@@ -134,12 +166,76 @@ bool HashedBlockStream::readHashedBlock()
qint64 HashedBlockStream::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_blockSize - m_buffer.size()));
+
+ m_buffer.append(data + offset, bytesToCopy);
+
+ offset += bytesToCopy;
+ bytesRemaining -= bytesToCopy;
+
+ if (m_buffer.size() == m_blockSize) {
+ if (!writeHashedBlock()) {
+ if (m_error) {
+ return -1;
+ }
+ else {
+ return maxSize - bytesRemaining;
+ }
+ }
+ }
+ }
+
+ return maxSize;
}
bool HashedBlockStream::writeHashedBlock()
{
- // TODO implement
- return false;
+ if (!Endian::writeInt32(m_blockIndex, m_baseDevice, BYTEORDER)) {
+ // TODO error
+ Q_ASSERT(false);
+ return false;
+ }
+ m_blockIndex++;
+
+ QByteArray hash;
+ if (!m_buffer.isEmpty()) {
+ hash = CryptoHash::hash(m_buffer, CryptoHash::Sha256);
+ }
+ else {
+ hash.fill(0, 32);
+ }
+
+ if (m_baseDevice->write(hash) != hash.size()) {
+ // TODO error
+ Q_ASSERT(false);
+ return false;
+ }
+
+ if (!Endian::writeInt32(m_buffer.size(), m_baseDevice, BYTEORDER)) {
+ // TODO error
+ Q_ASSERT(false);
+ return false;
+ }
+
+ if (!m_buffer.isEmpty()) {
+ if (m_baseDevice->write(m_buffer) != m_buffer.size()) {
+ // TODO error
+ Q_ASSERT(false);
+ return false;
+ }
+
+ m_buffer.clear();
+ }
+
+ return true;
}
diff --git a/src/streams/HashedBlockStream.h b/src/streams/HashedBlockStream.h
index 626974878..3aa23bf22 100644
--- a/src/streams/HashedBlockStream.h
+++ b/src/streams/HashedBlockStream.h
@@ -18,9 +18,9 @@
#ifndef KEEPASSX_HASHEDBLOCKSTREAM_H
#define KEEPASSX_HASHEDBLOCKSTREAM_H
+#include <QtCore/QSysInfo>
+
#include "LayeredStream.h"
-#include "core/Endian.h"
-#include "crypto/CryptoHash.h"
class HashedBlockStream : public LayeredStream
{
@@ -30,6 +30,7 @@ public:
explicit HashedBlockStream(QIODevice* baseDevice);
HashedBlockStream(QIODevice* baseDevice, qint32 blockSize);
+ bool reset();
void close();
protected:
@@ -47,6 +48,7 @@ private:
int m_bufferPos;
quint32 m_blockIndex;
bool m_eof;
+ bool m_error;
};
#endif // KEEPASSX_HASHEDBLOCKSTREAM_H