| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Crypt::OpenPGP::PacketFactory; |
|
2
|
14
|
|
|
14
|
|
546
|
use strict; |
|
|
14
|
|
|
|
|
28
|
|
|
|
14
|
|
|
|
|
415
|
|
|
3
|
|
|
|
|
|
|
|
|
4
|
14
|
|
|
14
|
|
78
|
use Crypt::OpenPGP::Constants qw( :packet ); |
|
|
14
|
|
|
|
|
21
|
|
|
|
14
|
|
|
|
|
164
|
|
|
5
|
14
|
|
|
14
|
|
3610
|
use Crypt::OpenPGP::ErrorHandler; |
|
|
14
|
|
|
|
|
30
|
|
|
|
14
|
|
|
|
|
401
|
|
|
6
|
14
|
|
|
14
|
|
83
|
use base qw( Crypt::OpenPGP::ErrorHandler ); |
|
|
14
|
|
|
|
|
30
|
|
|
|
14
|
|
|
|
|
1015
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
14
|
|
|
14
|
|
83
|
use vars qw( %PACKET_TYPES %PACKET_TYPES_BY_CLASS ); |
|
|
14
|
|
|
|
|
21
|
|
|
|
14
|
|
|
|
|
11547
|
|
|
9
|
|
|
|
|
|
|
%PACKET_TYPES = ( |
|
10
|
|
|
|
|
|
|
PGP_PKT_PUBKEY_ENC() => { class => 'Crypt::OpenPGP::SessionKey' }, |
|
11
|
|
|
|
|
|
|
PGP_PKT_SIGNATURE() => { class => 'Crypt::OpenPGP::Signature' }, |
|
12
|
|
|
|
|
|
|
PGP_PKT_SYMKEY_ENC() => { class => 'Crypt::OpenPGP::SKSessionKey' }, |
|
13
|
|
|
|
|
|
|
PGP_PKT_ONEPASS_SIG() => { class => 'Crypt::OpenPGP::OnePassSig' }, |
|
14
|
|
|
|
|
|
|
PGP_PKT_SECRET_KEY() => { class => 'Crypt::OpenPGP::Certificate', |
|
15
|
|
|
|
|
|
|
args => [ 1, 0 ] }, |
|
16
|
|
|
|
|
|
|
PGP_PKT_PUBLIC_KEY() => { class => 'Crypt::OpenPGP::Certificate', |
|
17
|
|
|
|
|
|
|
args => [ 0, 0 ] }, |
|
18
|
|
|
|
|
|
|
PGP_PKT_SECRET_SUBKEY() => { class => 'Crypt::OpenPGP::Certificate', |
|
19
|
|
|
|
|
|
|
args => [ 1, 1 ] }, |
|
20
|
|
|
|
|
|
|
PGP_PKT_USER_ID() => { class => 'Crypt::OpenPGP::UserID' }, |
|
21
|
|
|
|
|
|
|
PGP_PKT_PUBLIC_SUBKEY() => { class => 'Crypt::OpenPGP::Certificate', |
|
22
|
|
|
|
|
|
|
args => [ 0, 1 ] }, |
|
23
|
|
|
|
|
|
|
PGP_PKT_COMPRESSED() => { class => 'Crypt::OpenPGP::Compressed' }, |
|
24
|
|
|
|
|
|
|
PGP_PKT_ENCRYPTED() => { class => 'Crypt::OpenPGP::Ciphertext' }, |
|
25
|
|
|
|
|
|
|
PGP_PKT_MARKER() => { class => 'Crypt::OpenPGP::Marker' }, |
|
26
|
|
|
|
|
|
|
PGP_PKT_PLAINTEXT() => { class => 'Crypt::OpenPGP::Plaintext' }, |
|
27
|
|
|
|
|
|
|
PGP_PKT_RING_TRUST() => { class => 'Crypt::OpenPGP::Trust' }, |
|
28
|
|
|
|
|
|
|
PGP_PKT_ENCRYPTED_MDC() => { class => 'Crypt::OpenPGP::Ciphertext', |
|
29
|
|
|
|
|
|
|
args => [ 1 ] }, |
|
30
|
|
|
|
|
|
|
PGP_PKT_MDC() => { class => 'Crypt::OpenPGP::MDC' }, |
|
31
|
|
|
|
|
|
|
); |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
%PACKET_TYPES_BY_CLASS = map { $PACKET_TYPES{$_}{class} => $_ } keys %PACKET_TYPES; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub parse { |
|
36
|
317
|
|
|
317
|
1
|
1495
|
my $class = shift; |
|
37
|
317
|
|
|
|
|
467
|
my($buf, $find, $parse) = @_; |
|
38
|
317
|
100
|
66
|
|
|
1506
|
return unless $buf && $buf->offset < $buf->length; |
|
39
|
234
|
|
|
|
|
1910
|
my(%find, %parse); |
|
40
|
234
|
100
|
|
|
|
519
|
if ($find) { |
|
41
|
57
|
50
|
|
|
|
303
|
%find = ref($find) eq 'ARRAY' ? (map { $_ => 1 } @$find) : |
|
|
258
|
|
|
|
|
547
|
|
|
42
|
|
|
|
|
|
|
($find => 1); |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
else { |
|
45
|
182
|
|
|
|
|
1062
|
%find = map { $_ => 1 } keys %PACKET_TYPES; |
|
|
2837
|
|
|
|
|
4110
|
|
|
46
|
|
|
|
|
|
|
} |
|
47
|
234
|
100
|
|
|
|
845
|
if ($parse) { |
|
48
|
53
|
50
|
|
|
|
193
|
%parse = ref($parse) eq 'ARRAY' ? (map { $_ => 1 } @$parse) : |
|
|
161
|
|
|
|
|
338
|
|
|
49
|
|
|
|
|
|
|
($parse => 1); |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
else { |
|
52
|
186
|
|
|
|
|
1083
|
%parse = %find; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
234
|
|
|
|
|
419
|
my($type, $len, $partial, $hdrlen, $b); |
|
56
|
|
|
|
|
|
|
do { |
|
57
|
397
|
|
|
|
|
1010
|
($type, $len, $partial, $hdrlen) = $class->_parse_header($buf); |
|
58
|
397
|
100
|
|
|
|
2357
|
$b = $buf->extract($len ? $len : $buf->length - $buf->offset); |
|
59
|
397
|
100
|
|
|
|
10640
|
return unless $type; |
|
60
|
234
|
|
|
|
|
343
|
} while !$find{$type}; ## Skip |
|
61
|
|
|
|
|
|
|
|
|
62
|
226
|
|
|
|
|
654
|
while ($partial) { |
|
63
|
5
|
|
|
|
|
6
|
my $off = $buf->offset; |
|
64
|
5
|
|
|
|
|
88
|
(my($nlen), $partial) = $class->_parse_new_len_header($buf); |
|
65
|
5
|
|
|
|
|
33
|
$len += $nlen + ($buf->offset - $off); |
|
66
|
5
|
|
|
|
|
6
|
$b->append( $buf->get_bytes($nlen) ); |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
|
|
69
|
226
|
|
|
|
|
353
|
my $obj; |
|
70
|
226
|
100
|
66
|
|
|
1277
|
if ($parse{$type} && (my $ref = $PACKET_TYPES{$type})) { |
|
71
|
220
|
|
|
|
|
478
|
my $pkt_class = $ref->{class}; |
|
72
|
220
|
100
|
|
|
|
731
|
my @args = $ref->{args} ? @{ $ref->{args} } : (); |
|
|
65
|
|
|
|
|
188
|
|
|
73
|
220
|
|
|
11
|
|
20794
|
eval "use $pkt_class;"; |
|
|
7
|
|
|
11
|
|
2228
|
|
|
|
7
|
|
|
11
|
|
31
|
|
|
|
7
|
|
|
11
|
|
132
|
|
|
|
7
|
|
|
11
|
|
1298
|
|
|
|
7
|
|
|
11
|
|
40
|
|
|
|
7
|
|
|
10
|
|
123
|
|
|
|
7
|
|
|
9
|
|
1296
|
|
|
|
7
|
|
|
4
|
|
33
|
|
|
|
7
|
|
|
3
|
|
121
|
|
|
|
7
|
|
|
3
|
|
546
|
|
|
|
7
|
|
|
3
|
|
38
|
|
|
|
7
|
|
|
1
|
|
120
|
|
|
|
7
|
|
|
1
|
|
47
|
|
|
|
7
|
|
|
1
|
|
37
|
|
|
|
7
|
|
|
1
|
|
150
|
|
|
|
7
|
|
|
1
|
|
39
|
|
|
|
7
|
|
|
1
|
|
34
|
|
|
|
7
|
|
|
1
|
|
108
|
|
|
|
6
|
|
|
1
|
|
33
|
|
|
|
6
|
|
|
1
|
|
25
|
|
|
|
6
|
|
|
1
|
|
93
|
|
|
|
6
|
|
|
1
|
|
28
|
|
|
|
6
|
|
|
1
|
|
26
|
|
|
|
6
|
|
|
1
|
|
75
|
|
|
|
1
|
|
|
1
|
|
1
|
|
|
|
1
|
|
|
1
|
|
16
|
|
|
|
1
|
|
|
1
|
|
7
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
24
|
|
|
|
1
|
|
|
1
|
|
8
|
|
|
|
1
|
|
|
1
|
|
3
|
|
|
|
1
|
|
|
1
|
|
24
|
|
|
|
1
|
|
|
1
|
|
8
|
|
|
|
1
|
|
|
1
|
|
3
|
|
|
|
1
|
|
|
1
|
|
21
|
|
|
|
1
|
|
|
1
|
|
9
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
23
|
|
|
|
1
|
|
|
1
|
|
9
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
19
|
|
|
|
1
|
|
|
1
|
|
11
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
23
|
|
|
|
1
|
|
|
1
|
|
5
|
|
|
|
1
|
|
|
1
|
|
15
|
|
|
|
1
|
|
|
1
|
|
17
|
|
|
|
1
|
|
|
1
|
|
5
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
14
|
|
|
|
1
|
|
|
1
|
|
4
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
13
|
|
|
|
1
|
|
|
1
|
|
8
|
|
|
|
1
|
|
|
1
|
|
1
|
|
|
|
1
|
|
|
1
|
|
25
|
|
|
|
1
|
|
|
1
|
|
8
|
|
|
|
1
|
|
|
1
|
|
4
|
|
|
|
1
|
|
|
1
|
|
22
|
|
|
|
1
|
|
|
1
|
|
6
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
17
|
|
|
|
1
|
|
|
1
|
|
5
|
|
|
|
1
|
|
|
1
|
|
1
|
|
|
|
1
|
|
|
1
|
|
12
|
|
|
|
1
|
|
|
1
|
|
9
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
21
|
|
|
|
1
|
|
|
1
|
|
10
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
19
|
|
|
|
1
|
|
|
1
|
|
12
|
|
|
|
1
|
|
|
1
|
|
1
|
|
|
|
1
|
|
|
1
|
|
26
|
|
|
|
1
|
|
|
1
|
|
9
|
|
|
|
1
|
|
|
1
|
|
3
|
|
|
|
1
|
|
|
1
|
|
21
|
|
|
|
1
|
|
|
1
|
|
10
|
|
|
|
1
|
|
|
1
|
|
2
|
|
|
|
1
|
|
|
1
|
|
26
|
|
|
|
1
|
|
|
1
|
|
7
|
|
|
|
1
|
|
|
1
|
|
3
|
|
|
|
1
|
|
|
1
|
|
22
|
|
|
|
1
|
|
|
|
|
9
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
28
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
24
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
27
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
23
|
|
|
|
1
|
|
|
|
|
12
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
25
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
16
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
15
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
11
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
13
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
14
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
12
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
18
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
31
|
|
|
|
1
|
|
|
|
|
10
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
20
|
|
|
|
1
|
|
|
|
|
11
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
23
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
26
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
24
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
22
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
20
|
|
|
|
1
|
|
|
|
|
10
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
25
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
23
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
18
|
|
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
17
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
23
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
17
|
|
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
18
|
|
|
74
|
220
|
50
|
|
|
|
878
|
return $class->error("Loading $pkt_class failed: $@") if $@; |
|
75
|
220
|
|
|
|
|
1600
|
$obj = $pkt_class->parse($b, @args); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
else { |
|
78
|
11
|
|
|
|
|
45
|
$obj = { type => $type, length => $len, |
|
79
|
|
|
|
|
|
|
__pkt_len => $len + $hdrlen, __unparsed => 1 }; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
226
|
|
|
|
|
2279
|
$obj; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub _parse_header { |
|
85
|
396
|
|
|
397
|
|
491
|
my $class = shift; |
|
86
|
396
|
|
|
|
|
445
|
my($buf) = @_; |
|
87
|
396
|
100
|
66
|
|
|
1474
|
return unless $buf && $buf->offset < $buf->length; |
|
88
|
|
|
|
|
|
|
|
|
89
|
388
|
|
|
|
|
2453
|
my $off_start = $buf->offset; |
|
90
|
388
|
|
|
|
|
1394
|
my $tag = $buf->get_int8; |
|
91
|
388
|
50
|
|
|
|
5398
|
return $class->error("Parse error: bit 7 not set!") |
|
92
|
|
|
|
|
|
|
unless $tag & 0x80; |
|
93
|
387
|
|
|
|
|
510
|
my $is_new = $tag & 0x40; |
|
94
|
387
|
|
|
|
|
518
|
my($type, $len, $partial); |
|
95
|
387
|
100
|
|
|
|
702
|
if ($is_new) { |
|
96
|
136
|
|
|
|
|
188
|
$type = $tag & 0x3f; |
|
97
|
136
|
|
|
|
|
337
|
($len, $partial) = $class->_parse_new_len_header($buf); |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
else { |
|
100
|
254
|
|
|
|
|
519
|
$type = ($tag>>2)&0xf; |
|
101
|
254
|
50
|
|
|
|
780
|
my $lenbytes = (($tag&3)==3) ? 0 : (1<<($tag & 3)); |
|
102
|
254
|
|
|
|
|
269
|
$len = 0; |
|
103
|
254
|
|
|
|
|
635
|
for (1..$lenbytes) { |
|
104
|
352
|
|
|
|
|
1255
|
$len <<= 8; |
|
105
|
352
|
|
|
|
|
807
|
$len += $buf->get_int8; |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
} |
|
108
|
385
|
|
|
|
|
2922
|
($type, $len, $partial, $buf->offset - $off_start); |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub _parse_new_len_header { |
|
112
|
134
|
|
|
138
|
|
178
|
my $class = shift; |
|
113
|
134
|
|
|
|
|
162
|
my($buf) = @_; |
|
114
|
134
|
50
|
33
|
|
|
537
|
return unless $buf && $buf->offset < $buf->length; |
|
115
|
134
|
|
|
|
|
863
|
my $lb1 = $buf->get_int8; |
|
116
|
134
|
|
|
|
|
1382
|
my($partial, $len); |
|
117
|
134
|
50
|
|
|
|
257
|
if ($lb1 <= 191) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
118
|
134
|
|
|
|
|
192
|
$len = $lb1; |
|
119
|
|
|
|
|
|
|
} elsif ($lb1 <= 223) { |
|
120
|
1
|
|
|
|
|
2
|
$len = (($lb1-192) << 8) + $buf->get_int8 + 192; |
|
121
|
|
|
|
|
|
|
} elsif ($lb1 < 255) { |
|
122
|
1
|
|
|
|
|
12
|
$partial++; |
|
123
|
1
|
|
|
|
|
5
|
$len = 1 << ($lb1 & 0x1f); |
|
124
|
|
|
|
|
|
|
} else { |
|
125
|
1
|
|
|
|
|
2
|
$len = $buf->get_int32; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
134
|
|
|
|
|
303
|
($len, $partial); |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub save { |
|
131
|
59
|
|
|
63
|
1
|
1106
|
my $class = shift; |
|
132
|
59
|
|
|
|
|
138
|
my @objs = @_; |
|
133
|
59
|
|
|
|
|
129
|
my $ser = ''; |
|
134
|
59
|
|
|
|
|
140
|
for my $obj (@objs) { |
|
135
|
95
|
|
|
|
|
722
|
my $body = $obj->save; |
|
136
|
95
|
|
|
|
|
1040
|
my $len = length($body); |
|
137
|
|
|
|
|
|
|
my $type = $obj->can('pkt_type') ? $obj->pkt_type : |
|
138
|
95
|
100
|
|
|
|
745
|
$PACKET_TYPES_BY_CLASS{ref($obj)}; |
|
139
|
95
|
100
|
|
|
|
460
|
my $hdrlen = $obj->can('pkt_hdrlen') ? $obj->pkt_hdrlen : undef; |
|
140
|
95
|
|
|
|
|
311
|
my $buf = Crypt::OpenPGP::Buffer->new; |
|
141
|
95
|
100
|
66
|
|
|
1112
|
if ($obj->{is_new} || $type > 15) { |
|
142
|
3
|
|
|
|
|
7
|
my $tag = 0xc0 | ($type & 0x3f); |
|
143
|
3
|
|
|
|
|
28
|
$buf->put_int8($tag); |
|
144
|
3
|
50
|
|
|
|
22
|
return $class->error("Can't write partial length packets") |
|
145
|
|
|
|
|
|
|
unless $len; |
|
146
|
3
|
50
|
|
|
|
6
|
if ($len < 192) { |
|
|
|
0
|
|
|
|
|
|
|
147
|
3
|
|
|
|
|
26
|
$buf->put_int8($len); |
|
148
|
|
|
|
|
|
|
} elsif ($len < 8384) { |
|
149
|
1
|
|
|
|
|
9
|
$len -= 192; |
|
150
|
1
|
|
|
|
|
2
|
$buf->put_int8(int($len / 256) + 192); |
|
151
|
1
|
|
|
|
|
20
|
$buf->put_int8($len % 256); |
|
152
|
|
|
|
|
|
|
} else { |
|
153
|
1
|
|
|
|
|
10
|
$buf->put_int8(0xff); |
|
154
|
1
|
|
|
|
|
2
|
$buf->put_int32($len); |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
else { |
|
158
|
93
|
100
|
|
|
|
255
|
unless ($hdrlen) { |
|
159
|
82
|
50
|
|
|
|
321
|
if (!defined $len) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
160
|
1
|
|
|
|
|
2
|
$hdrlen = 0; |
|
161
|
|
|
|
|
|
|
} elsif ($len < 256) { |
|
162
|
67
|
|
|
|
|
105
|
$hdrlen = 1; |
|
163
|
|
|
|
|
|
|
} elsif ($len < 65536) { |
|
164
|
16
|
|
|
|
|
34
|
$hdrlen = 2; |
|
165
|
|
|
|
|
|
|
} else { |
|
166
|
1
|
|
|
|
|
2
|
$hdrlen = 4; |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
} |
|
169
|
93
|
50
|
66
|
|
|
435
|
return $class->error("Packet overflow: overflow preset len") |
|
170
|
|
|
|
|
|
|
if $hdrlen == 1 && $len > 255; |
|
171
|
93
|
50
|
66
|
|
|
365
|
$hdrlen = 4 if $hdrlen == 2 && $len > 65535; |
|
172
|
93
|
|
|
|
|
173
|
my $tag = 0x80 | ($type << 2); |
|
173
|
93
|
50
|
|
|
|
333
|
if ($hdrlen == 0) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
174
|
1
|
|
|
|
|
8
|
$buf->put_int8($tag | 3); |
|
175
|
|
|
|
|
|
|
} elsif ($hdrlen == 1) { |
|
176
|
67
|
|
|
|
|
193
|
$buf->put_int8($tag); |
|
177
|
67
|
|
|
|
|
481
|
$buf->put_int8($len); |
|
178
|
|
|
|
|
|
|
} elsif ($hdrlen == 2) { |
|
179
|
27
|
|
|
|
|
137
|
$buf->put_int8($tag | 1); |
|
180
|
27
|
|
|
|
|
289
|
$buf->put_int16($len); |
|
181
|
|
|
|
|
|
|
} else { |
|
182
|
1
|
|
|
|
|
20
|
$buf->put_int8($tag | 2); |
|
183
|
1
|
|
|
|
|
11
|
$buf->put_int32($len); |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
} |
|
186
|
95
|
|
|
|
|
517
|
$buf->put_bytes($body); |
|
187
|
95
|
|
|
|
|
675
|
$ser .= $buf->bytes; |
|
188
|
|
|
|
|
|
|
} |
|
189
|
59
|
|
|
|
|
745
|
$ser; |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
1; |
|
193
|
|
|
|
|
|
|
__END__ |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head1 NAME |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Crypt::OpenPGP::PacketFactory - Parse and save PGP packet streams |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
use Crypt::OpenPGP::PacketFactory; |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
my $buf = Crypt::OpenPGP::Buffer->new; |
|
204
|
|
|
|
|
|
|
while (my $packet = Crypt::OpenPGP::PacketFactory->parse($buf)) { |
|
205
|
|
|
|
|
|
|
## Do something with $packet |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
my @packets; |
|
209
|
|
|
|
|
|
|
my $serialized = Crypt::OpenPGP::PacketFactory->save(@packets); |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
I<Crypt::OpenPGP::PacketFactory> parses PGP buffers (objects of type |
|
214
|
|
|
|
|
|
|
I<Crypt::OpenPGP::Buffer>) and generates packet objects of various |
|
215
|
|
|
|
|
|
|
packet classes (for example, I<Crypt::OpenPGP::Certificate> objects, |
|
216
|
|
|
|
|
|
|
I<Crypt::OpenPGP::Signature> objects, etc.). It also takes lists of |
|
217
|
|
|
|
|
|
|
packets, serializes each of them, and adds type/length headers to |
|
218
|
|
|
|
|
|
|
them, forming a stream of packets suitable for armouring, writing |
|
219
|
|
|
|
|
|
|
to disk, sending through email, etc. |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 USAGE |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head2 Crypt::OpenPGP::PacketFactory->parse($buffer [, $find ]) |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Given a buffer object I<$buffer> of type I<Crypt::OpenPGP::Buffer>, |
|
226
|
|
|
|
|
|
|
iterates through the packets serialized in the buffer, parsing |
|
227
|
|
|
|
|
|
|
each one, and returning each packet one by one. In other words, given |
|
228
|
|
|
|
|
|
|
a buffer, it acts as a standard iterator. |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
By default I<parse> parses and returns all packets in the buffer, of |
|
231
|
|
|
|
|
|
|
any packet type. If you are only looking for packets of a specific |
|
232
|
|
|
|
|
|
|
type, though, it makes no sense to return every packet; you can |
|
233
|
|
|
|
|
|
|
control which packets I<parse> parses and returns with I<$find>, which |
|
234
|
|
|
|
|
|
|
should be a reference to a list of packet types to find in the buffer. |
|
235
|
|
|
|
|
|
|
Only packets of those types will be parsed and returned to you. You |
|
236
|
|
|
|
|
|
|
can get the packet type constants from I<Crypt::OpenPGP::Constants> |
|
237
|
|
|
|
|
|
|
by importing the C<:packet> tag. |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Returns the next packet in the buffer until the end of the buffer |
|
240
|
|
|
|
|
|
|
is reached (or until there are no more of the packets which you wish |
|
241
|
|
|
|
|
|
|
to find), at which point returns a false value. |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=head2 Crypt::OpenPGP::PacketFactory->save(@packets) |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
Given a list of packets I<@packets>, serializes each packet, then |
|
246
|
|
|
|
|
|
|
adds a type/length header on to each one, resulting in a string of |
|
247
|
|
|
|
|
|
|
octets representing the serialized packets, suitable for passing in |
|
248
|
|
|
|
|
|
|
to I<parse>, or for writing to disk, or anywhere else. |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head1 AUTHOR & COPYRIGHTS |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
Please see the Crypt::OpenPGP manpage for author, copyright, and |
|
253
|
|
|
|
|
|
|
license information. |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=cut |