UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/secure.h
Go to the documentation of this file.
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