2 * Copyright (c) 2004 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include "ref/pkcs11.h"
43 #define P11_SESSION_IN_USE 2
44 #define P11_LOGIN_REQ 4
45 #define P11_LOGIN_DONE 8
46 #define P11_TOKEN_PRESENT 16
47 CK_SESSION_HANDLE session
;
54 CK_MECHANISM_TYPE_PTR list
;
56 CK_MECHANISM_INFO_PTR
*infos
;
62 CK_FUNCTION_LIST_PTR funcs
;
65 unsigned int selected_slot
;
66 struct p11_slot
*slot
;
69 #define P11FUNC(module,f,args) (*(module)->funcs->C_##f)args
71 static int p11_get_session(hx509_context
,
76 static int p11_put_session(struct p11_module
*,
79 static void p11_release_module(struct p11_module
*);
81 static int p11_list_keys(hx509_context
,
94 struct p11_slot
*slot
;
95 CK_OBJECT_HANDLE private_key
;
96 CK_OBJECT_HANDLE public_key
;
100 p11_rsa_public_encrypt(int flen
,
101 const unsigned char *from
,
110 p11_rsa_public_decrypt(int flen
,
111 const unsigned char *from
,
121 p11_rsa_private_encrypt(int flen
,
122 const unsigned char *from
,
127 struct p11_rsa
*p11rsa
= RSA_get_app_data(rsa
);
128 CK_OBJECT_HANDLE key
= p11rsa
->private_key
;
129 CK_SESSION_HANDLE session
;
130 CK_MECHANISM mechanism
;
134 if (padding
!= RSA_PKCS1_PADDING
)
137 memset(&mechanism
, 0, sizeof(mechanism
));
138 mechanism
.mechanism
= CKM_RSA_PKCS
;
140 ck_sigsize
= RSA_size(rsa
);
142 ret
= p11_get_session(NULL
, p11rsa
->p
, p11rsa
->slot
, NULL
, &session
);
146 ret
= P11FUNC(p11rsa
->p
, SignInit
, (session
, &mechanism
, key
));
148 p11_put_session(p11rsa
->p
, p11rsa
->slot
, session
);
152 ret
= P11FUNC(p11rsa
->p
, Sign
,
153 (session
, (CK_BYTE
*)(intptr_t)from
, flen
, to
, &ck_sigsize
));
154 p11_put_session(p11rsa
->p
, p11rsa
->slot
, session
);
162 p11_rsa_private_decrypt(int flen
, const unsigned char *from
, unsigned char *to
,
163 RSA
* rsa
, int padding
)
165 struct p11_rsa
*p11rsa
= RSA_get_app_data(rsa
);
166 CK_OBJECT_HANDLE key
= p11rsa
->private_key
;
167 CK_SESSION_HANDLE session
;
168 CK_MECHANISM mechanism
;
172 if (padding
!= RSA_PKCS1_PADDING
)
175 memset(&mechanism
, 0, sizeof(mechanism
));
176 mechanism
.mechanism
= CKM_RSA_PKCS
;
178 ck_sigsize
= RSA_size(rsa
);
180 ret
= p11_get_session(NULL
, p11rsa
->p
, p11rsa
->slot
, NULL
, &session
);
184 ret
= P11FUNC(p11rsa
->p
, DecryptInit
, (session
, &mechanism
, key
));
186 p11_put_session(p11rsa
->p
, p11rsa
->slot
, session
);
190 ret
= P11FUNC(p11rsa
->p
, Decrypt
,
191 (session
, (CK_BYTE
*)(intptr_t)from
, flen
, to
, &ck_sigsize
));
192 p11_put_session(p11rsa
->p
, p11rsa
->slot
, session
);
200 p11_rsa_init(RSA
*rsa
)
206 p11_rsa_finish(RSA
*rsa
)
208 struct p11_rsa
*p11rsa
= RSA_get_app_data(rsa
);
209 p11_release_module(p11rsa
->p
);
214 static const RSA_METHOD p11_rsa_pkcs1_method
= {
215 "hx509 PKCS11 PKCS#1 RSA",
216 p11_rsa_public_encrypt
,
217 p11_rsa_public_decrypt
,
218 p11_rsa_private_encrypt
,
219 p11_rsa_private_decrypt
,
236 p11_mech_info(hx509_context context
,
237 struct p11_module
*p
,
238 struct p11_slot
*slot
,
244 ret
= P11FUNC(p
, GetMechanismList
, (slot
->id
, NULL_PTR
, &i
));
246 hx509_set_error_string(context
, 0, HX509_PKCS11_NO_MECH
,
247 "Failed to get mech list count for slot %d",
249 return HX509_PKCS11_NO_MECH
;
252 hx509_set_error_string(context
, 0, HX509_PKCS11_NO_MECH
,
253 "no mech supported for slot %d", num
);
254 return HX509_PKCS11_NO_MECH
;
256 slot
->mechs
.list
= calloc(i
, sizeof(slot
->mechs
.list
[0]));
257 if (slot
->mechs
.list
== NULL
) {
258 hx509_set_error_string(context
, 0, ENOMEM
,
263 ret
= P11FUNC(p
, GetMechanismList
, (slot
->id
, slot
->mechs
.list
, &i
));
265 hx509_set_error_string(context
, 0, HX509_PKCS11_NO_MECH
,
266 "Failed to get mech list for slot %d",
268 return HX509_PKCS11_NO_MECH
;
270 assert(i
== slot
->mechs
.num
);
272 slot
->mechs
.infos
= calloc(i
, sizeof(*slot
->mechs
.infos
));
273 if (slot
->mechs
.list
== NULL
) {
274 hx509_set_error_string(context
, 0, ENOMEM
,
279 for (i
= 0; i
< slot
->mechs
.num
; i
++) {
280 slot
->mechs
.infos
[i
] = calloc(1, sizeof(*(slot
->mechs
.infos
[0])));
281 if (slot
->mechs
.infos
[i
] == NULL
) {
282 hx509_set_error_string(context
, 0, ENOMEM
,
286 ret
= P11FUNC(p
, GetMechanismInfo
, (slot
->id
, slot
->mechs
.list
[i
],
287 slot
->mechs
.infos
[i
]));
289 hx509_set_error_string(context
, 0, HX509_PKCS11_NO_MECH
,
290 "Failed to get mech info for slot %d",
292 return HX509_PKCS11_NO_MECH
;
300 p11_init_slot(hx509_context context
,
301 struct p11_module
*p
,
305 struct p11_slot
*slot
)
307 CK_SESSION_HANDLE session
;
308 CK_SLOT_INFO slot_info
;
309 CK_TOKEN_INFO token_info
;
316 ret
= P11FUNC(p
, GetSlotInfo
, (slot
->id
, &slot_info
));
318 hx509_set_error_string(context
, 0, HX509_PKCS11_TOKEN_CONFUSED
,
319 "Failed to init PKCS11 slot %d",
321 return HX509_PKCS11_TOKEN_CONFUSED
;
324 for (i
= sizeof(slot_info
.slotDescription
) - 1; i
> 0; i
--) {
325 char c
= slot_info
.slotDescription
[i
];
326 if (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r' || c
== '\0')
332 ret
= asprintf(&slot
->name
, "%.*s", (int)i
,
333 slot_info
.slotDescription
);
337 if ((slot_info
.flags
& CKF_TOKEN_PRESENT
) == 0)
340 ret
= P11FUNC(p
, GetTokenInfo
, (slot
->id
, &token_info
));
342 hx509_set_error_string(context
, 0, HX509_PKCS11_NO_TOKEN
,
343 "Failed to init PKCS11 slot %d "
346 return HX509_PKCS11_NO_TOKEN
;
348 slot
->flags
|= P11_TOKEN_PRESENT
;
350 if (token_info
.flags
& CKF_LOGIN_REQUIRED
)
351 slot
->flags
|= P11_LOGIN_REQ
;
353 ret
= p11_get_session(context
, p
, slot
, lock
, &session
);
357 ret
= p11_mech_info(context
, p
, slot
, num
);
361 ret
= p11_list_keys(context
, p
, slot
, session
, lock
, &slot
->certs
);
363 p11_put_session(p
, slot
, session
);
369 p11_get_session(hx509_context context
,
370 struct p11_module
*p
,
371 struct p11_slot
*slot
,
373 CK_SESSION_HANDLE
*psession
)
377 if (slot
->flags
& P11_SESSION_IN_USE
)
378 _hx509_abort("slot already in session");
380 if (slot
->flags
& P11_SESSION
) {
381 slot
->flags
|= P11_SESSION_IN_USE
;
382 *psession
= slot
->session
;
386 ret
= P11FUNC(p
, OpenSession
, (slot
->id
,
393 hx509_set_error_string(context
, 0, HX509_PKCS11_OPEN_SESSION
,
394 "Failed to OpenSession for slot id %d "
395 "with error: 0x%08x",
397 return HX509_PKCS11_OPEN_SESSION
;
400 slot
->flags
|= P11_SESSION
;
403 * If we have have to login, and haven't tried before and have a
404 * prompter or known to work pin code.
406 * This code is very conversative and only uses the prompter in
407 * the hx509_lock, the reason is that it's bad to try many
408 * passwords on a pkcs11 token, it might lock up and have to be
409 * unlocked by a administrator.
411 * XXX try harder to not use pin several times on the same card.
414 if ( (slot
->flags
& P11_LOGIN_REQ
)
415 && (slot
->flags
& P11_LOGIN_DONE
) == 0
416 && (lock
|| slot
->pin
))
422 if (slot
->pin
== NULL
) {
424 memset(&prompt
, 0, sizeof(prompt
));
426 ret
= asprintf(&str
, "PIN code for %s: ", slot
->name
);
427 if (ret
== -1 || str
== NULL
) {
429 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
433 prompt
.type
= HX509_PROMPT_TYPE_PASSWORD
;
434 prompt
.reply
.data
= pin
;
435 prompt
.reply
.length
= sizeof(pin
);
437 ret
= hx509_lock_prompt(lock
, &prompt
);
441 hx509_set_error_string(context
, 0, ret
,
442 "Failed to get pin code for slot "
443 "id %d with error: %d",
449 strlcpy(pin
, slot
->pin
, sizeof(pin
));
452 ret
= P11FUNC(p
, Login
, (slot
->session
, CKU_USER
,
453 (unsigned char*)pin
, strlen(pin
)));
456 hx509_set_error_string(context
, 0, HX509_PKCS11_LOGIN
,
457 "Failed to login on slot id %d "
458 "with error: 0x%08x",
462 return HX509_PKCS11_PIN_LOCKED
;
463 case CKR_PIN_EXPIRED
:
464 return HX509_PKCS11_PIN_EXPIRED
;
465 case CKR_PIN_INCORRECT
:
466 return HX509_PKCS11_PIN_INCORRECT
;
467 case CKR_USER_PIN_NOT_INITIALIZED
:
468 return HX509_PKCS11_PIN_NOT_INITIALIZED
;
470 return HX509_PKCS11_LOGIN
;
473 slot
->flags
|= P11_LOGIN_DONE
;
475 if (slot
->pin
== NULL
) {
476 slot
->pin
= strdup(pin
);
477 if (slot
->pin
== NULL
) {
479 hx509_set_error_string(context
, 0, ENOMEM
,
485 slot
->flags
|= P11_LOGIN_DONE
;
487 slot
->flags
|= P11_SESSION_IN_USE
;
489 *psession
= slot
->session
;
495 p11_put_session(struct p11_module
*p
,
496 struct p11_slot
*slot
,
497 CK_SESSION_HANDLE session
)
499 if ((slot
->flags
& P11_SESSION_IN_USE
) == 0)
500 _hx509_abort("slot not in session");
501 slot
->flags
&= ~P11_SESSION_IN_USE
;
507 iterate_entries(hx509_context context
,
508 struct p11_module
*p
, struct p11_slot
*slot
,
509 CK_SESSION_HANDLE session
,
510 CK_ATTRIBUTE
*search_data
, int num_search_data
,
511 CK_ATTRIBUTE
*query
, int num_query
,
512 int (*func
)(hx509_context
,
513 struct p11_module
*, struct p11_slot
*,
514 CK_SESSION_HANDLE session
,
515 CK_OBJECT_HANDLE object
,
516 void *, CK_ATTRIBUTE
*, int), void *ptr
)
518 CK_OBJECT_HANDLE object
;
519 CK_ULONG object_count
;
522 ret
= P11FUNC(p
, FindObjectsInit
, (session
, search_data
, num_search_data
));
527 ret
= P11FUNC(p
, FindObjects
, (session
, &object
, 1, &object_count
));
531 if (object_count
== 0)
534 for (i
= 0; i
< num_query
; i
++)
535 query
[i
].pValue
= NULL
;
537 ret
= P11FUNC(p
, GetAttributeValue
,
538 (session
, object
, query
, num_query
));
542 for (i
= 0; i
< num_query
; i
++) {
543 query
[i
].pValue
= malloc(query
[i
].ulValueLen
);
544 if (query
[i
].pValue
== NULL
) {
549 ret
= P11FUNC(p
, GetAttributeValue
,
550 (session
, object
, query
, num_query
));
556 ret
= (*func
)(context
, p
, slot
, session
, object
, ptr
, query
, num_query
);
560 for (i
= 0; i
< num_query
; i
++) {
562 free(query
[i
].pValue
);
563 query
[i
].pValue
= NULL
;
568 for (i
= 0; i
< num_query
; i
++) {
570 free(query
[i
].pValue
);
571 query
[i
].pValue
= NULL
;
574 ret2
= P11FUNC(p
, FindObjectsFinal
, (session
));
575 if (ret2
!= CKR_OK
) {
583 getattr_bn(struct p11_module
*p
,
584 struct p11_slot
*slot
,
585 CK_SESSION_HANDLE session
,
586 CK_OBJECT_HANDLE object
,
595 query
.ulValueLen
= 0;
597 ret
= P11FUNC(p
, GetAttributeValue
,
598 (session
, object
, &query
, 1));
602 query
.pValue
= malloc(query
.ulValueLen
);
604 ret
= P11FUNC(p
, GetAttributeValue
,
605 (session
, object
, &query
, 1));
610 bn
= BN_bin2bn(query
.pValue
, query
.ulValueLen
, NULL
);
617 collect_private_key(hx509_context context
,
618 struct p11_module
*p
, struct p11_slot
*slot
,
619 CK_SESSION_HANDLE session
,
620 CK_OBJECT_HANDLE object
,
621 void *ptr
, CK_ATTRIBUTE
*query
, int num_query
)
623 struct hx509_collector
*collector
= ptr
;
624 hx509_private_key key
;
625 heim_octet_string localKeyId
;
628 struct p11_rsa
*p11rsa
;
630 localKeyId
.data
= query
[0].pValue
;
631 localKeyId
.length
= query
[0].ulValueLen
;
633 ret
= hx509_private_key_init(&key
, NULL
, NULL
);
639 _hx509_abort("out of memory");
642 * The exponent and modulus should always be present according to
643 * the pkcs11 specification, but some smartcards leaves it out,
644 * let ignore any failure to fetch it.
646 rsa
->n
= getattr_bn(p
, slot
, session
, object
, CKA_MODULUS
);
647 rsa
->e
= getattr_bn(p
, slot
, session
, object
, CKA_PUBLIC_EXPONENT
);
649 p11rsa
= calloc(1, sizeof(*p11rsa
));
651 _hx509_abort("out of memory");
655 p11rsa
->private_key
= object
;
658 _hx509_abort("pkcs11 ref == 0 on alloc");
660 if (p
->ref
== UINT_MAX
)
661 _hx509_abort("pkcs11 ref == UINT_MAX on alloc");
663 RSA_set_method(rsa
, &p11_rsa_pkcs1_method
);
664 ret
= RSA_set_app_data(rsa
, p11rsa
);
666 _hx509_abort("RSA_set_app_data");
668 hx509_private_key_assign_rsa(key
, rsa
);
670 ret
= _hx509_collector_private_key_add(context
,
672 hx509_signature_rsa(),
678 hx509_private_key_free(&key
);
685 p11_cert_release(hx509_cert cert
, void *ctx
)
687 struct p11_module
*p
= ctx
;
688 p11_release_module(p
);
693 collect_cert(hx509_context context
,
694 struct p11_module
*p
, struct p11_slot
*slot
,
695 CK_SESSION_HANDLE session
,
696 CK_OBJECT_HANDLE object
,
697 void *ptr
, CK_ATTRIBUTE
*query
, int num_query
)
699 struct hx509_collector
*collector
= ptr
;
700 heim_error_t error
= NULL
;
704 if ((CK_LONG
)query
[0].ulValueLen
== -1 ||
705 (CK_LONG
)query
[1].ulValueLen
== -1)
710 cert
= hx509_cert_init_data(context
, query
[1].pValue
,
711 query
[1].ulValueLen
, &error
);
713 ret
= heim_error_get_code(error
);
719 _hx509_abort("pkcs11 ref == 0 on alloc");
721 if (p
->ref
== UINT_MAX
)
722 _hx509_abort("pkcs11 ref to high");
724 _hx509_cert_set_release(cert
, p11_cert_release
, p
);
727 heim_octet_string data
;
729 data
.data
= query
[0].pValue
;
730 data
.length
= query
[0].ulValueLen
;
732 _hx509_set_cert_attribute(context
,
734 &asn1_oid_id_pkcs_9_at_localKeyId
,
738 if ((CK_LONG
)query
[2].ulValueLen
!= -1) {
741 ret
= asprintf(&str
, "%.*s",
742 (int)query
[2].ulValueLen
, (char *)query
[2].pValue
);
743 if (ret
!= -1 && str
) {
744 hx509_cert_set_friendly_name(cert
, str
);
749 ret
= _hx509_collector_certs_add(context
, collector
, cert
);
750 hx509_cert_free(cert
);
757 p11_list_keys(hx509_context context
,
758 struct p11_module
*p
,
759 struct p11_slot
*slot
,
760 CK_SESSION_HANDLE session
,
764 struct hx509_collector
*collector
;
765 CK_OBJECT_CLASS key_class
;
766 CK_ATTRIBUTE search_data
[] = {
767 {CKA_CLASS
, NULL
, 0},
769 CK_ATTRIBUTE query_data
[3] = {
771 {CKA_VALUE
, NULL
, 0},
776 search_data
[0].pValue
= &key_class
;
777 search_data
[0].ulValueLen
= sizeof(key_class
);
780 lock
= _hx509_empty_lock
;
782 ret
= _hx509_collector_alloc(context
, lock
, &collector
);
786 key_class
= CKO_PRIVATE_KEY
;
787 ret
= iterate_entries(context
, p
, slot
, session
,
790 collect_private_key
, collector
);
794 key_class
= CKO_CERTIFICATE
;
795 ret
= iterate_entries(context
, p
, slot
, session
,
798 collect_cert
, collector
);
802 ret
= _hx509_collector_collect_certs(context
, collector
, &slot
->certs
);
805 _hx509_collector_free(collector
);
812 p11_init(hx509_context context
,
813 hx509_certs certs
, void **data
, int flags
,
814 const char *residue
, hx509_lock lock
)
816 CK_C_GetFunctionList getFuncs
;
817 struct p11_module
*p
;
823 if (flags
& HX509_CERTS_NO_PRIVATE_KEYS
) {
824 hx509_set_error_string(context
, 0, ENOTSUP
,
825 "PKCS#11 store does not support "
826 "HX509_CERTS_NO_PRIVATE_KEYS flag");
830 if (residue
== NULL
|| residue
[0] == '\0') {
831 hx509_set_error_string(context
, 0, EINVAL
,
832 "PKCS#11 store not specified");
835 list
= strdup(residue
);
839 p
= calloc(1, sizeof(*p
));
846 p
->selected_slot
= 0;
848 str
= strchr(list
, ',');
853 strnext
= strchr(str
, ',');
856 if (strncasecmp(str
, "slot=", 5) == 0)
857 p
->selected_slot
= atoi(str
+ 5);
861 p
->dl_handle
= dlopen(list
, RTLD_NOW
| RTLD_LOCAL
| RTLD_GROUP
);
862 if (p
->dl_handle
== NULL
) {
863 ret
= HX509_PKCS11_LOAD
;
864 hx509_set_error_string(context
, 0, ret
,
865 "Failed to open %s: %s", list
, dlerror());
869 getFuncs
= (CK_C_GetFunctionList
) dlsym(p
->dl_handle
, "C_GetFunctionList");
870 if (getFuncs
== NULL
) {
871 ret
= HX509_PKCS11_LOAD
;
872 hx509_set_error_string(context
, 0, ret
,
873 "C_GetFunctionList missing in %s: %s",
878 ret
= (*getFuncs
)(&p
->funcs
);
880 ret
= HX509_PKCS11_LOAD
;
881 hx509_set_error_string(context
, 0, ret
,
882 "C_GetFunctionList failed in %s", list
);
886 ret
= P11FUNC(p
, Initialize
, (NULL_PTR
));
888 ret
= HX509_PKCS11_TOKEN_CONFUSED
;
889 hx509_set_error_string(context
, 0, ret
,
890 "Failed initialize the PKCS11 module");
894 ret
= P11FUNC(p
, GetSlotList
, (FALSE
, NULL
, &p
->num_slots
));
896 ret
= HX509_PKCS11_TOKEN_CONFUSED
;
897 hx509_set_error_string(context
, 0, ret
,
898 "Failed to get number of PKCS11 slots");
902 if (p
->num_slots
== 0) {
903 ret
= HX509_PKCS11_NO_SLOT
;
904 hx509_set_error_string(context
, 0, ret
,
905 "Selected PKCS11 module have no slots");
911 CK_SLOT_ID_PTR slot_ids
;
915 slot_ids
= malloc(p
->num_slots
* sizeof(*slot_ids
));
916 if (slot_ids
== NULL
) {
917 hx509_clear_error_string(context
);
922 ret
= P11FUNC(p
, GetSlotList
, (FALSE
, slot_ids
, &p
->num_slots
));
925 hx509_set_error_string(context
, 0, HX509_PKCS11_TOKEN_CONFUSED
,
926 "Failed getting slot-list from "
928 ret
= HX509_PKCS11_TOKEN_CONFUSED
;
932 p
->slot
= calloc(p
->num_slots
, sizeof(p
->slot
[0]));
933 if (p
->slot
== NULL
) {
935 hx509_set_error_string(context
, 0, ENOMEM
,
936 "Failed to get memory for slot-list");
941 for (i
= 0; i
< p
->num_slots
; i
++) {
942 if ((p
->selected_slot
!= 0) && (slot_ids
[i
] != (p
->selected_slot
- 1)))
944 ret
= p11_init_slot(context
, p
, lock
, slot_ids
[i
], i
, &p
->slot
[i
]);
946 if (p
->slot
[i
].flags
& P11_TOKEN_PRESENT
)
953 if (num_tokens
== 0) {
954 ret
= HX509_PKCS11_NO_TOKEN
;
967 p11_release_module(p
);
972 p11_release_module(struct p11_module
*p
)
977 _hx509_abort("pkcs11 ref to low");
981 for (i
= 0; i
< p
->num_slots
; i
++) {
982 if (p
->slot
[i
].flags
& P11_SESSION_IN_USE
)
983 _hx509_abort("pkcs11 module release while session in use");
984 if (p
->slot
[i
].flags
& P11_SESSION
) {
985 P11FUNC(p
, CloseSession
, (p
->slot
[i
].session
));
989 free(p
->slot
[i
].name
);
990 if (p
->slot
[i
].pin
) {
991 memset(p
->slot
[i
].pin
, 0, strlen(p
->slot
[i
].pin
));
992 free(p
->slot
[i
].pin
);
994 if (p
->slot
[i
].mechs
.num
) {
995 free(p
->slot
[i
].mechs
.list
);
997 if (p
->slot
[i
].mechs
.infos
) {
1000 for (j
= 0 ; j
< p
->slot
[i
].mechs
.num
; j
++)
1001 free(p
->slot
[i
].mechs
.infos
[j
]);
1002 free(p
->slot
[i
].mechs
.infos
);
1009 P11FUNC(p
, Finalize
, (NULL
));
1012 dlclose(p
->dl_handle
);
1014 memset(p
, 0, sizeof(*p
));
1019 p11_free(hx509_certs certs
, void *data
)
1021 struct p11_module
*p
= data
;
1024 for (i
= 0; i
< p
->num_slots
; i
++) {
1025 if (p
->slot
[i
].certs
)
1026 hx509_certs_free(&p
->slot
[i
].certs
);
1028 p11_release_module(p
);
1038 p11_iter_start(hx509_context context
,
1039 hx509_certs certs
, void *data
, void **cursor
)
1041 struct p11_module
*p
= data
;
1042 struct p11_cursor
*c
;
1046 c
= malloc(sizeof(*c
));
1048 hx509_clear_error_string(context
);
1051 ret
= hx509_certs_init(context
, "MEMORY:pkcs11-iter", 0, NULL
, &c
->certs
);
1057 for (i
= 0 ; i
< p
->num_slots
; i
++) {
1058 if (p
->slot
[i
].certs
== NULL
)
1060 ret
= hx509_certs_merge(context
, c
->certs
, p
->slot
[i
].certs
);
1062 hx509_certs_free(&c
->certs
);
1068 ret
= hx509_certs_start_seq(context
, c
->certs
, &c
->cursor
);
1070 hx509_certs_free(&c
->certs
);
1080 p11_iter(hx509_context context
,
1081 hx509_certs certs
, void *data
, void *cursor
, hx509_cert
*cert
)
1083 struct p11_cursor
*c
= cursor
;
1084 return hx509_certs_next_cert(context
, c
->certs
, c
->cursor
, cert
);
1088 p11_iter_end(hx509_context context
,
1089 hx509_certs certs
, void *data
, void *cursor
)
1091 struct p11_cursor
*c
= cursor
;
1093 ret
= hx509_certs_end_seq(context
, c
->certs
, c
->cursor
);
1094 hx509_certs_free(&c
->certs
);
1099 #define MECHFLAG(x) { "unknown-flag-" #x, x }
1100 static struct units mechflags
[] = {
1101 MECHFLAG(0x80000000),
1102 MECHFLAG(0x40000000),
1103 MECHFLAG(0x20000000),
1104 MECHFLAG(0x10000000),
1105 MECHFLAG(0x08000000),
1106 MECHFLAG(0x04000000),
1107 {"ec-compress", 0x2000000 },
1108 {"ec-uncompress", 0x1000000 },
1109 {"ec-namedcurve", 0x0800000 },
1110 {"ec-ecparameters", 0x0400000 },
1111 {"ec-f-2m", 0x0200000 },
1112 {"ec-f-p", 0x0100000 },
1113 {"derive", 0x0080000 },
1114 {"unwrap", 0x0040000 },
1115 {"wrap", 0x0020000 },
1116 {"genereate-key-pair", 0x0010000 },
1117 {"generate", 0x0008000 },
1118 {"verify-recover", 0x0004000 },
1119 {"verify", 0x0002000 },
1120 {"sign-recover", 0x0001000 },
1121 {"sign", 0x0000800 },
1122 {"digest", 0x0000400 },
1123 {"decrypt", 0x0000200 },
1124 {"encrypt", 0x0000100 },
1138 p11_printinfo(hx509_context context
,
1141 int (*func
)(void *, const char *),
1144 struct p11_module
*p
= data
;
1147 _hx509_pi_printf(func
, ctx
, "pkcs11 driver with %d slot%s",
1148 p
->num_slots
, p
->num_slots
> 1 ? "s" : "");
1150 for (i
= 0; i
< p
->num_slots
; i
++) {
1151 struct p11_slot
*s
= &p
->slot
[i
];
1153 _hx509_pi_printf(func
, ctx
, "slot %d: id: %d name: %s flags: %08x",
1154 i
, (int)s
->id
, s
->name
, s
->flags
);
1156 _hx509_pi_printf(func
, ctx
, "number of supported mechanisms: %lu",
1157 (unsigned long)s
->mechs
.num
);
1158 for (j
= 0; j
< s
->mechs
.num
; j
++) {
1159 const char *mechname
= "unknown";
1160 char flags
[256], unknownname
[40];
1161 #define MECHNAME(s,n) case s: mechname = n; break
1162 switch(s
->mechs
.list
[j
]) {
1163 MECHNAME(CKM_RSA_PKCS_KEY_PAIR_GEN
, "rsa-pkcs-key-pair-gen");
1164 MECHNAME(CKM_RSA_PKCS
, "rsa-pkcs");
1165 MECHNAME(CKM_RSA_X_509
, "rsa-x-509");
1166 MECHNAME(CKM_MD5_RSA_PKCS
, "md5-rsa-pkcs");
1167 MECHNAME(CKM_SHA1_RSA_PKCS
, "sha1-rsa-pkcs");
1168 MECHNAME(CKM_SHA256_RSA_PKCS
, "sha256-rsa-pkcs");
1169 MECHNAME(CKM_SHA384_RSA_PKCS
, "sha384-rsa-pkcs");
1170 MECHNAME(CKM_SHA512_RSA_PKCS
, "sha512-rsa-pkcs");
1171 MECHNAME(CKM_RIPEMD160_RSA_PKCS
, "ripemd160-rsa-pkcs");
1172 MECHNAME(CKM_RSA_PKCS_OAEP
, "rsa-pkcs-oaep");
1173 MECHNAME(CKM_SHA512_HMAC
, "sha512-hmac");
1174 MECHNAME(CKM_SHA512
, "sha512");
1175 MECHNAME(CKM_SHA384_HMAC
, "sha384-hmac");
1176 MECHNAME(CKM_SHA384
, "sha384");
1177 MECHNAME(CKM_SHA256_HMAC
, "sha256-hmac");
1178 MECHNAME(CKM_SHA256
, "sha256");
1179 MECHNAME(CKM_SHA_1
, "sha1");
1180 MECHNAME(CKM_MD5
, "md5");
1181 MECHNAME(CKM_RIPEMD160
, "ripemd-160");
1182 MECHNAME(CKM_DES_ECB
, "des-ecb");
1183 MECHNAME(CKM_DES_CBC
, "des-cbc");
1184 MECHNAME(CKM_AES_ECB
, "aes-ecb");
1185 MECHNAME(CKM_AES_CBC
, "aes-cbc");
1186 MECHNAME(CKM_DH_PKCS_PARAMETER_GEN
, "dh-pkcs-parameter-gen");
1188 snprintf(unknownname
, sizeof(unknownname
),
1190 (unsigned long)s
->mechs
.list
[j
]);
1191 mechname
= unknownname
;
1195 unparse_flags(s
->mechs
.infos
[j
]->flags
, mechflags
,
1196 flags
, sizeof(flags
));
1198 _hx509_pi_printf(func
, ctx
, " %s: %s", mechname
, flags
);
1205 static struct hx509_keyset_ops keyset_pkcs11
= {
1222 #endif /* HAVE_DLOPEN */
1224 HX509_LIB_FUNCTION
void HX509_LIB_CALL
1225 _hx509_ks_pkcs11_register(hx509_context context
)
1228 _hx509_ks_register(context
, &keyset_pkcs11
);