diff --git a/include/mtxclient/crypto/client.hpp b/include/mtxclient/crypto/client.hpp index 3813f1f6c19cf9917c6157be4d8148cd5d66c709..fb7ede0dd6113bc753de7ac5f012ce8a3316332e 100644 --- a/include/mtxclient/crypto/client.hpp +++ b/include/mtxclient/crypto/client.hpp @@ -31,51 +31,79 @@ namespace crypto { //! Data representation used to interact with libolm. using BinaryBuf = std::vector<uint8_t>; +enum class OlmErrorCode { + UNKNOWN_ERROR = - 1, + SUCCESS, + NOT_ENOUGH_RANDOM, + OUTPUT_BUFFER_TOO_SMALL, + BAD_MESSAGE_VERSION, + BAD_MESSAGE_FORMAT, + BAD_MESSAGE_MAC, + BAD_MESSAGE_KEY_ID, + INVALID_BASE64, + BAD_ACCOUNT_KEY, + UNKNOWN_PICKLE_VERSION, + CORRUPTED_PICKLE, + BAD_SESSION_KEY, + UNKNOWN_MESSAGE_INDEX, + BAD_LEGACY_ACCOUNT_PICKLE, + BAD_SIGNATURE, + OLM_INPUT_BUFFER_TOO_SMALL, + OLM_SAS_THEIR_KEY_NOT_SET +}; + //! Errors returned by the olm library class olm_exception : public std::exception { -public: - olm_exception(std::string func, OlmSession *s) - : msg_(func + ": " + std::string(olm_session_last_error(s))) - {} + public: + olm_exception(std::string func, OlmSession *s) + : olm_exception(std::move(func), std::string(olm_session_last_error(s))) + {} - olm_exception(std::string func, OlmAccount *acc) - : msg_(func + ": " + std::string(olm_account_last_error(acc))) - {} + olm_exception(std::string func, OlmAccount *acc) + : olm_exception(std::move(func), std::string(olm_account_last_error(acc))) + {} - olm_exception(std::string func, OlmUtility *util) - : msg_(func + ": " + std::string(olm_utility_last_error(util))) - {} + olm_exception(std::string func, OlmUtility *util) + : olm_exception(std::move(func), std::string(olm_utility_last_error(util))) + {} - olm_exception(std::string func, OlmPkDecryption *s) - : msg_(func + ": " + std::string(olm_pk_decryption_last_error(s))) - {} + olm_exception(std::string func, OlmPkDecryption *s) + : olm_exception(std::move(func), std::string(olm_pk_decryption_last_error(s))) + {} - olm_exception(std::string func, OlmPkSigning *s) - : msg_(func + ": " + std::string(olm_pk_signing_last_error(s))) - {} + olm_exception(std::string func, OlmPkSigning *s) + : olm_exception(std::move(func), std::string(olm_pk_signing_last_error(s))) + {} - olm_exception(std::string func, OlmOutboundGroupSession *s) - : msg_(func + ": " + std::string(olm_outbound_group_session_last_error(s))) - {} + olm_exception(std::string func, OlmOutboundGroupSession *s) + : olm_exception(std::move(func), std::string(olm_outbound_group_session_last_error(s))) + {} - olm_exception(std::string func, OlmInboundGroupSession *s) - : msg_(func + ": " + std::string(olm_inbound_group_session_last_error(s))) - {} + olm_exception(std::string func, OlmInboundGroupSession *s) + : olm_exception(std::move(func), std::string(olm_inbound_group_session_last_error(s))) + {} - olm_exception(std::string func, OlmSAS *s) - : msg_(func + ":" + std::string(olm_sas_last_error(s))) - {} + olm_exception(std::string func, OlmSAS *s) + : olm_exception(std::move(func), std::string(olm_sas_last_error(s))) + {} - olm_exception(std::string msg) - : msg_(msg) - {} + //! Returns a description of the olm error. + const char *what() const noexcept override { return msg_.c_str(); } - //! Returns a description of the olm error. - const char *what() const noexcept override { return msg_.c_str(); } + //! Returns an error code reconstructed from the error string returned by olm + OlmErrorCode error_code() const noexcept { return ec_; } + + private: + olm_exception(std::string &&func, std::string error_string) + : msg_(func + ": " + error_string) + , ec_(ec_from_string(error_string)) + {} + + OlmErrorCode ec_from_string(std::string_view); -private: std::string msg_; + OlmErrorCode ec_ = OlmErrorCode::UNKNOWN_ERROR; }; //! Serialize olm objects into strings encrypted using key to persist them on non volatile storage. diff --git a/lib/crypto/client.cpp b/lib/crypto/client.cpp index feb8574d98a2c54ab3aa3583b8ce273fe1a617c4..73e3ea78d7b022b5b387ff066a048d1ad342a849 100644 --- a/lib/crypto/client.cpp +++ b/lib/crypto/client.cpp @@ -14,6 +14,40 @@ using namespace mtx::crypto; static constexpr auto pwhash_SALTBYTES = 16u; +using namespace std::string_view_literals; + +static const std::array olmErrorStrings{ + "SUCCESS"sv, + "NOT_ENOUGH_RANDOM"sv, + "OUTPUT_BUFFER_TOO_SMALL"sv, + "BAD_MESSAGE_VERSION"sv, + "BAD_MESSAGE_FORMAT"sv, + "BAD_MESSAGE_MAC"sv, + "BAD_MESSAGE_KEY_ID"sv, + "INVALID_BASE64"sv, + "BAD_ACCOUNT_KEY"sv, + "UNKNOWN_PICKLE_VERSION"sv, + "CORRUPTED_PICKLE"sv, + "BAD_SESSION_KEY"sv, + "UNKNOWN_MESSAGE_INDEX"sv, + "BAD_LEGACY_ACCOUNT_PICKLE"sv, + "BAD_SIGNATURE"sv, + "OLM_INPUT_BUFFER_TOO_SMALL"sv, + "OLM_SAS_THEIR_KEY_NOT_SET"sv, + +}; + +OlmErrorCode +olm_exception::ec_from_string(std::string_view error) +{ + for (size_t i = 0; i < olmErrorStrings.size(); i++) { + if (olmErrorStrings[i] == error) + return static_cast<OlmErrorCode>(i); + } + + return OlmErrorCode::UNKNOWN_ERROR; +} + void OlmClient::create_new_account() {