From 040bc76c958209dabe4e69ac7069172aa4553e34 Mon Sep 17 00:00:00 2001 From: Ravin Perera <33562092+ravinsp@users.noreply.github.com> Date: Tue, 1 Oct 2019 14:47:21 +0530 Subject: [PATCH] Replaced custom base64 code with sodium base64 helpers. --- src/base64.cpp | 94 ----------------------------- src/base64.h | 11 ---- src/conf.cpp | 14 ++--- src/crypto.cpp | 156 ++++++++++++++++++++++++++++++------------------- src/crypto.h | 5 -- 5 files changed, 103 insertions(+), 177 deletions(-) delete mode 100644 src/base64.cpp delete mode 100644 src/base64.h diff --git a/src/base64.cpp b/src/base64.cpp deleted file mode 100644 index ef9e25b1..00000000 --- a/src/base64.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "base64.h" -#include - -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -static inline bool is_base64(BYTE c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(BYTE const* buf, unsigned int bufLen) { - std::string ret; - int i = 0; - int j = 0; - BYTE char_array_3[3]; - BYTE char_array_4[4]; - - while (bufLen--) { - char_array_3[i++] = *(buf++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - } - - return ret; -} - -std::vector base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - BYTE char_array_4[4], char_array_3[3]; - std::vector ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret.push_back(char_array_3[i]); - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); - } - - return ret; -} \ No newline at end of file diff --git a/src/base64.h b/src/base64.h deleted file mode 100644 index 2efa17df..00000000 --- a/src/base64.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _BASE64_H_ -#define _BASE64_H_ - -#include -#include -typedef unsigned char BYTE; - -std::string base64_encode(BYTE const* buf, unsigned int bufLen); -std::vector base64_decode(std::string const&); - -#endif \ No newline at end of file diff --git a/src/conf.cpp b/src/conf.cpp index 6bb11539..03c4d29a 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -144,18 +144,18 @@ void save_config() d.SetObject(); Document::AllocatorType &allocator = d.GetAllocator(); d.AddMember("version", StringRef(_HP_VERSION_), allocator); - d.AddMember("pubkeyb64", StringRef(cfg.pubkeyb64.c_str()), allocator); - d.AddMember("seckeyb64", StringRef(cfg.seckeyb64.c_str()), allocator); - d.AddMember("binary", StringRef(cfg.binary.c_str()), allocator); - d.AddMember("binargs", StringRef(cfg.binargs.c_str()), allocator); - d.AddMember("listenip", StringRef(cfg.listenip.c_str()), allocator); + d.AddMember("pubkeyb64", StringRef(cfg.pubkeyb64.data()), allocator); + d.AddMember("seckeyb64", StringRef(cfg.seckeyb64.data()), allocator); + d.AddMember("binary", StringRef(cfg.binary.data()), allocator); + d.AddMember("binargs", StringRef(cfg.binargs.data()), allocator); + d.AddMember("listenip", StringRef(cfg.listenip.data()), allocator); Value peers(kArrayType); d.AddMember("peers", peers, allocator); for (int i = 0; i < cfg.peers.size(); i++) { Value v; - v.SetString(StringRef(cfg.peers[i].c_str()), allocator); + v.SetString(StringRef(cfg.peers[i].data()), allocator); peers.PushBack(v, allocator); } @@ -164,7 +164,7 @@ void save_config() for (int i = 0; i < cfg.unl.size(); i++) { Value v; - v.SetString(StringRef(cfg.unl[i].c_str()), allocator); + v.SetString(StringRef(cfg.unl[i].data()), allocator); unl.PushBack(v, allocator); } diff --git a/src/crypto.cpp b/src/crypto.cpp index 0ebf57f8..aa3456a0 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -1,7 +1,6 @@ #include #include #include -#include "base64.h" #include "conf.h" #include "crypto.h" @@ -10,10 +9,12 @@ using namespace rapidjson; namespace crypto { -unsigned long long get_sig_len() -{ - return crypto_sign_BYTES; -} + +void generate_crypto_keys(); +string base64_encode(unsigned char *bin, size_t bin_len); +int base64_decode(string base64_str, unsigned char *decoded, size_t decoded_len); +void binpair_to_b64(); +int b64pair_to_bin(); void sign(const unsigned char *msg, unsigned long long msg_len, unsigned char *sig) { @@ -23,7 +24,7 @@ void sign(const unsigned char *msg, unsigned long long msg_len, unsigned char *s string sign_b64(string msg) { unsigned char sig[crypto_sign_BYTES]; - crypto_sign_detached(sig, NULL, (unsigned char *)msg.c_str(), msg.size() + 1, conf::cfg.seckey); + crypto_sign_detached(sig, NULL, (unsigned char *)msg.data(), msg.size() + 1, conf::cfg.seckey); return base64_encode(sig, crypto_sign_BYTES); } @@ -35,63 +36,16 @@ bool verify(const unsigned char *msg, unsigned long long msg_len, const unsigned bool verify_b64(string msg, string sigb64, string pubkeyb64) { - vector sigVector = base64_decode(sigb64); - unsigned char sig[sigVector.size()]; - for (int i = 0; i < sigVector.size(); i++) - sig[i] = sigVector[i]; + unsigned char decoded_pubkey[crypto_sign_PUBLICKEYBYTES]; + base64_decode(pubkeyb64, decoded_pubkey, crypto_sign_PUBLICKEYBYTES); - vector pubkeyVector = base64_decode(pubkeyb64); - unsigned char pubkey[pubkeyVector.size()]; - for (int i = 0; i < pubkeyVector.size(); i++) - pubkey[i] = pubkeyVector[i]; + unsigned char decoded_sig[crypto_sign_BYTES]; + base64_decode(sigb64, decoded_sig, crypto_sign_BYTES); - int result = crypto_sign_verify_detached(sig, (unsigned char *)msg.c_str(), msg.size() + 1, pubkey); + int result = crypto_sign_verify_detached(decoded_sig, (unsigned char *)msg.data(), msg.size() + 1, decoded_pubkey); return result == 0; } -void cryptopair_to_b64() -{ - conf::cfg.pubkeyb64 = base64_encode(conf::cfg.pubkey, crypto_sign_PUBLICKEYBYTES); - conf::cfg.seckeyb64 = base64_encode(conf::cfg.seckey, crypto_sign_SECRETKEYBYTES); -} - -void b64pair_to_crypto() -{ - vector pubDecoded = base64_decode(conf::cfg.pubkeyb64); - vector privDecoded = base64_decode(conf::cfg.seckeyb64); - - unsigned char *pubDecodedBytes = (unsigned char *)malloc(pubDecoded.size()); - unsigned char *privDecodedBytes = (unsigned char *)malloc(privDecoded.size()); - - for (size_t i = 0; i < pubDecoded.size(); ++i) - pubDecodedBytes[i] = pubDecoded[i]; - - for (size_t i = 0; i < privDecoded.size(); ++i) - privDecodedBytes[i] = privDecoded[i]; - - if (conf::cfg.pubkey != NULL) - free(conf::cfg.pubkey); - - if (conf::cfg.seckey != NULL) - free(conf::cfg.seckey); - - conf::cfg.pubkey = pubDecodedBytes; - conf::cfg.seckey = privDecodedBytes; -} - -void generate_crypto_keys() -{ - if (conf::cfg.pubkey != NULL) - free(conf::cfg.pubkey); - - if (conf::cfg.seckey != NULL) - free(conf::cfg.seckey); - - conf::cfg.pubkey = (unsigned char *)malloc(crypto_sign_PUBLICKEYBYTES); - conf::cfg.seckey = (unsigned char *)malloc(crypto_sign_SECRETKEYBYTES); - crypto_sign_keypair(conf::cfg.pubkey, conf::cfg.seckey); -} - int init() { if (sodium_init() < 0) @@ -104,7 +58,8 @@ int init() { cout << "Generating new keys.\n"; generate_crypto_keys(); - cryptopair_to_b64(); + binpair_to_b64(); + conf::save_config(); } else if (conf::ctx.command == "run") @@ -117,7 +72,8 @@ int init() else { //Decode b64 keys into bytes and store in memory. - b64pair_to_crypto(); + if (!b64pair_to_bin()) + return 0; //Sign and verify a sample to ensure we have a matching key pair. string msg = "hotpocket"; @@ -133,4 +89,84 @@ int init() return 1; } +void generate_crypto_keys() +{ + if (conf::cfg.pubkey != NULL) + free(conf::cfg.pubkey); + + if (conf::cfg.seckey != NULL) + free(conf::cfg.seckey); + + conf::cfg.pubkey = (unsigned char *)malloc(crypto_sign_PUBLICKEYBYTES); + conf::cfg.seckey = (unsigned char *)malloc(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(conf::cfg.pubkey, conf::cfg.seckey); +} + +string base64_encode(unsigned char *bin, size_t bin_len) +{ + const size_t base64_max_len = sodium_base64_encoded_len(bin_len, sodium_base64_VARIANT_ORIGINAL); + char base64_str[base64_max_len]; + + char *encoded_str_char = sodium_bin2base64( + base64_str, base64_max_len, + bin, bin_len, + sodium_base64_VARIANT_ORIGINAL); + + if (encoded_str_char == NULL) + throw "Base64 Error: Failed to encode string"; + + string s(base64_str); + return s; +} + +int base64_decode(string base64_str, unsigned char *decoded, size_t decoded_len) +{ + const char *b64_end; + size_t bin_len; + if (sodium_base642bin( + decoded, decoded_len, + base64_str.data(), base64_str.size() + 1, + "", &bin_len, &b64_end, + sodium_base64_VARIANT_ORIGINAL)) + { + return 0; + } + + return 1; +} + +void binpair_to_b64() +{ + conf::cfg.pubkeyb64 = base64_encode(conf::cfg.pubkey, crypto_sign_PUBLICKEYBYTES); + conf::cfg.seckeyb64 = base64_encode(conf::cfg.seckey, crypto_sign_SECRETKEYBYTES); +} + +int b64pair_to_bin() +{ + unsigned char *decoded_pubkey = (unsigned char *)malloc(crypto_sign_PUBLICKEYBYTES); + unsigned char *decoded_seckey = (unsigned char *)malloc(crypto_sign_SECRETKEYBYTES); + + if (!base64_decode(conf::cfg.pubkeyb64, decoded_pubkey, crypto_sign_PUBLICKEYBYTES)) + { + cerr << "Error decoding public key.\n"; + return 0; + } + + if (!base64_decode(conf::cfg.seckeyb64, decoded_seckey, crypto_sign_SECRETKEYBYTES)) + { + cerr << "Error decoding secret key.\n"; + return 0; + } + + if (conf::cfg.pubkey != NULL) + free(conf::cfg.pubkey); + + if (conf::cfg.seckey != NULL) + free(conf::cfg.seckey); + + conf::cfg.pubkey = decoded_pubkey; + conf::cfg.seckey = decoded_seckey; + return 1; +} + } // namespace crypto \ No newline at end of file diff --git a/src/crypto.h b/src/crypto.h index 92d9ebd1..925553c9 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -8,11 +8,6 @@ namespace crypto int init(); -/** - * Returns the length of the singature generated using crypto library. - */ -unsigned long long get_sig_len(); - /** * Generates the signature for the given message using the contract's secret key. */