ucommon
|
00001 // Copyright (C) 2010-2014 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00041 #ifndef _UCOMMON_SECURE_H_ 00042 #define _UCOMMON_SECURE_H_ 00043 00044 #ifndef _UCOMMON_CONFIG_H_ 00045 #include <ucommon/platform.h> 00046 #endif 00047 00048 #ifndef _UCOMMON_UCOMMON_H_ 00049 #include <ucommon/ucommon.h> 00050 #endif 00051 00052 #define MAX_CIPHER_KEYSIZE 512 00053 #define MAX_DIGEST_HASHSIZE 512 00054 00055 namespace ucommon { 00056 00062 class __SHARED secure 00063 { 00064 public: 00068 typedef enum {OK=0, INVALID, MISSING_CERTIFICATE, MISSING_PRIVATEKEY, INVALID_CERTIFICATE, INVALID_AUTHORITY, INVALID_PEERNAME, INVALID_CIPHER} error_t; 00069 00070 protected: 00074 error_t error; 00075 00076 inline secure() {error = OK;} 00077 00078 public: 00083 virtual ~secure(); 00084 00088 typedef secure *client_t; 00089 00090 typedef secure *server_t; 00091 00095 typedef void *session_t; 00096 00100 typedef void *bufio_t; 00101 00107 static bool init(void); 00108 00115 static bool fips(void); 00116 00122 static int oscerts(const char *path); 00123 00128 static const char *oscerts(void); 00129 00139 static error_t verify(session_t session, const char *peername = NULL); 00140 00150 static server_t server(const char *keyfile = NULL, const char *authority = NULL); 00151 00158 static client_t client(const char *authority = NULL); 00159 00166 static client_t user(const char *authority); 00167 00173 static void cipher(secure *context, const char *ciphers); 00174 00179 inline bool is_valid(void) const 00180 {return error == OK;}; 00181 00186 inline error_t err(void) 00187 {return error;}; 00188 00193 static void uuid(char *string); 00194 00195 static String uuid(void); 00196 00197 template <typename T> 00198 inline static void erase(T *object) 00199 {memset(object, 0, sizeof(T)); delete object;} 00200 00201 inline operator bool() 00202 {return is_valid();} 00203 00204 inline bool operator!() 00205 {return !is_valid();} 00206 00207 }; 00208 00216 class __SHARED SSLBuffer : public TCPBuffer 00217 { 00218 protected: 00219 secure::session_t ssl; 00220 secure::bufio_t bio; 00221 bool server; 00222 bool verify; 00223 00224 public: 00225 SSLBuffer(secure::client_t context); 00226 SSLBuffer(const TCPServer *server, secure::server_t context, size_t size = 536); 00227 ~SSLBuffer(); 00228 00236 void open(const char *host, const char *service, size_t size = 536); 00237 00238 void close(void); 00239 00240 void release(void); 00241 00242 size_t _push(const char *address, size_t size); 00243 00244 size_t _pull(char *address, size_t size); 00245 00246 bool _flush(void); 00247 00248 bool _pending(void); 00249 00250 inline bool is_secure(void) 00251 {return bio != NULL;} 00252 }; 00253 00263 class __SHARED Cipher 00264 { 00265 public: 00266 typedef enum {ENCRYPT = 1, DECRYPT = 0} mode_t; 00267 00275 class __SHARED Key 00276 { 00277 protected: 00278 friend class Cipher; 00279 00280 union { 00281 const void *algotype; 00282 int algoid; 00283 }; 00284 00285 union { 00286 const void *hashtype; 00287 int hashid; 00288 }; 00289 00290 int modeid; 00291 00292 // assume 512 bit cipher keys possible... 00293 unsigned char keybuf[MAX_CIPHER_KEYSIZE / 8], ivbuf[MAX_CIPHER_KEYSIZE / 8]; 00294 00295 // generated keysize 00296 size_t keysize, blksize; 00297 00298 Key(const char *cipher); 00299 Key(); 00300 00301 void set(const char *cipher); 00302 00303 void set(const char *cipher, const char *digest); 00304 00305 void assign(const char *key, size_t size, const unsigned char *salt, unsigned rounds); 00306 00307 public: 00308 Key(const char *cipher, const char *digest, const char *text, size_t size = 0, const unsigned char *salt = NULL, unsigned rounds = 1); 00309 00310 Key(const char *cipher, const char *digest); 00311 00312 ~Key(); 00313 00314 void assign(const char *key, size_t size = 0); 00315 00316 void clear(void); 00317 00318 inline size_t size(void) 00319 {return keysize;} 00320 00321 inline size_t iosize(void) 00322 {return blksize;} 00323 00324 inline operator bool() 00325 {return keysize > 0;} 00326 00327 inline bool operator!() 00328 {return keysize == 0;} 00329 00330 inline Key& operator=(const char *pass) 00331 {assign(pass); return *this;} 00332 00333 static void options(const unsigned char *salt = NULL, unsigned rounds = 1); 00334 }; 00335 00336 typedef Key *key_t; 00337 00338 private: 00339 Key keys; 00340 size_t bufsize, bufpos; 00341 mode_t bufmode; 00342 unsigned char *bufaddr; 00343 void *context; 00344 00345 protected: 00346 virtual void push(unsigned char *address, size_t size); 00347 00348 void release(void); 00349 00350 public: 00351 Cipher(); 00352 00353 Cipher(key_t key, mode_t mode, unsigned char *address = NULL, size_t size = 0); 00354 00355 virtual ~Cipher(); 00356 00357 void set(unsigned char *address, size_t size = 0); 00358 00359 void set(key_t key, mode_t mode, unsigned char *address, size_t size = 0); 00360 00365 size_t flush(void); 00366 00375 size_t put(const unsigned char *data, size_t size); 00376 00383 size_t puts(const char *string); 00384 00396 size_t pad(const unsigned char *address, size_t size); 00397 00406 size_t process(unsigned char *address, size_t size, bool flag = false); 00407 00408 inline size_t size(void) 00409 {return bufsize;} 00410 00411 inline size_t pos(void) 00412 {return bufpos;} 00413 00414 inline size_t align(void) 00415 {return keys.iosize();} 00416 00422 static bool has(const char *name); 00423 }; 00424 00431 class __SHARED Digest 00432 { 00433 private: 00434 void *context; 00435 00436 union { 00437 const void *hashtype; 00438 int hashid; 00439 }; 00440 00441 unsigned bufsize; 00442 unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; 00443 char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; 00444 00445 protected: 00446 void release(void); 00447 00448 public: 00449 Digest(const char *type); 00450 00451 Digest(); 00452 00453 ~Digest(); 00454 00455 inline bool puts(const char *str) 00456 {return put(str, strlen(str));} 00457 00458 inline Digest &operator<<(const char *str) 00459 {puts(str); return *this;} 00460 00461 inline Digest &operator<<(int16_t value) 00462 {int16_t v = htons(value); put(&v, 2); return *this;} 00463 00464 inline Digest &operator<<(int32_t value) 00465 {int32_t v = htonl(value); put(&v, 4); return *this;} 00466 00467 inline Digest &operator<<(const PrintProtocol& p) 00468 {const char *cp = p._print(); if(cp) puts(cp); return *this;} 00469 00470 bool put(const void *memory, size_t size); 00471 00472 inline unsigned size() const 00473 {return bufsize;} 00474 00475 const unsigned char *get(void); 00476 00477 const char *c_str(void); 00478 00479 inline String str(void) 00480 {return String(c_str());} 00481 00482 inline operator String() 00483 {return String(c_str());} 00484 00485 void set(const char *id); 00486 00487 inline void operator=(const char *id) 00488 {set(id);}; 00489 00490 inline bool operator *=(const char *text) 00491 {return puts(text);} 00492 00493 inline bool operator +=(const char *text) 00494 {return puts(text);} 00495 00496 inline const char *operator*() 00497 {return c_str();} 00498 00499 inline bool operator!() const 00500 {return !bufsize && context == NULL;} 00501 00502 inline operator bool() const 00503 {return bufsize > 0 || context != NULL;} 00504 00510 void recycle(bool binary = false); 00511 00515 void reset(void); 00516 00522 static bool has(const char *name); 00523 00524 static void uuid(char *string, const char *name, const unsigned char *ns = NULL); 00525 00526 static String uuid(const char *name, const unsigned char *ns = NULL); 00527 }; 00528 00535 class __SHARED HMAC 00536 { 00537 private: 00538 void *context; 00539 00540 union { 00541 const void *hmactype; 00542 int hmacid; 00543 }; 00544 00545 unsigned bufsize; 00546 unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; 00547 char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; 00548 00549 protected: 00550 void release(void); 00551 00552 public: 00553 HMAC(const char *digest, const char *key, size_t keylen = 0); 00554 00555 HMAC(); 00556 00557 ~HMAC(); 00558 00559 inline bool puts(const char *str) 00560 {return put(str, strlen(str));} 00561 00562 inline HMAC &operator<<(const char *str) 00563 {puts(str); return *this;} 00564 00565 inline HMAC &operator<<(int16_t value) 00566 {int16_t v = htons(value); put(&v, 2); return *this;} 00567 00568 inline HMAC &operator<<(int32_t value) 00569 {int32_t v = htonl(value); put(&v, 4); return *this;} 00570 00571 inline HMAC &operator<<(const PrintProtocol& p) 00572 {const char *cp = p._print(); if(cp) puts(cp); return *this;} 00573 00574 bool put(const void *memory, size_t size); 00575 00576 inline unsigned size() const 00577 {return bufsize;} 00578 00579 const unsigned char *get(void); 00580 00581 const char *c_str(void); 00582 00583 inline String str(void) 00584 {return String(c_str());} 00585 00586 inline operator String() 00587 {return String(c_str());} 00588 00589 void set(const char *digest, const char *key, size_t len); 00590 00591 inline bool operator *=(const char *text) 00592 {return puts(text);} 00593 00594 inline bool operator +=(const char *text) 00595 {return puts(text);} 00596 00597 inline const char *operator*() 00598 {return c_str();} 00599 00600 inline bool operator!() const 00601 {return !bufsize && context == NULL;} 00602 00603 inline operator bool() const 00604 {return bufsize > 0 || context != NULL;} 00605 00611 static bool has(const char *name); 00612 }; 00613 00619 class __SHARED Random 00620 { 00621 public: 00628 static bool seed(const unsigned char *buffer, size_t size); 00629 00633 static void seed(void); 00634 00643 static size_t key(unsigned char *memory, size_t size); 00644 00653 static size_t fill(unsigned char *memory, size_t size); 00654 00659 static int get(void); 00660 00667 static int get(int min, int max); 00668 00673 static double real(void); 00674 00681 static double real(double min, double max); 00682 00688 static bool status(void); 00689 00694 static void uuid(char *string); 00695 00696 static String uuid(void); 00697 }; 00698 00702 typedef SSLBuffer ssl_t; 00703 00707 typedef Digest digest_t; 00708 00712 typedef HMAC hmac_t; 00713 00717 typedef Cipher cipher_t; 00718 00722 typedef Cipher::Key skey_t; 00723 00724 inline void zerofill(void *addr, size_t size) 00725 { 00726 ::memset(addr, 0, size); 00727 } 00728 00729 #if defined(OLD_STDCPP) || defined(NEW_STDCPP) 00730 00739 class __SHARED sstream : public tcpstream 00740 { 00741 protected: 00742 secure::session_t ssl; 00743 secure::bufio_t bio; 00744 bool server; 00745 bool verify; 00746 00747 private: 00748 // kill copy constructor 00749 sstream(const sstream&); 00750 00751 public: 00752 sstream(secure::client_t context); 00753 sstream(const TCPServer *server, secure::server_t context, size_t size = 536); 00754 ~sstream(); 00755 00756 void open(const char *host, const char *service, size_t size = 536); 00757 00758 void close(void); 00759 00760 int sync(); 00761 00762 void release(void); 00763 00764 ssize_t _write(const char *address, size_t size); 00765 00766 ssize_t _read(char *address, size_t size); 00767 00768 bool _wait(void); 00769 00770 inline void flush(void) 00771 {sync();} 00772 00773 inline bool is_secure(void) 00774 {return bio != NULL;} 00775 }; 00776 00785 template<size_t S> 00786 class keystring 00787 { 00788 private: 00789 char buffer[S]; 00790 00794 inline keystring(const keystring& copy) {} 00795 00796 public: 00800 inline keystring() 00801 {buffer[0] = 0;} 00802 00808 inline keystring(const char *text) 00809 {String::set(buffer, S, text);} 00810 00814 inline ~keystring() 00815 {memset(buffer, 0, S);} 00816 00820 inline void clear(void) 00821 {memset(buffer, 0, S);} 00822 00827 inline void operator=(const char *text) 00828 {String::set(buffer, S, text);} 00829 00835 inline void operator+=(const char *text) 00836 {String::add(buffer, S, text);} 00837 00842 inline operator bool() const 00843 {return buffer[0];} 00844 00849 inline bool operator!() const 00850 {return buffer[0] == 0;} 00851 00856 inline operator char *() 00857 {return buffer;} 00858 00863 inline char *operator*() 00864 {return buffer;} 00865 00871 inline char& operator[](size_t offset) const 00872 {return buffer[offset];} 00873 00879 inline char *operator()(size_t offset) 00880 {return buffer + offset;} 00881 00886 inline size_t size(void) const 00887 {return S;} 00888 00893 inline size_t len(void) const 00894 {return strlen(buffer);} 00895 }; 00896 00902 template<size_t S> 00903 class keyrandom 00904 { 00905 private: 00906 unsigned char buffer[S]; 00907 00911 inline keyrandom(const keyrandom& copy) {} 00912 00913 public: 00917 inline keyrandom() 00918 {Random::key(buffer, S);} 00919 00923 inline ~keyrandom() 00924 {memset(buffer, 0, S);} 00925 00929 inline void update(void) 00930 {Random::key(buffer, S);} 00931 00935 inline void clear(void) 00936 {memset(buffer, 0, S);} 00937 00942 inline operator unsigned char *() 00943 {return buffer;} 00944 00949 inline unsigned char *operator*() 00950 {return buffer;} 00951 00956 inline size_t size(void) const 00957 {return S;} 00958 }; 00959 00960 00961 #endif 00962 00963 } // namespace ucommon 00964 00965 #endif