UCommon
secure.h
Go to the documentation of this file.
1 // Copyright (C) 2010-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
42 #ifndef _UCOMMON_SECURE_H_
43 #define _UCOMMON_SECURE_H_
44 
45 #ifndef _UCOMMON_CONFIG_H_
46 #include <ucommon/platform.h>
47 #endif
48 
49 #ifndef _UCOMMON_UCOMMON_H_
50 #include <ucommon/ucommon.h>
51 #endif
52 
53 #define MAX_CIPHER_KEYSIZE 512
54 #define MAX_DIGEST_HASHSIZE 512
55 
56 namespace ucommon {
57 
58 namespace Type {
59 
60  class SecChars
61  {
62  public:
63  typedef enum {GENERIC_STRING, B64_STRING, HEX_STRING, MD5_DIGEST, SHA_DIGEST, PEM_PUBLIC, PEM_PRIVATE} strtype_t;
64  };
65 
66  class KeyBytes
67  {
68  public:
69  typedef enum {UNDEFINED_KEYTYPE, IV_BUFFER, UNPAIRED_KEYTYPE, RSA_KEYTYPE, KEY_DIGEST} keytype_t;
70  };
71 
72 }
73 
74 template <>
75 class __SHARED typeref<Type::SecChars> : protected TypeRef, public Type::SecChars
76 {
77 public:
78  class storage : public Counted
79  {
80  private:
81  friend class typeref;
82 
83  strtype_t type;
84  char mem[1];
85 
86  __DELETE_COPY(storage);
87 
88  storage(caddr_t addr, size_t size, const char *str, strtype_t strtype = GENERIC_STRING);
89 
90  virtual void dealloc() __FINAL;
91 
92  inline const char *get() {
93  return &mem[0];
94  }
95 
96  inline size_t len() {
97  return strlen(mem);
98  }
99 
100  inline size_t max() {
101  return size;
102  }
103  };
104 
105  typeref();
106 
107  typeref(const typeref& copy);
108 
109  typeref(const char *str, strtype_t strtype = GENERIC_STRING);
110 
111  const char *operator*() const;
112 
113  inline operator const char *() const {
114  return operator*();
115  }
116 
117  bool operator==(const typeref& ptr) const;
118 
119  bool operator==(const char *obj) const;
120 
121  inline bool operator!=(const typeref& ptr) const {
122  return !(*this == ptr);
123  }
124 
125  inline bool operator!=(const char *obj) const {
126  return !(*this == obj);
127  }
128 
129  typeref& operator=(const typeref& objref);
130 
131  typeref& operator=(const char *str);
132 
133  void set(const char *str, strtype_t strtype = GENERIC_STRING);
134 
135  void b64(const uint8_t *bytes, size_t bsize);
136 
137  void hex(const uint8_t *bytes, size_t bsize);
138 
139  strtype_t type(void) const;
140 
141  size_t size(void) const;
142 
143  size_t len(void) const;
144 };
145 
146 template <>
147 class __SHARED typeref<Type::KeyBytes> : protected TypeRef, public Type::KeyBytes
148 {
149 public:
150  class storage : public Counted
151  {
152  private:
153  friend class typeref;
154 
155  __DELETE_COPY(storage);
156 
157  keytype_t type;
158  uint8_t mem[1];
159 
160  storage(caddr_t addr, size_t size, const uint8_t *key = NULL, keytype_t keytype = UNPAIRED_KEYTYPE);
161 
162  virtual void dealloc() __FINAL;
163 
164  inline const uint8_t *get() {
165  return &mem[0];
166  }
167  };
168 
169  typeref();
170 
171  typeref(const typeref& copy);
172 
173  typeref(size_t keysize, keytype_t keytype = UNPAIRED_KEYTYPE);
174 
175  typeref(const uint8_t *key, size_t keysize, keytype_t keytype = UNPAIRED_KEYTYPE);
176 
177  const uint8_t *operator*() const;
178 
179  inline operator const uint8_t *() const {
180  return operator*();
181  }
182 
183  bool operator==(const typeref& ptr) const;
184 
185  inline bool operator!=(const typeref& ptr) const {
186  return !(*this == ptr);
187  }
188 
189  typeref& operator=(const typeref& objref);
190 
191  void set(const uint8_t *str, size_t keysize, keytype_t keytype = UNPAIRED_KEYTYPE);
192 
193  void generate(size_t keysize, keytype_t keytype = UNPAIRED_KEYTYPE);
194 
195  keytype_t type(void) const;
196 
197  size_t size(void) const;
198 
199  size_t bytes(void) const;
200 };
201 
202 template<>
203 inline size_t mapkeypath<Type::SecChars>(typeref<Type::SecChars>& object)
204 {
205  size_t path = 1;
206  return MapRef::index(path, (const uint8_t *)(*object), object.len());
207 }
208 
209 template<>
210 inline size_t mapkeypath<Type::KeyBytes>(typeref<Type::KeyBytes>& object)
211 {
212  size_t path = object.size();
213  return MapRef::index(path, *object, object.size() / 8);
214 }
215 
221 class __SHARED secure : public Type::SecChars, public Type::KeyBytes
222 {
223 public:
227  typedef enum {OK=0, INVALID, MISSING_CERTIFICATE, MISSING_PRIVATEKEY, INVALID_CERTIFICATE, INVALID_AUTHORITY, INVALID_PEERNAME, INVALID_CIPHER} error_t;
228 
229  typedef typeref<Type::SecChars> string;
230 
231  typedef arrayref<Type::SecChars> strarray;
232 
233  typedef queueref<Type::SecChars> strqueue;
234 
235  typedef typeref<Type::KeyBytes> keybytes;
236 
237  typedef typeref<Type::KeyBytes> keyarray;
238 
239  typedef typeref<Type::KeyBytes> keyqueue;
240 
241 protected:
246 
247  inline secure() {error = OK;}
248 
249 public:
254  virtual ~secure();
255 
259  typedef secure *client_t;
260 
261  typedef secure *server_t;
262 
266  typedef void *session_t;
267 
271  typedef void *bufio_t;
272 
278  static bool init(void);
279 
286  static bool fips(void);
287 
293  static int oscerts(const char *path);
294 
299  static const char *oscerts(void);
300 
310  static error_t verify(session_t session, const char *peername = NULL);
311 
321  static server_t server(const char *keyfile = NULL, const char *authority = NULL);
322 
329  static client_t client(const char *authority = NULL);
330 
337  static client_t user(const char *authority);
338 
344  static void cipher(secure *context, const char *ciphers);
345 
350  inline bool is_valid(void) const
351  {return error == OK;};
352 
357  inline error_t err(void) const
358  {return error;};
359 
364  static void uuid(char *string);
365 
366  static secure::string uuid(void);
367 
368  template <typename T>
369  inline static void erase(T *object)
370  {memset(object, 0, sizeof(T)); delete object;}
371 
372  inline operator bool() const
373  {return is_valid();}
374 
375  inline bool operator!() const
376  {return !is_valid();}
377 
378 };
379 
387 class __SHARED SSLBuffer : public TCPBuffer
388 {
389 private:
390  __DELETE_COPY(SSLBuffer);
391 
392 protected:
393  secure::session_t ssl;
394  secure::bufio_t bio;
395  bool server;
396  bool verify;
397 
398 public:
399  SSLBuffer(secure::client_t context);
400  SSLBuffer(const TCPServer *server, secure::server_t context, size_t size = 536);
401  ~SSLBuffer();
402 
410  void open(const char *host, const char *service, size_t size = 536);
411 
412  void close(void);
413 
414  void release(void);
415 
416  size_t _push(const char *address, size_t size);
417 
418  size_t _pull(char *address, size_t size);
419 
420  bool _flush(void);
421 
422  bool _pending(void);
423 
424  inline bool is_secure(void) const
425  {return bio != NULL;}
426 };
427 
437 class __SHARED Cipher
438 {
439 public:
440  typedef enum {ENCRYPT = 1, DECRYPT = 0} mode_t;
441 
449  class __SHARED Key
450  {
451  protected:
452  friend class Cipher;
453 
454  union {
455  const void *algotype;
456  int algoid;
457  };
458 
459  union {
460  const void *hashtype;
461  int hashid;
462  };
463 
464  int modeid;
465 
466  // assume 512 bit cipher keys possible...
467  unsigned char keybuf[MAX_CIPHER_KEYSIZE / 8], ivbuf[MAX_CIPHER_KEYSIZE / 8];
468 
469  // generated keysize
470  size_t keysize, blksize;
471 
472  Key(const char *ciper);
473 
474  void set(const char *cipher);
475 
476  public:
477  Key();
478 
479  Key(const char *cipher, const char *digest, const char *text, size_t size = 0, const unsigned char *salt = NULL, unsigned rounds = 1);
480 
481  Key(const char *cipher, const uint8_t *iv, size_t ivsize);
482 
483  Key(const char *cipher, secure::keybytes& iv);
484 
485  Key(const char *cipher, const char *digest);
486 
487  ~Key();
488 
489  inline secure::keybytes key() {
490  return secure::keybytes(keybuf, keysize);
491  }
492 
493  inline secure::keybytes iv() {
494  return secure::keybytes(ivbuf, blksize, secure::IV_BUFFER);
495  }
496 
497  void set(const unsigned char *key, size_t size);
498 
499  bool set(const secure::keybytes& key);
500 
501  void set(const char *cipher, const char *digest);
502 
503  void set(const char *cipher, const uint8_t *iv, size_t ivsize);
504 
505  bool set(const char *cipher, const secure::keybytes& iv);
506 
507  void assign(const char *key, size_t size, const unsigned char *salt, unsigned rounds);
508 
509  void assign(const char *key, size_t size = 0);
510 
511  void clear(void);
512 
513  secure::string b64(void);
514 
515  void b64(const char *string);
516 
517  size_t get(uint8_t *key, uint8_t *ivout = NULL);
518 
519  inline size_t size(void) const
520  {return keysize;}
521 
522  inline size_t iosize(void) const
523  {return blksize;}
524 
525  inline operator bool() const
526  {return keysize > 0;}
527 
528  inline bool operator!() const
529  {return keysize == 0;}
530 
531  inline Key& operator=(const char *pass)
532  {assign(pass); return *this;}
533 
534  static void options(const unsigned char *salt = NULL, unsigned rounds = 1);
535  };
536 
537  typedef Key *key_t;
538 
539 private:
540  Key keys;
541  size_t bufsize, bufpos;
542  mode_t bufmode;
543  unsigned char *bufaddr;
544  void *context;
545 
546 protected:
547  virtual void push(unsigned char *address, size_t size);
548 
549  void release(void);
550 
551 public:
552  Cipher();
553 
554  Cipher(key_t key, mode_t mode, unsigned char *address = NULL, size_t size = 0);
555 
556  virtual ~Cipher();
557 
558  void set(unsigned char *address, size_t size = 0);
559 
560  void set(key_t key, mode_t mode, unsigned char *address, size_t size = 0);
561 
562  inline secure::keybytes iv() {
563  return keys.iv();
564  }
565 
566  inline secure::keybytes key() {
567  return keys.key();
568  }
569 
574  size_t flush(void);
575 
584  size_t put(const unsigned char *data, size_t size);
585 
592  size_t puts(const char *string);
593 
605  size_t pad(const unsigned char *address, size_t size);
606 
615  size_t process(unsigned char *address, size_t size, bool flag = false);
616 
617  inline size_t size(void) const
618  {return bufsize;}
619 
620  inline size_t pos(void) const
621  {return bufpos;}
622 
623  inline size_t align(void) const
624  {return keys.iosize();}
625 
631  static bool has(const char *name);
632 };
633 
640 class __SHARED Digest
641 {
642 private:
643  void *context;
644 
645  union {
646  const void *hashtype;
647  int hashid;
648  };
649 
650  unsigned bufsize;
651  unsigned char buffer[MAX_DIGEST_HASHSIZE / 8];
652  char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1];
653 
654 protected:
655  void release(void);
656 
657 public:
658  Digest(const char *type);
659 
660  Digest();
661 
662  ~Digest();
663 
664  inline bool puts(const char *str)
665  {return put(str, strlen(str));}
666 
667  inline Digest &operator<<(const char *str)
668  {puts(str); return *this;}
669 
670  inline Digest &operator<<(int16_t value)
671  {int16_t v = htons(value); put(&v, 2); return *this;}
672 
673  inline Digest &operator<<(int32_t value)
674  {int32_t v = htonl(value); put(&v, 4); return *this;}
675 
676  inline Digest &operator<<(const PrintProtocol& p)
677  {const char *cp = p._print(); if(cp) puts(cp); return *this;}
678 
679  bool put(const void *memory, size_t size);
680 
681  inline unsigned size() const
682  {return bufsize;}
683 
684  const unsigned char *get(void);
685 
686  const char *c_str(void);
687 
688  inline secure::string str(void)
689  {return secure::string(c_str());}
690 
691  inline operator secure::string()
692  {return secure::string(c_str());}
693 
694  void set(const char *id);
695 
696  inline void operator=(const char *id)
697  {set(id);};
698 
699  inline bool operator *=(const char *text)
700  {return puts(text);}
701 
702  inline bool operator +=(const char *text)
703  {return puts(text);}
704 
705  inline const char *operator*()
706  {return c_str();}
707 
708  inline bool operator!() const
709  {return !bufsize && context == NULL;}
710 
711  inline operator bool() const
712  {return bufsize > 0 || context != NULL;}
713 
719  void recycle(bool binary = false);
720 
724  void reset(void);
725 
731  static bool has(const char *name);
732 
733  static void uuid(char *string, const char *name, const unsigned char *ns = NULL);
734 
735  static secure::string uuid(const char *name, const unsigned char *ns = NULL);
736 
742  static secure::string md5(const char *text);
743 
744  static secure::string sha1(const char *text);
745 
746  static secure::string sha256(const char *text);
747 
748  static secure::string sha384(const char *text);
749 
750  static secure::keybytes md5(const uint8_t *mem, size_t size);
751 
752  static secure::keybytes sha1(const uint8_t *mem, size_t size);
753 
754  static secure::keybytes sha256(const uint8_t *mem, size_t size);
755 
756  static secure::keybytes sha384(const uint8_t *mem, size_t size);
757 
758 };
759 
766 class __SHARED HMAC
767 {
768 private:
769  void *context;
770 
771  union {
772  const void *hmactype;
773  int hmacid;
774  };
775 
776  unsigned bufsize;
777  unsigned char buffer[MAX_DIGEST_HASHSIZE / 8];
778  char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1];
779 
780 protected:
781  void release(void);
782 
783 public:
784  HMAC(const char *digest, const char *key, size_t keylen = 0);
785 
786  HMAC(const char *digest, const secure::keybytes& key);
787 
788  HMAC();
789 
790  ~HMAC();
791 
792  inline bool puts(const char *str)
793  {return put(str, strlen(str));}
794 
795  inline HMAC &operator<<(const char *str)
796  {puts(str); return *this;}
797 
798  inline HMAC &operator<<(int16_t value)
799  {int16_t v = htons(value); put(&v, 2); return *this;}
800 
801  inline HMAC &operator<<(int32_t value)
802  {int32_t v = htonl(value); put(&v, 4); return *this;}
803 
804  inline HMAC &operator<<(const PrintProtocol& p)
805  {const char *cp = p._print(); if(cp) puts(cp); return *this;}
806 
807  bool put(const void *memory, size_t size);
808 
809  inline unsigned size() const
810  {return bufsize;}
811 
812  const unsigned char *get(void);
813 
814  const char *c_str(void);
815 
816  inline secure::string str(void)
817  {return secure::string(c_str());}
818 
819  inline operator secure::string()
820  {return secure::string(c_str());}
821 
822  void set(const char *digest, const char *key, size_t len);
823 
824  void set(const char *digest, const secure::keybytes& key);
825 
826  inline bool operator *=(const char *text)
827  {return puts(text);}
828 
829  inline bool operator +=(const char *text)
830  {return puts(text);}
831 
832  inline const char *operator*()
833  {return c_str();}
834 
835  inline bool operator!() const
836  {return !bufsize && context == NULL;}
837 
838  inline operator bool() const
839  {return bufsize > 0 || context != NULL;}
840 
846  static bool has(const char *name);
847 
848  static secure::keybytes sha256(secure::keybytes key, const uint8_t *mem, size_t size);
849 
850  static secure::keybytes sha384(secure::keybytes key, const uint8_t *mem, size_t soze);
851 };
852 
853 class __SHARED RSA
854 {
855 private:
856  void *keypair;
857 
858  __DELETE_COPY(RSA);
859 
860 public:
861  RSA(secure::string privkey, secure::string pubkey); // pem
862  RSA(size_t keysize);
863  ~RSA();
864 
865  secure::string pem(secure::strtype_t type);
866 };
867 
873 class __SHARED Random
874 {
875 private:
876  __DELETE_DEFAULTS(Random);
877 
878 public:
885  static bool seed(const unsigned char *buffer, size_t size);
886 
890  static void seed(void);
891 
900  static size_t key(unsigned char *memory, size_t size);
901 
910  static size_t fill(unsigned char *memory, size_t size);
911 
916  static int get(void);
917 
924  static int get(int min, int max);
925 
930  static double real(void);
931 
938  static double real(double min, double max);
939 
945  static bool status(void);
946 
951  static void uuid(char *string);
952 
953  static secure::string uuid(void);
954 
955  template <class T>
956  inline static T value(void) {
957  T tmp;
958  Random::key(reinterpret_cast<unsigned char *>(&tmp), sizeof(tmp));
959  return tmp;
960  }
961 
962  template <class T>
963  inline static T value(T max) {
964  T slice;
965  T value;
966 
967  value = 0xffffffff;
968  slice = 0xffffffff / max;
969  while(value >= max) {
970  value = Random::value<T>() / slice;
971  }
972  return value;
973  }
974 
975  template <class T>
976  inline static T value(T min, T max)
977  {
978  return min + Random::value<T>(max - min);
979  }
980 };
981 
985 typedef SSLBuffer ssl_t;
986 
990 typedef Digest digest_t;
991 
995 typedef HMAC hmac_t;
996 
1001 
1006 
1007 inline void zerofill(void *addr, size_t size)
1008 {
1009  ::memset(addr, 0, size);
1010 }
1011 
1012 #ifndef UCOMMON_SYSRUNTIME
1013 
1022 class __SHARED sstream : public tcpstream
1023 {
1024 private:
1025  __DELETE_COPY(sstream);
1026 
1027 protected:
1028  secure::session_t ssl;
1029  secure::bufio_t bio;
1030  bool server;
1031  bool verify;
1032 
1033 public:
1034  sstream(secure::client_t context);
1035  sstream(const TCPServer *server, secure::server_t context, size_t size = 536);
1036  ~sstream();
1037 
1038  void open(const char *host, const char *service, size_t size = 536);
1039 
1040  void close(void);
1041 
1042  int sync();
1043 
1044  void release(void);
1045 
1046  ssize_t _write(const char *address, size_t size);
1047 
1048  ssize_t _read(char *address, size_t size);
1049 
1050  bool _wait(void);
1051 
1052  inline void flush(void)
1053  {sync();}
1054 
1055  inline bool is_secure(void) const
1056  {return bio != NULL;}
1057 };
1058 
1059 typedef secure::string keystring_t;
1060 
1066 template<size_t S>
1068 {
1069 private:
1070  unsigned char buffer[S];
1071 
1072  __DELETE_COPY(keyrandom);
1073 
1074 public:
1078  inline keyrandom()
1079  {Random::key(buffer, S);}
1080 
1084  inline ~keyrandom()
1085  {memset(buffer, 0, S);}
1086 
1090  inline void update(void)
1091  {Random::key(buffer, S);}
1092 
1096  inline void clear(void)
1097  {memset(buffer, 0, S);}
1098 
1103  inline operator unsigned char *()
1104  {return buffer;}
1105 
1110  inline unsigned char *operator*()
1111  {return buffer;}
1112 
1117  inline size_t size(void) const
1118  {return S;}
1119 };
1120 
1121 #endif
1122 
1123 } // namespace ucommon
1124 
1125 #endif
SSLBuffer ssl_t
Convenience type for secure socket.
Definition: secure.h:985
A generic data ciphering class.
Definition: secure.h:437
void release(SharedAccess &object)
Convenience function to unlock shared object through it's protocol.
Definition: access.h:280
Secure socket using std::iostream.
Definition: secure.h:1022
Cipher::Key skey_t
Convenience type for generic cipher key.
Definition: secure.h:1005
A cryptographic message authentication code class.
Definition: secure.h:766
Various miscellaneous platform specific headers and defines.
Common secure socket support.
Definition: secure.h:221
bool is_valid(void) const
Determine if the current security context is valid.
Definition: secure.h:350
error_t error
Last error flagged for this context.
Definition: secure.h:245
A generic tcp socket class that offers i/o buffering.
Definition: buffer.h:59
Digest digest_t
Convenience type for generic digests.
Definition: secure.h:990
Cipher key formed by hash algorithm.
Definition: secure.h:449
Traditional keypair config file parsing class.
Definition: keydata.h:156
error_t err(void) const
Get last error code associated with the security context.
Definition: secure.h:357
A template to create a random generated key of specified size.
Definition: secure.h:1067
ObjectProtocol * copy(ObjectProtocol *object)
Convenience function to access object copy.
Definition: object.h:510
secure * client_t
Convenience type to represent a security context.
Definition: secure.h:259
Used for forming stream output.
Definition: protocols.h:138
void update(void)
Update with new random key.
Definition: secure.h:1090
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition: platform.h:510
Secure socket buffer.
Definition: secure.h:387
Cryptographically relevant random numbers.
Definition: secure.h:873
static size_t key(unsigned char *memory, size_t size)
Get high-entropy random data.
void * bufio_t
Convenience type to represent a secure socket buf i/o stream.
Definition: secure.h:271
struct sockaddr * addr(Socket::address &address)
A convenience function to convert a socket address list into a socket address.
Definition: socket.h:2015
keyrandom()
Create a new character buffer with an empty string.
Definition: secure.h:1078
A cryptographic digest class.
Definition: secure.h:640
error_t
Different error states of the security context.
Definition: secure.h:227
Streamable tcp connection between client and server.
Definition: stream.h:113
Common namespace for all ucommon objects.
Definition: access.h:47
void * session_t
Convenience type to represent a secure socket session.
Definition: secure.h:266
void clear(void)
Clear current key memory.
Definition: secure.h:1096
virtual const char * _print(void) const =0
Extract formatted string for object.
Cipher cipher_t
Convenience type for generic ciphers.
Definition: secure.h:1000
unsigned char * operator*()
Get text by object pointer reference.
Definition: secure.h:1110
T &() min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition: generics.h:425
Top level include file for the GNU uCommon C++ core library.
HMAC hmac_t
Convenience type for generic digests.
Definition: secure.h:995
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:414
A generic tcp server class.
Definition: socket.h:1861
~keyrandom()
Clear memory when destroyed.
Definition: secure.h:1084
A generic socket address class.
Definition: socket.h:359
size_t size(void) const
Get allocated size of the object.
Definition: secure.h:1117