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 )