AWS API Dlang, hmac sha256 function.
holo via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Oct 11 16:16:49 PDT 2015
After long fight with previous code i try to rewrite "one-to-one"
python example from
http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html (GET part) from begging to D with full success. Here is working code in clear D. Im using hmac function which is available from 2.069 of phobos). It is not too beautiful but like i said im beginner, here it is:
#!/usr/bin/rdmd -L-lcurl
module sigawsv4;
import std.stdio, std.process;
import std.digest.sha, std.digest.hmac;
import std.string;
import std.conv;
import std.datetime;
import std.net.curl;
void main()
{
auto accessKey = environment["AWS_ACCESS_KEY"];
auto secretKey = environment["AWS_SECRET_KEY"];
auto currentClock = Clock.currTime(UTC());
auto currentDate = cast(Date)currentClock;
auto curDateStr = currentDate.toISOString;
auto currentTime = cast(TimeOfDay)currentClock;
auto curTimeStr = currentTime.toISOString;
auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z";
string method = "GET";
string service = "ec2";
string host = "ec2.amazonaws.com";
string region = "us-east-1";
string endpoint = "https://ec2.amazonaws.com";
string request_parameters =
"Action=DescribeInstances&Version=2013-10-15";
auto hmac_sha256(ubyte[] key, ubyte[] msg)
{
auto hmac = hmac!SHA256(key);
hmac.put(msg);
auto digest = hmac.finish;
return digest;
}
alias sign = hmac_sha256;
auto getSignatureKey(string key, string dateStamp, string
regionName, string serviceName)
{
ubyte[] kString = cast(ubyte[])("AWS4" ~ key);
auto kDate = sign(kString, cast(ubyte[])dateStamp);
auto kRegion = sign(kDate, cast(ubyte[])regionName);
auto kService = sign(kRegion, cast(ubyte[])serviceName);
auto kSigning = sign(kService, cast(ubyte[])"aws4_request");
return kSigning;
}
string canonicalURI = "/";
string canonicalQueryString = request_parameters;
string canonicalHeadersString = "host:" ~ host ~ "\n" ~
"x-amz-date:" ~ xamztime ~ "\n";
string signedHeaders = "host;x-amz-date";
string payloadHash = sha256Of("").toHexString.toLower;
string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~
canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~
signedHeaders ~ "\n" ~ payloadHash;
string algorithm = "AWS4-HMAC-SHA256";
string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~
service ~ "/" ~ "aws4_request";
string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~
credentialScope ~ "\n" ~
sha256Of(canonicalRequest).toHexString.toLower;
auto signingKey = getSignatureKey(secretKey, curDateStr, region,
service);
string signature = hmac_sha256(signingKey,
cast(ubyte[])stringToSign).toHexString.toLower;
string authorizationHeader = algorithm ~ " " ~ "Credential=" ~
accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~
signedHeaders ~ ", " ~ "Signature=" ~ signature;
auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString);
client.method = HTTP.Method.get;
client.addRequestHeader("x-amz-date", xamztime);
client.addRequestHeader("Authorization", authorizationHeader);
auto content = client.perform();
writeln(content);
}
Now will try to "pack" it to some class and make it more usable
and universal. I think that thread can be closed/solved (if
something like this exist here)
Thank you all for help.
//holo
More information about the Digitalmars-d-learn
mailing list