diff --git a/src/conf.cpp b/src/conf.cpp index 819ec2ae..3658a808 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -143,7 +143,7 @@ int load_config() ifs.close(); // Check whether the contract version is specified. - std::string cfgversion = d["version"].GetString(); + std::string_view cfgversion = util::getsv(d["version"]); if (cfgversion.empty()) { std::cerr << "Contract config version missing.\n"; @@ -151,7 +151,7 @@ int load_config() } // Check whether this contract complies with the min version requirement. - int verresult = util::version_compare(cfgversion, std::string(util::MIN_CONTRACT_VERSION)); + int verresult = util::version_compare(std::string(cfgversion), std::string(util::MIN_CONTRACT_VERSION)); if (verresult == -1) { std::cerr << "Contract version too old. Minimum " diff --git a/src/crypto.cpp b/src/crypto.cpp index 2c51ec09..3a03a388 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -45,7 +45,7 @@ void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string * @param seckey Secret key bytes. * @return Signature bytes. */ -std::string sign(const std::string &msg, const std::string &seckey) +std::string sign(std::string_view msg, std::string_view seckey) { //Generate the signature using libsodium. @@ -68,7 +68,7 @@ std::string sign(const std::string &msg, const std::string &seckey) * @param seckeyb64 Base64 secret key string. * @return Base64 signature string. */ -std::string sign_b64(const std::string &msg, const std::string &seckeyb64) +std::string sign_b64(std::string_view msg, std::string_view seckeyb64) { //Decode b64 string and generate the signature using libsodium. @@ -96,7 +96,7 @@ std::string sign_b64(const std::string &msg, const std::string &seckeyb64) * @param pubkey Public key bytes. * @return 0 for successful verification. -1 for failure. */ -int verify(const std::string &msg, const std::string &sig, const std::string &pubkey) +int verify(std::string_view msg, std::string_view sig, std::string_view pubkey) { return crypto_sign_verify_detached( reinterpret_cast(sig.data()), @@ -113,7 +113,7 @@ int verify(const std::string &msg, const std::string &sig, const std::string &pu * @param pubkeyb64 Base64 secret key. * @return 0 for successful verification. -1 for failure. */ -int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64) +int verify_b64(std::string_view msg, std::string_view sigb64, std::string_view pubkeyb64) { //Decode b64 string and verify the signature using libsodium. diff --git a/src/crypto.hpp b/src/crypto.hpp index 128c5ff5..d7a825b0 100644 --- a/src/crypto.hpp +++ b/src/crypto.hpp @@ -12,13 +12,13 @@ int init(); void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string &keytype); -std::string sign(const std::string &msg, const std::string &seckey); +std::string sign(std::string_view msg, std::string_view seckey); -std::string sign_b64(const std::string &msg, const std::string &seckeyb64); +std::string sign_b64(std::string_view msg, std::string_view seckeyb64); -int verify(const std::string &msg, const std::string &sig, const std::string &pubkey); +int verify(std::string_view msg, std::string_view sig, std::string_view pubkey); -int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64); +int verify_b64(std::string_view msg, std::string_view sigb64, std::string_view pubkeyb64); } // namespace crypto diff --git a/src/sock/socket_session.cpp b/src/sock/socket_session.cpp index 8fcb9524..9c5265a8 100644 --- a/src/sock/socket_session.cpp +++ b/src/sock/socket_session.cpp @@ -17,7 +17,7 @@ socket_session::socket_session(websocket::stream &websocket, } //port and address will be used to identify from which client the message recieved in the handler -void socket_session::server_run(const std::uint16_t port, const std::string &address) +void socket_session::server_run(const std::uint16_t port, std::string_view address) { port_ = port; address_ = address; @@ -31,15 +31,11 @@ void socket_session::server_run(const std::uint16_t port, const std::string &add } //port and address will be used to identify from which server the message recieved in the handler -void socket_session::client_run(const std::uint16_t port, const std::string &address, error ec) +void socket_session::client_run(const std::uint16_t port, std::string_view address, error ec) { port_ = port; address_ = address; - // Create a unique id for the session combining ip and port. - uniqueid_ = address + ":"; - uniqueid_.append(std::to_string(port)); - if (ec) return fail(ec, "handshake"); diff --git a/src/sock/socket_session.hpp b/src/sock/socket_session.hpp index b63e5f03..e37d8f30 100644 --- a/src/sock/socket_session.hpp +++ b/src/sock/socket_session.hpp @@ -59,8 +59,8 @@ public: // Setting and reading flags to this is completely managed by user-code. std::bitset<8> flags_; - void server_run(const std::uint16_t port, const std::string &address); - void client_run(const std::uint16_t port, const std::string &address, error ec); + void server_run(const std::uint16_t port, std::string_view address); + void client_run(const std::uint16_t port, std::string_view address, error ec); // Used to send message through an active websocket connection. void send(std::shared_ptr const &ss); diff --git a/src/usr/user_session_handler.cpp b/src/usr/user_session_handler.cpp index 6cfef107..0b3b26b5 100644 --- a/src/usr/user_session_handler.cpp +++ b/src/usr/user_session_handler.cpp @@ -58,7 +58,7 @@ void user_session_handler::on_message(sock::socket_session *session, const std:: if (itr != usr::pending_challenges.end()) { std::string userpubkey; - const std::string &original_challenge = itr->second; + std::string_view original_challenge = itr->second; if (usr::verify_user_challenge_response(userpubkey, message, original_challenge) == 0) { // Challenge verification successful. diff --git a/src/usr/usr.cpp b/src/usr/usr.cpp index aca23f5e..5eb3a403 100644 --- a/src/usr/usr.cpp +++ b/src/usr/usr.cpp @@ -23,13 +23,13 @@ namespace usr * Global user list. (Exposed to other sub systems) * Map key: User socket session id () */ -std::map users; +std::map> users; /** * Keep track of verification-pending challenges issued to newly connected users. * Map key: User socket session id () */ -std::map pending_challenges; +std::map> pending_challenges; /** * User session handler instance. This instance's methods will be fired for any user socket activity. @@ -127,7 +127,7 @@ void create_user_challenge(std::string &msg, std::string &challengeb64) * @param original_challenge The original base64 challenge string issued to the user. * @return 0 if challenge response is verified. -1 if challenge not met or an error occurs. */ -int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge) +int verify_user_challenge_response(std::string &extracted_pubkeyb64, std::string_view response, std::string_view original_challenge) { // We load response raw bytes into json document. rapidjson::Document d; @@ -167,10 +167,10 @@ int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std:: } // Verify the challenge signature. We do this last due to signature verification cost. - std::string sigb64 = d[CHALLENGE_RESP_SIG].GetString(); - extracted_pubkeyb64 = d[CHALLENGE_RESP_PUBKEY].GetString(); - - if (crypto::verify_b64(original_challenge, sigb64, extracted_pubkeyb64) != 0) + if (crypto::verify_b64( + original_challenge, + util::getsv(d[CHALLENGE_RESP_SIG]), + util::getsv(d[CHALLENGE_RESP_PUBKEY])) != 0) { std::cerr << "User challenge response signature verification failed.\n"; return -1; @@ -187,7 +187,7 @@ int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std:: * @param pubkeyb64 User's base64 public key. * @return 0 on successful additions. -1 on failure. */ -int add_user(const std::string &sessionid, const std::string &pubkeyb64) +int add_user(std::string_view sessionid, std::string_view pubkeyb64) { if (users.count(sessionid) == 1) { @@ -228,7 +228,7 @@ int add_user(const std::string &sessionid, const std::string &pubkeyb64) * * @return 0 on successful removals. -1 on failure. */ -int remove_user(const std::string &sessionid) +int remove_user(std::string_view sessionid) { auto itr = users.find(sessionid); diff --git a/src/usr/usr.hpp b/src/usr/usr.hpp index 1d3049a5..2bf2967e 100644 --- a/src/usr/usr.hpp +++ b/src/usr/usr.hpp @@ -2,7 +2,7 @@ #define _HP_USR_H_ #include -#include +#include #include #include "../util.hpp" @@ -15,27 +15,22 @@ namespace usr /** * Global authenticated (challenge-verified) user list. */ -extern std::map users; +extern std::map> users; /** * Keep track of verification-pending challenges issued to newly connected users. */ -extern std::map pending_challenges; - -/** - * Keep track of verification-pending challenges issued to newly connected users. - */ -extern std::map pending_challenges; +extern std::map> pending_challenges; int init(); void create_user_challenge(std::string &msg, std::string &challengeb64); -int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge); +int verify_user_challenge_response(std::string &extracted_pubkeyb64, std::string_view response, std::string_view original_challenge); -int add_user(const std::string &sessionid, const std::string &pubkeyb64); +int add_user(std::string_view sessionid, std::string_view pubkeyb64); -int remove_user(const std::string &sessionid); +int remove_user(std::string_view sessionid); int read_contract_user_outputs(); diff --git a/src/util.cpp b/src/util.cpp index 94091bf7..381beee1 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace util { @@ -41,7 +42,7 @@ int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t * @param decodedbuf_len Decoded buffer size. * @param base64_str Base64 string to decode. */ -int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, const std::string &base64_str) +int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, std::string_view base64_str) { const char *b64_end; size_t bin_len; @@ -63,6 +64,11 @@ int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, const std::s * v1 == v2 -> returns 0 * v1 > v2 -> returns +1 * Error -> returns -2 + * + * Remark on string_view: In other places of the code-base we utilize string_view + * to pass immutable string references around. However in this function we keep the 'const string&' + * syntax because istringstream doesn't support string_view. It's not worth optmising + * this code as it's not being used in high-scale processing. */ int version_compare(const std::string &x, const std::string &y) { @@ -88,4 +94,14 @@ int version_compare(const std::string &x, const std::string &y) return 0; } +/** + * Returns a std::string_view pointing to the rapidjson Value which is assumed + * to be a string. We use this function because rapidjson does not have build-in string_view + * support. Passing a non-string 'v' is not supported. + */ +std::string_view getsv(const rapidjson::Value &v) +{ + return std::string_view(v.GetString(), v.GetStringLength()); +} + } // namespace util \ No newline at end of file diff --git a/src/util.hpp b/src/util.hpp index 50a7e8de..c6955b41 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -3,6 +3,7 @@ #include #include +#include /** * Contains helper functions and data structures used by multiple other subsystems. @@ -42,7 +43,7 @@ struct contract_user int outpipe[2]; // Pipe to receive output produced by the contract std::string outbuffer; // Holds the contract output to be processed by consensus rounds - contract_user(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2]) + contract_user(std::string_view _pubkeyb64, int _inpipe[2], int _outpipe[2]) { pubkeyb64 = _pubkeyb64; inpipe[0] = _inpipe[0]; @@ -61,7 +62,7 @@ struct peer_node int inpipe[2]; // NPL pipe from HP to SC int outpipe[2]; // NPL pipe from SC to HP - peer_node(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2]) + peer_node(std::string_view _pubkeyb64, int _inpipe[2], int _outpipe[2]) { pubkeyb64 = _pubkeyb64; inpipe[0] = _inpipe[0]; @@ -73,9 +74,11 @@ struct peer_node int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t bin_len); -int base64_decode(unsigned char *decoded, size_t decoded_len, const std::string &base64_str); +int base64_decode(unsigned char *decoded, size_t decoded_len, std::string_view base64_str); -int version_compare(const std::string &v1, const std::string &v2); +int version_compare(const std::string &x, const std::string &y); + +std::string_view getsv(const rapidjson::Value &v); } // namespace util