line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Class::Usul::Crypt; |
2
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
1435
|
use strict; |
|
4
|
|
|
|
|
29
|
|
|
4
|
|
|
|
|
125
|
|
4
|
4
|
|
|
4
|
|
24
|
use warnings; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
120
|
|
5
|
|
|
|
|
|
|
|
6
|
4
|
|
|
4
|
|
490
|
use Class::Usul::Constants qw( NUL ); |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
29
|
|
7
|
4
|
|
|
4
|
|
3595
|
use Class::Usul::Functions qw( create_token is_coderef is_hashref ); |
|
4
|
|
|
|
|
19
|
|
|
4
|
|
|
|
|
48
|
|
8
|
4
|
|
|
4
|
|
8978
|
use Crypt::CBC; |
|
4
|
|
|
|
|
15802
|
|
|
4
|
|
|
|
|
186
|
|
9
|
4
|
|
|
4
|
|
47
|
use English qw( -no_match_vars ); |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
46
|
|
10
|
4
|
|
|
4
|
|
2037
|
use Exporter 5.57 qw( import ); |
|
4
|
|
|
|
|
115
|
|
|
4
|
|
|
|
|
144
|
|
11
|
4
|
|
|
4
|
|
3098
|
use MIME::Base64; |
|
4
|
|
|
|
|
2683
|
|
|
4
|
|
|
|
|
265
|
|
12
|
4
|
|
|
4
|
|
40
|
use Sys::Hostname; |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
2611
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our @EXPORT_OK = qw( cipher_list decrypt default_cipher encrypt ); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $DEFAULT = 'Twofish2'; my $SEED = do { local $RS = undef; <DATA> }; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Private functions |
19
|
|
|
|
|
|
|
my $_decode = sub { |
20
|
|
|
|
|
|
|
my $v = $_[ 0 ]; $v =~ tr{ \t}{01}; pack 'b*', $v; |
21
|
|
|
|
|
|
|
}; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my $_prepare = sub { |
24
|
|
|
|
|
|
|
my $v = $_[ 0 ]; my $pad = " \t" x 8; $v =~ s{^$pad|[^ \t]}{}g; $v; |
25
|
|
|
|
|
|
|
}; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $_dref = sub { |
28
|
|
|
|
|
|
|
(is_coderef $_[ 0 ]) ? ($_[ 0 ]->() // NUL) : ($_[ 0 ] // NUL); |
29
|
|
|
|
|
|
|
}; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $_eval = sub { |
32
|
|
|
|
|
|
|
my $v = $_prepare->( $_[ 0 ] ); $v ? ((eval $_decode->( $v )) || NUL) : NUL; |
33
|
|
|
|
|
|
|
}; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my $_cipher_name = sub { |
36
|
|
|
|
|
|
|
(is_hashref $_[ 0 ]) ? $_[ 0 ]->{cipher} || $DEFAULT : $DEFAULT; |
37
|
|
|
|
|
|
|
}; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $_compose = sub { |
40
|
|
|
|
|
|
|
$_eval->( $_dref->( $_[ 0 ]->{seed} ) || $SEED ).$_dref->( $_[ 0 ]->{salt} ); |
41
|
|
|
|
|
|
|
}; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my $_new_crypt_cbc = sub { |
44
|
|
|
|
|
|
|
Crypt::CBC->new( -cipher => $_[ 0 ], -key => $_[ 1 ] ); |
45
|
|
|
|
|
|
|
}; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
my $_token = sub { |
48
|
|
|
|
|
|
|
create_token( $_compose->( $_[ 0 ] || {} ) ); |
49
|
|
|
|
|
|
|
}; |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my $_wards = sub { |
52
|
|
|
|
|
|
|
(is_hashref $_[ 0 ]) || !$_[ 0 ] ? $_token->( $_[ 0 ] ) : $_[ 0 ]; |
53
|
|
|
|
|
|
|
}; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
my $_cipher = sub { |
56
|
|
|
|
|
|
|
$_new_crypt_cbc->( $_cipher_name->( $_[ 0 ] ), $_wards->( $_[ 0 ] ) ); |
57
|
|
|
|
|
|
|
}; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# Public functions |
60
|
|
|
|
|
|
|
sub cipher_list () { |
61
|
1
|
|
|
1
|
1
|
988
|
return ( qw( Blowfish Rijndael Twofish2 ) ); |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub decrypt (;$$) { |
65
|
5
|
|
|
5
|
1
|
8630
|
return $_cipher->( $_[ 0 ] )->decrypt( decode_base64( $_[ 1 ] ) ); |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub default_cipher () { |
69
|
2
|
|
|
2
|
1
|
9
|
return $DEFAULT; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub encrypt (;$$) { |
73
|
5
|
|
|
5
|
1
|
3661
|
return encode_base64( $_cipher->( $_[ 0 ] )->encrypt( $_[ 1 ] ), NUL ); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
1; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=pod |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head1 Name |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
Class::Usul::Crypt - Encryption / decryption functions |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head1 Synopsis |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
use Class::Usul::Crypt qw(decrypt encrypt); |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
my $args = q(); # OR |
89
|
|
|
|
|
|
|
my $args = 'salt'; # OR |
90
|
|
|
|
|
|
|
my $args = { salt => 'salt', seed => 'whiten this' }; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
$args->{cipher} = 'Twofish2'; # Optionally |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
my $base64_encrypted_text = encrypt( $args, $plain_text ); |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
my $plain_text = decrypt( $args, $base64_encrypted_text ); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=head1 Description |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Exports a pair of functions to encrypt / decrypt data. Obfuscates the default |
101
|
|
|
|
|
|
|
encryption key |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=head1 Configuration and Environment |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
The C<$key> can be a string (including the null string) or a hash reference |
106
|
|
|
|
|
|
|
with I<salt> and I<seed> keys. The I<seed> attribute can be a code reference in |
107
|
|
|
|
|
|
|
which case it will be called with no argument and the return value used |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Lifted from L<Acme::Bleach> the default seed for the key generator has been |
110
|
|
|
|
|
|
|
whitened and included in this source file |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
The seed is C<eval>'d in string context and then the salt is concatenated onto |
113
|
|
|
|
|
|
|
it before being passed to L<create token|Class::Usul::Functions/create_token>. |
114
|
|
|
|
|
|
|
Uses this value as the key for a L<Crypt::CBC> object |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head1 Subroutines/Methods |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head2 decrypt |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
my $plain = decrypt( $salt || \%params, $encoded ); |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
Decodes and decrypts the C<$encoded> argument and returns the plain |
123
|
|
|
|
|
|
|
text result. See the L</encrypt> method |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 encrypt |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
my $encoded = encrypt( $salt || \%params, $plain ); |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Encrypts the plain text passed in the C<$plain> argument and returns |
130
|
|
|
|
|
|
|
it Base64 encoded. By default L<Crypt::Twofish2> is used to do the |
131
|
|
|
|
|
|
|
encryption. The optional C<< $params->{cipher} >> attribute overrides this |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 cipher_list |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
@list_of_ciphers = cipher_list(); |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Returns the list of ciphers supported by L<Crypt::CBC>. These may not |
138
|
|
|
|
|
|
|
all be installed |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=head2 default_cipher |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
$ciper_name = default_cipher(); |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Returns I<Twofish2> |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head1 Diagnostics |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
None |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head1 Dependencies |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=over 3 |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item L<Crypt::CBC> |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=item L<Crypt::Twofish2> |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item L<Exporter> |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item L<MIME::Base64> |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=back |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head1 Incompatibilities |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
There are no known incompatibilities in this module |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=head1 Bugs and Limitations |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
There are no known bugs in this module. |
171
|
|
|
|
|
|
|
Please report problems to the address below. |
172
|
|
|
|
|
|
|
Patches are welcome |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=head1 Author |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
Peter Flanigan, C<< <pjfl@cpan.org> >> |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head1 License and Copyright |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Copyright (c) 2017 Peter Flanigan. All rights reserved |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
183
|
|
|
|
|
|
|
under the same terms as Perl itself. See L<perlartistic> |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, |
186
|
|
|
|
|
|
|
but WITHOUT WARRANTY; without even the implied warranty of |
187
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=cut |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Local Variables: |
192
|
|
|
|
|
|
|
# mode: perl |
193
|
|
|
|
|
|
|
# tab-width: 3 |
194
|
|
|
|
|
|
|
# End: |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
__DATA__ |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|