Libmacro  0.2
Libmacro is an extensible macro and hotkey library.
safe_string.h
Go to the documentation of this file.
1 /* Libmacro - A multi-platform, extendable macro and hotkey C library
2  Copyright (C) 2013 Jonathan Pelletier, New Paradigm Software
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
25 #ifndef MCR_EXTRAS_SAFE_STRING_H_
26 #define MCR_EXTRAS_SAFE_STRING_H_
27 
28 #include "mcr/extras/util/string.h"
29 #include <cstring>
30 
31 /* 256 / 8, 256 bits => 32 bytes */
33 #define MCR_AES_BLOCK_SIZE 32
34 
35 #define MCR_AES_IV_SIZE 16
36 
37 #define MCR_AES_TAG_SIZE 16
38 
39 namespace mcr
40 {
42 class MCR_API IKeyProvider
43 {
44 public:
46 
47 
54  virtual void key(const void *obj,
55  const unsigned char *keyOut[MCR_AES_BLOCK_SIZE]) = 0;
61  virtual void deregister(const void *obj) = 0;
62 };
63 
65 class MCR_API SafeString
66 {
67 public:
73  SafeString(IKeyProvider *keyProvider = nullptr,
74  const String &str = String(),
75  bool cryptic = true)
76  : _cryptic(cryptic
77  && keyProvider), _encrypted(nullptr), _encryptedBufferSize(0),
78  _encryptedBytes(0), _keyProvider(keyProvider), _iv {0}, _lenMem(0),
79  _plain(nullptr), _plainBufferSize(0), _stateless(false), _tag {0}
80  {
81  if (_cryptic)
82  resetIv();
83  setText(str);
84  }
85  SafeString(const SafeString &copytron);
87  virtual ~SafeString();
88  SafeString &operator =(const SafeString &copytron)
89  {
90  if (&copytron != this)
91  setText(copytron.text());
92  return *this;
93  }
94  inline SafeString &operator =(const String &str)
95  {
96  setText(str);
97  return *this;
98  }
99  inline SafeString &operator =(const char *str)
100  {
101  if (!str)
102  str = "";
103  setText(str, strlen(str));
104  return *this;
105  }
106 
122  static inline int encrypt(const String &plainText,
123  const unsigned char key[MCR_AES_BLOCK_SIZE],
124  const unsigned char iv[MCR_AES_IV_SIZE],
125  unsigned char tagOut[MCR_AES_TAG_SIZE], unsigned char *bufferOut)
126  {
127  return encrypt(*plainText, plainText.length(), key, iv, tagOut, bufferOut);
128  }
135  static int encrypt(const char *plain, size_t plainLen,
136  const unsigned char key[MCR_AES_BLOCK_SIZE],
137  const unsigned char iv[MCR_AES_IV_SIZE],
138  unsigned char tagOut[MCR_AES_TAG_SIZE], unsigned char *bufferOut);
151  static inline String decrypt(const unsigned char *encrypted,
152  int encryptedLength,
153  const unsigned char key[MCR_AES_BLOCK_SIZE],
154  const unsigned char iv[MCR_AES_IV_SIZE],
155  const unsigned char tag[])
156  {
157  String ret;
158  size_t decLen = 0;
159  if (!encrypted || !encryptedLength)
160  return ret ? ret : nullptr;
161  ret.resize(encryptedLength);
162  /* May throw, string will delete self */
163  decLen = decrypt(encrypted, encryptedLength, key, iv, tag, ret.string());
164  if (static_cast<int>(decLen) != -1)
165  ret.setLength(decLen);
166  return ret;
167  }
174  static size_t decrypt(const unsigned char *encrypted, int encryptedLength,
175  const unsigned char key[MCR_AES_BLOCK_SIZE],
176  const unsigned char iv[MCR_AES_IV_SIZE],
177  const unsigned char tag[], char *bufferOut);
185  static void randomize(unsigned char *bufferOut, int bufferSize);
191  static inline void sha(const String &text,
192  unsigned char bufferOut[MCR_AES_BLOCK_SIZE])
193  {
194  sha(*text, text.length(), bufferOut);
195  }
201  static void sha(const char *text, size_t textLen,
202  unsigned char bufferOut[MCR_AES_BLOCK_SIZE]);
208  static void initialize();
214  static void deinitialize();
218  static inline void generateKey(unsigned char keyOut[MCR_AES_BLOCK_SIZE])
219  {
220  if (keyOut)
221  randomize(keyOut, MCR_AES_BLOCK_SIZE);
222  }
226  static inline void initializer(unsigned char ivOut[MCR_AES_IV_SIZE])
227  {
228  if (ivOut)
229  randomize(ivOut, MCR_AES_IV_SIZE);
230  }
231 
233  int compare(const SafeString &rhs) const;
234 
236  inline bool cryptic() const
237  {
238  return _cryptic;
239  }
246  void setCryptic(bool val);
248  inline IKeyProvider *keyProvider() const
249  {
250  return _keyProvider;
251  }
256  void setKeyProvider(IKeyProvider *provider);
258  inline const unsigned char *iv() const
259  {
260  return _iv;
261  }
266  void setIv(unsigned char *iv);
271  void resetIv();
276  inline bool stateless() const
277  {
278  return _stateless;
279  }
284  void setStateless(bool val);
285 
287  inline size_t length() const
288  {
289  return _lenMem;
290  }
292  inline String text() const
293  {
294  String ret;
295  if (!_cryptic)
296  return _plain ? _plain : "";
297  if (!_lenMem)
298  return "";
299  ret.resize(_lenMem);
300  text(ret.string());
301  ret.setLength(_lenMem);
302  return ret;
303  }
308  size_t text(char *bufferOut) const;
311  inline void setText(const String &str = String())
312  {
313  setText(*str, str.length());
314  }
319  void setText(const char *str, size_t len);
324  inline void setText(const String &str, bool cryptic)
325  {
326  setText(*str, str.length(), cryptic);
327  }
332  void setText(const char *str, size_t len, bool cryptic);
333 
337  void clear();
338 private:
339  bool _cryptic;
340  unsigned char *_encrypted;
341  int _encryptedBufferSize;
342  int _encryptedBytes;
343  IKeyProvider *_keyProvider;
344  unsigned char _iv[MCR_AES_IV_SIZE];
345  size_t _lenMem;
346  char *_plain;
347  size_t _plainBufferSize;
348  bool _stateless;
349  unsigned char _tag[MCR_AES_TAG_SIZE];
350 };
351 }
352 
353 #endif
const unsigned char * iv() const
Definition: safe_string.h:258
void setText(const String &str, bool cryptic)
Definition: safe_string.h:324
String text() const
Definition: safe_string.h:292
static void generateKey(unsigned char keyOut[32])
Definition: safe_string.h:218
IKeyProvider * keyProvider() const
Definition: safe_string.h:248
#define MCR_DECL_INTERFACE(className)
Definition: defines.h:434
#define MCR_AES_IV_SIZE
Definition: safe_string.h:35
#define MCR_AES_BLOCK_SIZE
Definition: safe_string.h:33
size_t length() const
Definition: safe_string.h:287
void resize(size_t val)
static void sha(const String &text, unsigned char bufferOut[32])
Definition: safe_string.h:191
Libmacro, by Jonathan Pelletier, New Paradigm Software. Alpha version.
Definition: classes.h:31
static int encrypt(const String &plainText, const unsigned char key[32], const unsigned char iv[16], unsigned char tagOut[16], unsigned char *bufferOut)
Definition: safe_string.h:122
static void initializer(unsigned char ivOut[16])
Definition: safe_string.h:226
void setText(const String &str=String())
Definition: safe_string.h:311
static String decrypt(const unsigned char *encrypted, int encryptedLength, const unsigned char key[32], const unsigned char iv[16], const unsigned char tag[])
Definition: safe_string.h:151
SafeString(IKeyProvider *keyProvider=nullptr, const String &str=String(), bool cryptic=true)
Definition: safe_string.h:73
bool stateless() const
Definition: safe_string.h:276
void setLength(size_t val)
#define MCR_AES_TAG_SIZE
Definition: safe_string.h:37
bool cryptic() const
Definition: safe_string.h:236