| // Copyright (C) 2010 David Sugar, Tycho Softworks. |
| // |
| // This file is part of GNU uCommon C++. |
| // |
| // GNU uCommon C++ is free software: you can redistribute it and/or modify |
| // it under the terms of the GNU Lesser General Public License as published |
| // by the Free Software Foundation, either version 3 of the License, or |
| // (at your option) any later version. |
| // |
| // GNU uCommon C++ is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU Lesser General Public License for more details. |
| // |
| // You should have received a copy of the GNU Lesser General Public License |
| // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. |
| |
| /** |
| * This library holds basic cryptographic functions and secure socket support |
| * for use with GNU uCommon C++. This library might be used in conjunction |
| * with openssl, gnutls, etc. If no secure socket library is available, then |
| * a stub library may be used with very basic cryptographic support. |
| * @file ucommon/secure.h |
| */ |
| |
| /** |
| * Example of SSL socket code. |
| * @example ssl.cpp |
| */ |
| |
| /** |
| * Example of cryptographic digest code. |
| * @example digest.cpp |
| */ |
| |
| /** |
| * Example of cipher code. |
| * @example cipher.cpp |
| */ |
| |
| #ifndef _UCOMMON_SECURE_H_ |
| #define _UCOMMON_SECURE_H_ |
| |
| #ifndef _UCOMMON_CONFIG_H_ |
| #include <ucommon/platform.h> |
| #endif |
| |
| #ifndef _UCOMMON_UCOMMON_H_ |
| #include <ucommon/ucommon.h> |
| #endif |
| |
| #define MAX_CIPHER_KEYSIZE 512 |
| #define MAX_DIGEST_HASHSIZE 512 |
| |
| NAMESPACE_UCOMMON |
| |
| /** |
| * Common secure socket support. This offers common routines needed for |
| * secure/ssl socket support code. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED secure |
| { |
| public: |
| /** |
| * Different error states of the security context. |
| */ |
| typedef enum {OK=0, INVALID, MISSING_CERTIFICATE, MISSING_PRIVATEKEY, INVALID_CERTIFICATE, INVALID_AUTHORITY, INVALID_PEERNAME, INVALID_CIPHER} error_t; |
| |
| protected: |
| /** |
| * Last error flagged for this context. |
| */ |
| error_t error; |
| |
| inline secure() {error = OK;}; |
| |
| public: |
| /** |
| * This is derived in different back-end libraries, and will be used to |
| * clear certificate credentials. |
| */ |
| virtual ~secure(); |
| |
| /** |
| * Convenience type to represent a security context. |
| */ |
| typedef secure *client_t; |
| |
| typedef secure *server_t; |
| |
| /** |
| * Convenience type to represent a secure socket session. |
| */ |
| typedef void *session_t; |
| |
| /** |
| * Convenience type to represent a secure socket buf i/o stream. |
| */ |
| typedef void *bufio_t; |
| |
| /** |
| * Initialize secure stack for first use, and report if SSL support is |
| * compiled in. |
| * @return true if ssl support is available, false if not. |
| */ |
| static bool init(void); |
| |
| /** |
| * Initialize secure stack with fips support. If fips support is not |
| * successfully enabled, the secure stack is also not initialized. Hence |
| * init() can be used for non-fips certified operation if fips fails. |
| * @return true if fips support enabled and stack initialized. |
| */ |
| static bool fips(void); |
| |
| /** |
| * Copy system certificates to a local path. |
| * @param path to copy to. |
| * @return 0 or error number on failure. |
| */ |
| static int oscerts(const char *path); |
| |
| /** |
| * Get path to system certificates. |
| * @return path to system certificates. |
| */ |
| static const char *oscerts(void); |
| |
| /** |
| * Verify a certificate chain through your certificate authority. |
| * This uses the ca loaded as an optional argument for client and |
| * server. Optionally the hostname of the connection can also be |
| * verified by pulling the peer certificate. |
| * @param session that is connected. |
| * @param peername that we expect. |
| * @return secure error level or secure::OK if none. |
| */ |
| static error_t verify(session_t session, const char *peername = NULL); |
| |
| /** |
| * Create a sever context. The certificate file used will be based on |
| * the init() method name. This may often be /etc/ssl/certs/initname.pem. |
| * Similarly, a matching private key certificate will also be loaded. An |
| * optional certificate authority document can be used when we are |
| * establishing a service which ssl clients have their own certificates. |
| * @param authority path to use or NULL if none. |
| * @return a security context that is cast from derived library. |
| */ |
| static server_t server(const char *keyfile = NULL, const char *authority = NULL); |
| |
| /** |
| * Create an anonymous client context with an optional authority to |
| * validate. |
| * @param authority path to use or NULL if none. |
| * @return a basic client security context. |
| */ |
| static client_t client(const char *authority = NULL); |
| |
| /** |
| * Create a peer user client context. This assumes a user certificate |
| * in ~/.ssl/certs and the user private key in ~/.ssl/private. The |
| * path to an authority is also sent. |
| * @param authority path to use. |
| */ |
| static client_t user(const char *authority); |
| |
| /** |
| * Assign a non-default cipher to the context. |
| * @param context to set cipher for. |
| * @param ciphers to set. |
| */ |
| static void cipher(secure *context, const char *ciphers); |
| |
| /** |
| * Determine if the current security context is valid. |
| * @return true if valid, -1 if not. |
| */ |
| inline bool is_valid(void) const |
| {return error == OK;}; |
| |
| /** |
| * Get last error code associated with the security context. |
| * @return last error code or 0/OK if none. |
| */ |
| inline error_t err(void) |
| {return error;}; |
| |
| /** |
| * Create 36 character traditional version 1 uuid. |
| * @param string to write uuid into, must be 37 bytes or more. |
| */ |
| static void uuid(char *string); |
| |
| static String uuid(void); |
| |
| template <typename T> |
| inline static void erase(T *object) |
| {memset(object, 0, sizeof(object)); delete object;} |
| |
| inline operator bool() |
| {return is_valid();} |
| |
| inline bool operator!() |
| {return !is_valid();} |
| |
| }; |
| |
| /** |
| * Secure socket buffer. This is used to create ssl socket connections |
| * for both clients and servers. The use depends in part on the type of |
| * context created and passed at construction time. If no context is |
| * passed (NULL), then this reverts to TCPBuffer behavior. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED SSLBuffer : public TCPBuffer |
| { |
| protected: |
| secure::session_t ssl; |
| secure::bufio_t bio; |
| bool server; |
| bool verify; |
| |
| public: |
| SSLBuffer(secure::client_t context); |
| SSLBuffer(const TCPServer *server, secure::server_t context, size_t size = 536); |
| ~SSLBuffer(); |
| |
| /** |
| * Connect a ssl client session to a specific host uri. If the socket |
| * was already connected, it is automatically closed first. |
| * @param host we are connecting to. |
| * @param service to connect to. |
| * @param size of buffer and tcp fragments. |
| */ |
| void open(const char *host, const char *service, size_t size = 536); |
| |
| void close(void); |
| |
| void release(void); |
| |
| size_t _push(const char *address, size_t size); |
| |
| size_t _pull(char *address, size_t size); |
| |
| bool _flush(void); |
| |
| bool _pending(void); |
| |
| inline bool is_secure(void) |
| {return bio != NULL;}; |
| }; |
| |
| /** |
| * A generic data ciphering class. This is used to construct cryptographic |
| * ciphers to encode and decode data as needed. The cipher type is specified |
| * by the key object. This class can be used to send output streaming to |
| * memory or in a fixed size buffer. If the latter is used, a push() method |
| * is called through a virtual when the buffer is full. Since block ciphers |
| * are used, buffers should be aligned to the block size. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED Cipher |
| { |
| public: |
| typedef enum {ENCRYPT = 1, DECRYPT = 0} mode_t; |
| |
| /** |
| * Cipher key formed by hash algorithm. This can generate both a |
| * key and iv table based on the algorithms used and required. Normally |
| * it is used from a pass-phrase, though any block of data may be |
| * supplied. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED Key |
| { |
| protected: |
| friend class Cipher; |
| |
| union { |
| const void *algotype; |
| int algoid; |
| }; |
| |
| union { |
| const void *hashtype; |
| int hashid; |
| }; |
| |
| int modeid; |
| |
| // assume 512 bit cipher keys possible... |
| unsigned char keybuf[MAX_CIPHER_KEYSIZE / 8], ivbuf[MAX_CIPHER_KEYSIZE / 8]; |
| |
| // generated keysize |
| size_t keysize, blksize; |
| |
| Key(const char *cipher); |
| Key(); |
| |
| void set(const char *cipher); |
| |
| void set(const char *cipher, const char *digest); |
| |
| void assign(const char *key, size_t size, const unsigned char *salt, unsigned rounds); |
| |
| public: |
| Key(const char *cipher, const char *digest, const char *text, size_t size = 0, const unsigned char *salt = NULL, unsigned rounds = 1); |
| |
| Key(const char *cipher, const char *digest); |
| |
| ~Key(); |
| |
| void assign(const char *key, size_t size = 0); |
| |
| void clear(void); |
| |
| inline size_t size(void) |
| {return keysize;}; |
| |
| inline size_t iosize(void) |
| {return blksize;}; |
| |
| inline operator bool() |
| {return keysize > 0;}; |
| |
| inline bool operator!() |
| {return keysize == 0;}; |
| |
| inline Key& operator=(const char *pass) |
| {assign(pass); return *this;}; |
| |
| static void options(const unsigned char *salt = NULL, unsigned rounds = 1); |
| }; |
| |
| typedef Key *key_t; |
| |
| private: |
| Key keys; |
| size_t bufsize, bufpos; |
| mode_t bufmode; |
| unsigned char *bufaddr; |
| void *context; |
| |
| protected: |
| virtual void push(unsigned char *address, size_t size); |
| |
| void release(void); |
| |
| public: |
| Cipher(); |
| |
| Cipher(key_t key, mode_t mode, unsigned char *address = NULL, size_t size = 0); |
| |
| virtual ~Cipher(); |
| |
| void set(unsigned char *address, size_t size = 0); |
| |
| void set(key_t key, mode_t mode, unsigned char *address, size_t size = 0); |
| |
| /** |
| * Push a final cipher block. This is used to push the final buffer into |
| * the push method for any remaining data. |
| */ |
| size_t flush(void); |
| |
| /** |
| * Process cipher data. This requires the size to be a multiple of the |
| * cipher block size. If an unaligned sized block of data is used, it |
| * will be ignored and the size returned will be 0. |
| * @param data to process. |
| * @param size of data to process. |
| * @return size of processed output, should be same as size or 0 if error. |
| */ |
| size_t put(const unsigned char *data, size_t size); |
| |
| /** |
| * This essentially encrypts a single string and pads with NULL bytes |
| * as needed. |
| * @param string to encrypt. |
| * @return total encrypted size. |
| */ |
| size_t puts(const char *string); |
| |
| /** |
| * This is used to process any data unaligned to the blocksize at the end |
| * of a cipher session. On an encryption, it will add padding or an |
| * entire padding block with the number of bytes to strip. On decryption |
| * it will remove padding at the end. The pkcs5 method of padding with |
| * removal count is used. This also sets the address buffer to NULL |
| * to prevent further puts until reset. |
| * @param address of data to add before final pad. |
| * @param size of data to add before final pad. |
| * @return actual bytes encrypted or decrypted. |
| */ |
| size_t pad(const unsigned char *address, size_t size); |
| |
| /** |
| * Process encrypted data in-place. This assumes no need to set the |
| * address buffer. |
| * @param address of data to process. |
| * @param size of data to process. |
| * @param flag if to pad data. |
| * @return bytes processed and written back to buffer. |
| */ |
| size_t process(unsigned char *address, size_t size, bool flag = false); |
| |
| inline size_t size(void) |
| {return bufsize;}; |
| |
| inline size_t pos(void) |
| {return bufpos;}; |
| |
| inline size_t align(void) |
| {return keys.iosize();}; |
| |
| /** |
| * Check if a specific cipher is supported. |
| * @param name of cipher to check. |
| * @return true if supported, false if not. |
| */ |
| static bool has(const char *name); |
| }; |
| |
| /** |
| * A cryptographic digest class. This class can support md5 digests, sha1, |
| * sha256, etc, depending on what the underlying library supports. The |
| * hash class accumulates the hash in the object. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED Digest |
| { |
| private: |
| void *context; |
| |
| union { |
| const void *hashtype; |
| int hashid; |
| }; |
| |
| unsigned bufsize; |
| unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; |
| char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; |
| |
| protected: |
| void release(void); |
| |
| public: |
| Digest(const char *type); |
| |
| Digest(); |
| |
| ~Digest(); |
| |
| inline bool puts(const char *str) |
| {return put(str, strlen(str));}; |
| |
| inline Digest &operator<<(const char *str) |
| {puts(str); return *this;} |
| |
| inline Digest &operator<<(int16_t value) |
| {int16_t v = htons(value); put(&v, 2); return *this;} |
| |
| inline Digest &operator<<(int32_t value) |
| {int32_t v = htonl(value); put(&v, 4); return *this;} |
| |
| inline Digest &operator<<(const PrintProtocol& p) |
| {const char *cp = p._print(); if(cp) puts(cp); return *this;} |
| |
| bool put(const void *memory, size_t size); |
| |
| inline unsigned size() const |
| {return bufsize;}; |
| |
| const unsigned char *get(void); |
| |
| const char *c_str(void); |
| |
| inline String str(void) |
| {return String(c_str());}; |
| |
| inline operator String() |
| {return String(c_str());}; |
| |
| void set(const char *id); |
| |
| inline void operator=(const char *id) |
| {set(id);}; |
| |
| inline bool operator *=(const char *text) |
| {return puts(text);}; |
| |
| inline bool operator +=(const char *text) |
| {return puts(text);}; |
| |
| inline const char *operator*() |
| {return c_str();}; |
| |
| inline bool operator!() const |
| {return !bufsize && context == NULL;}; |
| |
| inline operator bool() const |
| {return bufsize > 0 || context != NULL;}; |
| |
| /** |
| * Finalize and recycle current digest to start a new |
| * digest. |
| * @param binary digest used rather than text if true. |
| */ |
| void recycle(bool binary = false); |
| |
| /** |
| * Reset and restart digest object. |
| */ |
| void reset(void); |
| |
| /** |
| * Test to see if a specific digest type is supported. |
| * @param name of digest we want to check. |
| * @return true if supported, false if not. |
| */ |
| static bool has(const char *name); |
| |
| static void uuid(char *string, const char *name, const unsigned char *ns = NULL); |
| |
| static String uuid(const char *name, const unsigned char *ns = NULL); |
| }; |
| |
| /** |
| * A cryptographic message authentication code class. This class can support |
| * md5 digests, sha1, sha256, etc, depending on what the underlying library |
| * supports. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED HMAC |
| { |
| private: |
| void *context; |
| |
| union { |
| const void *hmactype; |
| int hmacid; |
| }; |
| |
| unsigned bufsize; |
| unsigned char buffer[MAX_DIGEST_HASHSIZE / 8]; |
| char textbuf[MAX_DIGEST_HASHSIZE / 8 + 1]; |
| |
| protected: |
| void release(void); |
| |
| public: |
| HMAC(const char *digest, const char *key, size_t keylen = 0); |
| |
| HMAC(); |
| |
| ~HMAC(); |
| |
| inline bool puts(const char *str) |
| {return put(str, strlen(str));}; |
| |
| inline HMAC &operator<<(const char *str) |
| {puts(str); return *this;} |
| |
| inline HMAC &operator<<(int16_t value) |
| {int16_t v = htons(value); put(&v, 2); return *this;} |
| |
| inline HMAC &operator<<(int32_t value) |
| {int32_t v = htonl(value); put(&v, 4); return *this;} |
| |
| inline HMAC &operator<<(const PrintProtocol& p) |
| {const char *cp = p._print(); if(cp) puts(cp); return *this;} |
| |
| bool put(const void *memory, size_t size); |
| |
| inline unsigned size() const |
| {return bufsize;}; |
| |
| const unsigned char *get(void); |
| |
| const char *c_str(void); |
| |
| inline String str(void) |
| {return String(c_str());}; |
| |
| inline operator String() |
| {return String(c_str());}; |
| |
| void set(const char *digest, const char *key, size_t len); |
| |
| inline bool operator *=(const char *text) |
| {return puts(text);}; |
| |
| inline bool operator +=(const char *text) |
| {return puts(text);}; |
| |
| inline const char *operator*() |
| {return c_str();}; |
| |
| inline bool operator!() const |
| {return !bufsize && context == NULL;}; |
| |
| inline operator bool() const |
| {return bufsize > 0 || context != NULL;}; |
| |
| /** |
| * Test to see if a specific digest type is supported. |
| * @param name of digest we want to check. |
| * @return true if supported, false if not. |
| */ |
| static bool has(const char *name); |
| }; |
| |
| /** |
| * Cryptographically relevant random numbers. This is used both to gather |
| * entropy pools and pseudo-random values. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED Random |
| { |
| public: |
| /** |
| * Push entropic seed. |
| * @param buffer of random data to push. |
| * @param size of buffer. |
| * @return true if successful. |
| */ |
| static bool seed(const unsigned char *buffer, size_t size); |
| |
| /** |
| * Re-seed pseudo-random generation and entropy pools. |
| */ |
| static void seed(void); |
| |
| /** |
| * Get high-entropy random data. This is often used to |
| * initialize keys. This operation may block if there is |
| * insufficient entropy immediately available. |
| * @param memory buffer to fill. |
| * @param size of buffer. |
| * @return number of bytes filled. |
| */ |
| static size_t key(unsigned char *memory, size_t size); |
| |
| /** |
| * Fill memory with pseudo-random values. This is used |
| * as the basis for all get and real operations and does |
| * not depend on seed entropy. |
| * @param memory buffer to fill. |
| * @param size of buffer to fill. |
| * @return number of bytes set. |
| */ |
| static size_t fill(unsigned char *memory, size_t size); |
| |
| /** |
| * Get a pseudo-random integer, range 0 - 32767. |
| * @return random integer. |
| */ |
| static int get(void); |
| |
| /** |
| * Get a pseudo-random integer in a preset range. |
| * @param min value of random integer. |
| * @param max value of random integer. |
| * @return random value from min to max. |
| */ |
| static int get(int min, int max); |
| |
| /** |
| * Get a pseudo-random floating point value. |
| * @return psudo-random value 0 to 1. |
| */ |
| static double real(void); |
| |
| /** |
| * Get a pseudo-random floating point value in a preset range. |
| * @param min value of random floating point number. |
| * @param max value of random floating point number. |
| * @return random value from min to max. |
| */ |
| static double real(double min, double max); |
| |
| /** |
| * Determine if we have sufficient entropy to return random |
| * values. |
| * @return true if sufficient entropy. |
| */ |
| static bool status(void); |
| |
| /** |
| * Create 36 character random uuid string. |
| * @param string to write uuid into, must be 37 bytes or more. |
| */ |
| static void uuid(char *string); |
| |
| static String uuid(void); |
| }; |
| |
| /** |
| * Convenience type for secure socket. |
| */ |
| typedef SSLBuffer ssl_t; |
| |
| /** |
| * Convenience type for generic digests. |
| */ |
| typedef Digest digest_t; |
| |
| /** |
| * Convenience type for generic digests. |
| */ |
| typedef HMAC hmac_t; |
| |
| /** |
| * Convenience type for generic ciphers. |
| */ |
| typedef Cipher cipher_t; |
| |
| /** |
| * Convenience type for generic cipher key. |
| */ |
| typedef Cipher::Key skey_t; |
| |
| inline void zerofill(void *addr, size_t size) |
| { |
| ::memset(addr, 0, size); |
| } |
| |
| #if defined(OLD_STDCPP) || defined(NEW_STDCPP) |
| |
| /** |
| * Secure socket using std::iostream. This class is similar to SSLBuffer |
| * but uses the libstdc++ library to stream i/o. Being based on tcpstream, |
| * it also inherits the character protocol. Like SSLBuffer, if no context |
| * is given or the handshake fails, then the stream defaults to insecure TCP |
| * connection behavior. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| class __SHARED sstream : public tcpstream |
| { |
| protected: |
| secure::session_t ssl; |
| secure::bufio_t bio; |
| bool server; |
| bool verify; |
| |
| private: |
| // kill copy constructor |
| sstream(const sstream&); |
| |
| public: |
| sstream(secure::client_t context); |
| sstream(const TCPServer *server, secure::server_t context, size_t size = 536); |
| ~sstream(); |
| |
| void open(const char *host, const char *service, size_t size = 536); |
| |
| void close(void); |
| |
| int sync(); |
| |
| void release(void); |
| |
| ssize_t _write(const char *address, size_t size); |
| |
| ssize_t _read(char *address, size_t size); |
| |
| bool _wait(void); |
| |
| inline void flush(void) |
| {sync();} |
| |
| inline bool is_secure(void) |
| {return bio != NULL;} |
| }; |
| |
| /** |
| * A template to create a string array that automatically erases. |
| * This is a mini string/stringbuf class that supports a subset of |
| * functionality but does not require a complex supporting object. Like |
| * stringbuf, this can be used to create local string variables. When |
| * the object falls out of scope it's memory is reset. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| template<size_t S> |
| class keystring |
| { |
| private: |
| char buffer[S]; |
| |
| /** |
| * Disable copy constructor. |
| */ |
| inline keystring(const keystring& copy) {}; |
| |
| public: |
| /** |
| * Create a new character buffer with an empty string. |
| */ |
| inline keystring() |
| {buffer[0] = 0;} |
| |
| /** |
| * Create a character buffer with assigned text. If the text is |
| * larger than the size of the object, it is truncated. |
| * @param text to assign. |
| */ |
| inline keystring(const char *text) |
| {String::set(buffer, S, text);} |
| |
| /** |
| * Clear memory when destroyed. |
| */ |
| inline ~keystring() |
| {memset(buffer, 0, S);} |
| |
| /** |
| * Clear current key memory. |
| */ |
| inline void clear(void) |
| {memset(buffer, 0, S);} |
| |
| /** |
| * Assign null terminated text to the object. |
| * @param text to assign. |
| */ |
| inline void operator=(const char *text) |
| {String::set(buffer, S, text);} |
| |
| /** |
| * Concatenate text into the object. If the text is larger than the |
| * size of the object, then it is truncated. |
| * @param text to append. |
| */ |
| inline void operator+=(const char *text) |
| {String::add(buffer, S, text);} |
| |
| /** |
| * Test if data is contained in the object. |
| * @return true if there is text. |
| */ |
| inline operator bool() const |
| {return buffer[0];} |
| |
| /** |
| * Test if the object is empty. |
| * @return true if the object is empty. |
| */ |
| inline bool operator!() const |
| {return buffer[0] == 0;} |
| |
| /** |
| * Get text by casting reference. |
| * @return pointer to text in object. |
| */ |
| inline operator char *() |
| {return buffer;} |
| |
| /** |
| * Get text by object pointer reference. |
| * @return pointer to text in object. |
| */ |
| inline char *operator*() |
| {return buffer;} |
| |
| /** |
| * Array operator to get a character from the object. |
| * @param offset of character in string buffer. |
| * @return character at offset. |
| */ |
| inline char& operator[](size_t offset) const |
| {return buffer[offset];} |
| |
| /** |
| * Get a pointer to an offset in the object by expression operator. |
| * @param offset of character in string buffer. |
| * @return pointer to offset in object. |
| */ |
| inline char *operator()(size_t offset) |
| {return buffer + offset;} |
| |
| /** |
| * Get allocated size of the object. |
| * @return allocated size. |
| */ |
| inline size_t size(void) const |
| {return S;} |
| |
| /** |
| * Get current length of string. |
| * @return length of string. |
| */ |
| inline size_t len(void) const |
| {return strlen(buffer);} |
| }; |
| |
| /** |
| * A template to create a random generated key of specified size. The |
| * key memory is cleared when the object is destroyed. |
| * @author David Sugar <dyfet@gnutelephony.org> |
| */ |
| template<size_t S> |
| class keyrandom |
| { |
| private: |
| unsigned char buffer[S]; |
| |
| /** |
| * Disable copy constructor. |
| */ |
| inline keyrandom(const keyrandom& copy) {}; |
| |
| public: |
| /** |
| * Create a new character buffer with an empty string. |
| */ |
| inline keyrandom() |
| {Random::key(buffer, S);} |
| |
| /** |
| * Clear memory when destroyed. |
| */ |
| inline ~keyrandom() |
| {memset(buffer, 0, S);} |
| |
| /** |
| * Update with new random key. |
| */ |
| inline void update(void) |
| {Random::key(buffer, S);} |
| |
| /** |
| * Clear current key memory. |
| */ |
| inline void clear(void) |
| {memset(buffer, 0, S);} |
| |
| /** |
| * Get text by casting reference. |
| * @return pointer to text in object. |
| */ |
| inline operator unsigned char *() |
| {return buffer;} |
| |
| /** |
| * Get text by object pointer reference. |
| * @return pointer to text in object. |
| */ |
| inline unsigned char *operator*() |
| {return buffer;} |
| |
| /** |
| * Get allocated size of the object. |
| * @return allocated size. |
| */ |
| inline size_t size(void) const |
| {return S;} |
| }; |
| |
| |
| #endif |
| |
| END_NAMESPACE |
| |
| #endif |