@@ -153,6 +153,20 @@ void KeyAuth::api::init()
153153
154154 std::hash<int > hasher;
155155 int expectedHash = hasher (42 );
156+
157+ // 4 lines down, used for debug
158+ /* std::cout << "[DEBUG] Preparing to verify payload..." << std::endl;
159+ std::cout << "[DEBUG] Signature: " << signature << std::endl;
160+ std::cout << "[DEBUG] Timestamp: " << signatureTimestamp << std::endl;
161+ std::cout << "[DEBUG] Raw body: " << response << std::endl;*/
162+
163+ if (signature.empty () || signatureTimestamp.empty ()) { // used for debug
164+ std::cerr << " [ERROR] Signature or timestamp is empty. Cannot verify." << std::endl;
165+ MessageBoxA (0 , " Missing signature headers in response" , " KeyAuth" , MB_ICONERROR);
166+ exit (99 ); // Temporary debug exit code
167+ }
168+
169+
156170 int result = VerifyPayload (signature, signatureTimestamp, response.data ());
157171 if ((hasher (result ^ 0xA5A5 ) & 0xFFFF ) == (expectedHash & 0xFFFF ))
158172 {
@@ -213,32 +227,30 @@ size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) {
213227size_t header_callback (char * buffer, size_t size, size_t nitems, void * userdata) {
214228 size_t totalSize = size * nitems;
215229
216- // Convert the header to a string for easier processing
217230 std::string header (buffer, totalSize);
218231
219- // Find the x-signature-ed25519 header
220- const std::string signatureHeaderName = " x-signature-ed25519: " ;
221- if (header.find (signatureHeaderName) == 0 ) {
222- // Extract the header value
223- signature = header.substr (signatureHeaderName.length ());
232+ // Convert to lowercase for comparison
233+ std::string lowercase = header;
234+ std::transform (lowercase.begin (), lowercase.end (), lowercase.begin (), ::tolower);
224235
225- // Remove any trailing newline or carriage return characters
236+ // Signature
237+ if (lowercase.find (" x-signature-ed25519: " ) == 0 ) {
238+ signature = header.substr (header.find (" : " ) + 2 );
226239 signature.erase (signature.find_last_not_of (" \r\n " ) + 1 );
240+ // std::cout << "[DEBUG] Captured signature header: " << signature << std::endl;
227241 }
228242
229- // Find the x-signature-timestamp header
230- const std::string signatureTimeHeaderName = " x-signature-timestamp: " ;
231- if (header.find (signatureTimeHeaderName) == 0 ) {
232- // Extract the header value
233- signatureTimestamp = header.substr (signatureTimeHeaderName.length ());
234-
235- // Remove any trailing newline or carriage return characters
243+ // Timestamp
244+ if (lowercase.find (" x-signature-timestamp: " ) == 0 ) {
245+ signatureTimestamp = header.substr (header.find (" : " ) + 2 );
236246 signatureTimestamp.erase (signatureTimestamp.find_last_not_of (" \r\n " ) + 1 );
247+ // std::cout << "[DEBUG] Captured timestamp header: " << signatureTimestamp << std::endl;
237248 }
238249
239250 return totalSize;
240251}
241252
253+
242254void KeyAuth::api::login (std::string username, std::string password, std::string code)
243255{
244256 checkInit ();
@@ -254,7 +266,7 @@ void KeyAuth::api::login(std::string username, std::string password, std::string
254266 XorStr (" &name=" ) + name +
255267 XorStr (" &ownerid=" ) + ownerid;
256268 auto response = req (data, url);
257-
269+ // std::cout << "[DEBUG] Login response: " << response << std::endl;
258270 std::hash<int > hasher;
259271 int expectedHash = hasher (42 );
260272 int result = VerifyPayload (signature, signatureTimestamp, response.data ());
@@ -271,6 +283,8 @@ void KeyAuth::api::login(std::string username, std::string password, std::string
271283 size_t expectedHash = hasher (68 );
272284 size_t resultCode = hasher (json[(XorStr (" code" ))]);
273285
286+ // std::cout << "[DEBUG] Login response:" << response << std::endl;
287+
274288 if (!json[(XorStr (" success" ))] || (json[(XorStr (" success" ))] && (resultCode == expectedHash))) {
275289 load_response_data (json);
276290 if (json[(XorStr (" success" ))])
@@ -1587,53 +1601,65 @@ void KeyAuth::api::logout() {
15871601
15881602int VerifyPayload (std::string signature, std::string timestamp, std::string body)
15891603{
1590- // Step 1: Convert the string to a long long integer
15911604 long long unix_timestamp = std::stoll (timestamp);
15921605
1593- // Step 2: Get the current time as Unix timestamp (seconds since epoch)
15941606 auto current_time = std::chrono::system_clock::now ();
15951607 long long current_unix_time = std::chrono::duration_cast<std::chrono::seconds>(
15961608 current_time.time_since_epoch ()).count ();
15971609
1598- // Step 3: Compare the timestamps
15991610 if (current_unix_time - unix_timestamp > 20 ) {
1600- // std::cout << "The timestamp is older than 20 seconds." << std::endl;
1601- LI_FN (exit)(3 );
1611+ std::cerr << " [ERROR] Timestamp too old (diff = "
1612+ << (current_unix_time - unix_timestamp) << " s)\n " ;
1613+ MessageBoxA (0 , " Signature verification failed (timestamp too old)" , " KeyAuth" , MB_ICONERROR);
1614+ exit (3 );
16021615 }
16031616
16041617 if (sodium_init () < 0 ) {
1605- // std::cerr << "Failed to initialize sodium" << std::endl;
1606- LI_FN (exit)(4 );
1618+ std::cerr << " [ERROR] Failed to initialize libsodium\n " ;
1619+ MessageBoxA (0 , " Signature verification failed (libsodium init)" , " KeyAuth" , MB_ICONERROR);
1620+ exit (4 );
16071621 }
16081622
16091623 std::string message = timestamp + body;
16101624
16111625 unsigned char sig[64 ];
16121626 unsigned char pk[32 ];
1613- if (sodium_hex2bin (sig, sizeof (sig), signature.c_str (), signature.length (), NULL , NULL , NULL ) != 0 )
1614- {
1615- // std::cerr << "Invalid signature format" << std::endl;
1616- LI_FN (exit)(5 );
1627+
1628+ if (sodium_hex2bin (sig, sizeof (sig), signature.c_str (), signature.length (), NULL , NULL , NULL ) != 0 ) {
1629+ std::cerr << " [ERROR] Failed to parse signature hex.\n " ;
1630+ MessageBoxA (0 , " Signature verification failed (invalid signature format)" , " KeyAuth" , MB_ICONERROR);
1631+ exit (5 );
16171632 }
16181633
1619- if (sodium_hex2bin (pk, sizeof (pk), API_PUBLIC_KEY.c_str (), API_PUBLIC_KEY.length (), NULL , NULL , NULL ) != 0 )
1620- {
1621- // std::cerr << "Invalid public key format" << std::endl;
1622- LI_FN (exit)(6 );
1623- };
1634+ if (sodium_hex2bin (pk, sizeof (pk), API_PUBLIC_KEY.c_str (), API_PUBLIC_KEY.length (), NULL , NULL , NULL ) != 0 ) {
1635+ std::cerr << " [ERROR] Failed to parse public key hex.\n " ;
1636+ MessageBoxA (0 , " Signature verification failed (invalid public key)" , " KeyAuth" , MB_ICONERROR);
1637+ exit (6 );
1638+ }
1639+
1640+ /* std::cout << "[DEBUG] Timestamp: " << timestamp << std::endl;
1641+ std::cout << "[DEBUG] Signature: " << signature << std::endl;
1642+ std::cout << "[DEBUG] Body: " << body << std::endl;
1643+ std::cout << "[DEBUG] Message (timestamp + body): " << message << std::endl;
1644+ std::cout << "[DEBUG] Public Key: " << API_PUBLIC_KEY << std::endl;*/
16241645
1625- if (crypto_sign_ed25519_verify_detached (sig, reinterpret_cast <const unsigned char *>(message.c_str ()), message.length (), pk) != 0 )
1646+ if (crypto_sign_ed25519_verify_detached (sig,
1647+ reinterpret_cast <const unsigned char *>(message.c_str ()),
1648+ message.length (),
1649+ pk) != 0 )
16261650 {
1627- // std::cerr << "Signature verification failed" << std::endl;
1628- LI_FN (exit)(7 );
1651+ std::cerr << " [ERROR] Signature verification failed.\n " ;
1652+ MessageBoxA (0 , " Signature verification failed (invalid signature)" , " KeyAuth" , MB_ICONERROR);
1653+ exit (7 );
16291654 }
16301655
1631- // std::cout << "\n Payload verfied" << std::endl ;
1632-
1656+ // std::cout << "[DEBUG] Payload verified successfully.\n" ;
1657+
16331658 int value = 42 ^ 0xA5A5 ;
16341659 return value & 0xFFFF ;
16351660}
16361661
1662+
16371663// credits https://stackoverflow.com/a/3790661
16381664static std::string hexDecode (const std::string& hex)
16391665{
@@ -1665,6 +1691,8 @@ void KeyAuth::api::setDebug(bool value) {
16651691}
16661692
16671693std::string KeyAuth::api::req (const std::string& data, const std::string& url) {
1694+ signature.clear ();
1695+ signatureTimestamp.clear ();
16681696
16691697 CURL* curl = curl_easy_init ();
16701698 if (!curl) {
0 commit comments