File Coverage

blib/lib/Crypt/Keyczar.pm
Criterion Covered Total %
statement 85 95 89.4
branch 14 18 77.7
condition 3 9 33.3
subroutine 22 24 91.6
pod 0 6 0.0
total 124 152 81.5


line stmt bran cond sub pod time code
1             package Crypt::Keyczar;
2 15     15   58562 use base 'Exporter';
  15         27  
  15         918  
3 15     15   81 use strict;
  15         25  
  15         225  
4 15     15   61 use warnings;
  15         27  
  15         345  
5 15     15   107 use Carp;
  15         34  
  15         705  
6 15     15   4449 use Crypt::Keyczar::FileReader;
  15         39  
  15         415  
7 15     15   4342 use Crypt::Keyczar::KeyMetadata;
  15         42  
  15         339  
8 15     15   2940 use Crypt::Keyczar::Key;
  15         35  
  15         484  
9              
10              
11             our $VERSION = 0.09;
12              
13 15     15   76 use constant FORMAT_VERSION => 0;
  15         25  
  15         972  
14 15     15   86 use constant FORMAT_BYTES => pack 'C', 0;
  15         27  
  15         619  
15 15     15   76 use constant KEY_HASH_SIZE => 4;
  15         27  
  15         537  
16 15     15   87 use constant HEADER_SIZE => 1 + 4;
  15         25  
  15         6588  
17              
18             our @EXPORT_OK = qw(FORMAT_VERSION FORMAT_BYTES KEY_HASH_SIZE HEADER_SIZE);
19              
20              
21             sub new {
22 78     78 0 1857 my $class = shift;
23 78         132 my $reader = shift;
24              
25 78 50       495 if (UNIVERSAL::isa($reader, 'Crypt::Keyczar::Reader')) {
26 0         0 return $class->_new($reader);
27             }
28             else {
29 78         386 return $class->_new(Crypt::Keyczar::FileReader->new($reader));
30             }
31             }
32              
33              
34             sub _new {
35 78     78   143 my $class = shift;
36 78         125 my $reader = shift;
37              
38 78         300 my $self = bless {
39             metadata => undef,
40             primary_version => undef,
41             version_map => {},
42             hash_map => {},
43             }, $class;
44              
45 78         261 $self->metadata(Crypt::Keyczar::KeyMetadata->read($reader->get_metadata()));
46 78         190 for my $v ($self->metadata->get_versions) {
47 170 100       444 next if !$v;
48 162 100       377 if ($v->status eq 'PRIMARY') {
49 59 50       170 if ($self->primary) {
50 0         0 croak "duplicate primary key";
51             }
52 59         129 $self->primary($v);
53             }
54 162         348 my $key = Crypt::Keyczar::Key->read_key(
55             $self->metadata->get_type(), $reader->get_key($v->get_number()));
56 162         501 my $key_hash = Crypt::Keyczar::_KeyHash->new($key->hash());
57 162         421 $self->{hash_map}->{$key_hash->hash_code()} = $key;
58 162         513 $self->{version_map}->{$v->get_number()} = $key;
59             }
60 78         375 return $self;
61             }
62              
63              
64             sub metadata {
65 467     467 0 704 my $self = shift;
66 467 100       1051 $self->{metadata} = shift if @_;
67 467         1185 return $self->{metadata};
68             }
69              
70              
71             sub primary {
72 192     192 0 308 my $self = shift;
73 192 100       429 $self->{primary_version} = shift if @_;
74 192         482 return $self->{primary_version};
75             }
76              
77              
78             sub get_key_by_number {
79 0     0 0 0 my $self = shift;
80 0         0 my $num = shift;
81 0         0 return $self->{version_map}->{$num};
82             }
83              
84              
85             sub get_key {
86 89     89 0 156 my $self = shift;
87 89         153 my $id = shift;
88 89 100 66     590 if (ref $id && $id->isa('Crypt::Keyczar::KeyVersion')) {
    50 33        
89             # find by KeyVersion
90 44         148 return $self->{version_map}->{$id->get_number};
91             }
92             elsif (ref $id && $id->isa('Crypt::Keyczar::Key')) {
93 0         0 return $self->{hash_map}->{$id->hash};
94             }
95             else {
96             # find by hash code
97 45         163 my $hash = Crypt::Keyczar::_KeyHash->new($id);
98 45         150 return $self->{hash_map}->{$hash->hash_code};
99             }
100             }
101              
102              
103             sub add_key {
104 17     17 0 38 my $self = shift;
105 17         48 my ($version, $key) = @_;
106              
107 17         49 my $hash = Crypt::Keyczar::_KeyHash->new($key->hash);
108 17         50 $self->{hash_map}->{$hash->hash_code} = $key;
109 17         90 $self->{version_map}->{$version->get_number} = $key;
110              
111 17         62 $self->metadata->add_version($version);
112             }
113              
114              
115             1;
116              
117              
118             package Crypt::Keyczar::_KeyHash;
119 15     15   102 use strict;
  15         33  
  15         274  
120 15     15   73 use warnings;
  15         31  
  15         320  
121 15     15   66 use Carp;
  15         25  
  15         2126  
122              
123              
124             sub new {
125 224     224   377 my $class = shift;
126 224         373 my $data = shift;
127 224 50       525 if (length $data != Crypt::Keyczar::KEY_HASH_SIZE()) {
128 0         0 confess "is not keyczar hash";
129             }
130 224         448 my $self = bless \$data, $class;
131 224         405 return $self;
132             }
133              
134              
135             sub equals {
136 0     0   0 my $self = shift;
137 0         0 my $obj = shift;
138 0   0     0 return $obj->isa('Crypt::Keyczar::_KeyHash') && $obj->hash_code() == $self->hash_code();
139             }
140              
141              
142             sub hash_code {
143 224     224   344 my $self = shift;
144 224         1025 return unpack 'N', $$self;
145             }
146              
147             1;
148             __END__