forked from keepassxreboot/keepassxc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpVaultReader.h
120 lines (100 loc) · 4.53 KB
/
OpVaultReader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
* Copyright (C) 2019 KeePassXC Team <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPVAULT_READER_H_
#define OPVAULT_READER_H_
#include <QDir>
class Database;
class Group;
class Entry;
/*!
* Imports a directory in the 1Password \c opvault format into a \c Database.
* \sa https://support.1password.com/opvault-overview/
* \sa https://support.1password.com/opvault-design/
* \sa https://cache.agilebits.com/security-kb/freddy-2013-12-04.tar.gz is the sample data used to test this class,
* and its password is \c freddy
*/
class OpVaultReader : public QObject
{
Q_OBJECT
public:
explicit OpVaultReader(QObject* parent = nullptr);
~OpVaultReader() override;
Database* readDatabase(QDir& opdataDir, const QString& password);
bool hasError();
QString errorString();
private:
struct DerivedKeyHMAC
{
QByteArray encrypt;
QByteArray hmac;
bool error;
QString errorStr;
};
QJsonObject readAndAssertJsonFile(QFile& file, const QString& stripLeading, const QString& stripTrailing);
DerivedKeyHMAC* deriveKeysFromPassPhrase(QByteArray& salt, const QString& password, unsigned long iterations);
DerivedKeyHMAC* decodeB64CompositeKeys(const QString& b64, const QByteArray& encKey, const QByteArray& hmacKey);
DerivedKeyHMAC* decodeCompositeKeys(const QByteArray& keyKey);
/*!
* \sa https://support.1password.com/opvault-design/#profile-js
* @param profileJson the contents of \c profile.js
* @return \c true if the profile data was decrypted successfully, \c false otherwise
*/
bool processProfileJson(QJsonObject& profileJson, const QString& password, Group* rootGroup);
/*!
* \sa https://support.1password.com/opvault-design/#folders-js
* @param foldersJson the map from a folder UUID to its data (name and any smart query)
* @return \c true if the folder data was decrypted successfully, \c false otherwise
*/
bool processFolderJson(QJsonObject& foldersJson, Group* rootGroup);
/*!
* Decrypts the provided band object into its interior structure,
* as well as the encryption key and HMAC key declared therein,
* which are used to decrypt the attachments, also.
* @returns \c nullptr if unable to do the decryption, otherwise the interior object and its keys
*/
bool decryptBandEntry(const QJsonObject& bandEntry, QJsonObject& data, QByteArray& key, QByteArray& hmacKey);
Entry* processBandEntry(const QJsonObject& bandEntry, const QDir& attachmentDir, Group* rootGroup);
bool readAttachment(const QString& filePath,
const QByteArray& itemKey,
const QByteArray& itemHmacKey,
QJsonObject& metadata,
QByteArray& payload);
void fillAttachment(Entry* entry,
const QFileInfo& attachmentFileInfo,
const QByteArray& entryKey,
const QByteArray& entryHmacKey);
void fillAttachments(Entry* entry,
const QDir& attachmentDir,
const QByteArray& entryKey,
const QByteArray& entryHmacKey);
bool fillAttributes(Entry* entry, const QJsonObject& bandEntry);
void fillFromSection(Entry* entry, const QJsonObject& section);
void fillFromSectionField(Entry* entry, const QString& sectionName, const QJsonObject& field);
QString resolveAttributeName(const QString& section, const QString& name, const QString& text);
void populateCategoryGroups(Group* rootGroup);
/*! Used to blank the memory after the keys have been used. */
void zeroKeys();
bool m_error;
QString m_errorStr;
QByteArray m_masterKey;
QByteArray m_masterHmacKey;
/*! Used to decrypt overview text, such as folder names. */
QByteArray m_overviewKey;
QByteArray m_overviewHmacKey;
friend class TestOpVaultReader;
};
#endif /* OPVAULT_READER_H_ */