File Coverage

blib/lib/File/KDBX/Constants.pm
Criterion Covered Total %
statement 43 44 97.7
branch 5 6 83.3
condition 7 12 58.3
subroutine 13 13 100.0
pod 4 4 100.0
total 72 79 91.1


line stmt bran cond sub pod time code
1             package File::KDBX::Constants;
2             # ABSTRACT: All the KDBX-related constants you could ever want
3              
4             # HOW TO add new constants:
5             # 1. Add it to the %CONSTANTS structure below.
6             # 2. List it in the pod at the bottom of this file in the section corresponding to its tag.
7             # 3. There is no step three.
8              
9 27     27   226053 use 5.010;
  27         259  
10 27     27   126 use warnings;
  27         42  
  27         678  
11 27     27   115 use strict;
  27         40  
  27         526  
12              
13 27     27   122 use Exporter qw(import);
  27         43  
  27         935  
14 27     27   11696 use File::KDBX::Util qw(int64);
  27         103  
  27         2400  
15 27     27   233 use Scalar::Util qw(dualvar);
  27         90  
  27         1240  
16 27     27   146 use namespace::clean -except => 'import';
  27         49  
  27         142  
17              
18             our $VERSION = '0.904'; # VERSION
19              
20             BEGIN {
21 27     27   5177 my %CONSTANTS = (
22             magic => {
23             __prefix => 'KDBX',
24             SIG1 => 0x9aa2d903,
25             SIG1_FIRST_BYTE => 0x03,
26             SIG2_1 => 0xb54bfb65,
27             SIG2_2 => 0xb54bfb67,
28             },
29             version => {
30             __prefix => 'KDBX_VERSION',
31             _2_0 => 0x00020000,
32             _3_0 => 0x00030000,
33             _3_1 => 0x00030001,
34             _4_0 => 0x00040000,
35             _4_1 => 0x00040001,
36             OLDEST => 0x00020000,
37             LATEST => 0x00040001,
38             MAJOR_MASK => 0xffff0000,
39             MINOR_MASK => 0x0000ffff,
40             },
41             header => {
42             __prefix => 'HEADER',
43             END => dualvar( 0, 'end'),
44             COMMENT => dualvar( 1, 'comment'),
45             CIPHER_ID => dualvar( 2, 'cipher_id'),
46             COMPRESSION_FLAGS => dualvar( 3, 'compression_flags'),
47             MASTER_SEED => dualvar( 4, 'master_seed'),
48             TRANSFORM_SEED => dualvar( 5, 'transform_seed'),
49             TRANSFORM_ROUNDS => dualvar( 6, 'transform_rounds'),
50             ENCRYPTION_IV => dualvar( 7, 'encryption_iv'),
51             INNER_RANDOM_STREAM_KEY => dualvar( 8, 'inner_random_stream_key'),
52             STREAM_START_BYTES => dualvar( 9, 'stream_start_bytes'),
53             INNER_RANDOM_STREAM_ID => dualvar( 10, 'inner_random_stream_id'),
54             KDF_PARAMETERS => dualvar( 11, 'kdf_parameters'),
55             PUBLIC_CUSTOM_DATA => dualvar( 12, 'public_custom_data'),
56             },
57             compression => {
58             __prefix => 'COMPRESSION',
59             NONE => dualvar( 0, 'none'),
60             GZIP => dualvar( 1, 'gzip'),
61             },
62             cipher => {
63             __prefix => 'CIPHER',
64             UUID_AES128 => "\x61\xab\x05\xa1\x94\x64\x41\xc3\x8d\x74\x3a\x56\x3d\xf8\xdd\x35",
65             UUID_AES256 => "\x31\xc1\xf2\xe6\xbf\x71\x43\x50\xbe\x58\x05\x21\x6a\xfc\x5a\xff",
66             UUID_CHACHA20 => "\xd6\x03\x8a\x2b\x8b\x6f\x4c\xb5\xa5\x24\x33\x9a\x31\xdb\xb5\x9a",
67             UUID_SALSA20 => "\x71\x6e\x1c\x8a\xee\x17\x4b\xdc\x93\xae\xa9\x77\xb8\x82\x83\x3a",
68             UUID_SERPENT => "\x09\x85\x63\xff\xdd\xf7\x4f\x98\x86\x19\x80\x79\xf6\xdb\x89\x7a",
69             UUID_TWOFISH => "\xad\x68\xf2\x9f\x57\x6f\x4b\xb9\xa3\x6a\xd4\x7a\xf9\x65\x34\x6c",
70             },
71             kdf => {
72             __prefix => 'KDF',
73             UUID_AES => "\xc9\xd9\xf3\x9a\x62\x8a\x44\x60\xbf\x74\x0d\x08\xc1\x8a\x4f\xea",
74             UUID_AES_CHALLENGE_RESPONSE => "\x7c\x02\xbb\x82\x79\xa7\x4a\xc0\x92\x7d\x11\x4a\x00\x64\x82\x38",
75             UUID_ARGON2D => "\xef\x63\x6d\xdf\x8c\x29\x44\x4b\x91\xf7\xa9\xa4\x03\xe3\x0a\x0c",
76             UUID_ARGON2ID => "\x9e\x29\x8b\x19\x56\xdb\x47\x73\xb2\x3d\xfc\x3e\xc6\xf0\xa1\xe6",
77             PARAM_UUID => '$UUID',
78             PARAM_AES_ROUNDS => 'R',
79             PARAM_AES_SEED => 'S',
80             PARAM_ARGON2_SALT => 'S',
81             PARAM_ARGON2_PARALLELISM => 'P',
82             PARAM_ARGON2_MEMORY => 'M',
83             PARAM_ARGON2_ITERATIONS => 'I',
84             PARAM_ARGON2_VERSION => 'V',
85             PARAM_ARGON2_SECRET => 'K',
86             PARAM_ARGON2_ASSOCDATA => 'A',
87             DEFAULT_AES_ROUNDS => 100_000,
88             DEFAULT_ARGON2_ITERATIONS => 10,
89             DEFAULT_ARGON2_MEMORY => 1 << 16,
90             DEFAULT_ARGON2_PARALLELISM => 2,
91             DEFAULT_ARGON2_VERSION => 0x13,
92             },
93             random_stream => {
94             __prefix => 'STREAM',
95             ID_RC4_VARIANT => 1,
96             ID_SALSA20 => 2,
97             ID_CHACHA20 => 3,
98             SALSA20_IV => "\xe8\x30\x09\x4b\x97\x20\x5d\x2a",
99              
100             },
101             variant_map => {
102             __prefix => 'VMAP',
103             VERSION => 0x0100,
104             VERSION_MAJOR_MASK => 0xff00,
105             TYPE_END => 0x00,
106             TYPE_UINT32 => 0x04,
107             TYPE_UINT64 => 0x05,
108             TYPE_BOOL => 0x08,
109             TYPE_INT32 => 0x0C,
110             TYPE_INT64 => 0x0D,
111             TYPE_STRING => 0x18,
112             TYPE_BYTEARRAY => 0x42,
113             },
114             inner_header => {
115             __prefix => 'INNER_HEADER',
116             END => dualvar( 0, 'end'),
117             INNER_RANDOM_STREAM_ID => dualvar( 1, 'inner_random_stream_id'),
118             INNER_RANDOM_STREAM_KEY => dualvar( 2, 'inner_random_stream_key'),
119             BINARY => dualvar( 3, 'binary'),
120             BINARY_FLAG_PROTECT => 1,
121             },
122             key_file => {
123             __prefix => 'KEY_FILE',
124             TYPE_BINARY => dualvar( 1, 'binary'),
125             TYPE_HASHED => dualvar( 3, 'hashed'),
126             TYPE_HEX => dualvar( 2, 'hex'),
127             TYPE_XML => dualvar( 4, 'xml'),
128             },
129             history => {
130             __prefix => 'HISTORY',
131             DEFAULT_MAX_AGE => 365,
132             DEFAULT_MAX_ITEMS => 10,
133             DEFAULT_MAX_SIZE => 6_291_456, # 6 MiB
134             },
135             iteration => {
136             ITERATION_BFS => dualvar(1, 'bfs'),
137             ITERATION_DFS => dualvar(2, 'dfs'),
138             ITERATION_IDS => dualvar(3, 'ids'),
139             },
140             icon => {
141             __prefix => 'ICON',
142             PASSWORD => dualvar( 0, 'Password'),
143             PACKAGE_NETWORK => dualvar( 1, 'Package_Network'),
144             MESSAGEBOX_WARNING => dualvar( 2, 'MessageBox_Warning'),
145             SERVER => dualvar( 3, 'Server'),
146             KLIPPER => dualvar( 4, 'Klipper'),
147             EDU_LANGUAGES => dualvar( 5, 'Edu_Languages'),
148             KCMDF => dualvar( 6, 'KCMDF'),
149             KATE => dualvar( 7, 'Kate'),
150             SOCKET => dualvar( 8, 'Socket'),
151             IDENTITY => dualvar( 9, 'Identity'),
152             KONTACT => dualvar( 10, 'Kontact'),
153             CAMERA => dualvar( 11, 'Camera'),
154             IRKICKFLASH => dualvar( 12, 'IRKickFlash'),
155             KGPG_KEY3 => dualvar( 13, 'KGPG_Key3'),
156             LAPTOP_POWER => dualvar( 14, 'Laptop_Power'),
157             SCANNER => dualvar( 15, 'Scanner'),
158             MOZILLA_FIREBIRD => dualvar( 16, 'Mozilla_Firebird'),
159             CDROM_UNMOUNT => dualvar( 17, 'CDROM_Unmount'),
160             DISPLAY => dualvar( 18, 'Display'),
161             MAIL_GENERIC => dualvar( 19, 'Mail_Generic'),
162             MISC => dualvar( 20, 'Misc'),
163             KORGANIZER => dualvar( 21, 'KOrganizer'),
164             ASCII => dualvar( 22, 'ASCII'),
165             ICONS => dualvar( 23, 'Icons'),
166             CONNECT_ESTABLISHED => dualvar( 24, 'Connect_Established'),
167             FOLDER_MAIL => dualvar( 25, 'Folder_Mail'),
168             FILESAVE => dualvar( 26, 'FileSave'),
169             NFS_UNMOUNT => dualvar( 27, 'NFS_Unmount'),
170             MESSAGE => dualvar( 28, 'Message'),
171             KGPG_TERM => dualvar( 29, 'KGPG_Term'),
172             KONSOLE => dualvar( 30, 'Konsole'),
173             FILEPRINT => dualvar( 31, 'FilePrint'),
174             FSVIEW => dualvar( 32, 'FSView'),
175             RUN => dualvar( 33, 'Run'),
176             CONFIGURE => dualvar( 34, 'Configure'),
177             KRFB => dualvar( 35, 'KRFB'),
178             ARK => dualvar( 36, 'Ark'),
179             KPERCENTAGE => dualvar( 37, 'KPercentage'),
180             SAMBA_UNMOUNT => dualvar( 38, 'Samba_Unmount'),
181             HISTORY => dualvar( 39, 'History'),
182             MAIL_FIND => dualvar( 40, 'Mail_Find'),
183             VECTORGFX => dualvar( 41, 'VectorGfx'),
184             KCMMEMORY => dualvar( 42, 'KCMMemory'),
185             TRASHCAN_FULL => dualvar( 43, 'Trashcan_Full'),
186             KNOTES => dualvar( 44, 'KNotes'),
187             CANCEL => dualvar( 45, 'Cancel'),
188             HELP => dualvar( 46, 'Help'),
189             KPACKAGE => dualvar( 47, 'KPackage'),
190             FOLDER => dualvar( 48, 'Folder'),
191             FOLDER_BLUE_OPEN => dualvar( 49, 'Folder_Blue_Open'),
192             FOLDER_TAR => dualvar( 50, 'Folder_Tar'),
193             DECRYPTED => dualvar( 51, 'Decrypted'),
194             ENCRYPTED => dualvar( 52, 'Encrypted'),
195             APPLY => dualvar( 53, 'Apply'),
196             SIGNATURE => dualvar( 54, 'Signature'),
197             THUMBNAIL => dualvar( 55, 'Thumbnail'),
198             KADDRESSBOOK => dualvar( 56, 'KAddressBook'),
199             VIEW_TEXT => dualvar( 57, 'View_Text'),
200             KGPG => dualvar( 58, 'KGPG'),
201             PACKAGE_DEVELOPMENT => dualvar( 59, 'Package_Development'),
202             KFM_HOME => dualvar( 60, 'KFM_Home'),
203             SERVICES => dualvar( 61, 'Services'),
204             TUX => dualvar( 62, 'Tux'),
205             FEATHER => dualvar( 63, 'Feather'),
206             APPLE => dualvar( 64, 'Apple'),
207             W => dualvar( 65, 'W'),
208             MONEY => dualvar( 66, 'Money'),
209             CERTIFICATE => dualvar( 67, 'Certificate'),
210             SMARTPHONE => dualvar( 68, 'Smartphone'),
211             },
212             bool => {
213             FALSE => !1,
214             TRUE => 1,
215             },
216             time => {
217             __prefix => 'TIME',
218             SECONDS_AD1_TO_UNIX_EPOCH => int64('62135596800'),
219             },
220             yubikey => {
221             YUBICO_VID => dualvar( 0x1050, 'Yubico'),
222             YUBIKEY_PID => dualvar( 0x0010, 'YubiKey 1/2'),
223             NEO_OTP_PID => dualvar( 0x0110, 'YubiKey NEO OTP'),
224             NEO_OTP_CCID_PID => dualvar( 0x0111, 'YubiKey NEO OTP+CCID'),
225             NEO_CCID_PID => dualvar( 0x0112, 'YubiKey NEO CCID'),
226             NEO_U2F_PID => dualvar( 0x0113, 'YubiKey NEO FIDO'),
227             NEO_OTP_U2F_PID => dualvar( 0x0114, 'YubiKey NEO OTP+FIDO'),
228             NEO_U2F_CCID_PID => dualvar( 0x0115, 'YubiKey NEO FIDO+CCID'),
229             NEO_OTP_U2F_CCID_PID => dualvar( 0x0116, 'YubiKey NEO OTP+FIDO+CCID'),
230             YK4_OTP_PID => dualvar( 0x0401, 'YubiKey 4/5 OTP'),
231             YK4_U2F_PID => dualvar( 0x0402, 'YubiKey 4/5 FIDO'),
232             YK4_OTP_U2F_PID => dualvar( 0x0403, 'YubiKey 4/5 OTP+FIDO'),
233             YK4_CCID_PID => dualvar( 0x0404, 'YubiKey 4/5 CCID'),
234             YK4_OTP_CCID_PID => dualvar( 0x0405, 'YubiKey 4/5 OTP+CCID'),
235             YK4_U2F_CCID_PID => dualvar( 0x0406, 'YubiKey 4/5 FIDO+CCID'),
236             YK4_OTP_U2F_CCID_PID => dualvar( 0x0407, 'YubiKey 4/5 OTP+FIDO+CCID'),
237             PLUS_U2F_OTP_PID => dualvar( 0x0410, 'YubiKey Plus OTP+FIDO'),
238              
239             ONLYKEY_VID => dualvar( 0x1d50, 'OnlyKey'),
240             ONLYKEY_PID => dualvar( 0x60fc, 'OnlyKey'),
241              
242             YK_EUSBERR => dualvar( 0x01, 'USB error'),
243             YK_EWRONGSIZ => dualvar( 0x02, 'wrong size'),
244             YK_EWRITEERR => dualvar( 0x03, 'write error'),
245             YK_ETIMEOUT => dualvar( 0x04, 'timeout'),
246             YK_ENOKEY => dualvar( 0x05, 'no yubikey present'),
247             YK_EFIRMWARE => dualvar( 0x06, 'unsupported firmware version'),
248             YK_ENOMEM => dualvar( 0x07, 'out of memory'),
249             YK_ENOSTATUS => dualvar( 0x08, 'no status structure given'),
250             YK_ENOTYETIMPL => dualvar( 0x09, 'not yet implemented'),
251             YK_ECHECKSUM => dualvar( 0x0a, 'checksum mismatch'),
252             YK_EWOULDBLOCK => dualvar( 0x0b, 'operation would block'),
253             YK_EINVALIDCMD => dualvar( 0x0c, 'invalid command for operation'),
254             YK_EMORETHANONE => dualvar( 0x0d, 'expected only one YubiKey but serveral present'),
255             YK_ENODATA => dualvar( 0x0e, 'no data returned from device'),
256              
257             CONFIG1_VALID => 0x01,
258             CONFIG2_VALID => 0x02,
259             CONFIG1_TOUCH => 0x04,
260             CONFIG2_TOUCH => 0x08,
261             CONFIG_LED_INV => 0x10,
262             CONFIG_STATUS_MASK => 0x1f,
263             },
264             );
265              
266 27         77 our %EXPORT_TAGS;
267 27         38 my %seen;
268 27     27   29122 no strict 'refs'; ## no critic (ProhibitNoStrict)
  27         70  
  27         6873  
269 27         168 while (my ($tag, $constants) = each %CONSTANTS) {
270 432         681 my $prefix = delete $constants->{__prefix};
271 432         1232 while (my ($name, $value) = each %$constants) {
272 5211         6464 my $val = $value;
273 5211 100       7401 $val = $val+0 if $tag eq 'icon'; # TODO
274 5211         6867 $name =~ s/^_+//;
275 5211 100       8972 my $full_name = $prefix ? "${prefix}_${name}" : $name;
276 5211 50       7775 die "Duplicate constant: $full_name\n" if $seen{$full_name};
277 5211         24228 *{$full_name} = sub() { $value };
  5211         16728  
  0         0  
278 5211   100     6807 push @{$EXPORT_TAGS{$tag} //= []}, $full_name;
  5211         11212  
279 5211         29339 $seen{$full_name}++;
280             }
281             }
282             }
283              
284             our %EXPORT_TAGS;
285             push @{$EXPORT_TAGS{header}}, 'to_header_constant';
286             push @{$EXPORT_TAGS{compression}}, 'to_compression_constant';
287             push @{$EXPORT_TAGS{inner_header}}, 'to_inner_header_constant';
288             push @{$EXPORT_TAGS{icon}}, 'to_icon_constant';
289              
290             $EXPORT_TAGS{all} = [map { @$_ } values %EXPORT_TAGS];
291             our @EXPORT_OK = sort @{$EXPORT_TAGS{all}};
292              
293             my %HEADER;
294             for my $header (
295             HEADER_END, HEADER_COMMENT, HEADER_CIPHER_ID, HEADER_COMPRESSION_FLAGS,
296             HEADER_MASTER_SEED, HEADER_TRANSFORM_SEED, HEADER_TRANSFORM_ROUNDS,
297             HEADER_ENCRYPTION_IV, HEADER_INNER_RANDOM_STREAM_KEY, HEADER_STREAM_START_BYTES,
298             HEADER_INNER_RANDOM_STREAM_ID, HEADER_KDF_PARAMETERS, HEADER_PUBLIC_CUSTOM_DATA,
299             ) {
300             $HEADER{$header} = $HEADER{0+$header} = $header;
301             }
302 371   50 371 1 1119 sub to_header_constant { $HEADER{$_[0] // ''} }
303              
304             my %COMPRESSION;
305             for my $compression (COMPRESSION_NONE, COMPRESSION_GZIP) {
306             $COMPRESSION{$compression} = $COMPRESSION{0+$compression} = $compression;
307             }
308 1   50 1 1 6 sub to_compression_constant { $COMPRESSION{$_[0] // ''} }
309              
310             my %INNER_HEADER;
311             for my $inner_header (
312             INNER_HEADER_END, INNER_HEADER_INNER_RANDOM_STREAM_ID,
313             INNER_HEADER_INNER_RANDOM_STREAM_KEY, INNER_HEADER_BINARY,
314             ) {
315             $INNER_HEADER{$inner_header} = $INNER_HEADER{0+$inner_header} = $inner_header;
316             }
317 46   50 46 1 190 sub to_inner_header_constant { $INNER_HEADER{$_[0] // ''} }
318              
319             my %ICON;
320             for my $icon (
321             ICON_PASSWORD, ICON_PACKAGE_NETWORK, ICON_MESSAGEBOX_WARNING, ICON_SERVER, ICON_KLIPPER,
322             ICON_EDU_LANGUAGES, ICON_KCMDF, ICON_KATE, ICON_SOCKET, ICON_IDENTITY, ICON_KONTACT, ICON_CAMERA,
323             ICON_IRKICKFLASH, ICON_KGPG_KEY3, ICON_LAPTOP_POWER, ICON_SCANNER, ICON_MOZILLA_FIREBIRD,
324             ICON_CDROM_UNMOUNT, ICON_DISPLAY, ICON_MAIL_GENERIC, ICON_MISC, ICON_KORGANIZER, ICON_ASCII, ICON_ICONS,
325             ICON_CONNECT_ESTABLISHED, ICON_FOLDER_MAIL, ICON_FILESAVE, ICON_NFS_UNMOUNT, ICON_MESSAGE, ICON_KGPG_TERM,
326             ICON_KONSOLE, ICON_FILEPRINT, ICON_FSVIEW, ICON_RUN, ICON_CONFIGURE, ICON_KRFB, ICON_ARK,
327             ICON_KPERCENTAGE, ICON_SAMBA_UNMOUNT, ICON_HISTORY, ICON_MAIL_FIND, ICON_VECTORGFX, ICON_KCMMEMORY,
328             ICON_TRASHCAN_FULL, ICON_KNOTES, ICON_CANCEL, ICON_HELP, ICON_KPACKAGE, ICON_FOLDER,
329             ICON_FOLDER_BLUE_OPEN, ICON_FOLDER_TAR, ICON_DECRYPTED, ICON_ENCRYPTED, ICON_APPLY, ICON_SIGNATURE,
330             ICON_THUMBNAIL, ICON_KADDRESSBOOK, ICON_VIEW_TEXT, ICON_KGPG, ICON_PACKAGE_DEVELOPMENT, ICON_KFM_HOME,
331             ICON_SERVICES, ICON_TUX, ICON_FEATHER, ICON_APPLE, ICON_W, ICON_MONEY, ICON_CERTIFICATE, ICON_SMARTPHONE,
332             ) {
333             $ICON{$icon} = $ICON{0+$icon} = $icon;
334             }
335 104   50 104 1 430 sub to_icon_constant { $ICON{$_[0] // ''} // ICON_PASSWORD }
      50        
336              
337             1;
338              
339             __END__