/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #ifndef CPPCMS_CRYPTO_H #define CPPCMS_CRYPTO_H #include #include #include #include #include namespace cppcms { /// /// \brief This namespace holds basic cryptographic utilities useful for save interaction with user. /// /// One of the limitations of these functions is the fact that they do not use so called cryptographic memory, /// however it is not required as all secret keys are stored as plain text in configuration files, /// The only protection that is given is that values of keys are erased when the object is deleted /// to prevent key-leaks due to use of uninitialized memory in user applications. /// /// namespace crypto { /// /// \brief Key object, holds the string that represents the binary key. /// /// When the key is destroyed it zeros all the memory it uses to prevent accidental /// leaks of the highly confidential data /// class CPPCMS_API key { public: /// /// Create an empty key on 0 length /// key(); /// /// Copy the key /// key(key const &other); /// /// Assign the key /// key const &operator=(key const &); /// /// Destroy they key object clearing the area used by it. /// ~key(); /// /// Create a key using binary representation pointed by \a data of \a length bytes /// key(void const *data,size_t length); /// /// Create a key using the hexadecimal representation /// explicit key(char const *s); /// /// Create a key using the hexadecimal representation /// explicit key(std::string const &); /// /// Get the pointer to data, never returns NULL even if size() == 0 /// char const *data() const; /// /// Get the size of the key /// size_t size() const; /// /// Clear the key - and clear the area it was stored it /// void reset(); /// /// Set the binary value for the key /// void set(void const *ptr,size_t len); /// /// Set the value for the key using hexadecimal representation /// void set_hex(char const *ptr,size_t len); /// /// Read the key from file. Under windows file_name should be UTF-8 encoded /// string. /// void read_from_file(std::string const &file_name); private: static unsigned from_hex(char c); char *data_; size_t size_; }; /// /// \brief this class provides an API to calculate various cryptographic hash functions /// class CPPCMS_API message_digest : public booster::noncopyable { protected: /// It should be implemented in derived classes message_digest() { } public: virtual ~message_digest() { } /// /// Get the size of message digest, for example for MD5 it is 16, for SHA1 it is 20 /// virtual unsigned digest_size() const = 0; /// /// Get processing block size, returns 64 or 128, used mostly for correct HMAC calculations /// virtual unsigned block_size() const = 0; /// /// Add more data of size bytes for processing /// virtual void append(void const *ptr,size_t size) = 0; /// /// Read the message digest for the data and reset it into initial state, /// provided buffer must be digest_size() bytes /// virtual void readout(void *ptr) = 0; /// /// Make a polymorphic copy of this object, note the state of copied object is reset to /// initial /// virtual message_digest *clone() const = 0; /// /// Get the name of the hash function /// virtual char const *name() const = 0; /// /// Create MD5 message digest /// static std::auto_ptr md5(); /// /// Create SHA1 message digest /// static std::auto_ptr sha1(); /// /// Create message digest by name, more then sha1 and md5 may be supported, /// if CppCMS is compiled with cryptography library like libgcrypt or openssl /// static std::auto_ptr create_by_name(std::string const &name); }; /// /// \brief This object calculates the HMAC signature for the input data /// class CPPCMS_API hmac : public booster::noncopyable { public: /// /// Create hmac that uses given \a digest algorithm and a binary key - \a key /// hmac(std::auto_ptr digest,key const &k); /// /// Create hmac that uses message digest algorithm called \a name and use a binary key - \a key /// hmac(std::string const &name,key const &k); ~hmac(); /// /// Get the size of the signtature /// unsigned digest_size() const; /// /// Add data for signing /// void append(void const *ptr,size_t size); /// /// Get the signature for all the data, after calling this function /// the state of the hmac is reset and it can be used for signing again /// /// Note: provided buffer must be digest_size() bytes long. /// void readout(void *ptr); private: void init(); struct data_; booster::hold_ptr d; std::auto_ptr md_,md_opad_; key key_; }; /// /// \brief Cipher-block chaining encryption and decryption cryptographic service. /// /// \note In order to use it, you \b must compile CppCMS with OpenSSL (libcrypto) or GNU-TLS (libgcrypt) library. /// class CPPCMS_API cbc : public booster::noncopyable { public: /// /// CBC encryption type /// typedef enum { aes128 = 0, ///< AES-128 aes192 = 1, ///< AES-192 aes256 = 2 ///< AES-256 } cbc_type; /// /// Create a new cbc object that performs encryption using \a type method. /// /// If the encryption method is not supported returns an empty pointer! /// static std::auto_ptr create(cbc_type type); /// /// Create a new cbc object that performs encryption using algorithm \a name /// /// If the encryption method is not supported returns an empty pointer! /// /// Currently supported aes128, aes192, aes256, with names "aes" = "aes-128" = "aes128" , "aes-192" "aes192", /// "aes-256" = "aes256". They require CppCMS to be compiled with OpenSSL or GNU-TLS library /// static std::auto_ptr create(std::string const &name); /// /// Get the size of the block CBC works on /// virtual unsigned block_size() const = 0; /// /// Get the required key size in bytes /// virtual unsigned key_size() const = 0; /// /// Set the key value /// virtual void set_key(key const &) = 0; /// /// Set initial vector value, size should be equal to block_size() /// virtual void set_iv(void const *ptr,size_t size) = 0; /// /// Set randomly created initial vector value /// virtual void set_nonce_iv() = 0; /// /// Encrypt the data \a in to \a out of size \a len. \a len should be multiple of block_size() /// virtual void encrypt(void const *in,void *out,unsigned len) = 0; /// /// Decrypt the data \a in to \a out of size \a len. \a len should be multiple of block_size() /// virtual void decrypt(void const *in,void *out,unsigned len) = 0; virtual ~cbc() { } }; } // crypto } // cppcms #endif