UCommon
ucommon/secure.h
Go to the documentation of this file.
00001 // Copyright (C) 2010 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 __EXPORT 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 
00073     typedef enum {
00074         SYSTEM_CERTIFICATES, SYSTEM_KEYS} path_t;
00075 
00076 protected:
00080     error_t error;
00081 
00082     inline secure() {error = OK;};
00083 
00084 public:
00089     virtual ~secure();
00090 
00094     typedef secure *client_t;
00095 
00096     typedef secure *server_t;
00097 
00101     typedef void *session_t;
00102 
00106     typedef void *bufio_t;
00107 
00115     static bool init(const char *program = NULL);
00116 
00124     static bool fips(const char *program = NULL);
00125 
00132     static String path(path_t id);
00133 
00139     static int oscerts(const char *path);
00140 
00150     static error_t verify(session_t session, const char *peername = NULL);
00151 
00161     static server_t server(const char *authority = NULL);
00162 
00169     static client_t client(const char *authority = NULL);
00170 
00177     static client_t user(const char *authority);
00178 
00184     static void cipher(secure *context, const char *ciphers);
00185 
00190     inline bool is(void)
00191         {return error == OK;};
00192 
00197     inline error_t err(void)
00198         {return error;};
00199 
00204     static void uuid(char *string);
00205 
00206     static String uuid(void);
00207 };
00208 
00216 class __EXPORT 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 __EXPORT Cipher
00264 {
00265 public:
00266     typedef enum {ENCRYPT = 1, DECRYPT = 0} mode_t;
00267 
00275     class __EXPORT 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     ~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 is(const char *name);
00423 };
00424 
00431 class __EXPORT 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     bool put(const void *memory, size_t size);
00459 
00460     inline unsigned size() const
00461         {return bufsize;};
00462 
00463     const unsigned char *get(void);
00464 
00465     const char *c_str(void);
00466 
00467     inline String str(void)
00468         {return String(c_str());};
00469 
00470     inline operator String()
00471         {return String(c_str());};
00472 
00473     void set(const char *id);
00474 
00475     inline void operator=(const char *id)
00476         {set(id);};
00477 
00478     inline bool operator *=(const char *text)
00479         {return puts(text);};
00480 
00481     inline bool operator +=(const char *text)
00482         {return puts(text);};
00483 
00484     inline const char *operator*()
00485         {return c_str();};
00486 
00487     inline bool operator!() const
00488         {return !bufsize && context == NULL;};
00489 
00490     inline operator bool() const
00491         {return bufsize > 0 || context != NULL;};
00492 
00498     void recycle(bool binary = false);
00499 
00503     void reset(void);
00504 
00510     static bool is(const char *name);
00511 
00512     static void uuid(char *string, const char *name, const unsigned char *ns = NULL);
00513 
00514     static String uuid(const char *name, const unsigned char *ns = NULL);
00515 };
00516 
00522 class __EXPORT Random
00523 {
00524 public:
00531     static bool seed(const unsigned char *buffer, size_t size);
00532 
00536     static void seed(void);
00537 
00546     static size_t key(unsigned char *memory, size_t size);
00547 
00556     static size_t fill(unsigned char *memory, size_t size);
00557 
00562     static int get(void);
00563 
00570     static int get(int min, int max);
00571 
00576     static double real(void);
00577 
00584     static double real(double min, double max);
00585 
00591     static bool status(void);
00592 
00597     static void uuid(char *string);
00598 
00599     static String uuid(void);
00600 };
00601 
00605 typedef SSLBuffer ssl_t;
00606 
00610 typedef Digest digest_t;
00611 
00615 typedef Cipher cipher_t;
00616 
00620 typedef Cipher::Key skey_t;
00621 
00622 inline void zerofill(void *addr, size_t size)
00623 {
00624     ::memset(addr, 0, size);
00625 }
00626 
00627 #if defined(OLD_STDCPP) || defined(NEW_STDCPP)
00628 
00637 class __EXPORT sstream : public tcpstream
00638 {
00639 protected:
00640     secure::session_t ssl;
00641     secure::bufio_t bio;
00642     bool server;
00643     bool verify;
00644 
00645 private:
00646     // kill copy constructor
00647     sstream(const sstream&);
00648 
00649 public:
00650     sstream(secure::client_t context);
00651     sstream(const TCPServer *server, secure::server_t context, size_t size = 536);
00652     ~sstream();
00653 
00654     void open(const char *host, const char *service, size_t size = 536);
00655 
00656     void close(void);
00657 
00658     int sync();
00659 
00660     void release(void);
00661 
00662     ssize_t _write(const char *address, size_t size);
00663 
00664     ssize_t _read(char *address, size_t size);
00665 
00666     bool _wait(void);
00667 
00668     inline void flush(void)
00669         {sync();}
00670 
00671     inline bool is_secure(void)
00672         {return bio != NULL;}
00673 };
00674 
00675 #endif
00676 
00677 END_NAMESPACE
00678 
00679 #endif