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