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   11 use strict;
  2         2  
  2         69  
4 2     2   8 use warnings;
  2         17  
  2         148  
5 2     2   20 use Carp qw( croak );
  2         3  
  2         127  
6 2     2   8 use Convert::PEM;
  2         9  
  2         80  
7 2     2   8 use Crypt::DSA::Key;
  2         2  
  2         85  
8              
9             our $VERSION = '1.23'; #VERSION
10              
11 2     2   8 use vars qw{$VERSION @ISA};
  2         2  
  2         149  
12             BEGIN {
13 2     2   8240 @ISA = 'Crypt::DSA::Key';
14             }
15              
16             sub deserialize {
17 4     4 0 6 my $key = shift;
18 4         14 my %param = @_;
19 4 100       31 $param{Content} =~ /DSA PRIVATE KEY/ ?
20             $key->_deserialize_privkey(%param) :
21             $key->_deserialize_pubkey(%param);
22             }
23              
24             sub _deserialize_privkey {
25 2     2   4 my $key = shift;
26 2         5 my %param = @_;
27              
28 2         6 my $pem = $key->_pem;
29             my $pkey = $pem->decode( Content => $param{Content},
30             Password => $param{Password},
31 2         11 Macro => 'DSAPrivateKey' );
32 2 50       118094 return unless $pkey;
33              
34 2         6 for my $m (qw( p q g pub_key priv_key )) {
35 10         60 $key->$m( $pkey->{$m} );
36             }
37 2         63 $key;
38             }
39              
40             sub _deserialize_pubkey {
41 2     2   5 my $key = shift;
42 2         4 my %param = @_;
43              
44 2         5 my $pem = $key->_pem;
45             my $pkey = $pem->decode( Content => $param{Content},
46             Password => $param{Password},
47 2         13 Macro => 'DSAPublicKey',
48             Name => 'PUBLIC KEY' );
49 2 50       107762 return unless $pkey;
50              
51 2         12 my $asn = $pem->asn->find('DSAPubKeyInner');
52 2 50       55 my $num = $asn->decode($pkey->{pub_key}[0]) or croak $asn->{error};
53              
54 2         47858 for my $m (qw( p q g )) {
55 6         53 $key->$m( $pkey->{inner}{DSAParams}{$m} );
56             }
57 2         13 $key->pub_key($num);
58              
59 2         66 $key;
60             }
61              
62             sub serialize {
63 3     3 0 4 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       11 $key->priv_key ? $key->_serialize_privkey(@_) : $key->_serialize_pubkey(@_);
67             }
68              
69             sub _serialize_privkey {
70 2     2   58 my $key = shift;
71 2         7 my %param = @_;
72              
73 2         6 my $pkey = { version => 0 };
74 2         5 for my $m (qw( p q g pub_key priv_key )) {
75 10         42 $pkey->{$m} = $key->$m();
76             }
77              
78 2         5 my $pem = $key->_pem;
79             my $buf = $pem->encode(
80             Content => $pkey,
81             Password => $param{Password},
82 2 50       17 Name => 'DSA PRIVATE KEY',
83             Macro => 'DSAPrivateKey',
84             ) or croak $pem->errstr;
85 2         241854 $buf;
86             }
87              
88             sub _serialize_pubkey {
89 1     1   2 my $key = shift;
90 1         3 my %param = @_;
91 1         3 my $pem = $key->_pem;
92 1         6 my $asn = $pem->asn->find('DSAPubKeyInner');
93             ## Force stringification.
94 1 50       26 my $str = $asn->encode($key->pub_key . '') or croak $asn->{error};
95 1         31557 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       9 Name => 'PUBLIC KEY',
110             Macro => 'DSAPublicKey',
111             ) or return $key->error($pem->errstr);
112 1         73640 $buf;
113             }
114              
115             sub _pem {
116 7     7   11 my $key = shift;
117 7 100       24 unless (defined $key->{__pem}) {
118 5         51 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         22313 $key->{__pem} = $pem;
145             }
146 7         15 $key->{__pem};
147             }
148              
149             1;
150             __END__