It appears there are a few things you need to get familiar with. (Sorry I can't help because I've never had to do it).
First is the Security Architecture. You can find some reading at Beginner's Guide to OAuth – Part III : Security Architecture.
Second is the HMAC-SHA1 signature and format. You can find the overview at OAuth Core HMAC-SHA1.
Third, you need to understand OAuth's encoding and presentation format. You can find some reading at OAuth Core Parameter Encoding.
To answer some of your questions:
You will need to parse and decode the parameters to get the key, signed data, and signature. So you will need to parse and decode three values: oauth_key
, oauth_data
and oauth_signature
.
Then, you will set up your Crypto++ HMAC key
as follows.
SecByteBlock key(SHA1::BLOCKSIZE);
memcpy(key.data(), key.size(), oauth_key);
After that, you would verify with the following:
byte oauth_key[] = ...; // Your parsed and decoded key
string oauth_data = ...; // Your parsed and decoded data
string oauth_signature = ...; // // Your parsed and decoded signature
try
{
SecByteBlock key(SHA1::BLOCKSIZE);
memcpy(key.data(), key.size(), oauth_key);
HMAC< SHA1 > hmac(key, key.size());
const int flags = HashVerificationFilter::THROW_EXCEPTION | HashVerificationFilter::HASH_AT_END;
StringSource ss(oauth_data + oauth_signature + mac, true,
new HashVerificationFilter(hmac, NULL, flags)
); // StringSource
cout << "Verified message" << endl;
}
catch(const CryptoPP::Exception& e)
{
// Handle failure
cerr << e.what() << endl;
}
Another thing Crypto++ might be able to help with is Base64 decoding. Below is from the HexDecoder wiki page, but it applies to Base64Decoder
because the encoders and decoders use the same interface.
string encoded = ...;
string decoded;
StringSource ss(encoded,
new HexDecoder(
new StringSink(decoded)
) // HexDecoder
); // StringSource
So your code would be:
string encoded = ...;
string decoded;
StringSource ss(encoded,
new Base64Decoder(
new StringSink(decoded)
) // Base64Decoder
); // StringSource
The above uses Crypto++'s pipline interface, where data flows from a source to a sink. You can also do it in a more "C" like manner using Put
and Get
on the Base64Decoder
object:
string encoded = ...;
string decoded;
Base64Decoder decoder;
decoder.Put( (byte*)encoded.data(), encoded.size() );
decoder.MessageEnd();
word64 size = decoder.MaxRetrievable();
if(size && size <= SIZE_MAX)
{
decoded.resize(size);
decoder.Get((byte*)decoded.data(), decoded.size());
}