AWS-Signature-V4

 view release on metacpan or  search on metacpan

t/basic.t  view on Meta::CPAN

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 )