]> Dogcows Code - chaz/p5-File-KDBX/blob - t/otp.t
add initial WIP
[chaz/p5-File-KDBX] / t / otp.t
1 #!/usr/bin/env perl
2
3 use warnings;
4 use strict;
5
6 use lib 't/lib';
7 use TestCommon;
8
9 use File::KDBX::Entry;
10 use Test::More;
11
12 eval { require Pass::OTP } or plan skip_all => 'Pass::OTP required to test one-time-passwords';
13
14 my $secret_txt = 'hello';
15 my $secret_b32 = 'NBSWY3DP';
16 my $secret_b64 = 'aGVsbG8=';
17 my $secret_hex = '68656c6c6f';
18 my $when = 1655488780;
19
20 for my $test (
21 {
22 name => 'HOTP - Basic',
23 input => {otp => "otpauth://hotp/Issuer:user?secret=${secret_b32}&issuer=Issuer"},
24 codes => [qw(029578 825147 676217)],
25 uri => 'otpauth://hotp/Issuer:user?secret=NBSWY3DP&issuer=Issuer',
26 },
27 {
28 name => 'HOTP - Start from 42',
29 input => {
30 otp => "otpauth://hotp/Issuer:user?secret=${secret_b32}&issuer=Issuer",
31 'HmacOtp-Counter' => 42,
32 },
33 codes => [qw(528783 171971 115730)],
34 uri => 'otpauth://hotp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&counter=42',
35 },
36 {
37 name => 'HOTP - 7 digits',
38 input => {otp => "otpauth://hotp/Issuer:user?secret=${secret_b32}&issuer=Issuer&digits=7"},
39 codes => [qw(3029578 9825147 9676217)],
40 uri => 'otpauth://hotp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&digits=7',
41 },
42 {
43 name => 'HOTP - KeePass 2 storage (Base32)',
44 input => {'HmacOtp-Secret-Base32' => $secret_b32},
45 codes => [qw(029578 825147 676217)],
46 uri => 'otpauth://hotp/KDBX:none?secret=NBSWY3DP&issuer=KDBX',
47 },
48 {
49 name => 'HOTP - KeePass 2 storage (Base64)',
50 input => {'HmacOtp-Secret-Base64' => $secret_b64},
51 codes => [qw(029578 825147 676217)],
52 uri => 'otpauth://hotp/KDBX:none?secret=NBSWY3DP&issuer=KDBX',
53 },
54 {
55 name => 'HOTP - KeePass 2 storage (Hex)',
56 input => {'HmacOtp-Secret-Hex' => $secret_hex},
57 codes => [qw(029578 825147 676217)],
58 uri => 'otpauth://hotp/KDBX:none?secret=NBSWY3DP&issuer=KDBX',
59 },
60 {
61 name => 'HOTP - KeePass 2 storage (Text)',
62 input => {'HmacOtp-Secret' => $secret_txt},
63 codes => [qw(029578 825147 676217)],
64 uri => 'otpauth://hotp/KDBX:none?secret=NBSWY3DP&issuer=KDBX',
65 },
66 {
67 name => 'HOTP - KeePass 2, start from 42',
68 input => {'HmacOtp-Secret' => $secret_txt, 'HmacOtp-Counter' => 42},
69 codes => [qw(528783 171971 115730)],
70 uri => 'otpauth://hotp/KDBX:none?secret=NBSWY3DP&issuer=KDBX&counter=42',
71 },
72 {
73 name => 'HOTP - Non-default attributes',
74 input => {'HmacOtp-Secret' => $secret_txt, Title => 'Website', UserName => 'foo!?'},
75 codes => [qw(029578 825147 676217)],
76 uri => 'otpauth://hotp/Website:foo%21%3F?secret=NBSWY3DP&issuer=Website',
77 },
78 ) {
79 my $entry = File::KDBX::Entry->new;
80 $entry->string($_ => $test->{input}{$_}) for keys %{$test->{input}};
81 is $entry->hmac_otp_uri, $test->{uri}, "$test->{name}: Valid URI";
82 for my $code (@{$test->{codes}}) {
83 my $counter = $entry->string_value('HmacOtp-Counter') || 'undef';
84 is $entry->hmac_otp, $code, "$test->{name}: Valid OTP ($counter)";
85 }
86 }
87
88 for my $test (
89 {
90 name => 'TOTP - Basic',
91 input => {otp => "otpauth://totp/Issuer:user?secret=${secret_b32}&period=30&digits=6&issuer=Issuer"},
92 code => '875357',
93 uri => 'otpauth://totp/Issuer:user?secret=NBSWY3DP&issuer=Issuer',
94 },
95 {
96 name => 'TOTP - SHA256',
97 input => {otp => "otpauth://totp/Issuer:user?secret=${secret_b32}&period=30&algorithm=SHA256"},
98 code => '630489',
99 uri => 'otpauth://totp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&algorithm=SHA256',
100 },
101 {
102 name => 'TOTP - 60s period',
103 input => {otp => "otpauth://totp/Issuer:user?secret=${secret_b32}&period=60&digits=6&issuer=Issuer"},
104 code => '647601',
105 uri => 'otpauth://totp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&period=60',
106 },
107 {
108 name => 'TOTP - 7 digits',
109 input => {otp => "otpauth://totp/Issuer:user?secret=${secret_b32}&period=30&digits=7&issuer=Issuer"},
110 code => '9875357',
111 uri => 'otpauth://totp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&digits=7',
112 },
113 {
114 name => 'TOTP - Steam',
115 input => {otp => "otpauth://totp/Issuer:user?secret=${secret_b32}&issuer=Issuer&encoder=steam"},
116 code => '55YH2',
117 uri => 'otpauth://totp/Issuer:user?secret=NBSWY3DP&issuer=Issuer&encoder=steam',
118 },
119 {
120 name => 'TOTP - KeePass 2 storage',
121 input => {'TimeOtp-Secret-Base32' => $secret_b32},
122 code => '875357',
123 uri => 'otpauth://totp/KDBX:none?secret=NBSWY3DP&issuer=KDBX',
124 },
125 {
126 name => 'TOTP - KeePass 2 storage, SHA256',
127 input => {'TimeOtp-Secret-Base32' => $secret_b32, 'TimeOtp-Algorithm' => 'HMAC-SHA-256'},
128 code => '630489',
129 uri => 'otpauth://totp/KDBX:none?secret=NBSWY3DP&issuer=KDBX&algorithm=SHA256',
130 },
131 {
132 name => 'TOTP - KeePass 2 storage, 60s period',
133 input => {'TimeOtp-Secret-Base32' => $secret_b32, 'TimeOtp-Period' => '60'},
134 code => '647601',
135 uri => 'otpauth://totp/KDBX:none?secret=NBSWY3DP&issuer=KDBX&period=60',
136 },
137 {
138 name => 'TOTP - KeePass 2 storage, 7 digits',
139 input => {'TimeOtp-Secret-Base32' => $secret_b32, 'TimeOtp-Length' => '7'},
140 code => '9875357',
141 uri => 'otpauth://totp/KDBX:none?secret=NBSWY3DP&issuer=KDBX&digits=7',
142 },
143 {
144 name => 'TOTP - Non-default attributes',
145 input => {'TimeOtp-Secret-Base32' => $secret_b32, Title => 'Website', UserName => 'foo!?'},
146 code => '875357',
147 uri => 'otpauth://totp/Website:foo%21%3F?secret=NBSWY3DP&issuer=Website',
148 },
149 ) {
150 my $entry = File::KDBX::Entry->new;
151 $entry->string($_ => $test->{input}{$_}) for keys %{$test->{input}};
152 is $entry->time_otp_uri, $test->{uri}, "$test->{name}: Valid URI";
153 is $entry->time_otp(now => $when), $test->{code}, "$test->{name}: Valid OTP";
154 }
155
156 {
157 my $entry = File::KDBX::Entry->new;
158 $entry->string('TimeOtp-Secret-Base32' => $secret_b32);
159 $entry->string('TimeOtp-Secret' => 'wat');
160 my $warning = warning { $entry->time_otp_uri };
161 like $warning, qr/Found multiple/, 'Alert if redundant secrets'
162 or diag 'Warnings: ', explain $warning;
163 }
164
165 done_testing;
This page took 0.048915 seconds and 4 git commands to generate.