2121#include < QFile>
2222#include < QIODevice>
2323
24+ #ifdef QT_DEBUG
25+ #include < QDebug>
26+ #endif
27+
2428#include " core/Database.h"
2529#include " core/Endian.h"
2630#include " crypto/CryptoHash.h"
@@ -40,7 +44,23 @@ KeePass2Writer::KeePass2Writer()
4044{
4145}
4246
43- void KeePass2Writer::writeDatabase (QIODevice* device, Database* db)
47+ #ifdef QT_DEBUG
48+ /* *
49+ * @brief printByteArray - debug raw data
50+ * @param a array input
51+ * @return string representation of array
52+ */
53+ static inline QString printByteArray (const QByteArray& a)
54+ {
55+ QString s;
56+ for (int i = 0 ; i < a.size (); i++)
57+ s.append (QString::number (a[i] & 0xff , 16 ).rightJustified (2 , ' 0' ));
58+ return s;
59+ }
60+ #endif
61+
62+
63+ bool KeePass2Writer::writeDatabase (QIODevice* device, Database* db)
4464{
4565 m_error = false ;
4666 m_errorStr.clear ();
@@ -50,10 +70,25 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
5070 QByteArray protectedStreamKey = randomGen ()->randomArray (32 );
5171 QByteArray startBytes = randomGen ()->randomArray (32 );
5272 QByteArray endOfHeader = " \r\n\r\n " ;
73+ QByteArray challengedMasterSeed = db->challengeMasterSeed (masterSeed);
74+
75+ if (challengedMasterSeed == " false" ) {
76+ raiseError (" could not receive masterseed challenge response" );
77+
78+ #ifdef QT_DEBUG
79+ qDebug ().nospace () << " could not receive masterseed challenge response" ;
80+ #endif
81+
82+ return false ;
83+ }
84+
85+ #ifdef QT_DEBUG
86+ qDebug ().nospace () << " masterseed challenge response: " << printByteArray (challengedMasterSeed);
87+ #endif
5388
5489 CryptoHash hash (CryptoHash::Sha256);
5590 hash.addData (masterSeed);
56- hash.addData (db-> challengeMasterSeed (masterSeed) );
91+ hash.addData (challengedMasterSeed );
5792 Q_ASSERT (!db->transformedMasterKey ().isEmpty ());
5893 hash.addData (db->transformedMasterKey ());
5994 QByteArray finalKey = hash.result ();
@@ -62,37 +97,37 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
6297 header.open (QIODevice::WriteOnly);
6398 m_device = &header;
6499
65- CHECK_RETURN (writeData (Endian::int32ToBytes (KeePass2::SIGNATURE_1, KeePass2::BYTEORDER)));
66- CHECK_RETURN (writeData (Endian::int32ToBytes (KeePass2::SIGNATURE_2, KeePass2::BYTEORDER)));
67- CHECK_RETURN (writeData (Endian::int32ToBytes (KeePass2::FILE_VERSION, KeePass2::BYTEORDER)));
100+ CHECK_RETURN_FALSE (writeData (Endian::int32ToBytes (KeePass2::SIGNATURE_1, KeePass2::BYTEORDER)));
101+ CHECK_RETURN_FALSE (writeData (Endian::int32ToBytes (KeePass2::SIGNATURE_2, KeePass2::BYTEORDER)));
102+ CHECK_RETURN_FALSE (writeData (Endian::int32ToBytes (KeePass2::FILE_VERSION, KeePass2::BYTEORDER)));
68103
69- CHECK_RETURN (writeHeaderField (KeePass2::CipherID, db->cipher ().toByteArray ()));
70- CHECK_RETURN (writeHeaderField (KeePass2::CompressionFlags,
104+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::CipherID, db->cipher ().toByteArray ()));
105+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::CompressionFlags,
71106 Endian::int32ToBytes (db->compressionAlgo (),
72107 KeePass2::BYTEORDER)));
73- CHECK_RETURN (writeHeaderField (KeePass2::MasterSeed, masterSeed));
74- CHECK_RETURN (writeHeaderField (KeePass2::TransformSeed, db->transformSeed ()));
75- CHECK_RETURN (writeHeaderField (KeePass2::TransformRounds,
108+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::MasterSeed, masterSeed));
109+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::TransformSeed, db->transformSeed ()));
110+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::TransformRounds,
76111 Endian::int64ToBytes (db->transformRounds (),
77112 KeePass2::BYTEORDER)));
78- CHECK_RETURN (writeHeaderField (KeePass2::EncryptionIV, encryptionIV));
79- CHECK_RETURN (writeHeaderField (KeePass2::ProtectedStreamKey, protectedStreamKey));
80- CHECK_RETURN (writeHeaderField (KeePass2::StreamStartBytes, startBytes));
81- CHECK_RETURN (writeHeaderField (KeePass2::InnerRandomStreamID,
113+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::EncryptionIV, encryptionIV));
114+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::ProtectedStreamKey, protectedStreamKey));
115+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::StreamStartBytes, startBytes));
116+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::InnerRandomStreamID,
82117 Endian::int32ToBytes (KeePass2::Salsa20,
83118 KeePass2::BYTEORDER)));
84- CHECK_RETURN (writeHeaderField (KeePass2::EndOfHeader, endOfHeader));
119+ CHECK_RETURN_FALSE (writeHeaderField (KeePass2::EndOfHeader, endOfHeader));
85120
86121 header.close ();
87122 m_device = device;
88123 QByteArray headerHash = CryptoHash::hash (header.data (), CryptoHash::Sha256);
89- CHECK_RETURN (writeData (header.data ()));
124+ CHECK_RETURN_FALSE (writeData (header.data ()));
90125
91126 SymmetricCipherStream cipherStream (device, SymmetricCipher::Aes256, SymmetricCipher::Cbc,
92127 SymmetricCipher::Encrypt, finalKey, encryptionIV);
93128 cipherStream.open (QIODevice::WriteOnly);
94129 m_device = &cipherStream;
95- CHECK_RETURN (writeData (startBytes));
130+ CHECK_RETURN_FALSE (writeData (startBytes));
96131
97132 HashedBlockStream hashedStream (&cipherStream);
98133 hashedStream.open (QIODevice::WriteOnly);
@@ -113,6 +148,7 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
113148
114149 KeePass2XmlWriter xmlWriter;
115150 xmlWriter.writeDatabase (m_device, db, &randomStream, headerHash);
151+ return true ;
116152}
117153
118154bool KeePass2Writer::writeData (const QByteArray& data)
@@ -140,14 +176,14 @@ bool KeePass2Writer::writeHeaderField(KeePass2::HeaderFieldID fieldId, const QBy
140176 return true ;
141177}
142178
143- void KeePass2Writer::writeDatabase (const QString& filename, Database* db)
179+ bool KeePass2Writer::writeDatabase (const QString& filename, Database* db)
144180{
145181 QFile file (filename);
146182 if (!file.open (QIODevice::WriteOnly|QIODevice::Truncate)) {
147183 raiseError (file.errorString ());
148- return ;
184+ return false ;
149185 }
150- writeDatabase (&file, db);
186+ return writeDatabase (&file, db);
151187}
152188
153189bool KeePass2Writer::hasError ()
0 commit comments