File Coverage

blib/lib/Crypt/PKCS11/Session.pm
Criterion Covered Total %
statement 490 494 99.1
branch 380 384 98.9
condition 129 129 100.0
subroutine 62 64 96.8
pod 58 58 100.0
total 1119 1129 99.1


line stmt bran cond sub pod time code
1             # Copyright (c) 2015 Jerry Lundström
2             # Copyright (c) 2015 .SE (The Internet Infrastructure Foundation)
3             # All rights reserved.
4             #
5             # Redistribution and use in source and binary forms, with or without
6             # modification, are permitted provided that the following conditions
7             # are met:
8             # 1. Redistributions of source code must retain the above copyright
9             # notice, this list of conditions and the following disclaimer.
10             # 2. Redistributions in binary form must reproduce the above copyright
11             # notice, this list of conditions and the following disclaimer in the
12             # documentation and/or other materials provided with the distribution.
13             #
14             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15             # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16             # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17             # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18             # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19             # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20             # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21             # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22             # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23             # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24             # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25              
26             package Crypt::PKCS11::Session;
27              
28 6     6   320 use common::sense;
  6         12  
  6         53  
29 6     6   340 use Carp;
  6         13  
  6         527  
30 6     6   38 use Scalar::Util qw(blessed);
  6         11  
  6         522  
31              
32 6     6   31 use Crypt::PKCS11 qw(:constant);
  6         10  
  6         19516  
33 6     6   3341 use Crypt::PKCS11::Object;
  6         17  
  6         62729  
