Authen-U2F-Tester

 view release on metacpan or  search on metacpan

lib/Authen/U2F/Tester.pm  view on Meta::CPAN


    # check if this device has already been registered
    for my $registered (@registered_handles) {
        if ($self->keystore->exists($registered)) {
            return Authen::U2F::Tester::Error->new(DEVICE_INELIGIBLE);
        }
    }

    # generate a new keypair for this application
    my $keypair = Authen::U2F::Tester::Keypair->new;
    my $handle  = $self->keystore->put($keypair->private_key);
    my $cert    = $self->certificate->as_string(Crypt::OpenSSL::X509::FORMAT_ASN1);

    my %client_data = (
        typ        => 'navigator.id.finishEnrollment',
        challenge  => $challenge,
        origin     => $app_id,
        cid_pubkey => 'unused');

    my $client_data = encode_json(\%client_data);

lib/Authen/U2F/Tester/Keypair.pm  view on Meta::CPAN

use strictures 2;
use Crypt::PK::ECC;
use namespace::autoclean;



has keypair => (is => 'lazy', isa => 'Crypt::PK::ECC');



has [qw(public_key private_key)] => (is => 'lazy', isa => 'Value');

single_arg 'keypair';

sub _build_keypair {
    my $pk = Crypt::PK::ECC->new;

    $pk->generate_key('nistp256');

    return $pk;
}

sub _build_public_key {
    shift->keypair->export_key_raw('public');
}

sub _build_private_key {
    shift->keypair->export_key_raw('private');
}

__PACKAGE__->meta->make_immutable;

__END__

=pod

=head1 NAME

lib/Authen/U2F/Tester/Keypair.pm  view on Meta::CPAN


=head1 VERSION

version 0.03

=head1 SYNOPSIS

 my $keypair = Authen::U2F::Tester::Keypair->new;

 # private key in DER format
 my $private_key = $keypair->private_key;

 # public key in DER format
 my $public_key = $keypair->public_key;

 print $keypair->handle;

=head1 DESCRIPTION

This module manages L<Crypt::PK::ECC> keypairs for L<Authen::U2F::Tester>.

lib/Authen/U2F/Tester/Keypair.pm  view on Meta::CPAN


=head2 keypair(): Crypt::PK::ECC

Gets the keypair for this object.  If a keypair was not passed to the
constructor, a new key will be generated.

=head2 public_key(): scalar

Get the public key (in C<DER> format) for this keypair.

=head2 private_key(): scalar

Get the private key (in C<DER> format) for this keypair.

=head1 SOURCE

The development version is on github at L<http://https://github.com/mschout/perl-authen-u2f-tester>
and may be cloned from L<git://https://github.com/mschout/perl-authen-u2f-tester.git>

=head1 BUGS

lib/Authen/U2F/Tester/Keystore/Wrapped.pm  view on Meta::CPAN

        return 1;
    }
    else {
        return 0;
    }
}

sub get {
    my ($self, $handle) = @_;

    my $private_key = $self->key->decrypt(decode_base64url($handle));

    my $pkec = Crypt::PK::ECC->new;
    $pkec->import_key_raw($private_key, 'nistp256');

    return $pkec;
}

sub put {
    my ($self, $private_key) = @_;

    my $handle = $self->key->encrypt($private_key, 'SHA256');

    return $handle;
}

sub remove {
    require Carp;
    Carp::croak 'Keys cannot be removed from the Wrapped Keystore';
}

__PACKAGE__->meta->make_immutable;

lib/Authen/U2F/Tester/Keystore/Wrapped.pm  view on Meta::CPAN


version 0.03

=head1 SYNOPSIS

 my $key = Crypt::PK::ECC->new;
 ...
 my $keystore = Authen::U2F::Tester::Keystore->new(key => $key);

 my $keypair = Authen::U2F::Tester::Keypair->new;
 my $handle = $keystore->put($keypair->private_key);

 if ($keystore->exists($handle)) {
     my $pkec = $keystore->get($handle);
 }

=head1 DESCRIPTION

This is a "wrapped" key store for L<Authen::U2F::Tester>.  This is the default
key store used by L<Authen::U2F::Tester>.  This key store does not require any
backing storage at all to keep track of registered keys.  Instead, it generates

lib/Authen/U2F/Tester/Role/Keystore.pm  view on Meta::CPAN

     my ($self, $handle) = @_;
     ...
     # if handle is valid and exists in the keystore:
     return 1;

     # else
     return 0;
 }

 sub put {
     my ($self, $private_key) = @_;

     # somehow generate a unique handle
     return $handle;
 }

 sub get {
     my ($self, $handle) = @_;

     $handle = decode_base64url($handle);

lib/Authen/U2F/Tester/Role/Keystore.pm  view on Meta::CPAN


=head2 exists($handle): bool

Check if the given handle (in Base64 URL format) exists (or is valid) in the key store.

=head2 get($handle): Crypt::PK::ECC

Given the key handle (in Base64 URL format), return the private key (as a
L<Crypt::PK::ECC> object) associated with it in the key store.

=head2 put($private_key): scalar

Save the given keypair in the keystore, returning a unique key handle that
uniquely identifies the keypair.  The returned handle should B<NOT> be Base64
URL encoded.  C<$private_key> is a raw private key string.

=head2 remove($handle): void

Remove the given key handle from the key store.

=head1 SOURCE

The development version is on github at L<http://https://github.com/mschout/perl-authen-u2f-tester>
and may be cloned from L<git://https://github.com/mschout/perl-authen-u2f-tester.git>

t/keystore/wrapped.t  view on Meta::CPAN

isa_ok $pk, 'Crypt::PK::ECC';

my $keystore = Authen::U2F::Tester::Keystore::Wrapped->new(key => $pk);
isa_ok $keystore, 'Authen::U2F::Tester::Keystore::Wrapped';

can_ok $keystore, qw(exists get put);

my $keypair = Authen::U2F::Tester::Keypair->new;
isa_ok $keypair, 'Authen::U2F::Tester::Keypair';

my $handle = $keystore->put($keypair->private_key);

ok defined $handle;

$handle = encode_base64url($handle);

# valid handle exists
ok $keystore->exists($handle);

# invalid handle does not exist
ok !$keystore->exists('aaa');

$pk = $keystore->get($handle);
isa_ok $pk, 'Crypt::PK::ECC';

# compare the private key to the original keypair private key
my $ks_keypair = Authen::U2F::Tester::Keypair->new(keypair => $pk);

is $ks_keypair->private_key, $keypair->private_key;

dies_ok { $keystore->remove($handle) };

done_testing;



( run in 0.250 second using v1.01-cache-2.11-cpan-a5abf4f5562 )