From 97d5faa0284703546d63b7c1fe78d0ec0227bc05 Mon Sep 17 00:00:00 2001 From: dakkar Date: Sun, 28 Dec 2014 15:27:10 +0000 Subject: crypto partially ported to p6 --- lib/Net/Hawk/Crypto.pm | 147 +++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 79 deletions(-) (limited to 'lib') diff --git a/lib/Net/Hawk/Crypto.pm b/lib/Net/Hawk/Crypto.pm index e70b210..e73cc82 100644 --- a/lib/Net/Hawk/Crypto.pm +++ b/lib/Net/Hawk/Crypto.pm @@ -1,68 +1,76 @@ -package Net::Hawk::Crypto; -use strict; -use warnings; -use 5.010; -use Moo; -use Types::Standard 1.000003 qw(Str Int Object Dict Optional Undef Any HasMethods HashRef slurpy); -use Types::URI qw(Uri); -use Type::Params qw(compile); -use Try::Tiny; -use Digest::SHA qw(hmac_sha1_base64 hmac_sha256_base64); -use Net::Hawk::Role::WithUtils; -use Net::Hawk::Types qw(Algorithm); - -with WithUtils(qw(parse_content_type)); - -sub header_version() { 1 } - -sub generate_normalized_string { - state $argcheck = compile(Object,Str,Dict[ - resource => Uri, - ts => Int, - nonce => Str, - method => Optional[Str], - host => Str, - port => Int, - hash => Optional[Str], - ext => Optional[Str|Undef], - app => Optional[Str|Undef], - dlg => Optional[Str|Undef], - slurpy Any, - ]); - my ($self,$type,$options) = $argcheck->(@_); - - my $normalized = sprintf( - "hawk.%d.%s\n%d\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n", - header_version(), $type, - $options->{ts}, - $options->{nonce}, - uc($options->{method} // ''), - $options->{resource}->path_query, - lc($options->{host}), - $options->{port}, - $options->{hash} // '', - ($options->{ext} // '') =~ s{\\}{\\\\}gr =~ s{\n}{\\n}gr, - ); +package Net::Hawk::Crypto { + use v6; + use URI; + use Digest::SHA; + use Digest::HMAC; + use MIME::Base64; + use Net::Hawk::Utils; + + sub header_version() { 1 } + + proto generate_normalized_string(*%x) returns Str is export {*}; + multi generate_normalized_string(Str:D :$resource!,*%named) returns Str { + return generate_normalized_string(|%named,resource=>URI.new($resource)); + }; + multi generate_normalized_string( + Str:D :$type!, + URI:D :$resource!, + Int:D :$ts!, + Str:D :$nonce!, + Str :$method, + Str:D :$host!, + Int:D :$port!, + Str :$hash, + Str :$ext, + Str :$app, + Str :$dlg, + *%, + ) returns Str is export { + my $normalized = sprintf( + "hawk.%d.%s\n%d\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n", + header_version(), $type, + $ts, + $nonce, + uc($method // ''), + $resource.path_query, + lc($host), + $port, + $hash // '', + ($ext // '').trans(['\\',"\n"] => ['\\\\','\\n']), + ); + + if ($app) { + $normalized .= sprintf( + "%s\n%s\n", + $app, + $dlg // '', + ); + } + + return $normalized; + }; - if ($options->{app}) { - $normalized .= sprintf( - "%s\n%s\n", - $options->{app}, - $options->{dlg} // '', - ); + sub digest_for(Str:D $algorithm) { + if ($algorithm eq 'sha1') { return &sha1 } + elsif ($algorithm eq 'sha256') { return &sha256 } + else { die "bad alg $algorithm" } } - return $normalized; + sub calculate_payload_hash( + Str $payload!, + Str:D $algorithm!, + Str $content_type!, + ) returns Str is export { + my $hash_function = digest_for($algorithm); + return MIME::Base64.encode( + $hash_function(sprintf("hawk.%d.payload\n%s\n%s\n", + header_version(), + parse_content_type($content_type), + $payload))); + }; } -sub calculate_payload_hash { - state $argcheck = compile(Object,Str|Undef,Algorithm,Str|Undef); - my ($self,$payload,$algorithm,$content_type) = $argcheck->(@_); - - my $hash = $self->initialize_payload_hash($algorithm,$content_type); - $hash->add($payload//''); - return $self->finalize_payload_hash($hash); -} +=begin finish sub calculate_mac { state $argcheck = compile( @@ -130,25 +138,6 @@ sub make_digest { return Digest::SHA->new($algorithm =~ s{^sha}{}r); } -sub initialize_payload_hash { - state $argcheck = compile(Object,Algorithm,Str|Undef); - my ($self,$algorithm,$content_type) = $argcheck->(@_); - - my $digest = $self->make_digest($algorithm); - - $digest->add(sprintf("hawk.%d.payload\n",header_version())); - $digest->add($self->_utils->parse_content_type($content_type)."\n"); - return $digest; -} - -sub finalize_payload_hash { - state $argcheck = compile(Object,HasMethods[qw(add b64digest)]); - my ($self,$digest) = $argcheck->(@_); - - $digest->add("\n"); - return _pad_b64($digest->b64digest); -} - sub _pad_b64 { my ($b64) = @_; -- cgit v1.2.3