/*! * \brief This provides device independent RSA 2048 bit data signing. * * It is based on OpenSSL, which is the most maintained and most * popular package, but it is not completely documented, and examples * across the web use different levels of the API and different versions * making this hard to code / recode. * * OpenSSL typically is part of most Linux distros and as it's the heart * of most HTTPS operations on Linux almost always available. It is * available as source code and there are binary installers for Windows, * Linux, Android, iOS, iPhone and many others. * * Note to use it as a developer on Windows with visual studio: * [C/C++ -> General -> Additional Include Directories] value: OpenSSL?s include directory in your machine (e.g C:\openssl\include) * [Linker -> General -> Additional Library Directories] value: OpenSSL?s lib directory in your machine (e.g C:\openssl\lib) * [Linker -> Input -> Additional Dependencies] value: libcrypto.lib libssl.lib * * Be aware some countries put import/export restrictions on anything cryptographic * and the license for OpenSSL makes that very clear. * * For ITAR compliance this includes nothing novel or new. All algorithms are published, * not restricted by US law and are used as is. * * Sunrise has an equivalent python3 module that is interoperable with this C++ code. * * \copyright 2023, Sunrise Labs, Inc. * * \file SignRsa.h * * \author PBraica * \date March 2023 */ #ifndef SIGN_RSA_H_ #define SIGN_RSA_H_ #include // Prototype internal class not part of the API. class _InternalDigest; // Forward declare RSA so that other classes building this object // don't pull in the giant includes of RSA over and over. typedef struct rsa_st RSA; /** * This wraps OpenSSL, we have an equivalent sign_rsa.py file * for scripting/tool based things that is basically call for call * equivalent and compatible. * * In some cases, the software is only used to handle verify in which case * the public key will exist and be loaded and the private is not. * *
 * At the API level:
 *   Digests are 256-bit SHA hash
 *   Signatures are base64 strings.
 * 
*/ class SignRsa { public: SignRsa(); SignRsa(const SignRsa &other); virtual ~SignRsa(); void create_keys(); void save_keys(const std::string& folder_name); void load_keys(const std::string& folder_name); /*! * \brief Set the keys from strings. * * \param public_key Public key string. * \param private_key Private key string. * * \return True on success. */ bool set_keys(const std::string& public_key, const std::string& private_key) { return set_public(public_key) && set_private(private_key); } bool set_public(const std::string& key); bool set_private(const std::string& key); void clear_digest(); void update_digest(const unsigned char* pData, std::size_t size_bytes); std::string sign_data(const unsigned char* pData, std::size_t size_bytes); std::string sign_file(FILE * pFile); std::string sign_digest(const unsigned char* pDigest); bool verify_data(const unsigned char* pData, std::size_t size_bytes, const std::string& signature); bool verify_file(FILE* pFile, const std::string& signature); bool verify_digest(const unsigned char* pDigest, const std::string& signature); /*! * \brief Does the public key exist? * * \return True if it exists. */ bool public_exists() const { return _pPublic != nullptr; } /*! * \brief Does the private key exist? * * \return True if it exists. */ bool private_exists() const { return _pPrivate != nullptr; } /*! * \brief Finalize the context and create the digest bytes. * * \return Digest bytes. */ const unsigned char* get_digest() const; // These are more tolerant versions than openSSL, which has a known // problem with it's decode making it incompatible with many // base64 encoders. std::string decodeBase64(const std::string& base64_str) const; std::string encodeBase64(const std::string& raw_str) const; std::string encodeBase64(const char * raw_str, std::size_t size) const; protected: _InternalDigest* _pDigest; ///< Internal digest. RSA* _pPublic; ///< Public key. RSA* _pPrivate; ///< Private key. std::string _lastPub; ///< Last public key. }; #endif // SIGN_RSA_H_