Authen-U2F
view release on metacpan or search on metacpan
lib/Authen/U2F.pm view on Meta::CPAN
$pkec->import_key_raw($key, "nistp256");
}
catch {
croak "invalid key argument (parse failure: $_)";
};
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 $sign_data = decode_base64url($args->{signature_data});
croak "couldn't decode signature data; not valid Base64-URL?"
unless $sign_data;
# $sig_data is packed like so
#
# 1-byte user presence
# 4-byte counter (big-endian)
# signature
my ($presence, $counter, $sig) = unpack 'a N a*', $sign_data;
# XXX presence check
# XXX counter check
# signature data. sha256 of:
#
# 32-byte sha256(app ID) (application parameter)
# 1-byte user presence
# 4-byte counter (big endian)
# 32-byte sha256(client data (JSON-encoded)) (challenge parameter)
my $app_id_sha = sha256($args->{app_id});
my $challenge_sha = sha256($client_data);
my $sigdata = pack "a32 a N a32", $app_id_sha, $presence, $counter, $challenge_sha;
my $sigdata_sha = sha256($sigdata);
$pkec->verify_hash($sig, $sigdata_sha)
or croak "invalid signature data (signature verification failed)";
return;
}
1;
__END__
=pod
=encoding UTF-8
=for markdown [](http://travis-ci.org/robn/Authen-U2F)
=head1 NAME
Authen-U2F - FIDO U2F library
=head1 SYNOPSIS
use Authen::U2F qw(
u2f_challenge
u2f_registration_verify
u2f_signature_verify);
# Create a challenge to send to the U2F host
my $challenge = u2f_challenge;
# Process a registration response from the U2F host
my ($key_handle, $key) = u2f_registration_verify(
challenge => $challenge,
app_id => $app_id,
origin => $origin,
registration_data => $registration_data,
client_data => $client_data,
);
# Process a signing (authentication) response from the U2F host
u2f_signature_verify(
challenge => $challenge,
app_id => $app_id,
origin => $origin,
key_handle => $key_handle,
key => $key,
signature_data => $signature_data,
client_data => $client_data,
);
# Or, if you don't like to clutter up your namespace
my $challenge = Authen::U2F->challenge;
my ($key_handle, $key) = Authen::U2F->registration_verify(...);
Authen::U2F->signature_verify(...);
=head1 DESCRIPTION
This module provides the tools you need to add support for U2F in your
application.
It's expected that you know the basics of U2F. More information about this can
be found at L<Yubico|https://www.yubico.com/about/background/fido/> and
L<FIDO|https://fidoalliance.org/specifications/overview/>.
This module does not handle the wire encoding of U2F challenges and response,
as these are different depending on the U2F host you're using and the style of
your application. In the C<examples> dir there are scripts that implement the
1.0 wire format, used by L<Yubico's libu2f-host|https://developers.yubico.com/libu2f-host/>,
and a Plack application that works with
L<Google's JavaScript module|https://github.com/google/u2f-ref-code/blob/master/u2f-gae-demo/war/js/u2f-api.js>.
Sadly, the documentation around U2F is rather more confusing than it should be,
and this short description is probably not making things better. Please improve
this or write something about U2F so we can improve application security
everywhere.
( run in 1.820 second using v1.01-cache-2.11-cpan-788537b7465 )