From 6462bfda05252884f317949ae08015940c6529d0 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Thu, 4 Sep 2025 00:23:11 +0300 Subject: [PATCH] Validate TOTP parameters --- hmac_utils.cpp | 33 ++++++++++++++++++++++++++++++--- hmac_utils.hpp | 38 +++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/hmac_utils.cpp b/hmac_utils.cpp index 397f6ba..46d67a3 100644 --- a/hmac_utils.cpp +++ b/hmac_utils.cpp @@ -85,10 +85,16 @@ namespace hmac { const void* key_ptr, size_t key_len, uint64_t timestamp, - int period, - int digits, + int period, + int digits, TypeHash hash_type) { - if (period <= 0 || digits <= 0 || digits > 9) return 0; + // Validate period and digit parameters + if (period <= 0) { + throw std::invalid_argument("TOTP: period must be positive"); + } + if (digits < 1 || digits > 9) { + throw std::invalid_argument("TOTP: digits must be in range [1, 9]"); + } uint64_t counter = timestamp / period; return get_hotp_code(key_ptr, key_len, counter, digits, hash_type); } @@ -99,6 +105,13 @@ namespace hmac { int period, int digits, TypeHash hash_type) { + // Validate period and digit parameters + if (period <= 0) { + throw std::invalid_argument("TOTP: period must be positive"); + } + if (digits < 1 || digits > 9) { + throw std::invalid_argument("TOTP: digits must be in range [1, 9]"); + } uint64_t timestamp = static_cast(std::time(nullptr)); return get_totp_code_at(key_ptr, key_len, timestamp, period, digits, hash_type); } @@ -111,6 +124,13 @@ namespace hmac { int period, int digits, TypeHash hash_type) { + // Validate period and digit parameters + if (period <= 0) { + throw std::invalid_argument("TOTP: period must be positive"); + } + if (digits < 1 || digits > 9) { + throw std::invalid_argument("TOTP: digits must be in range [1, 9]"); + } uint64_t counter = timestamp / period; if (token == get_hotp_code(key_ptr, key_len, counter, digits, hash_type)) return true; if (token == get_hotp_code(key_ptr, key_len, counter + 1, digits, hash_type)) return true; @@ -127,6 +147,13 @@ namespace hmac { int period, int digits, TypeHash hash_type) { + // Validate period and digit parameters + if (period <= 0) { + throw std::invalid_argument("TOTP: period must be positive"); + } + if (digits < 1 || digits > 9) { + throw std::invalid_argument("TOTP: digits must be in range [1, 9]"); + } uint64_t timestamp = static_cast(std::time(nullptr)); uint64_t counter = timestamp / period; if (token == get_hotp_code(key_ptr, key_len, counter, digits, hash_type)) return true; diff --git a/hmac_utils.hpp b/hmac_utils.hpp index a6bb949..446c837 100644 --- a/hmac_utils.hpp +++ b/hmac_utils.hpp @@ -81,12 +81,13 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (1 to 9, default: 6) /// \param hash_type Hash function to use (SHA1, SHA256, SHA512; default: SHA1) /// \return TOTP code as an integer + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] int get_totp_code_at( - const void* key_ptr, - size_t key_len, - uint64_t timestamp, - int period = 30, - int digits = 6, + const void* key_ptr, + size_t key_len, + uint64_t timestamp, + int period = 30, + int digits = 6, TypeHash hash_type = TypeHash::SHA1); /// \brief Computes TOTP code for a specific timestamp from a vector-based key @@ -97,11 +98,12 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return TOTP code as an integer + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] template inline int get_totp_code_at( - const std::vector& key, + const std::vector& key, uint64_t timestamp, - int period = 30, + int period = 30, int digits = 6, TypeHash hash_type = TypeHash::SHA1) { static_assert(std::is_same::value || std::is_same::value, @@ -116,11 +118,12 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return TOTP code as an integer + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] inline int get_totp_code_at( - const std::string& key, + const std::string& key, uint64_t timestamp, - int period = 30, - int digits = 6, + int period = 30, + int digits = 6, TypeHash hash_type = TypeHash::SHA1) { return get_totp_code_at(key.data(), key.size(), timestamp, period, digits, hash_type); } @@ -132,11 +135,12 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (default: 6). /// \param hash_type Hash function to use (default: SHA1). /// \return TOTP code as an integer. + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9]. int get_totp_code( - const void* key_ptr, + const void* key_ptr, size_t key_len, - int period = 30, - int digits = 6, + int period = 30, + int digits = 6, TypeHash hash_type = TypeHash::SHA1); /// \brief Computes current TOTP code from a vector-based key using system time (UTC) @@ -146,6 +150,7 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return TOTP code as an integer + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] template inline int get_totp_code(const std::vector& key, int period = 30, int digits = 6, TypeHash hash_type = TypeHash::SHA1) { return get_totp_code(key.data(), key.size(), period, digits, hash_type); @@ -157,6 +162,7 @@ namespace hmac { /// \param digits Number of digits in the resulting OTP code (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return TOTP code as an integer + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] inline int get_totp_code(const std::string& key, int period = 30, int digits = 6, TypeHash hash_type = TypeHash::SHA1) { return get_totp_code(key.data(), key.size(), period, digits, hash_type); } @@ -170,6 +176,7 @@ namespace hmac { /// \param digits Expected number of digits in the OTP (default: 6) /// \param hash_type Hash algorithm to use (SHA1, SHA256, SHA512). Default is SHA1 /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] bool is_totp_token_valid( int token, const void* key_ptr, @@ -188,6 +195,7 @@ namespace hmac { /// \param digits Number of digits in the OTP (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] template inline bool is_totp_token_valid( int token, @@ -209,6 +217,7 @@ namespace hmac { /// \param digits Number of digits in the OTP (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] inline bool is_totp_token_valid( int token, const std::string& key, @@ -227,6 +236,7 @@ namespace hmac { /// \param digits Expected number of digits in the OTP (default: 6) /// \param hash_type Hash algorithm to use (default: SHA1) /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] bool is_totp_token_valid( int token, const void* key_ptr, @@ -243,6 +253,7 @@ namespace hmac { /// \param digits Number of digits in the OTP (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] template inline bool is_totp_token_valid( int token, @@ -262,6 +273,7 @@ namespace hmac { /// \param digits Number of digits in the OTP (default: 6) /// \param hash_type Hash function to use (default: SHA1) /// \return true if the token is valid within [-1, 0, +1] time step range; false otherwise + /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] inline bool is_totp_token_valid( int token, const std::string& key,