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