34              
35             sub new {
36 6     6 1 1190 my $this = shift;
37 6   100     23 my $class = ref($this) || $this;
38 6         23 my $self = {
39             pkcs11xs => undef,
40             session => undef,
41             rv => CKR_OK
42             };
43 6         11 bless $self, $class;
44              
45 6 100 100     58 unless (blessed($self->{pkcs11xs} = shift) and $self->{pkcs11xs}->isa('Crypt::PKCS11::XSPtr')) {
46 2         4 delete $self->{pkcs11xs};
47 2         276 confess 'first argument is not a Crypt::PKCS11::XSPtr';
48             }
49 4 100       10 unless (defined ($self->{session} = shift)) {
50 1         3 delete $self->{pkcs11xs};
51 1         2 delete $self->{session};
52 1         108 confess 'second argument is not a session';
53             }
54              
55 3         14 return $self;
56             }
57              
58             sub DESTROY {
59 5 100 100 5   175 if (exists $_[0]->{session} and defined $_[0]->{pkcs11xs}) {
60 1         12 $_[0]->{pkcs11xs}->C_CloseSession($_[0]->{session});
61             }
62             }
63              
64             sub InitPIN {
65 6     6 1 963 my ($self, $pin) = @_;
66              
67 6 100       39 unless (exists $self->{session}) {
68 1         95 confess 'session is closed';
69             }
70 5 100       12 if (defined $pin) {
71 3         6 $pin .= '';
72 3 100       14 unless (length($pin)) {
73 1         184 confess '$pin can not be empty if defined';
74             }
75             }
76              
77 4         18 $self->{rv} = $self->{pkcs11xs}->C_InitPIN($self->{session}, $pin);
78 4 100       24 return $self->{rv} == CKR_OK ? 1 : undef;
79             }
80              
81             sub SetPIN {
82 9     9 1 1197 my ($self, $oldPin, $newPin) = @_;
83              
84 9 100       49 unless (exists $self->{session}) {
85 1         94 confess 'session is closed';
86             }
87 8 100       17 if (defined $oldPin) {
88 6         8 $oldPin .= '';
89 6 100       14 unless (length($oldPin)) {
90 1         103 confess '$oldPin can not be empty if defined';
91             }
92             }
93 7 100       16 if (defined $newPin) {
94 3         6 $newPin .= '';
95 3 100       9 unless (length($newPin)) {
96 1         103 confess '$newPin can not be empty if defined';
97             }
98             }
99              
100 6         27 $self->{rv} = $self->{pkcs11xs}->C_SetPIN($self->{session}, $oldPin, $newPin);
101 6 100       31 return $self->{rv} == CKR_OK ? 1 : undef;
102             }
103              
104             sub CloseSession {
105 2     2 1 424 my ($self) = @_;
106              
107 2 100       7 unless (exists $self->{session}) {
108 1         92 confess 'session is closed';
109             }
110              
111 1         5 $self->{rv} = $self->{pkcs11xs}->C_CloseSession($self->{session});
112 1 50       6 if ($self->{rv} == CKR_OK) {
113 0         0 delete $self->{session};
114             }
115 1 50       5 return $self->{rv} == CKR_OK ? 1 : undef;
116             }
117              
118             sub GetSessionInfo {
119 5     5 1 384 my ($self) = @_;
120 5         7 my $info = {};
121              
122 5 100       14 unless (exists $self->{session}) {
123 1         100 confess 'session is closed';
124             }
125              
126 4         23 $self->{rv} = $self->{pkcs11xs}->C_GetSessionInfo($self->{session}, $info);
127              
128 4 100       23 unless (ref($info) eq 'HASH') {
129 1         183 confess 'Internal Error: $info is not a hash reference';
130             }
131              
132 3 100       24 return $self->{rv} == CKR_OK ? wantarray ? %$info : $info : undef;
    100          
133             }
134              
135             sub GetOperationState {
136 4     4 1 890 my ($self) = @_;
137 4         6 my $operationState;
138              
139 4 100       14 unless (exists $self->{session}) {
140 1         100 confess 'session is closed';
141             }
142              
143 3         12 $self->{rv} = $self->{pkcs11xs}->C_GetOperationState($self->{session}, $operationState);
144 3 100       22 return $self->{rv} == CKR_OK ? $operationState : undef;
145             }
146              
147             sub SetOperationState {
148 11     11 1 1317 my ($self, $operationState, $encryptionKey, $authenticationKey) = @_;
149              
150 11 100       33 unless (exists $self->{session}) {
151 1         111 confess 'session is closed';
152             }
153 10 100       22 unless (defined $operationState) {
154 1         104 confess '$operationState must be defined';
155             }
156 9 100       20 if (defined $encryptionKey) {
157 6 100 100     58 unless (blessed($encryptionKey) and $encryptionKey->isa('Crypt::PKCS11::Object')) {
158 2         256 confess '$encryptionKey is defined but is not a Crypt::PKCS11::Object';
159             }
160             }
161 7 100       16 if (defined $authenticationKey) {
162 4 100 100     28 unless (blessed($authenticationKey) and $authenticationKey->isa('Crypt::PKCS11::Object')) {
163 2         212 confess '$authenticationKey is defined but is not a Crypt::PKCS11::Object';
164             }
165             }
166              
167 5 100       76 $self->{rv} = $self->{pkcs11xs}->C_SetOperationState($self->{session}, $operationState, $encryptionKey ? $encryptionKey->id : 0, $authenticationKey ? $authenticationKey->id : 0);
    100          
168 5 100       29 return $self->{rv} == CKR_OK ? 1 : undef;
169             }
170              
171             sub Login {
172 3     3 1 895 my ($self, $userType, $pin) = @_;
173              
174 3 100       12 unless (exists $self->{session}) {
175 1         97 confess 'session is closed';
176             }
177 2 100       8 unless (defined $userType) {
178 1         105 confess '$userType must be defined';
179             }
180              
181 1         15 $self->{rv} = $self->{pkcs11xs}->C_Login($self->{session}, $userType, $pin);
182 1 50       8 return $self->{rv} == CKR_OK ? 1 : undef;
183             }
184              
185             sub Logout {
186 3     3 1 378 my ($self) = @_;
187              
188 3 100       13 unless (exists $self->{session}) {
189 1         128 confess 'session is closed';
190             }
191              
192 2         11 $self->{rv} = $self->{pkcs11xs}->C_Logout($self->{session});
193 2 100       10 return $self->{rv} == CKR_OK ? 1 : undef;
194             }
195              
196             sub CreateObject {
197 9     9 1 1215 my ($self, $template) = @_;
198 9         12 my $object;
199              
200 9 100       26 unless (exists $self->{session}) {
201 1         95 confess 'session is closed';
202             }
203 8 100 100     69 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
204 6         660 confess '$template is not a Crypt::PKCS11::Attributes';
205             }
206              
207 2         15 $self->{rv} = $self->{pkcs11xs}->C_CreateObject($self->{session}, $template->toArray, $object);
208 2 100       33 return $self->{rv} == CKR_OK ? Crypt::PKCS11::Object->new($object) : undef;
209             }
210              
211             sub CopyObject {
212 9     9 1 1308 my ($self, $object, $template) = @_;
213 9         10 my $newObject;
214              
215 9 100       31 unless (exists $self->{session}) {
216 1         125 confess 'session is closed';
217             }
218 8 100 100     65 unless (blessed($object) and $object->isa('Crypt::PKCS11::Object')) {
219 3         307 confess '$object is not a Crypt::PKCS11::Object';
220             }
221 5 100 100     34 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
222 3         305 confess '$template is not a Crypt::PKCS11::Attributes';
223             }
224              
225 2         11 $self->{rv} = $self->{pkcs11xs}->C_CopyObject($self->{session}, $object->id, $template->toArray, $newObject);
226 2 100       20 return $self->{rv} == CKR_OK ? Crypt::PKCS11::Object->new($newObject) : undef;
227             }
228              
229             sub DestroyObject {
230 5     5 1 1250 my ($self, $object) = @_;
231              
232 5 100       21 unless (exists $self->{session}) {
233 1         93 confess 'session is closed';
234             }
235 4 100 100     32 unless (blessed($object) and $object->isa('Crypt::PKCS11::Object')) {
236 3         315 confess '$object is not a Crypt::PKCS11::Object';
237             }
238              
239 1         14 $self->{rv} = $self->{pkcs11xs}->C_DestroyObject($self->{session}, $object->id);
240 1 50       9 return $self->{rv} == CKR_OK ? 1 : undef;
241             }
242              
243             sub GetObjectSize {
244 6     6 1 1219 my ($self, $object) = @_;
245 6         8 my $size;
246              
247 6 100       21 unless (exists $self->{session}) {
248 1         121 confess 'session is closed';
249             }
250 5 100 100     43 unless (blessed($object) and $object->isa('Crypt::PKCS11::Object')) {
251 3         310 confess '$object is not a Crypt::PKCS11::Object';
252             }
253              
254 2         8 $self->{rv} = $self->{pkcs11xs}->C_GetObjectSize($self->{session}, $object->id, $size);
255 2 100       20 return $self->{rv} == CKR_OK ? $size : undef;
256             }
257              
258             sub GetAttributeValue {
259 11     11 1 1262 my ($self, $object, $template) = @_;
260 11         19 my $templateArray;
261              
262 11 100       26 unless (exists $self->{session}) {
263 1         131 confess 'session is closed';
264             }
265 10 100 100     69 unless (blessed($object) and $object->isa('Crypt::PKCS11::Object')) {
266 3         312 confess '$object is not a Crypt::PKCS11::Object';
267             }
268 7 100 100     48 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
269 3         310 confess '$template is not a Crypt::PKCS11::Attributes';
270             }
271              
272 4         15 $self->{rv} = $self->{pkcs11xs}->C_GetAttributeValue($self->{session}, $object->id, $templateArray = $template->toArray);
273              
274 4 100       26 if ($self->{rv} == CKR_OK) {
275 3         12 $template->fromArray($templateArray);
276 2 100       12 return wantarray ? $template->all : 1;
277             }
278              
279 1         4 return undef;
280             }
281              
282             sub SetAttributeValue {
283 10     10 1 1364 my ($self, $object, $template) = @_;
284              
285 10 100       43 unless (exists $self->{session}) {
286 1         100 confess 'session is closed';
287             }
288 9 100 100     55 unless (blessed($object) and $object->isa('Crypt::PKCS11::Object')) {
289 3         305 confess '$object is not a Crypt::PKCS11::Object';
290             }
291 6 100 100     39 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
292 3         300 confess '$template is not a Crypt::PKCS11::Attributes';
293             }
294              
295 3         10 $self->{rv} = $self->{pkcs11xs}->C_SetAttributeValue($self->{session}, $object->id, $template->toArray);
296 3 100       21 return $self->{rv} == CKR_OK ? 1 : undef;
297             }
298              
299             sub FindObjectsInit {
300 7     7 1 1213 my ($self, $template) = @_;
301              
302 7 100       23 unless (exists $self->{session}) {
303 1         94 confess 'session is closed';
304             }
305 6 100 100     43 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
306 3         314 confess '$template is not a Crypt::PKCS11::Attributes';
307             }
308              
309 3         11 $self->{rv} = $self->{pkcs11xs}->C_FindObjectsInit($self->{session}, $template->toArray);
310 3 100       20 return $self->{rv} == CKR_OK ? 1 : undef;
311             }
312              
313             sub FindObjects {
314 7     7 1 863 my ($self, $maxObjectCount) = @_;
315 7         12 my $objects = [];
316 7         11 my @objects;
317              
318 7 100       25 unless (exists $self->{session}) {
319 1         102 confess 'session is closed';
320             }
321 6 100       12 unless (defined $maxObjectCount) {
322 1         105 confess '$maxObjectCount must be defined';
323             }
324              
325 5         18 $self->{rv} = $self->{pkcs11xs}->C_FindObjects($self->{session}, $objects, $maxObjectCount);
326              
327 5 100       29 unless (ref($objects) eq 'ARRAY') {
328 1         191 confess 'Internal Error: $objects is not an array reference';
329             }
330              
331 4         8 foreach my $object (@$objects) {
332 4         12 push(@objects, Crypt::PKCS11::Object->new($object));
333             }
334              
335 4 100       23 return $self->{rv} == CKR_OK ? wantarray ? @objects : \@objects : undef;
    100          
336             }
337              
338             sub FindObjectsFinal {
339 3     3 1 1072 my ($self) = @_;
340              
341 3 100       13 unless (exists $self->{session}) {
342 1         95 confess 'session is closed';
343             }
344              
345 2         13 $self->{rv} = $self->{pkcs11xs}->C_FindObjectsFinal($self->{session});
346 2 100       15 return $self->{rv} == CKR_OK ? 1 : undef;
347             }
348              
349             sub EncryptInit {
350 9     9 1 2160 my ($self, $mechanism, $key) = @_;
351              
352 9 100       30 unless (exists $self->{session}) {
353 1         97 confess 'session is closed';
354             }
355 8 100 100     69 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
356 3         339 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
357             }
358 5 100 100     37 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
359 3         318 confess '$key is not a Crypt::PKCS11::Object';
360             }
361              
362 2         12 $self->{rv} = $self->{pkcs11xs}->C_EncryptInit($self->{session}, $mechanism->toHash, $key->id);
363 2 100       15 return $self->{rv} == CKR_OK ? 1 : undef;
364             }
365              
366             sub Encrypt {
367 4     4 1 832 my ($self, $data) = @_;
368 4         7 my $encryptedData;
369              
370 4 100       14 unless (exists $self->{session}) {
371 1         95 confess 'session is closed';
372             }
373 3 100       9 unless (defined $data) {
374 1         102 confess '$data must be defined';
375             }
376              
377 2         10 $self->{rv} = $self->{pkcs11xs}->C_Encrypt($self->{session}, $data, $encryptedData);
378 2 100       12 return $self->{rv} == CKR_OK ? $encryptedData : undef;
379             }
380              
381             sub EncryptUpdate {
382 4     4 1 847 my ($self, $part) = @_;
383 4         6 my $encryptedPart;
384              
385 4 100       18 unless (exists $self->{session}) {
386 1         99 confess 'session is closed';
387             }
388 3 100       13 unless (defined $part) {
389 1         900 confess '$part must be defined';
390             }
391              
392 2         12 $self->{rv} = $self->{pkcs11xs}->C_EncryptUpdate($self->{session}, $part, $encryptedPart);
393 2 100       17 return $self->{rv} == CKR_OK ? $encryptedPart : undef;
394             }
395              
396             sub EncryptFinal {
397 3     3 1 481 my ($self) = @_;
398 3         5 my $lastEncryptedPart;
399              
400 3 100       25 unless (exists $self->{session}) {
401 1         104 confess 'session is closed';
402             }
403              
404 2         14 $self->{rv} = $self->{pkcs11xs}->C_EncryptFinal($self->{session}, $lastEncryptedPart);
405 2 100       14 return $self->{rv} == CKR_OK ? $lastEncryptedPart : undef;
406             }
407              
408             sub DecryptInit {
409 9     9 1 2145 my ($self, $mechanism, $key) = @_;
410              
411 9 100       54 unless (exists $self->{session}) {
412 1         95 confess 'session is closed';
413             }
414 8 100 100     65 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
415 3         326 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
416             }
417 5 100 100     42 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
418 3         305 confess '$key is not a Crypt::PKCS11::Object';
419             }
420              
421 2         11 $self->{rv} = $self->{pkcs11xs}->C_DecryptInit($self->{session}, $mechanism->toHash, $key->id);
422 2 100       19 return $self->{rv} == CKR_OK ? 1 : undef;
423             }
424              
425             sub Decrypt {
426 4     4 1 828 my ($self, $encryptedData) = @_;
427 4         6 my $data;
428              
429 4 100       14 unless (exists $self->{session}) {
430 1         95 confess 'session is closed';
431             }
432 3 100       9 unless (defined $encryptedData) {
433 1         102 confess '$encryptedData must be defined';
434             }
435              
436 2         9 $self->{rv} = $self->{pkcs11xs}->C_Decrypt($self->{session}, $encryptedData, $data);
437 2 100       13 return $self->{rv} == CKR_OK ? $data : undef;
438             }
439              
440             sub DecryptUpdate {
441 4     4 1 805 my ($self, $encryptedPart) = @_;
442 4         7 my $part;
443              
444 4 100       16 unless (exists $self->{session}) {
445 1         104 confess 'session is closed';
446             }
447 3 100       8 unless (defined $encryptedPart) {
448 1         108 confess '$encryptedPart must be defined';
449             }
450              
451 2         17 $self->{rv} = $self->{pkcs11xs}->C_DecryptUpdate($self->{session}, $encryptedPart, $part);
452 2 100       16 return $self->{rv} == CKR_OK ? $part : undef;
453             }
454              
455             sub DecryptFinal {
456 3     3 1 444 my ($self) = @_;
457 3         5 my $lastPart;
458              
459 3 100       13 unless (exists $self->{session}) {
460 1         97 confess 'session is closed';
461             }
462              
463 2         11 $self->{rv} = $self->{pkcs11xs}->C_DecryptFinal($self->{session}, $lastPart);
464 2 100       14 return $self->{rv} == CKR_OK ? $lastPart : undef;
465             }
466              
467             sub DigestInit {
468 6     6 1 1341 my ($self, $mechanism) = @_;
469              
470 6 100       27 unless (exists $self->{session}) {
471 1         96 confess 'session is closed';
472             }
473 5 100 100     76 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
474 3         304 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
475             }
476              
477 2         10 $self->{rv} = $self->{pkcs11xs}->C_DigestInit($self->{session}, $mechanism->toHash);
478 2 100       13 return $self->{rv} == CKR_OK ? 1 : undef;
479             }
480              
481             sub Digest {
482 4     4 1 834 my ($self, $data) = @_;
483 4         5 my $digest;
484              
485 4 100       18 unless (exists $self->{session}) {
486 1         114 confess 'session is closed';
487             }
488 3 100       9 unless (defined $data) {
489 1         103 confess '$data must be defined';
490             }
491              
492 2         16 $self->{rv} = $self->{pkcs11xs}->C_Digest($self->{session}, $data, $digest);
493 2 100       18 return $self->{rv} == CKR_OK ? $digest : undef;
494             }
495              
496             sub DigestUpdate {
497 4     4 1 818 my ($self, $part) = @_;
498              
499 4 100       14 unless (exists $self->{session}) {
500 1         91 confess 'session is closed';
501             }
502 3 100       9 unless (defined $part) {
503 1         102 confess '$part must be defined';
504             }
505              
506 2         11 $self->{rv} = $self->{pkcs11xs}->C_DigestUpdate($self->{session}, $part);
507 2 100       14 return $self->{rv} == CKR_OK ? 1 : undef;
508             }
509              
510             sub DigestKey {
511 6     6 1 1230 my ($self, $key) = @_;
512              
513 6 100       21 unless (exists $self->{session}) {
514 1         109 confess 'session is closed';
515             }
516 5 100 100     38 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
517 3         306 confess '$key is not a Crypt::PKCS11::Object';
518             }
519              
520 2         10 $self->{rv} = $self->{pkcs11xs}->C_DigestKey($self->{session}, $key->id);
521 2 100       22 return $self->{rv} == CKR_OK ? 1 : undef;
522             }
523              
524             sub DigestFinal {
525 3     3 1 435 my ($self) = @_;
526 3         5 my $digest;
527              
528 3 100       12 unless (exists $self->{session}) {
529 1         96 confess 'session is closed';
530             }
531              
532 2         10 $self->{rv} = $self->{pkcs11xs}->C_DigestFinal($self->{session}, $digest);
533 2 100       13 return $self->{rv} == CKR_OK ? $digest : undef;
534             }
535              
536             sub SignInit {
537 9     9 1 2050 my ($self, $mechanism, $key) = @_;
538              
539 9 100       44 unless (exists $self->{session}) {
540 1         95 confess 'session is closed';
541             }
542 8 100 100     82 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
543 3         308 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
544             }
545 5 100 100     30 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
546 3         312 confess '$key is not a Crypt::PKCS11::Object';
547             }
548              
549 2         11 $self->{rv} = $self->{pkcs11xs}->C_SignInit($self->{session}, $mechanism->toHash, $key->id);
550 2 100       15 return $self->{rv} == CKR_OK ? 1 : undef;
551             }
552              
553             sub Sign {
554 4     4 1 855 my ($self, $data) = @_;
555 4         8 my $signature;
556              
557 4 100       15 unless (exists $self->{session}) {
558 1         94 confess 'session is closed';
559             }
560 3 100       7 unless (defined $data) {
561 1         106 confess '$data must be defined';
562             }
563              
564 2         11 $self->{rv} = $self->{pkcs11xs}->C_Sign($self->{session}, $data, $signature);
565 2 100       14 return $self->{rv} == CKR_OK ? $signature : undef;
566             }
567              
568             sub SignUpdate {
569 4     4 1 776 my ($self, $part) = @_;
570              
571 4 100       16 unless (exists $self->{session}) {
572 1         94 confess 'session is closed';
573             }
574 3 100       11 unless (defined $part) {
575 1         103 confess '$part must be defined';
576             }
577              
578 2         11 $self->{rv} = $self->{pkcs11xs}->C_SignUpdate($self->{session}, $part);
579 2 100       13 return $self->{rv} == CKR_OK ? 1 : undef;
580             }
581              
582             sub SignFinal {
583 3     3 1 439 my ($self) = @_;
584 3         5 my $signature;
585              
586 3 100       12 unless (exists $self->{session}) {
587 1         95 confess 'session is closed';
588             }
589              
590 2         17 $self->{rv} = $self->{pkcs11xs}->C_SignFinal($self->{session}, $signature);
591 2 100       21 return $self->{rv} == CKR_OK ? $signature : undef;
592             }
593              
594             sub SignRecoverInit {
595 9     9 1 2037 my ($self, $mechanism, $key) = @_;
596              
597 9 100       28 unless (exists $self->{session}) {
598 1         96 confess 'session is closed';
599             }
600 8 100 100     63 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
601 3         310 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
602             }
603 5 100 100     34 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
604 3         314 confess '$key is not a Crypt::PKCS11::Object';
605             }
606              
607 2         11 $self->{rv} = $self->{pkcs11xs}->C_SignRecoverInit($self->{session}, $mechanism->toHash, $key->id);
608 2 100       16 return $self->{rv} == CKR_OK ? 1 : undef;
609             }
610              
611             sub SignRecover {
612 4     4 1 868 my ($self, $data) = @_;
613 4         6 my $signature;
614              
615 4 100       15 unless (exists $self->{session}) {
616 1         175 confess 'session is closed';
617             }
618 3 100       7 unless (defined $data) {
619 1         104 confess '$data must be defined';
620             }
621              
622 2         10 $self->{rv} = $self->{pkcs11xs}->C_SignRecover($self->{session}, $data, $signature);
623 2 100       20 return $self->{rv} == CKR_OK ? $signature : undef;
624             }
625              
626             sub VerifyInit {
627 9     9 1 2234 my ($self, $mechanism, $key) = @_;
628              
629 9 100       26 unless (exists $self->{session}) {
630 1         112 confess 'session is closed';
631             }
632 8 100 100     57 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
633 3         305 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
634             }
635 5 100 100     29 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
636 3         310 confess '$key is not a Crypt::PKCS11::Object';
637             }
638              
639 2         9 $self->{rv} = $self->{pkcs11xs}->C_VerifyInit($self->{session}, $mechanism->toHash, $key->id);
640 2 100       20 return $self->{rv} == CKR_OK ? 1 : undef;
641             }
642              
643             sub Verify {
644 5     5 1 1235 my ($self, $data, $signature) = @_;
645              
646 5 100       17 unless (exists $self->{session}) {
647 1         99 confess 'session is closed';
648             }
649 4 100       10 unless (defined $data) {
650 1         103 confess '$data must be defined';
651             }
652 3 100       23 unless (defined $signature) {
653 1         102 confess '$signature must be defined';
654             }
655              
656 2         11 $self->{rv} = $self->{pkcs11xs}->C_Verify($self->{session}, $data, $signature);
657 2 100       12 return $self->{rv} == CKR_OK ? 1 : undef;
658             }
659              
660             sub VerifyUpdate {
661 4     4 1 828 my ($self, $part) = @_;
662              
663 4 100       16 unless (exists $self->{session}) {
664 1         137 confess 'session is closed';
665             }
666 3 100       7 unless (defined $part) {
667 1         106 confess '$part must be defined';
668             }
669              
670 2         10 $self->{rv} = $self->{pkcs11xs}->C_VerifyUpdate($self->{session}, $part);
671 2 100       25 return $self->{rv} == CKR_OK ? 1 : undef;
672             }
673              
674             sub VerifyFinal {
675 4     4 1 829 my ($self, $signature) = @_;
676              
677 4 100       18 unless (exists $self->{session}) {
678 1         103 confess 'session is closed';
679             }
680 3 100       10 unless (defined $signature) {
681 1         110 confess '$signature must be defined';
682             }
683              
684 2         16 $self->{rv} = $self->{pkcs11xs}->C_VerifyFinal($self->{session}, $signature);
685 2 100       14 return $self->{rv} == CKR_OK ? 1 : undef;
686             }
687              
688             sub VerifyRecoverInit {
689 9     9 1 2985 my ($self, $mechanism, $key) = @_;
690              
691 9 100       33 unless (exists $self->{session}) {
692 1         155 confess 'session is closed';
693             }
694 8 100 100     71 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
695 3         545 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
696             }
697 5 100 100     35 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
698 3         355 confess '$key is not a Crypt::PKCS11::Object';
699             }
700              
701 2         12 $self->{rv} = $self->{pkcs11xs}->C_VerifyRecoverInit($self->{session}, $mechanism->toHash, $key->id);
702 2 100       12 return $self->{rv} == CKR_OK ? 1 : undef;
703             }
704              
705             sub VerifyRecover {
706 4     4 1 865 my ($self, $signature) = @_;
707 4         7 my $data;
708              
709 4 100       13 unless (exists $self->{session}) {
710 1         152 confess 'session is closed';
711             }
712 3 100       9 unless (defined $signature) {
713 1         103 confess '$signature must be defined';
714             }
715              
716 2         9 $self->{rv} = $self->{pkcs11xs}->C_VerifyRecover($self->{session}, $signature, $data);
717 2 100       13 return $self->{rv} == CKR_OK ? $data : undef;
718             }
719              
720             sub DigestEncryptUpdate {
721 4     4 1 845 my ($self, $part) = @_;
722 4         8 my $encryptedPart;
723              
724 4 100       16 unless (exists $self->{session}) {
725 1         107 confess 'session is closed';
726             }
727 3 100       8 unless (defined $part) {
728 1         101 confess '$part must be defined';
729             }
730              
731 2         19 $self->{rv} = $self->{pkcs11xs}->C_DigestEncryptUpdate($self->{session}, $part, $encryptedPart);
732 2 100       12 return $self->{rv} == CKR_OK ? $encryptedPart : undef;
733             }
734              
735             sub DecryptDigestUpdate {
736 4     4 1 836 my ($self, $encryptedPart) = @_;
737 4         6 my $part;
738              
739 4 100       16 unless (exists $self->{session}) {
740 1         106 confess 'session is closed';
741             }
742 3 100       9 unless (defined $encryptedPart) {
743 1         147 confess '$encryptedPart must be defined';
744             }
745              
746 2         9 $self->{rv} = $self->{pkcs11xs}->C_DecryptDigestUpdate($self->{session}, $encryptedPart, $part);
747 2 100       13 return $self->{rv} == CKR_OK ? $part : undef;
748             }
749              
750             sub SignEncryptUpdate {
751 4     4 1 940 my ($self, $part) = @_;
752 4         3 my $encryptedPart;
753              
754 4 100       20 unless (exists $self->{session}) {
755 1         108 confess 'session is closed';
756             }
757 3 100       9 unless (defined $part) {
758 1         100 confess '$part must be defined';
759             }
760              
761 2         14 $self->{rv} = $self->{pkcs11xs}->C_SignEncryptUpdate($self->{session}, $part, $encryptedPart);
762 2 100       15 return $self->{rv} == CKR_OK ? $encryptedPart : undef;
763             }
764              
765             sub DecryptVerifyUpdate {
766 4     4 1 796 my ($self, $encryptedPart) = @_;
767 4         7 my $part;
768              
769 4 100       12 unless (exists $self->{session}) {
770 1         102 confess 'session is closed';
771             }
772 3 100       8 unless (defined $encryptedPart) {
773 1         100 confess '$encryptedPart must be defined';
774             }
775              
776 2         15 $self->{rv} = $self->{pkcs11xs}->C_DecryptVerifyUpdate($self->{session}, $encryptedPart, $part);
777 2 100       14 return $self->{rv} == CKR_OK ? $part : undef;
778             }
779              
780             sub GenerateKey {
781 9     9 1 2094 my ($self, $mechanism, $template) = @_;
782 9         11 my $key;
783              
784 9 100       29 unless (exists $self->{session}) {
785 1         96 confess 'session is closed';
786             }
787 8 100 100     57 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
788 3         300 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
789             }
790 5 100 100     36 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
791 3         315 confess '$template is not a Crypt::PKCS11::Attributes';
792             }
793              
794 2         9 $self->{rv} = $self->{pkcs11xs}->C_GenerateKey($self->{session}, $mechanism->toHash, $template->toArray, $key);
795 2 100       16 return $self->{rv} == CKR_OK ? Crypt::PKCS11::Object->new($key) : undef;
796             }
797              
798             sub GenerateKeyPair {
799 13     13 1 2120 my ($self, $mechanism, $publicKeyTemplate, $privateKeyTemplate) = @_;
800 13         13 my ($publicKey, $privateKey);
801 0         0 my @keys;
802              
803 13 100       33 unless (exists $self->{session}) {
804 1         95 confess 'session is closed';
805             }
806 12 100 100     81 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
807 3         298 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
808             }
809 9 100 100     53 unless (blessed($publicKeyTemplate) and $publicKeyTemplate->isa('Crypt::PKCS11::Attributes')) {
810 3         330 confess '$publicKeyTemplate is not a Crypt::PKCS11::Attributes';
811             }
812 6 100 100     35 unless (blessed($privateKeyTemplate) and $privateKeyTemplate->isa('Crypt::PKCS11::Attributes')) {
813 3         305 confess '$privateKeyTemplate is not a Crypt::PKCS11::Attributes';
814             }
815              
816 3         11 $self->{rv} = $self->{pkcs11xs}->C_GenerateKeyPair($self->{session}, $mechanism->toHash, $publicKeyTemplate->toArray, $privateKeyTemplate->toArray, $publicKey, $privateKey);
817              
818 3 100       18 if ($self->{rv} == CKR_OK) {
819 2         6 @keys = (
820             Crypt::PKCS11::Object->new($publicKey),
821             Crypt::PKCS11::Object->new($privateKey)
822             );
823 2 100       16 return wantarray ? @keys : \@keys;
824             }
825 1         4 return $self->{rv};
826             }
827              
828             sub WrapKey {
829 12     12 1 2149 my ($self, $mechanism, $wrappingKey, $key) = @_;
830 12         12 my $wrappedKey;
831              
832 12 100       29 unless (exists $self->{session}) {
833 1         97 confess 'session is closed';
834             }
835 11 100 100     75 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
836 3         301 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
837             }
838 8 100 100     48 unless (blessed($wrappingKey) and $wrappingKey->isa('Crypt::PKCS11::Object')) {
839 3         298 confess '$wrappingKey is not a Crypt::PKCS11::Object';
840             }
841 5 100 100     36 unless (blessed($key) and $key->isa('Crypt::PKCS11::Object')) {
842 3         327 confess '$key is not a Crypt::PKCS11::Object';
843             }
844              
845 2         8 $self->{rv} = $self->{pkcs11xs}->C_WrapKey($self->{session}, $mechanism->toHash, $wrappingKey->id, $key->id, $wrappedKey);
846 2 100       15 return $self->{rv} == CKR_OK ? $wrappedKey : undef;
847             }
848              
849             sub UnwrapKey {
850 13     13 1 2376 my ($self, $mechanism, $unwrappingKey, $wrappedKey, $template) = @_;
851 13         15 my $key;
852              
853 13 100       34 unless (exists $self->{session}) {
854 1         112 confess 'session is closed';
855             }
856 12 100 100     79 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
857 3         415 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
858             }
859 9 100 100     52 unless (blessed($unwrappingKey) and $unwrappingKey->isa('Crypt::PKCS11::Object')) {
860 3         370 confess '$unwrappingKey is not a Crypt::PKCS11::Object';
861             }
862 6 100       14 unless (defined $wrappedKey) {
863 1         99 confess '$wrappedKey must be defined';
864             }
865 5 100 100     29 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
866 3         329 confess '$template is not a Crypt::PKCS11::Attributes';
867             }
868              
869 2         9 $self->{rv} = $self->{pkcs11xs}->C_UnwrapKey($self->{session}, $mechanism->toHash, $unwrappingKey->id, $wrappedKey, $template->toArray, $key);
870 2 100       13 return $self->{rv} == CKR_OK ? Crypt::PKCS11::Object->new($key) : undef;
871             }
872              
873             sub DeriveKey {
874 12     12 1 2264 my ($self, $mechanism, $baseKey, $template) = @_;
875 12         16 my $key;
876              
877 12 100       42 unless (exists $self->{session}) {
878 1         97 confess 'session is closed';
879             }
880 11 100 100     74 unless (blessed($mechanism) and $mechanism->isa('Crypt::PKCS11::CK_MECHANISMPtr')) {
881 3         324 confess '$mechanism is not a Crypt::PKCS11::CK_MECHANISMPtr';
882             }
883 8 100 100     78 unless (blessed($baseKey) and $baseKey->isa('Crypt::PKCS11::Object')) {
884 3         342 confess '$baseKey is not a Crypt::PKCS11::Object';
885             }
886 5 100 100     34 unless (blessed($template) and $template->isa('Crypt::PKCS11::Attributes')) {
887 3         354 confess '$template is not a Crypt::PKCS11::Attributes';
888             }
889              
890 2         9 $self->{rv} = $self->{pkcs11xs}->C_DeriveKey($self->{session}, $mechanism->toHash, $baseKey->id, $template->toArray, $key);
891 2 100       15 return $self->{rv} == CKR_OK ? Crypt::PKCS11::Object->new($key) : undef;
892             }
893              
894             sub SeedRandom {
895 4     4 1 871 my ($self, $seed) = @_;
896 4         7 my $key;
897              
898 4 100       20 unless (exists $self->{session}) {
899 1         100 confess 'session is closed';
900             }
901 3 100       8 unless (defined $seed) {
902 1         100 confess '$seed must be defined';
903             }
904              
905 2         11 $self->{rv} = $self->{pkcs11xs}->C_SeedRandom($self->{session}, $seed);
906 2 100       13 return $self->{rv} == CKR_OK ? 1 : undef;
907             }
908              
909             sub GenerateRandom {
910 4     4 1 814 my ($self, $randomLen) = @_;
911 4         6 my $randomData;
912              
913 4 100       12 unless (exists $self->{session}) {
914 1         96 confess 'session is closed';
915             }
916 3 100       8 unless (defined $randomLen) {
917 1         101 confess '$randomLen must be defined';
918             }
919              
920 2         14 $self->{rv} = $self->{pkcs11xs}->C_GenerateRandom($self->{session}, $randomData, $randomLen);
921 2 100       16 return $self->{rv} == CKR_OK ? $randomData : undef;
922             }
923              
924             sub GetFunctionStatus {
925 2     2 1 472 my ($self) = @_;
926              
927 2 100       8 unless (exists $self->{session}) {
928 1         135 confess 'session is closed';
929             }
930              
931 1         8 $self->{rv} = $self->{pkcs11xs}->C_GetFunctionStatus($self->{session});
932 1         4 return $self->{rv};
933             }
934              
935             sub CancelFunction {
936 2     2 1 417 my ($self) = @_;
937              
938 2 100       11 unless (exists $self->{session}) {
939 1         97 confess 'session is closed';
940             }
941              
942 1         6 $self->{rv} = $self->{pkcs11xs}->C_CancelFunction($self->{session});
943 1         15 return $self->{rv};
944             }
945              
946             sub errno {
947 0     0 1   return $_[0]->{rv};
948             }
949              
950             sub errstr {
951 0     0 1   return Crypt::PKCS11::XS::rv2str($_[0]->{rv});
952             }
953              
954             1;
955              
956             __END__