Authen-U2F
view release on metacpan or search on metacpan
lib/Authen/U2F.pm view on Meta::CPAN
package Authen::U2F;
$Authen::U2F::VERSION = '0.003';
# ABSTRACT: FIDO U2F library
use warnings;
use strict;
use namespace::autoclean;
use Types::Standard -types, qw(slurpy);
use Type::Params qw(compile);
use Try::Tiny;
use Carp qw(croak);
use Math::Random::Secure qw(irand);
use MIME::Base64 3.11 qw(encode_base64url decode_base64url);
use Crypt::OpenSSL::X509 1.806;
use CryptX 0.034;
use Crypt::PK::ECC;
use Digest::SHA qw(sha256);
use JSON qw(decode_json);
use parent 'Exporter::Tiny';
our @EXPORT_OK = qw(u2f_challenge u2f_registration_verify u2f_signature_verify);
sub u2f_challenge { __PACKAGE__->challenge(@_) }
sub u2f_registration_verify { __PACKAGE__->registration_verify(@_) }
sub u2f_signature_verify { __PACKAGE__->signature_verify(@_) }
# Param checks
my $challenge_check;
my $registration_check;
my $signature_check;
sub challenge {
$challenge_check ||= compile(
ClassName,
);
my ($class) = $challenge_check->(@_);
my $raw = pack "L*", map { irand } 1..8;
my $challenge = encode_base64url($raw);
return $challenge;
}
sub registration_verify {
$registration_check ||= compile(
ClassName,
slurpy Dict[
challenge => Str,
app_id => Str,
origin => Str,
registration_data => Str,
client_data => Str,
],
);
my ($class, $args) = $registration_check->(@_);
my $client_data = decode_base64url($args->{client_data});
croak "couldn't decode client data; not valid Base64-URL?"
unless $client_data;
{
my $data = decode_json($client_data);
croak "invalid client data (challenge doesn't match)"
unless $data->{challenge} eq $args->{challenge};
croak "invalid client data (origin doesn't match)"
unless $data->{origin} eq $args->{origin};
}
my $reg_data = decode_base64url($args->{registration_data});
croak "couldn't decode registration data; not valid Base64-URL?"
( run in 1.299 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )