line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Crypt::OpenPGP::SKSessionKey; |
2
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
102
|
|
3
|
|
|
|
|
|
|
|
4
|
2
|
|
|
2
|
|
13
|
use Crypt::OpenPGP::Constants qw( DEFAULT_CIPHER ); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
16
|
|
5
|
2
|
|
|
2
|
|
11
|
use Crypt::OpenPGP::Buffer; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
51
|
|
6
|
2
|
|
|
2
|
|
552
|
use Crypt::OpenPGP::S2k; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
58
|
|
7
|
2
|
|
|
2
|
|
10
|
use Crypt::OpenPGP::ErrorHandler; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
50
|
|
8
|
2
|
|
|
2
|
|
9
|
use base qw( Crypt::OpenPGP::ErrorHandler ); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
1364
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub new { |
11
|
23
|
|
|
23
|
1
|
37
|
my $class = shift; |
12
|
23
|
|
|
|
|
62
|
my $key = bless { }, $class; |
13
|
23
|
|
|
|
|
82
|
$key->init(@_); |
14
|
|
|
|
|
|
|
} |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub init { |
17
|
23
|
|
|
23
|
0
|
35
|
my $key = shift; |
18
|
23
|
|
|
|
|
74
|
my %param = @_; |
19
|
23
|
|
|
|
|
77
|
$key->{version} = 4; |
20
|
23
|
100
|
66
|
|
|
137
|
if ((my $sym_key = $param{SymKey}) && (my $pass = $param{Passphrase})) { |
21
|
11
|
|
33
|
|
|
35
|
my $alg = $param{Cipher} || DEFAULT_CIPHER; |
22
|
11
|
|
|
|
|
56
|
my $cipher = Crypt::OpenPGP::Cipher->new($alg); |
23
|
11
|
|
|
|
|
37
|
my $keysize = $cipher->keysize; |
24
|
11
|
|
|
|
|
56
|
$key->{s2k_ciph} = $cipher->alg_id; |
25
|
11
|
|
33
|
|
|
42
|
$key->{s2k} = $param{S2k} || Crypt::OpenPGP::S2k->new('Salt_Iter'); |
26
|
11
|
|
|
|
|
42
|
$sym_key = substr $sym_key, 0, $keysize; |
27
|
11
|
|
|
|
|
37
|
my $s2k_key = $key->{s2k}->generate($pass, $keysize); |
28
|
11
|
|
|
|
|
67
|
$cipher->init($s2k_key); |
29
|
|
|
|
|
|
|
} |
30
|
23
|
|
|
|
|
113
|
$key; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub parse { |
34
|
12
|
|
|
12
|
1
|
20
|
my $class = shift; |
35
|
12
|
|
|
|
|
21
|
my($buf) = @_; |
36
|
12
|
|
|
|
|
30
|
my $key = $class->new; |
37
|
12
|
|
|
|
|
35
|
$key->{version} = $buf->get_int8; |
38
|
|
|
|
|
|
|
return $class->error("Unsupported version ($key->{version})") |
39
|
12
|
50
|
|
|
|
146
|
unless $key->{version} == 4; |
40
|
12
|
|
|
|
|
30
|
$key->{s2k_ciph} = $buf->get_int8; |
41
|
12
|
|
|
|
|
134
|
$key->{s2k} = Crypt::OpenPGP::S2k->parse($buf); |
42
|
12
|
50
|
|
|
|
34
|
if ($buf->offset < $buf->length) { |
43
|
0
|
|
|
|
|
0
|
$key->{encrypted} = $buf->get_bytes( $buf->length - $buf->offset ); |
44
|
|
|
|
|
|
|
} |
45
|
12
|
|
|
|
|
76
|
$key; |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub save { |
49
|
11
|
|
|
11
|
1
|
20
|
my $key = shift; |
50
|
11
|
|
|
|
|
57
|
my $buf = Crypt::OpenPGP::Buffer->new; |
51
|
11
|
|
|
|
|
133
|
$buf->put_int8($key->{version}); |
52
|
11
|
|
|
|
|
87
|
$buf->put_int8($key->{s2k_ciph}); |
53
|
11
|
|
|
|
|
87
|
$buf->put_bytes( $key->{s2k}->save ); |
54
|
11
|
|
|
|
|
157
|
$buf->bytes; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub decrypt { |
58
|
11
|
|
|
11
|
1
|
13
|
my $key = shift; |
59
|
11
|
|
|
|
|
21
|
my($passphrase) = @_; |
60
|
11
|
|
|
|
|
32
|
my $cipher = Crypt::OpenPGP::Cipher->new($key->{s2k_ciph}); |
61
|
11
|
|
|
|
|
54
|
my $keysize = $cipher->keysize; |
62
|
11
|
|
|
|
|
35
|
my $s2k_key = $key->{s2k}->generate($passphrase, $keysize); |
63
|
11
|
|
|
|
|
20
|
my($sym_key, $alg); |
64
|
11
|
50
|
|
|
|
359
|
if ($key->{encrypted}) { |
65
|
0
|
|
|
|
|
0
|
$cipher->init($s2k_key); |
66
|
0
|
|
|
|
|
0
|
$sym_key = $cipher->decrypt($key->{encrypted}); |
67
|
0
|
|
|
|
|
0
|
$alg = ord substr $sym_key, 0, 1, ''; |
68
|
|
|
|
|
|
|
} else { |
69
|
11
|
|
|
|
|
18
|
$sym_key = $s2k_key; |
70
|
11
|
|
|
|
|
88
|
$alg = $cipher->alg_id; |
71
|
|
|
|
|
|
|
} |
72
|
11
|
|
|
|
|
138
|
($sym_key, $alg); |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
1; |
76
|
|
|
|
|
|
|
__END__ |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head1 NAME |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Crypt::OpenPGP::SKSessionKey - Symmetric-Key Encrypted Session Key |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 SYNOPSIS |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
use Crypt::OpenPGP::SKSessionKey; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $passphrase = 'foobar'; # Not a very good passphrase |
87
|
|
|
|
|
|
|
my $key_data = 'f' x 64; # Not a very good key |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my $skey = Crypt::OpenPGP::SKSessionKey->new( |
90
|
|
|
|
|
|
|
Passphrase => $passphrase, |
91
|
|
|
|
|
|
|
SymKey => $key_data, |
92
|
|
|
|
|
|
|
); |
93
|
|
|
|
|
|
|
my $serialized = $skey->save; |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 DESCRIPTION |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
I<Crypt::OpenPGP::SKSessionKey> implements symmetric-key encrypted |
98
|
|
|
|
|
|
|
session key packets; these packets store symmetric-key-encrypted key data |
99
|
|
|
|
|
|
|
that, when decrypted using the proper passphrase, can be used to decrypt a |
100
|
|
|
|
|
|
|
block of ciphertext--that is, a I<Crypt::OpenPGP::Ciphertext> object. |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Symmetric-key encrypted session key packets can work in two different |
103
|
|
|
|
|
|
|
ways: in one scenario the passphrase you provide is used to encrypt |
104
|
|
|
|
|
|
|
a randomly chosen string of key material; the key material is the key |
105
|
|
|
|
|
|
|
that is actually used to encrypt the data packet, and the passphrase |
106
|
|
|
|
|
|
|
just serves to encrypt the key material. This encrypted key material |
107
|
|
|
|
|
|
|
is then serialized into the symmetric-key encrypted session key packet. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
The other method of using this encryption form is to use the passphrase |
110
|
|
|
|
|
|
|
directly to encrypt the data packet. In this scenario the need for any |
111
|
|
|
|
|
|
|
additional key material goes away, because all the receiver needs is |
112
|
|
|
|
|
|
|
the same passphrase that you have entered to encrypt the data. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
At the moment I<Crypt::OpenPGP> really only supports the first |
115
|
|
|
|
|
|
|
scenario; note also that the interface to I<new> may change in the |
116
|
|
|
|
|
|
|
future when support for the second scenario is added. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head1 USAGE |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=head2 Crypt::OpenPGP::SKSessionKey->new( %arg ) |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
Creates a new encrypted session key packet object and returns that |
123
|
|
|
|
|
|
|
object. If there are no arguments in I<%arg>, the object is created |
124
|
|
|
|
|
|
|
empty; this is used, for example in I<parse> (below), to create an |
125
|
|
|
|
|
|
|
empty packet which is then filled from the data in the buffer. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
If you wish to initialize a non-empty object, I<%arg> can contain: |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=over 4 |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=item * Passphrase |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
An arbitrary-length passphrase; that is, a string of octets. The |
134
|
|
|
|
|
|
|
passphrase is used to encrypt the actual session key such that it can |
135
|
|
|
|
|
|
|
only be decrypted by supplying the correct passphrase. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
This argument is required (for a non-empty object). |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item * SymKey |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
The symmetric cipher key: a string of octets that make up the key data |
142
|
|
|
|
|
|
|
of the symmetric cipher key. This should be at least long enough for |
143
|
|
|
|
|
|
|
the key length of your chosen cipher (see I<Cipher>, below), or, if |
144
|
|
|
|
|
|
|
you have not specified a cipher, at least 64 bytes (to allow for long |
145
|
|
|
|
|
|
|
cipher key sizes). |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
This argument is required (for a non-empty object). |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=item * S2k |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
An object of type I<Crypt::OpenPGP::S2k> (or rather, of one of its |
152
|
|
|
|
|
|
|
subclasses). If you use the passphrase directly to encrypt the data |
153
|
|
|
|
|
|
|
packet (scenario one, above), you will probably be generating the |
154
|
|
|
|
|
|
|
key material outside of this class, meaning that you will need to pass |
155
|
|
|
|
|
|
|
in the I<S2k> object that was used to generate that key material from |
156
|
|
|
|
|
|
|
the passphrase. This is the way to do that. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item * Cipher |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
The name (or ID) of a supported PGP cipher. See I<Crypt::OpenPGP::Cipher> |
161
|
|
|
|
|
|
|
for a list of valid cipher names. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
This argument is optional; by default I<Crypt::OpenPGP::Cipher> will |
164
|
|
|
|
|
|
|
use C<DES3>. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=back |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=head2 $skey->save |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Serializes the session key packet and returns the string of octets. |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 Crypt::OpenPGP::SKSessionKey->parse($buffer) |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Given I<$buffer>, a I<Crypt::OpenPGP::Buffer> object holding (or |
175
|
|
|
|
|
|
|
with offset pointing to) an encrypted session key packet, returns |
176
|
|
|
|
|
|
|
a new I<Crypt::OpenPGP::Ciphertext> object, initialized with the |
177
|
|
|
|
|
|
|
data in the buffer. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head2 $skey->decrypt($passphrase) |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
Given a passphrase I<$passphrase>, decrypts the encrypted session key |
182
|
|
|
|
|
|
|
data. The key data includes the symmetric key itself, along with a |
183
|
|
|
|
|
|
|
one-octet ID of the symmetric cipher used to encrypt the message. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Returns a list containing two items: the symmetric key and the cipher |
186
|
|
|
|
|
|
|
algorithm ID. These are suitable for passing off to the I<decrypt> |
187
|
|
|
|
|
|
|
method of a I<Crypt::OpenPGP::Ciphertext> object to decrypt a block |
188
|
|
|
|
|
|
|
of encrypted data. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head1 AUTHOR & COPYRIGHTS |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Please see the Crypt::OpenPGP manpage for author, copyright, and |
193
|
|
|
|
|
|
|
license information. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=cut |