Skip to content

Instantly share code, notes, and snippets.

@cheahjs
Created November 11, 2015 13:56
Show Gist options
  • Save cheahjs/d537808b6a081f98be6b to your computer and use it in GitHub Desktop.
Save cheahjs/d537808b6a081f98be6b to your computer and use it in GitHub Desktop.
/***
Whenever in the Warframe API they perform an important POST action they send what they call an Signed POST
Those task are from getting profile data, updating inventory, creating a clan, and many more...
sSignSalt is an static char[64] variable.
sSignSaltArray is an static char *[5] variable. It's statically initialized to:
{
"0DqsRt5PGQScH3W59Y7l4uzSBP5TkEa7sqmXwmYzdwQgxairOORGYaQTeYoH",
"ndzkZyDRTNlrcs2XYhOpp2c2VzignWUpWAujHuyiGbZWIu5QanVr4MRDHYh1",
"ODZG0DpTHhEOZe0g4dgtSBKJ4bbhQAZ13niCU5Gjsg4MQfSTldsc58407IaD",
"bFch8Wl6gJdMMF319woJAU5ytRCBaMn8mxuoiStHNoCEOH3frP4zTeRPWRC3",
"yMHqXkmONKrEzaGpjmANYzZwoFDLQKJCuth9PNEPpagIf4ZE9amDt6Em2IBn",
}
Util::Whirlpool is the crypto-utility class used by DE to create Whirlpool hashes.
Util::BinaryTextConvert::Base64 is the utility function used by DE convert binary data to Base64.
***/
/***
This function generates a signed payload used by certain Warframe HTTP API POST requests.
@param uri POST Uri
@param payload POST payload
@return POST payload signed
@note I don't know the actual name of this function. I called it this way
as within the game code an exception is thrown from Services/WebGetCommon.cpp:106
and one LUA API function which is called Engine.SignPost, calls this function.
@note String class is just like regular std::string but implemented with their own allocators.
For the purpose they have equal functionality, the only thing it would change is the way
it reserves memory from the game heap.
@note sSignSalt is 1 of 5 possible salts. Which salt it is used depends on the game status.
Warframe game uses Services::WebGetCommon::SetSignSalt for that purpose
***/
String Services::WebGetCommon::SignPostData(const String &uri, String &payload)
{
offset_t pos;
String base64_hash;
Util::Whirlpool hash;
char time_buffer[0x40];
const char *pSignSalt = GetSignSalt();
String signed_payload = payload + '\n';
sprintf_s(time_buffer, sizeof(time_buffer), "%u.", time(NULL))
signed_payload += time_buffer;
hash.Update(pSignSalt, strlen(pSignSalt))
if((pos = uri.find("//")) == String::npos)
throw Exception(__FILE__, __LINE__);
if((pos = uri.find('/', pos + 2)) == String::npos)
throw Exception(__FILE__, __LINE__);
hash.Update(&uri.c_str()[pos], uri.length() - pos);
hash.Update(signed_payload.c_str(), signed_payload.length());
Util::BinaryTextConvert::Base64(&base64_hash, hash.GetDigest(), Util::Whirlpool::HASH_SIZE, 0);
signed_payload+=base64_hash;
return signed_payload;
}
/***
This function returns the signing salt value
@return Signing salt value
@note If signing salt isn't initialized, then signing salt is set to its default value
***/
const char *Services::WebGetCommon::GetSignSalt()
{
if(!*sSignSalt)
Services::WebGetCommon::SetSignSalt(0);
return sSignSalt;
}
void Services::WebGetCommon::SetSignSalt(uint32 id)
{
if(id >= 5)
throw Exception(__FILE__, __LINE__);
strcpy_s(sSignSalt, sizeof(sSignSalt), sSignSaltArray[id]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment