lemonldap-ng/lemonldap-ng-common/lib/Lemonldap/NG/Common/TOTP.pm

41 lines
840 B
Perl
Raw Normal View History

package Lemonldap::NG::Common::TOTP;
use strict;
use Mouse;
our $VERSION = '2.0.0';
sub verifyCode {
my ( $self, $interval, $range, $secret, $code ) = @_;
my $s = eval { decode_base32($secret) };
if ($@) {
$self->logger->error('Bad characters in TOTP secret');
return -1;
}
for ( 0 .. $range ) {
if ( $code eq $self->_code( $s, $_, $interval ) ) {
return 1;
}
}
return 0;
}
sub _code {
my ( $self, $secret, $r, $interval ) = @_;
my $hmac = hmac_sha1_hex(
pack( 'H*',
sprintf( '%016x', int( ( time + $r * $interval ) / $interval ) ) ),
$secret,
);
return sprintf(
'%06d',
(
hex( substr( $hmac, hex( substr( $hmac, -1 ) ) * 2, 8 ) ) &
0x7fffffff
) % 1000000
);
}
1;