File Coverage

blib/lib/Crypt/DSA/Key/PEM.pm
Criterion Covered Total %
statement 64 64 100.0
branch 12 18 66.6
condition n/a
subroutine 14 14 100.0
pod 0 2 0.0
total 90 98 91.8


line stmt bran cond sub pod time code
1             package Crypt::DSA::Key::PEM;
2              
3 2     2   14 use strict;
  2         4  
  2         97  
4 2     2   19 use warnings;
  2         24  
  2         355  
5 2     2   22 use Carp qw( croak );
  2         9  
  2         244  
6 2     2   18 use Convert::PEM;
  2         22  
  2         139  
7 2     2   9 use Crypt::DSA::Key;
  2         4  
  2         116  
8              
9             our $VERSION = '1.20'; #VERSION
10              
11 2     2   23 use vars qw{$VERSION @ISA};
  2         5  
  2         237  
12             BEGIN {
13 2     2   1740 @ISA = 'Crypt::DSA::Key';
14             }
15              
16             sub deserialize {
17 4     4 0 18 my $key = shift;
18 4         15 my %param = @_;
19 4 100       36 $param{Content} =~ /DSA PRIVATE KEY/ ?
20             $key->_deserialize_privkey(%param) :
21             $key->_deserialize_pubkey(%param);
22             }
23              
24             sub _deserialize_privkey {
25 2     2   2 my $key = shift;
26 2         11 my %param = @_;
27              
28 2         6 my $pem = $key->_pem;
29             my $pkey = $pem->decode( Content => $param{Content},
30             Password => $param{Password},
31 2         26 Macro => 'DSAPrivateKey' );
32 2 50       184364 return unless $pkey;
33              
34 2         11 for my $m (qw( p q g pub_key priv_key )) {
35 10         99 $key->$m( $pkey->{$m} );
36             }
37 2         126 $key;
38             }
39              
40             sub _deserialize_pubkey {
41 2     2   5 my $key = shift;
42 2         7 my %param = @_;
43              
44 2         32 my $pem = $key->_pem;
45             my $pkey = $pem->decode( Content => $param{Content},
46             Password => $param{Password},
47 2         17 Macro => 'DSAPublicKey',
48             Name => 'PUBLIC KEY' );
49 2 50       207135 return unless $pkey;
50              
51 2         21 my $asn = $pem->asn->find('DSAPubKeyInner');
52 2 50       65 my $num = $asn->decode($pkey->{pub_key}[0]) or croak $asn->{error};
53              
54 2         81888 for my $m (qw( p q g )) {
55 6         69 $key->$m( $pkey->{inner}{DSAParams}{$m} );
56             }
57 2         15 $key->pub_key($num);
58              
59 2         79 $key;
60             }
61              
62             sub serialize {
63 3     3 0 7 my $key = shift;
64             ## If this is a private key (has the private key portion), serialize
65             ## it as a private key; otherwise use a public key ASN.1 object.
66 3 100       13 $key->priv_key ? $key->_serialize_privkey(@_) : $key->_serialize_pubkey(@_);
67             }
68              
69             sub _serialize_privkey {
70 2     2   76 my $key = shift;
71 2         9 my %param = @_;
72              
73 2         7 my $pkey = { version => 0 };
74 2         6 for my $m (qw( p q g pub_key priv_key )) {
75 10         42 $pkey->{$m} = $key->$m();
76             }
77              
78 2         35 my $pem = $key->_pem;
79             my $buf = $pem->encode(
80             Content => $pkey,
81             Password => $param{Password},
82 2 50       40 Name => 'DSA PRIVATE KEY',
83             Macro => 'DSAPrivateKey',
84             ) or croak $pem->errstr;
85 2         392176 $buf;
86             }
87              
88             sub _serialize_pubkey {
89 1     1   3 my $key = shift;
90 1         5 my %param = @_;
91 1         5 my $pem = $key->_pem;
92 1         8 my $asn = $pem->asn->find('DSAPubKeyInner');
93             ## Force stringification.
94 1 50       38 my $str = $asn->encode($key->pub_key . '') or croak $asn->{error};
95 1         49672 my $pkey = {
96             inner => {
97             objId => '1.2.840.10040.4.1',
98             DSAParams => {
99             p => $key->p,
100             q => $key->q,
101             g => $key->g
102             },
103             },
104             pub_key => $str
105             };
106             my $buf = $pem->encode(
107             Content => $pkey,
108             Password => $param{Password},
109 1 50       32 Name => 'PUBLIC KEY',
110             Macro => 'DSAPublicKey',
111             ) or return $key->error($pem->errstr);
112 1         158255 $buf;
113             }
114              
115             sub _pem {
116 7     7   13 my $key = shift;
117 7 100       32 unless (defined $key->{__pem}) {
118 5         89 my $pem = Convert::PEM->new(
119             Name => "DSA PRIVATE KEY",
120             ASN => qq(
121             DSAPrivateKey ::= SEQUENCE {
122             version INTEGER,
123             p INTEGER,
124             q INTEGER,
125             g INTEGER,
126             pub_key INTEGER,
127             priv_key INTEGER
128             }
129              
130             DSAPublicKey ::= SEQUENCE {
131             inner SEQUENCE {
132             objId OBJECT IDENTIFIER,
133             DSAParams SEQUENCE {
134             p INTEGER,
135             q INTEGER,
136             g INTEGER
137             }
138             }
139             pub_key BIT STRING
140             }
141              
142             DSAPubKeyInner ::= INTEGER
143             ));
144 5         28949 $key->{__pem} = $pem;
145             }
146 7         24 $key->{__pem};
147             }
148              
149             1;
150             __END__