From 600b4b2dc5231816bb826160d8759b129cd22556 Mon Sep 17 00:00:00 2001 From: Chris Andrews Date: Nov 12 2010 16:04:32 +0000 Subject: Roundtrip test for Redirect binding. --- diff --git a/lib/Net/SAML2/Binding/Redirect.pm b/lib/Net/SAML2/Binding/Redirect.pm index 8bd0851..4668160 100644 --- a/lib/Net/SAML2/Binding/Redirect.pm +++ b/lib/Net/SAML2/Binding/Redirect.pm @@ -31,6 +31,7 @@ use IO::Uncompress::RawInflate qw/ rawinflate /; use URI; use URI::QueryParam; use Crypt::OpenSSL::RSA; +use Crypt::OpenSSL::X509; use File::Slurp qw/ read_file /; =head2 new( ... ) @@ -88,7 +89,7 @@ sub sign_request { return $url; } -=head2 handle_response($response) +=head2 handle_request($url) Decode a Redirect binding URL. @@ -96,16 +97,31 @@ Should also verify the signature on the response. =cut -sub handle_response { - my ($self, $response) = @_; - my $deflated = decode_base64($response); - - my $output = ''; - rawinflate \$deflated => \$output; +sub handle_request { + my ($self, $url) = @_; + my $u = URI->new($url); + + # verify the response + my $sigalg = $u->query_param('SigAlg'); + die "can't verify '$sigalg' signatures" + unless $sigalg eq 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; + + my $cert = Crypt::OpenSSL::X509->new_from_file($self->{key}); + my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($cert->pubkey); + + my $sig = decode_base64($u->query_param_delete('Signature')); + my $signed = $u->query; + die "bad sig" unless $rsa_pub->verify($signed, $sig); + + # unpack the SAML request + my $deflated = decode_base64($u->query_param('SAMLRequest')); + my $request = ''; + rawinflate \$deflated => \$request; - # Should verify the response + # unpack the relaystate + my $relaystate = $u->query_param('RelayState'); - return $output; + return ($request, $relaystate); } 1; diff --git a/t/06-redirect-binding.t b/t/06-redirect-binding.t new file mode 100644 index 0000000..d767a6b --- /dev/null +++ b/t/06-redirect-binding.t @@ -0,0 +1,45 @@ +use Test::More; +use strict; +use warnings; +use Net::SAML2; +use MIME::Base64; +use Data::Dumper; +use File::Slurp; +use LWP::UserAgent; + +my $sp = Net::SAML2::SP->new( + id => 'http://localhost:3000', + url => 'http://localhost:3000', + cert => 't/sign-nopw-cert.pem', + cacert => 't/cacert.pem', + org_name => 'Test', + org_display_name => 'Test', + org_contact => 'test@example.com', +); +ok($sp); + +my $metadata = read_file('t/idp-metadata.xml'); +ok($metadata); +my $idp = Net::SAML2::IdP->new($metadata); +ok($idp); + +my $sso_url = $idp->sso_url('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'); +ok($sso_url); +my $authnreq = $sp->authn_request($sso_url)->as_xml; +ok($authnreq); + +my $redirect = $sp->redirect_binding($sso_url); +ok($redirect); + +my $location = $redirect->sign_request( + $authnreq, + 'http://return/url', +); +ok($location); + +my ($request, $relaystate) = $redirect->handle_request($location); +ok($request); +ok($relaystate); +ok($relaystate eq 'http://return/url'); + +done_testing;