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   3542093 use base 'Exporter';
  15         35  
  15         1459  
3 15     15   78 use strict;
  15         34  
  15         487  
4 15     15   71 use warnings;
  15         25  
  15         377  
5 15     15   220 use Carp;
  15         28  
  15         1173  
6 15     15   9910 use Crypt::Keyczar::FileReader;
  15         100  
  15         545  
7 15     15   9613 use Crypt::Keyczar::KeyMetadata;
  15         50  
  15         440  
8 15     15   5821 use Crypt::Keyczar::Key;
  15         37  
  15         719  
9              
10              
11             our $VERSION = 0.08;
12              
13 15     15   90 use constant FORMAT_VERSION => 0;
  15         25  
  15         1456  
14 15     15   83 use constant FORMAT_BYTES => pack 'C', 0;
  15         29  
  15         644  
15 15     15   78 use constant KEY_HASH_SIZE => 4;
  15         23  
  15         765  
16 15     15   74 use constant HEADER_SIZE => 1 + 4;
  15         542  
  15         15734  
17              
18             our @EXPORT_OK = qw(FORMAT_VERSION FORMAT_BYTES KEY_HASH_SIZE HEADER_SIZE);
19              
20              
21             sub new {
22 78     78 0 2707 my $class = shift;
23 78         151 my $reader = shift;
24              
25 78 50       695 if (UNIVERSAL::isa($reader, 'Crypt::Keyczar::Reader')) {
26 0         0 return $class->_new($reader);
27             }
28             else {
29 78         649 return $class->_new(Crypt::Keyczar::FileReader->new($reader));
30             }
31             }
32              
33              
34             sub _new {
35 78     78   142 my $class = shift;
36 78         135 my $reader = shift;
37              
38 78         679 my $self = bless {
39             metadata => undef,
40             primary_version => undef,
41             version_map => {},
42             hash_map => {},
43             }, $class;
44              
45 78         344 $self->metadata(Crypt::Keyczar::KeyMetadata->read($reader->get_metadata()));
46 78         289 for my $v ($self->metadata->get_versions) {
47 170 100       620 next if !$v;
48 162 100       464 if ($v->status eq 'PRIMARY') {
49 59 50       213 if ($self->primary) {
50 0         0 croak "duplicate primary key";
51             }
52 59         128 $self->primary($v);
53             }
54 162         429 my $key = Crypt::Keyczar::Key->read_key(
55             $self->metadata->get_type(), $reader->get_key($v->get_number()));
56 162         673 my $key_hash = Crypt::Keyczar::_KeyHash->new($key->hash());
57 162         1161 $self->{hash_map}->{$key_hash->hash_code()} = $key;
58 162         604 $self->{version_map}->{$v->get_number()} = $key;
59             }
60 78         390 return $self;
61             }
62              
63              
64             sub metadata {
65 467     467 0 625 my $self = shift;
66 467 100       1019 $self->{metadata} = shift if @_;
67 467         1844 return $self->{metadata};
68             }
69              
70              
71             sub primary {
72 192     192 0 233 my $self = shift;
73 192 100       615 $self->{primary_version} = shift if @_;
74 192         526 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 170 my $self = shift;
87 89         147 my $id = shift;
88 89 100 66     682 if (ref $id && $id->isa('Crypt::Keyczar::KeyVersion')) {
    50 33        
89             # find by KeyVersion
90 44         177 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         194 my $hash = Crypt::Keyczar::_KeyHash->new($id);
98 45         157 return $self->{hash_map}->{$hash->hash_code};
99             }
100             }
101              
102              
103             sub add_key {
104 17     17 0 27 my $self = shift;
105 17         43 my ($version, $key) = @_;
106              
107 17         64 my $hash = Crypt::Keyczar::_KeyHash->new($key->hash);
108 17         72 $self->{hash_map}->{$hash->hash_code} = $key;
109 17         105 $self->{version_map}->{$version->get_number} = $key;
110              
111 17         59 $self->metadata->add_version($version);
112             }
113              
114              
115             1;
116              
117              
118             package Crypt::Keyczar::_KeyHash;
119 15     15   111 use strict;
  15         29  
  15         526  
120 15     15   106 use warnings;
  15         25  
  15         472  
121 15     15   74 use Carp;
  15         28  
  15         4498  
122              
123              
124             sub new {
125 224     224   319 my $class = shift;
126 224         450 my $data = shift;
127 224 50       556 if (length $data != Crypt::Keyczar::KEY_HASH_SIZE()) {
128 0         0 confess "is not keyczar hash";
129             }
130 224         576 my $self = bless \$data, $class;
131 224         419 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   399 my $self = shift;
144 224         1461 return unpack 'N', $$self;
145             }
146              
147             1;
148             __END__