forked from goatpig/BitcoinArmory
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDecryptedDataContainer.h
More file actions
152 lines (119 loc) · 4.6 KB
/
DecryptedDataContainer.h
File metadata and controls
152 lines (119 loc) · 4.6 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2017, goatpig //
// Distributed under the MIT license //
// See LICENSE-MIT or https://opensource.org/licenses/MIT //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef _H_DECRYPTED_DATA_CONTAINER
#define _H_DECRYPTED_DATA_CONTAINER
#include <functional>
#include "Assets.h"
#include "ReentrantLock.h"
#include "BinaryData.h"
#include "lmdbpp.h"
#define ENCRYPTIONKEY_PREFIX 0xC0
#define ENCRYPTIONKEY_PREFIX_TEMP 0xCC
class AssetUnavailableException
{};
class DecryptedDataContainerException : public runtime_error
{
public:
DecryptedDataContainerException(const string& msg) : runtime_error(msg)
{}
};
class EncryptedDataMissing : public runtime_error
{
public:
EncryptedDataMissing() : runtime_error("")
{}
};
////////////////////////////////////////////////////////////////////////////////
class DecryptedDataContainer : public Lockable
{
struct DecryptedData
{
map<BinaryData, unique_ptr<DecryptedEncryptionKey>> encryptionKeys_;
map<unsigned, unique_ptr<DecryptedPrivateKey>> privateKeys_;
};
private:
map<BinaryData, shared_ptr<KeyDerivationFunction>> kdfMap_;
unique_ptr<DecryptedData> lockedDecryptedData_ = nullptr;
struct OtherLockedContainer
{
shared_ptr<DecryptedDataContainer> container_;
shared_ptr<ReentrantLock> lock_;
OtherLockedContainer(shared_ptr<DecryptedDataContainer> obj)
{
if (obj == nullptr)
throw runtime_error("emtpy DecryptedDataContainer ptr");
lock_ = make_unique<ReentrantLock>(obj.get());
}
};
vector<OtherLockedContainer> otherLocks_;
LMDBEnv* dbEnv_;
LMDB* dbPtr_;
/*
The default encryption key is used to encrypt the master encryption in
case no passphrase was provided at wallet creation. This is to prevent
for the master key being written in plain text on disk. It is encryption
but does not effectively result in the wallet being protected by encryption,
since the default encryption is written on disk in plain text.
This is mostly to allow for the entire container to be encrypted head to toe
without implementing large caveats to handle unencrypted use cases.
*/
const SecureBinaryData defaultEncryptionKey_;
const SecureBinaryData defaultEncryptionKeyId_;
protected:
map<BinaryData, shared_ptr<Asset_EncryptedData>> encryptionKeyMap_;
private:
function<SecureBinaryData(
const BinaryData&)> getPassphraseLambda_;
private:
unique_ptr<DecryptedEncryptionKey> deriveEncryptionKey(
unique_ptr<DecryptedEncryptionKey>, const BinaryData& kdfid) const;
unique_ptr<DecryptedEncryptionKey> promptPassphrase(
const BinaryData&, const BinaryData&) const;
void initAfterLock(void);
void cleanUpBeforeUnlock(void);
public:
DecryptedDataContainer(LMDBEnv* dbEnv, LMDB* dbPtr,
const SecureBinaryData& defaultEncryptionKey,
const BinaryData& defaultEncryptionKeyId) :
dbEnv_(dbEnv), dbPtr_(dbPtr),
defaultEncryptionKey_(defaultEncryptionKey),
defaultEncryptionKeyId_(defaultEncryptionKeyId)
{
resetPassphraseLambda();
}
const SecureBinaryData& getDecryptedPrivateKey(
shared_ptr<Asset_PrivateKey> data);
SecureBinaryData encryptData(
Cypher* const cypher, const SecureBinaryData& data);
void populateEncryptionKey(
const BinaryData& keyid, const BinaryData& kdfid);
void addKdf(shared_ptr<KeyDerivationFunction> kdfPtr)
{
kdfMap_.insert(make_pair(kdfPtr->getId(), kdfPtr));
}
void addEncryptionKey(shared_ptr<Asset_EncryptionKey> keyPtr)
{
encryptionKeyMap_.insert(make_pair(keyPtr->getId(), keyPtr));
}
void updateOnDisk(void);
void readFromDisk(void);
void updateKeyOnDiskNoPrefix(
const BinaryData&, shared_ptr<Asset_EncryptedData>);
void updateKeyOnDisk(
const BinaryData&, shared_ptr<Asset_EncryptedData>);
void deleteKeyFromDisk(const BinaryData& key);
void setPassphrasePromptLambda(
function<SecureBinaryData(const BinaryData&)> lambda)
{
getPassphraseLambda_ = lambda;
}
void resetPassphraseLambda(void) { getPassphraseLambda_ = nullptr; }
void encryptEncryptionKey(const BinaryData&, const SecureBinaryData&);
void lockOther(shared_ptr<DecryptedDataContainer> other);
};
#endif