Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ```perl
- sub _canonicalize {
- my ($uri, $EncodeSlash) = @_;
- defined $EncodeSlash ? $UNRESERVED{"/"} = 0 : $UNRESERVED{"/"} = 1;
- $uri =~ s/\+/%20/g;
- $uri =~ s{\G%(..)|(.)}{
- my $c = $1 ? chr(hex($1)) : $2;
- $UNRESERVED{$c} ? $c : sprintf "%%%02X", ord($c)
- }ge;
- $uri =~ s/\+/%20/g;
- return $uri;
- }
- sub _uri_encode {
- my ($uri, $EncodeSlash) = @_;
- my $unreserved_string = defined $EncodeSlash ? "A-Za-z0-9._~-" : "A-Za-z0-9._~/-";
- $uri =~ s{([^$unreserved_string])}{ sprintf '%%%02X',ord($1) }sge;
- $uri =~ s/\+/%20/g;
- $uri = _canonicalize($uri, $EncodeSlash);
- return $uri;
- }
- sub _str_to_datetime {
- my $date = shift;
- if ( $date =~ m/^\d{8}T\d{6}Z$/ ) {
- # assume basic ISO 8601, as demanded by AWS
- return strptime( '%Y%m%dT%H%M%SZ', $date );
- } else {
- # assume the format given in the AWS4 test suite
- $date =~ s/^.{4}//; # remove weekday, as Amazon's test suite contains internally inconsistent dates
- return strptime( '%d %b %Y %H:%M:%S %Z', $date );
- }
- }
- sub _canonicalize_headers_aws2 {
- my $headers = shift;
- my @keys = sort grep /^x-amz-/i, keys %$headers;
- my $out = '';
- for my $key ( @keys ) {
- $out .= lc($key).':'.( $headers->{$key} =~ s{^\s+|\s+$}{}sgr )."\012"
- }
- return $out;
- }
- sub _canonicalize_headers_aws4 {
- my $hdr = shift;
- my ($CanonicalHeaders,@SignedHeaders, %new_hdr);
- my @headers = grep(!/user-agent|Accept|x-real-ip|accept-language|connection|INTERNAL_REQUEST_ID/i,
- keys %$hdr);
- for my $header_name (@headers){
- $new_hdr{$header_name} = $hdr->{$header_name};
- }
- # %new_hdr = %$hdr;
- for my $key (sort keys %new_hdr){
- $new_hdr{$key} =~ s/[\s\t]+/ /g;
- $new_hdr{$key} =~ s/^\s?(.+)\s?$/$1/;
- $CanonicalHeaders .= "$key:$new_hdr{$key}\n";
- push @SignedHeaders, $key;
- }
- my $headers = join (";",@SignedHeaders);
- return $CanonicalHeaders, $headers;
- }
- sub _sort_query_string {
- return '' unless length $_[0];
- my @params;
- for my $param (split /&/, $_[0] ) {
- my ( $key, $value ) =
- map { tr/+/ /; uri_escape( uri_unescape( $_ ) ) }
- split /=/, $param;
- push @params, join '=', $key, $value;
- }
- return join '&', sort @params;
- }
- ```
- ```perl
- sub sign_request_aws4 {
- my ($state, $method, $uri, $hdr, $args) = @_;
- $args->{credentials} and $args->{credentials}->access_key or return;
- my $ak = $args->{credentials}->access_key;
- my $params;
- $params->{cred} = $args->{credentials};
- $params->{cred}{region} = "ru-msk" unless defined $params->{cred}{region};
- $params->{service} = "s3";
- # $hdr->{'x-amz-content-sha256'} //= sha256_hex ($args->{body});
- $params->{HashedPlayload} = $hdr->{'x-amz-content-sha256'} if $hdr->{'x-amz-content-sha256'};
- if ($hdr->{'x-amz-date'}) {
- delete $hdr->{date};
- $params->{timeStamp} = $hdr->{'x-amz-date'};
- $params->{dateStamp} = $params->{timeStamp} =~ s/T\d{6}Z//r;
- }
- elsif ($hdr->{date}) {
- my $dt = _str_to_datetime($hdr->{date});
- $params->{timeStamp} = $hdr->{date};
- $params->{dateStamp} = $dt->ymd('');
- }
- ($params->{CanonicalHeaders}, $params->{SignedHeaders}) = _canonicalize_headers_aws4($hdr);
- my $auth = _calculating_signature_aws4($method, $uri, $params);
- $hdr->{authorization} = "AWS4-HMAC-SHA256 Credential=$ak/$auth->{Scope}, SignedHeaders=$params->{SignedHeaders}, Signature=$auth->{Signature}";
- $state->{auth_params} = $auth;
- return $auth->{s2s};
- }
- ```
- ```perl
- my ($method, $uri, $params) = @_;
- my $CanonicalURI = _canonicalize($uri->path);
- my $CanonicalQueryString = _sort_query_string $uri->query;
- my $CanonicalRequest = join("\n",
- $method,
- $CanonicalURI,
- $CanonicalQueryString,
- $params->{CanonicalHeaders},
- $params->{SignedHeaders},
- $params->{HashedPlayload},
- );
- # p $CanonicalRequest;
- my $Scope = join ("/",
- $params->{dateStamp},
- $params->{cred}{region},
- $params->{service},
- "aws4_request",
- );
- my $s2s = join ("\n",
- "AWS4-HMAC-SHA256",
- $params->{timeStamp},
- $Scope,
- sha256_hex($CanonicalRequest)
- );
- # p $s2s;
- my $kSecret = encode('UTF-8', "AWS4".$params->{cred}{secret_key});
- my $kDate = hmac_sha256($params->{dateStamp}, $kSecret);
- my $kRegion = hmac_sha256($params->{cred}{region}, $kDate);
- my $kService = hmac_sha256($params->{service}, $kRegion);
- my $kSigning = hmac_sha256("aws4_request", $kService);
- my $Signature = hmac_sha256_hex( $s2s, $kSigning);
- return { CanonicalRequest => $CanonicalRequest, Scope => $Scope, s2s => $s2s, Signature => $Signature };
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement