@@ -154,78 +154,84 @@ around BUILDARGS => sub {
154154 return $self -> $orig (%params );
155155};
156156
157- =head2 sign( $request , $relaystate )
157+ =head2 get_redirect_uri($authn_request , $relaystate)
158158
159- Signs the given request, and returns the URL to which the user's
160- browser should be redirected.
159+ Get the redirect URI for a given request, and returns the URL to which the
160+ user's browser should be redirected.
161161
162162Accepts an optional RelayState parameter, a string which will be
163163returned to the requestor when the user returns from the
164164authentication process with the IdP.
165165
166+ The request is signed unless the the object has been instantiated with
167+ C<<insecure => 1>>.
168+
166169=cut
167170
168- sub sign {
169- my ($self , $request , $relaystate ) = @_ ;
171+ sub get_redirect_uri {
172+ my $self = shift ;
173+ my $request = shift ;
170174
171- my $input = " $request " ;
175+ if (!defined $request ) {
176+ croak(" Unable to create redirect URI without a request" );
177+ }
178+
179+ my $relaystate = shift ;
180+
181+ my $input = " $request " ;
172182 my $output = ' ' ;
173183
174184 rawdeflate \$input => \$output ;
175185 my $req = encode_base64($output , ' ' );
176186
177- my $u = URI-> new($self -> url);
178- $u -> query_param($self -> param, $req );
179- $u -> query_param(' RelayState' , $relaystate ) if defined $relaystate ;
187+ my $uri = URI-> new($self -> url);
188+ $uri -> query_param($self -> param, $req );
189+ $uri -> query_param(' RelayState' , $relaystate ) if defined $relaystate ;
180190
181- return $u -> as_string if $self -> insecure;
191+ return $uri -> as_string if $self -> insecure;
192+ return $self -> _sign_redirect_uri($uri );
193+ }
194+
195+ sub _sign_redirect_uri {
196+ my $self = shift ;
197+ my $uri = shift ;
182198
183199 my $key_string = read_text($self -> key);
184200 my $rsa_priv = Crypt::OpenSSL::RSA-> new_private_key($key_string );
185201
186202 my $method = " use_" . $self -> sig_hash . " _hash" ;
187203 $rsa_priv -> $method ;
188204
189- $u -> query_param(' SigAlg' ,
205+ $uri -> query_param(' SigAlg' ,
190206 $self -> sig_hash eq ' sha1'
191207 ? ' http://www.w3.org/2000/09/xmldsig#rsa-sha1'
192208 : ' http://www.w3.org/2001/04/xmldsig-more#rsa-' . $self -> sig_hash);
193209
194- my $to_sign = $u -> query;
210+ my $to_sign = $uri -> query;
195211 my $sig = encode_base64($rsa_priv -> sign($to_sign ), ' ' );
196- $u -> query_param(' Signature' , $sig );
197-
198- return $u -> as_string;
212+ $uri -> query_param(' Signature' , $sig );
213+ return $uri -> as_string;
199214}
200215
201- sub _verify {
202- my ($self , $sigalg , $signed , $sig ) = @_ ;
216+ =head2 sign( $request, $relaystate )
203217
204- foreach my $crt (@{$self -> cert}) {
205- my $cert = Crypt::OpenSSL::X509-> new_from_string($crt );
206- my $rsa_pub = Crypt::OpenSSL::RSA-> new_public_key($cert -> pubkey);
218+ Signs the given request, and returns the URL to which the user's
219+ browser should be redirected.
207220
208- if ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) {
209- $rsa_pub -> use_sha256_hash;
210- } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha224' ) {
211- $rsa_pub -> use_sha224_hash;
212- } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' ) {
213- $rsa_pub -> use_sha384_hash;
214- } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' ) {
215- $rsa_pub -> use_sha512_hash;
216- } elsif ($sigalg eq ' http://www.w3.org/2000/09/xmldsig#rsa-sha1' ) {
217- $rsa_pub -> use_sha1_hash;
218- }
219- else {
220- warn " Unsupported Signature Algorithim: $sigalg , defaulting to sha256" if $self -> debug;
221- }
221+ Accepts an optional RelayState parameter, a string which will be
222+ returned to the requestor when the user returns from the
223+ authentication process with the IdP.
222224
223- return 1 if $rsa_pub -> verify( $signed , $sig );
225+ =cut
224226
225- warn " Unable to verify with " . $cert -> subject if $self -> debug;
227+ sub sign {
228+ my $self = shift ;
229+
230+ if ($self -> insecure) {
231+ croak(" Cannot sign an insecure request!" );
226232 }
227233
228- croak( " Unable to verify the XML signature " );
234+ return $self -> get_redirect_uri( @_ );
229235}
230236
231237=head2 verify( $query_string )
@@ -272,4 +278,34 @@ sub verify {
272278 return ($request , $relaystate );
273279}
274280
281+ sub _verify {
282+ my ($self , $sigalg , $signed , $sig ) = @_ ;
283+
284+ foreach my $crt (@{$self -> cert}) {
285+ my $cert = Crypt::OpenSSL::X509-> new_from_string($crt );
286+ my $rsa_pub = Crypt::OpenSSL::RSA-> new_public_key($cert -> pubkey);
287+
288+ if ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) {
289+ $rsa_pub -> use_sha256_hash;
290+ } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha224' ) {
291+ $rsa_pub -> use_sha224_hash;
292+ } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' ) {
293+ $rsa_pub -> use_sha384_hash;
294+ } elsif ($sigalg eq ' http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' ) {
295+ $rsa_pub -> use_sha512_hash;
296+ } elsif ($sigalg eq ' http://www.w3.org/2000/09/xmldsig#rsa-sha1' ) {
297+ $rsa_pub -> use_sha1_hash;
298+ }
299+ else {
300+ warn " Unsupported Signature Algorithim: $sigalg , defaulting to sha256" if $self -> debug;
301+ }
302+
303+ return 1 if $rsa_pub -> verify($signed , $sig );
304+
305+ warn " Unable to verify with " . $cert -> subject if $self -> debug;
306+ }
307+
308+ croak(" Unable to verify the XML signature" );
309+ }
310+
275311__PACKAGE__ -> meta-> make_immutable;
0 commit comments