File Coverage

blib/lib/Crypt/DSA/Key/PEM.pm
Criterion Covered Total %
statement 60 60 100.0
branch 12 18 66.7
condition n/a
subroutine 12 12 100.0
pod 0 2 0.0
total 84 92 91.3


line stmt bran cond sub pod time code
1             # $Id: PEM.pm 1830 2005-05-25 21:58:57Z btrott $
2              
3             package Crypt::DSA::Key::PEM;
4 2     2   32 use strict;
  2         32  
  2         94  
5              
6 2     2   31 use Convert::PEM;
  2         18  
  2         75  
7              
8 2     2   32 use Crypt::DSA::Key;
  2         44  
  2         32  
9 2     2   28 use Carp qw( croak );
  2         19  
  2         83  
10 2     2   42 use base qw( Crypt::DSA::Key );
  2         19  
  2         125  
11              
12             sub deserialize {
13 4     4 0 39     my $key = shift;
14 4         50     my %param = @_;
15 4 100       71     $param{Content} =~ /DSA PRIVATE KEY/ ?
16                     $key->_deserialize_privkey(%param) :
17                     $key->_deserialize_pubkey(%param);
18             }
19              
20             sub _deserialize_privkey {
21 2     2   17     my $key = shift;
22 2         23     my %param = @_;
23              
24 2         24     my $pem = $key->_pem;
25 2         35     my $pkey = $pem->decode( Content => $param{Content},
26                                          Password => $param{Password},
27                                          Macro => 'DSAPrivateKey' );
28 2 50       64     return unless $pkey;
29              
30 2         19     for my $m (qw( p q g pub_key priv_key )) {
31 10         174         $key->$m( $pkey->{$m} );
32                 }
33 2         99     $key;
34             }
35              
36             sub _deserialize_pubkey {
37 2     2   20     my $key = shift;
38 2         25     my %param = @_;
39              
40 2         23     my $pem = $key->_pem;
41 2         39     my $pkey = $pem->decode( Content => $param{Content},
42                                          Password => $param{Password},
43                                          Macro => 'DSAPublicKey',
44                                          Name => 'PUBLIC KEY' );
45 2 50       71     return unless $pkey;
46              
47 2         30     my $asn = $pem->asn->find('DSAPubKeyInner');
48 2 50       164     my $num = $asn->decode($pkey->{pub_key}[0]) or croak $asn->{error};
49              
50 2         91     for my $m (qw( p q g )) {
51 6         130         $key->$m( $pkey->{inner}{DSAParams}{$m} );
52                 }
53 2         36     $key->pub_key($num);
54              
55 2         24     $key;
56             }
57              
58             sub serialize {
59 3     3 0 28     my $key = shift;
60             ## If this is a private key (has the private key portion), serialize
61             ## it as a private key; otherwise use a public key ASN.1 object.
62 3 100       73     $key->priv_key ? $key->_serialize_privkey(@_) : $key->_serialize_pubkey(@_);
63             }
64              
65             sub _serialize_privkey {
66 2     2   96     my $key = shift;
67 2         29     my %param = @_;
68              
69 2         22     my $pkey = { version => 0 };
70 2         19     for my $m (qw( p q g pub_key priv_key )) {
71 10         155         $pkey->{$m} = $key->$m();
72                 }
73              
74 2         23     my $pem = $key->_pem;
75 2 50       76     my $buf = $pem->encode(
76                         Content => $pkey,
77                         Password => $param{Password},
78                         Name => 'DSA PRIVATE KEY',
79                         Macro => 'DSAPrivateKey',
80                     ) or croak $pem->errstr;
81 2         224     $buf;
82             }
83              
84             sub _serialize_pubkey {
85 1     1   10     my $key = shift;
86 1         13     my %param = @_;
87 1         13     my $pem = $key->_pem;
88 1         18     my $asn = $pem->asn->find('DSAPubKeyInner');
89             ## Force stringification.
90 1 50       68     my $str = $asn->encode($key->pub_key . '') or croak $asn->{error};
91 1         474     my $pkey = {
92                     inner => {
93                         objId => '1.2.840.10040.4.1',
94                         DSAParams => {
95                             p => $key->p,
96                             q => $key->q,
97                             g => $key->g
98                         },
99                     },
100                     pub_key => $str
101                 };
102 1 50       20     my $buf = $pem->encode(
103                         Content => $pkey,
104                         Password => $param{Password},
105                         Name => 'PUBLIC KEY',
106                         Macro => 'DSAPublicKey',
107                     ) or return $key->error($pem->errstr);
108 1         11     $buf;
109             }
110              
111             sub _pem {
112 7     7   63     my $key = shift;
113 7 100       80     unless (defined $key->{__pem}) {
114 5         141         my $pem = Convert::PEM->new(
115                         Name => "DSA PRIVATE KEY",
116                         ASN => qq(
117             DSAPrivateKey ::= SEQUENCE {
118             version INTEGER,
119             p INTEGER,
120             q INTEGER,
121             g INTEGER,
122             pub_key INTEGER,
123             priv_key INTEGER
124             }
125            
126             DSAPublicKey ::= SEQUENCE {
127             inner SEQUENCE {
128             objId OBJECT IDENTIFIER,
129             DSAParams SEQUENCE {
130             p INTEGER,
131             q INTEGER,
132             g INTEGER
133             }
134             }
135             pub_key BIT STRING
136             }
137            
138             DSAPubKeyInner ::= INTEGER
139             ));
140 5         68253         $key->{__pem} = $pem;
141                 }
142 7         88     $key->{__pem};
143             }
144              
145             1;
146             __END__
147            
148             =head1 NAME
149            
150             Crypt::DSA::Key::PEM - Read/write DSA PEM files
151            
152             =head1 SYNOPSIS
153            
154             use Crypt::DSA::Key;
155             my $key = Crypt::DSA::Key->new( Type => 'PEM', ...);
156             $key->write( Type => 'PEM', ...);
157            
158             =head1 DESCRIPTION
159            
160             I<Crypt::DSA::Key::PEM> provides an interface to reading and
161             writing DSA PEM files, using I<Convert::PEM>. The files are
162             ASN.1-encoded and optionally encrypted.
163            
164             You shouldn't use this module directly. As the SYNOPSIS above
165             suggests, this module should be considered a plugin for
166             I<Crypt::DSA::Key>, and all access to PEM files (reading DSA
167             keys from disk, etc.) should be done through that module.
168            
169             Read the I<Crypt::DSA::Key> documentation for more details.
170            
171             =head1 AUTHOR & COPYRIGHTS
172            
173             Please see the Crypt::DSA manpage for author, copyright,
174             and license information.
175            
176             =cut
177