AWS-Signature-V4
view release on metacpan or search on metacpan
use v5.24;
use experimental 'signatures';
use Test2::V0;
use FindBin '$Bin';
use lib "$Bin/../lib";
use AWS::Signature::V4;
use File::Temp qw< tempdir >;
use Math::BigInt;
# Example from the AWS SigV4 documentation (IAM ListUsers)
my $s = AWS::Signature::V4->new(
service => 'iam', region => 'us-east-1',
credentials => {
access_key_id => 'AKIDEXAMPLE',
secret_access_key => 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY',
},
);
my $r = $s->sign(
method => 'GET',
url => 'https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08',
headers => {'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8'},
time => 1440938160, # 20150830T123600Z
);
is $r->{signature},
'5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7',
'HMAC signature matches AWS docs';
is $r->{signed_headers}, 'content-type;host;x-amz-date', 'signed headers';
# X.509 variant: verify with openssl itself
SKIP: {
my $dir = tempdir(CLEANUP => 1);
skip 'openssl not available', 20 if system("openssl version >/dev/null 2>&1");
for my $alg (qw< RSA ECDSA >) {
my $genkey = $alg eq 'RSA'
? "openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048"
: "openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256";
system("$genkey -out $dir/$alg.key 2>/dev/null") == 0 or die "genkey";
system("openssl req -new -x509 -key $dir/$alg.key -subj /CN=test "
. "-days 2 -out $dir/$alg.pem 2>/dev/null") == 0 or die "req";
system("openssl x509 -in $dir/$alg.pem -pubkey -noout > $dir/$alg.pub") == 0
or die "pubkey";
my $verifies = sub ($string_to_sign, $signature) {
open my $o, '>:raw', "$dir/sts" or die; print {$o} $string_to_sign; close $o;
open my $g, '>:raw', "$dir/sig" or die; print {$g} pack 'H*', $signature; close $g;
system("openssl dgst -sha256 -verify $dir/$alg.pub -signature $dir/sig $dir/sts >/dev/null") == 0;
};
open my $fh, '<', "$dir/$alg.pem" or die; my $pem = do { local $/; <$fh> };
my $x = AWS::Signature::V4->new(
service => 'rolesanywhere', region => 'eu-west-1',
x509 => {key_type => $alg, certificate => $pem,
private_key_file => "$dir/$alg.key"},
);
my $t = $x->sign(method => 'POST',
url => 'https://rolesanywhere.eu-west-1.amazonaws.com/sessions',
headers => {'Content-Type' => 'application/json'},
body => '{"a":1}', time => 1440938160);
my $xf = AWS::Signature::V4->new(
service => 'rolesanywhere', region => 'eu-west-1',
x509 => {key_type => $alg, certificate_file => "$dir/$alg.pem",
private_key => do { open my $k, '<', "$dir/$alg.key" or die; local $/; <$k> }},
);
my $tf = $xf->sign(method => 'POST',
url => 'https://rolesanywhere.eu-west-1.amazonaws.com/sessions',
headers => {'Content-Type' => 'application/json'},
body => '{"a":1}', time => 1440938160);
is $tf->{headers}{'x-amz-x509'}, $t->{headers}{'x-amz-x509'},
"$alg certificate_file equals certificate";
system("openssl pkey -in $dir/$alg.key -outform DER -out $dir/$alg.der") == 0
or die "pkey der";
my $der = do { open my $k, '<:raw', "$dir/$alg.der" or die; local $/; <$k> };
for my $variant ([private_key_file => "$dir/$alg.der"], [private_key => $der]) {
my ($opt, $val) = @$variant;
my $xd = AWS::Signature::V4->new(
( run in 1.031 second using v1.01-cache-2.11-cpan-85d3896f969 )