-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathSecureString.h
322 lines (281 loc) · 12 KB
/
SecureString.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
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
// The MIT License (MIT)
//
// Copyright (c) 2014 Alexander Nilsson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
/**
* This class considers takes the following compile time parameters:
* SECURESTRING_NOT_THREADSAFE (default: not set)
* Specifies wheater or not all public methods will be protected with mutexes
* SECURESTRING_OVERRIDE_DEFAULT_ALLOCATED (default: 80)
* Specifies the number of characters that is pre-allocated
* by the default constructor
*/
#ifndef SECURESTRING_H_INCLUDED
#define SECURESTRING_H_INCLUDED
#include <cstdlib>
#include <stdint.h>
#ifdef SECURESTRING_THREADSAFE
#include <mutex>
# define __securestring_thread_lock() std::lock_guard<std::mutex> lock(mutex_lock)
#else
# define __securestring_thread_lock()
#endif
#ifdef SECURESTRING_DEBUG
#define SECURESTRING_KEEP_PLAINTEXT_DEBUG_COPY
#endif
namespace Caelus {
namespace Utilities {
/**
* SecureString class, this is a container that does not keep strings in plain
* text in memory. The contents are not encrypted, they are only obfuscated.
* PLEASE NOTE THAT THIS IS IN NO WAY CRYTOGRAPHICALLY SECURE, IT ONLY PREVENTS
* THE STRING FROM BEING STORED IN PLAINTEXT.
*/
class SecureString {
public:
typedef uint32_t ssnr;
typedef char ssbyte;
typedef char* ssarr;
typedef const char* c_ssarr;
public:
/**
* Constructor:
* Simply creates an empty string
*/
SecureString(void);
/**
* Constructor:
* Simply creates an empty string, with size chunc of pre allocated
* memory for storage (bytes).
* @param size - bytes of memory to be allocated
*/
SecureString(ssnr size);
/**
* Constructor:
* Creates a SecureString initialized with str as its contents.
* OBS! This constructor performs delete on the str argument if
* deleteStr is true.
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
* @param deleteStr - performs delete on str if true
*/
SecureString(ssarr str, ssnr maxlen = 0, bool deleteStr = true, bool allowNull = false);
/**
* Constructor:
* Creates a SecureString initialized with str as its contents.
* OBS! This constructor does not perform delete on its str argument
* due to it being 'const'
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
*/
SecureString(c_ssarr str, ssnr maxlen = 0);
/** Copy-constructor **/
SecureString(const SecureString&);
/** Destructor **/
~SecureString(void);
/**
* This assigns a string to this string (replaces the content).
* OBS! This method performs delete on the str argument if
* deleteStr is true.
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
* @param deleteStr - performs delete on str if true
*/
void assign(ssarr str, ssnr maxlen = 0, bool deleteStr = true, bool allowNull = false);
/**
* This assigns a string to this string (replaces the content).
* OBS! This method does not perform delete on its str argument
* due to it being 'const'
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
*/
void assign(c_ssarr str, ssnr maxlen = 0);
/**
* This assigns a string to this string (replaces the content)
* @param str - The string to assign
*/
void assign(const SecureString& str);
/**
* Assignment operator
*/
inline SecureString& operator= (const SecureString& other)
{
assign(other);
return *this;
}
/**
* This appends a string to this string.
* OBS! This method performs delete on the str argument if
* deleteStr is true.
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
* @param deleteStr - performs delete on str if true
*/
void append(ssarr str, ssnr maxlen = 0, bool deleteStr = true, bool allowNull = false);
/**
* This appends a string to this string.
* OBS! This method does not perform delete on its str argument
* due to it being 'const'
* @param str - The string
* @param maxlen - The strings max length, 0 means auto
*/
void append(c_ssarr str, ssnr maxlen = 0);
/**
* This appends a string to this string
* @param str - The string to append
*/
void append(const SecureString& str);
/**
* This returns a pointer to a plaintext copy of the string.
* There can only be one unsecured copy of this string at any one time,
* multiple calls to this function will result in failure and NULL will
* be returned.
* When the copy is no longer needed call UnsecuredStringFinished() to
* perform a safe delete on the string.
* This copy is UnMutable and should thus not be modified!
* @return pointer to an unsecured plaintext string, NULL on failure
*/
c_ssarr getUnsecureString();
/**
* This returns a pointer to a plaintext copy of the string.
* There can only be one unsecured copy of this string at any one time,
* multiple calls to this function will result in failure and NULL will
* be returned.
* When the copy is no longer needed call UnsecuredStringFinished() to
* perform a safe delete on the string.
* This copy is Mutable and can be modified. On UnsecuredStringFinsished()
* the modifications will be imported to the internal representation of
* this SecureString.
* NOTE: The string length will be equal to length() and not allocated()
* Increasing the length by writing past the end of the buffer will result
* in heap corruption.
* @return pointer to an unsecured plaintext string, NULL on failure
*/
ssarr getUnsecureStringM();
/**
* This returns a pointer to a plaintext copy of the string, containing
* everything up until the next linefeed.
* There can only be one unsecured copy of this string at any one time,
* multiple calls to this function will result in failure and NULL will
* be returned.
* When the copy is no longer needed call UnsecuredStringFinished() to
* perform a safe delete on the string.
* This copy is UnMutable and should thus not be modified!
* @return pointer to an unsecured plaintext string, NULL on failure
*/
c_ssarr getUnsecureNextline();
/**
* This performs a safe delete on the unsecured copy of this string. If
* the copy is mutable (see getUnsecureStringM) then any changes to the
* copy will be imported to the internal representation of this SecureString
*/
void UnsecuredStringFinished();
/**
* This returns a single character at position pos of the string.
* @param pos - the position in the string to return
* @return character at position pos, 0 on failure
*/
inline ssbyte at(ssnr pos) const {
__securestring_thread_lock();
if (pos < length())
return _key[pos] ^ _data[pos];
else
return 0;
}
/**
* This returns the current length of the string, excluding trailing null character
* @return length of string
*/
inline ssnr length() const {
__securestring_thread_lock();
return ((ssnr)* _key) ^ _length;
}
/**
* This returns the current amount of allocated bytes.
* @return size of momory block
*/
inline ssnr allocated() const{
__securestring_thread_lock();
return ((ssnr)* _key) ^ _allocated;
}
/**
* This allocates a size block of memory for the string and transfers
* the current string to the new memory block.
* @param size
*/
void allocate(ssnr size);
/**
* This resets the position of the linefeed pointer, so that
* the next cal to getUnsecureNextline() will return the first line
* in the string.
*/
void resetLinefeedPosition() {
__securestring_thread_lock();
_nexlinefeedposition = ((ssnr)* _key) ^ 0;
}
/**
* This returns true if the argument contains an equal string
* @param s2 - the string to compare with
* @return true - if strings are equal
*/
bool equals(const SecureString& s2) const;
/**
* This returns true if the argument contains an equal string
* @param s2 - the string to compare with
* @return true - if strings are equal
*/
bool equals(const char* s2) const;
bool operator==(const SecureString& other) const
{
return equals(other);
}
/**
* This returns true if the argument contains an equal string
* @param s2 - the string to compare with
* @return the corresponding checksum of the string
*/
ssnr checksum() const{
return _checksum;
}
private:
void init();
c_ssarr getUnsecureStringImpl();
void allocateImpl(ssnr size);
#ifdef SECURESTRING_KEEP_PLAINTEXT_DEBUG_COPY
ssarr _debug_plaintextcopy;
void _store_debug_plaintextcopy();
#endif
private:
ssarr _plaintextcopy;
ssarr _data;
ssarr _key;
ssnr _length;
ssnr _allocated;
ssnr _nexlinefeedposition;
ssnr _checksum;
bool _mutableplaintextcopy;
#ifdef SECURESTRING_THREADSAFE
//only allow one thread to access this object at a time
mutable std::mutex mutex_lock;
#endif
};
}
}
#endif