The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

package Test::Crypt;
#----------------------------------------------------------------------
# To avoid needing Crypt::JWT for tests.
#----------------------------------------------------------------------
use strict;
BEGIN {
if ( $^V ge v5.10.1 ) {
require autodie;
}
}
use Carp;
use File::Temp ();
use JSON ();
use MIME::Base64 ();
#A stripped-down copy of Crypt::JWT::decode_jwt() that only knows
#how to do RSA SHA256, compact form.
sub decode_jwt {
my (%opts) = @_;
Call::Context::must_be_list();
$opts{'token'} =~ m<\A ( ([^.]+) \. ([^.]+) ) \. ([^.]+) \z>x or die "Bad token: “$opts{'token'}”";
my ($signed, @parts) = ( $1, $2, $3, $4 );
$_ = MIME::Base64::decode_base64url($_) for @parts;
my ($header, $payload, $signature) = @parts;
verify_rs256( $opts{'key'}, $signed, $signature );
$payload = JSON::decode_json($payload) if $payload =~ m<\A[ \[ \{ ]>x;
return JSON::decode_json($header), $payload;
}
sub verify_rs256 {
my ($key, $message, $signature) = @_;
confess "No key!" if !$key;
my $kobj = Crypt::Perl::PK::parse_key($key);
die "JWT verification failed!" if !$kobj->verify_RS256($message, $signature);
return;
}
1;