UCommon
|
00001 // Copyright (C) 2010-2014 David Sugar, Tycho Softworks. 00002 // Copyright (C) 2015 Cherokees of Idaho. 00003 // 00004 // This file is part of GNU uCommon C++. 00005 // 00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License as published 00008 // by the Free Software Foundation, either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // GNU uCommon C++ is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU Lesser General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public License 00017 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00018 00042 #ifndef _UCOMMON_SECURE_H_ 00043 #define _UCOMMON_SECURE_H_ 00044 00045 #ifndef _UCOMMON_CONFIG_H_ 00046 #include <ucommon/platform.h> 00047 #endif 00048 00049 #ifndef _UCOMMON_UCOMMON_H_ 00050 #include <ucommon/ucommon.h> 00051 #endif 00052 00053 #define MAX_CIPHER_KEYSIZE 512 00054 #define MAX_DIGEST_HASHSIZE 512 00055 00056 namespace ucommon { 00057 00063 class __SHARED secure 00064 { 00065 public: 00069 typedef enum {OK=0, INVALID, MISSING_CERTIFICATE, MISSING_PRIVATEKEY, INVALID_CERTIFICATE, INVALID_AUTHORITY, INVALID_PEERNAME, INVALID_CIPHER} error_t; 00070 00071 protected: 00075 error_t error; 00076 00077 inline secure() {error = OK;} 00078 00079 public: 00084 virtual ~secure(); 00085 00089 typedef secure *client_t; 00090 00091 typedef secure *server_t; 00092 00096 typedef void *session_t; 00097 00101 typedef void *bufio_t; 00102 00108 static bool init(void); 00109 00116 static bool fips(void); 00117 00123 static int oscerts(const char *path); 00124 00129 static const char *oscerts(void); 00130 00140 static error_t verify(session_t session, const char *peername = NULL); 00141 00151 static server_t server(const char *keyfile = NULL, const char *authority = NULL); 00152 00159 static client_t client(const char *authority = NULL); 00160 00167 static client_t user(const char *authority); 00168 00174 static void cipher(secure *context, const char *ciphers); 00175 00180 inline bool is_valid(void) const 00181 {return error == OK;}; 00182 00187 inline error_t err(void) const 00188 {return error;}; 00189 00194 static void uuid(char *string); 00195 00196 static String uuid(void); 00197 00198 template <typename T> 00199 inline static void erase(T *object) 00200 {memset(object, 0, sizeof(T)); delete object;} 00201 00202 inline operator bool() const 00203 {return is_valid();} 00204 00205 inline bool operator!() const 00206 {return !is_valid();} 00207 00208 }; 00209 00217 class __SHARED SSLBuffer : public TCPBuffer 00218 { 00219 protected: 00220 secure::session_t ssl; 00221 secure::bufio_t bio; 00222 bool server; 00223 bool verify; 00224 00225 public: 00226 SSLBuffer(secure::client_t context); 00227 SSLBuffer(const TCPServer *server, secure::server_t context, size_t size = 536); 00228 ~SSLBuffer(); 00229 00237 void open(const char *host, const char *service, size_t size = 536); 00238 00239 void close(void); 00240 00241 void release(void); 00242 00243 size_t _push(const char *address, size_t size); 00244 00245 size_t _pull(char *address, size_t size); 00246 00247 bool _flush(void); 00248 00249 bool _pending(void); 00250 00251 inline bool is_secure(void) const 00252 {return bio != NULL;} 00253 }; 00254 00264 class __SHARED Cipher 00265 { 00266 public: 00267 typedef enum {ENCRYPT = 1, DECRYPT = 0} mode_t; 00268 00276 class __SHARED Key 00277 { 00278 protected: 00279 friend class Cipher; 00280 00281 union { 00282 const void *algotype; 00283 int algoid; 00284 }; 00285 00286 union { 00287 const void *hashtype; 00288 int hashid; 00289 }; 00290 00291 int modeid; 00292 00293 // assume 512 bit cipher keys possible... 00294 unsigned char keybuf[MAX_CIPHER_KEYSIZE / 8], ivbuf[MAX_CIPHER_KEYSIZE / 8]; 00295 00296 // generated keysize 00297 size_t keysize, blksize; 00298 00299 Key(const char *ciper); 00300 00301 void set(const char *cipher); 00302 00303 public: 00304 Key(); 00305 00306 Key(const char *cipher, const char *digest, const char *text, size_t size = 0, const unsigned char *salt = NULL, unsigned rounds = 1); 00307 00308 Key(const char *cipher, const uint8_t *iv, size_t ivsize); 00309 00310 Key(const char *cipher, const char *digest); 00311 00312 ~Key(); 00313 00314 void set(const unsigned char *key, size_t size); 00315 00316 void set(const char *cipher, const char *digest); 00317 00318 void set(const char *cipher, const uint8_t *iv, size_t ivsize); 00319 00320 void assign(const char *key, size_t size, const unsigned char *salt, unsigned rounds); 00321 00322 void assign(const char *key, size_t size = 0); 00323 00324 void clear(void); 00325 00326 String b64(void); 00327 00328 void b64(const char *string); 00329 00330 size_t get(uint8_t *key, uint8_t *ivout = NULL); 00331 00332 inline size_t size(void) const 00333 {return keysize;} 00334 00335 inline size_t iosize(void) const 00336 {return blksize;} 00337 00338 inline operator bool() const 00339 {return keysize > 0;} 00340 00341 inline bool operator!() const 00342 {return keysize == 0;} 00343 00344 inline Key& operator=(const char *pass) 00345 {assign(pass); return *this;} 00346 00347 static void options(const unsigned char *salt = NULL, unsigned rounds = 1); 00348 }; 00349 00350 typedef Key *key_t; 00351 00352 private: 00353 Key keys; 00354 size_t bufsize, bufpos; 00355 mode_t bufmode; 00356 unsigned char *bufaddr; 00357 void *context; 00358 00359 protected: 00360 virtual void push(unsigned char *address, size_t size); 00361 00362 void release(void); 00363 00364 public: 00365 Cipher(); 00366 00367 Cipher(key_t key, mode_t mode, unsigned char *address = NULL, size_t size = 0); 00368 00369 virtual ~Cipher(); 00370 00371 void set(unsigned char *address, size_t size = 0); 00372 00373 void set(key_t key, mode_t mode, unsigned char *address, size_t size = 0); 00374 00379 size_t flush(void); 00380 00389 size_t put(const unsigned char *data, size_t size); 00390 00397 size_t puts(const char *string); 00398 00410 size_t pad(const unsigned char *address, size_t size); 00411 00420 size_t process(unsigned char *address, size_t size, bool flag = false); 00421 00422 inline size_t size(void) const 00423 {return bufsize;} 00424 00425 inline size_t pos(void) const 00426 {return bufpos;} 00427 00428 inline size_t align(void) const 00429 {return keys.iosize();} 00430 00436 static bool has(const char *name); 00437 }; 00438 00445 class __SHARED Digest 00446 { 00447 private: 00448 void *context; 00449 00450 union { 00451 const void *hashtype; 00452 int hashid; 00453 }; 00454 00455 unsigned bufsize; 00456 unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; 00457 char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; 00458 00459 protected: 00460 void release(void); 00461 00462 public: 00463 Digest(const char *type); 00464 00465 Digest(); 00466 00467 ~Digest(); 00468 00469 inline bool puts(const char *str) 00470 {return put(str, strlen(str));} 00471 00472 inline Digest &operator<<(const char *str) 00473 {puts(str); return *this;} 00474 00475 inline Digest &operator<<(int16_t value) 00476 {int16_t v = htons(value); put(&v, 2); return *this;} 00477 00478 inline Digest &operator<<(int32_t value) 00479 {int32_t v = htonl(value); put(&v, 4); return *this;} 00480 00481 inline Digest &operator<<(const PrintProtocol& p) 00482 {const char *cp = p._print(); if(cp) puts(cp); return *this;} 00483 00484 bool put(const void *memory, size_t size); 00485 00486 inline unsigned size() const 00487 {return bufsize;} 00488 00489 const unsigned char *get(void); 00490 00491 const char *c_str(void); 00492 00493 inline String str(void) 00494 {return String(c_str());} 00495 00496 inline operator String() 00497 {return String(c_str());} 00498 00499 void set(const char *id); 00500 00501 inline void operator=(const char *id) 00502 {set(id);}; 00503 00504 inline bool operator *=(const char *text) 00505 {return puts(text);} 00506 00507 inline bool operator +=(const char *text) 00508 {return puts(text);} 00509 00510 inline const char *operator*() 00511 {return c_str();} 00512 00513 inline bool operator!() const 00514 {return !bufsize && context == NULL;} 00515 00516 inline operator bool() const 00517 {return bufsize > 0 || context != NULL;} 00518 00524 void recycle(bool binary = false); 00525 00529 void reset(void); 00530 00536 static bool has(const char *name); 00537 00538 static void uuid(char *string, const char *name, const unsigned char *ns = NULL); 00539 00540 static String uuid(const char *name, const unsigned char *ns = NULL); 00541 00547 static String md5(const char *text); 00548 00549 static String sha1(const char *text); 00550 00551 static String sha256(const char *text); 00552 }; 00553 00560 class __SHARED HMAC 00561 { 00562 private: 00563 void *context; 00564 00565 union { 00566 const void *hmactype; 00567 int hmacid; 00568 }; 00569 00570 unsigned bufsize; 00571 unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; 00572 char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; 00573 00574 protected: 00575 void release(void); 00576 00577 public: 00578 HMAC(const char *digest, const char *key, size_t keylen = 0); 00579 00580 HMAC(); 00581 00582 ~HMAC(); 00583 00584 inline bool puts(const char *str) 00585 {return put(str, strlen(str));} 00586 00587 inline HMAC &operator<<(const char *str) 00588 {puts(str); return *this;} 00589 00590 inline HMAC &operator<<(int16_t value) 00591 {int16_t v = htons(value); put(&v, 2); return *this;} 00592 00593 inline HMAC &operator<<(int32_t value) 00594 {int32_t v = htonl(value); put(&v, 4); return *this;} 00595 00596 inline HMAC &operator<<(const PrintProtocol& p) 00597 {const char *cp = p._print(); if(cp) puts(cp); return *this;} 00598 00599 bool put(const void *memory, size_t size); 00600 00601 inline unsigned size() const 00602 {return bufsize;} 00603 00604 const unsigned char *get(void); 00605 00606 const char *c_str(void); 00607 00608 inline String str(void) 00609 {return String(c_str());} 00610 00611 inline operator String() 00612 {return String(c_str());} 00613 00614 void set(const char *digest, const char *key, size_t len); 00615 00616 inline bool operator *=(const char *text) 00617 {return puts(text);} 00618 00619 inline bool operator +=(const char *text) 00620 {return puts(text);} 00621 00622 inline const char *operator*() 00623 {return c_str();} 00624 00625 inline bool operator!() const 00626 {return !bufsize && context == NULL;} 00627 00628 inline operator bool() const 00629 {return bufsize > 0 || context != NULL;} 00630 00636 static bool has(const char *name); 00637 }; 00638 00644 class __SHARED Random 00645 { 00646 public: 00653 static bool seed(const unsigned char *buffer, size_t size); 00654 00658 static void seed(void); 00659 00668 static size_t key(unsigned char *memory, size_t size); 00669 00678 static size_t fill(unsigned char *memory, size_t size); 00679 00684 static int get(void); 00685 00692 static int get(int min, int max); 00693 00698 static double real(void); 00699 00706 static double real(double min, double max); 00707 00713 static bool status(void); 00714 00719 static void uuid(char *string); 00720 00721 static String uuid(void); 00722 }; 00723 00727 typedef SSLBuffer ssl_t; 00728 00732 typedef Digest digest_t; 00733 00737 typedef HMAC hmac_t; 00738 00742 typedef Cipher cipher_t; 00743 00747 typedef Cipher::Key skey_t; 00748 00749 inline void zerofill(void *addr, size_t size) 00750 { 00751 ::memset(addr, 0, size); 00752 } 00753 00754 #ifndef UCOMMON_SYSRUNTIME 00755 00764 class __SHARED sstream : public tcpstream 00765 { 00766 protected: 00767 secure::session_t ssl; 00768 secure::bufio_t bio; 00769 bool server; 00770 bool verify; 00771 00772 private: 00773 // kill copy constructor 00774 sstream(const sstream&); 00775 00776 public: 00777 sstream(secure::client_t context); 00778 sstream(const TCPServer *server, secure::server_t context, size_t size = 536); 00779 ~sstream(); 00780 00781 void open(const char *host, const char *service, size_t size = 536); 00782 00783 void close(void); 00784 00785 int sync(); 00786 00787 void release(void); 00788 00789 ssize_t _write(const char *address, size_t size); 00790 00791 ssize_t _read(char *address, size_t size); 00792 00793 bool _wait(void); 00794 00795 inline void flush(void) 00796 {sync();} 00797 00798 inline bool is_secure(void) const 00799 {return bio != NULL;} 00800 }; 00801 00810 template<size_t S> 00811 class keystring 00812 { 00813 private: 00814 char buffer[S]; 00815 00819 inline keystring(const keystring& copy) {} 00820 00821 public: 00825 inline keystring() 00826 {buffer[0] = 0;} 00827 00833 inline keystring(const char *text) 00834 {String::set(buffer, S, text);} 00835 00839 inline ~keystring() 00840 {memset(buffer, 0, S);} 00841 00845 inline void clear(void) 00846 {memset(buffer, 0, S);} 00847 00852 inline void operator=(const char *text) 00853 {String::set(buffer, S, text);} 00854 00860 inline void operator+=(const char *text) 00861 {String::add(buffer, S, text);} 00862 00867 inline operator bool() const 00868 {return buffer[0];} 00869 00874 inline bool operator!() const 00875 {return buffer[0] == 0;} 00876 00881 inline operator char *() 00882 {return buffer;} 00883 00888 inline char *operator*() 00889 {return buffer;} 00890 00896 inline char& operator[](size_t offset) const 00897 {return buffer[offset];} 00898 00904 inline char *operator()(size_t offset) 00905 {return buffer + offset;} 00906 00911 inline size_t size(void) const 00912 {return S;} 00913 00918 inline size_t len(void) const 00919 {return strlen(buffer);} 00920 }; 00921 00927 template<size_t S> 00928 class keyrandom 00929 { 00930 private: 00931 unsigned char buffer[S]; 00932 00936 inline keyrandom(const keyrandom& copy) {} 00937 00938 public: 00942 inline keyrandom() 00943 {Random::key(buffer, S);} 00944 00948 inline ~keyrandom() 00949 {memset(buffer, 0, S);} 00950 00954 inline void update(void) 00955 {Random::key(buffer, S);} 00956 00960 inline void clear(void) 00961 {memset(buffer, 0, S);} 00962 00967 inline operator unsigned char *() 00968 {return buffer;} 00969 00974 inline unsigned char *operator*() 00975 {return buffer;} 00976 00981 inline size_t size(void) const 00982 {return S;} 00983 }; 00984 00985 00986 #endif 00987 00988 } // namespace ucommon 00989 00990 #endif