mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Add support for stream cipher subclasses in SymmetricCipherStream
This commit is contained in:
parent
23347b392f
commit
656836950e
@ -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<qint64>(m_cipher->blockSize() - m_buffer.size()));
|
||||
int bytesToCopy = qMin(bytesRemaining, static_cast<qint64>(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<char>(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();
|
||||
}
|
||||
}
|
||||
|
@ -45,14 +45,16 @@ private:
|
||||
void resetInternalState();
|
||||
bool readBlock();
|
||||
bool writeBlock(bool lastBlock);
|
||||
int blockSize() const;
|
||||
|
||||
const QScopedPointer<SymmetricCipher> 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
|
||||
|
Loading…
Reference in New Issue
Block a user