Home | History | Annotate | Line # | Download | only in hx509
      1  1.3  christos /*	$NetBSD: ks_p11.c,v 1.4 2023/06/19 21:41:44 christos Exp $	*/
      2  1.1     elric 
      3  1.1     elric /*
      4  1.1     elric  * Copyright (c) 2004 - 2008 Kungliga Tekniska Hgskolan
      5  1.1     elric  * (Royal Institute of Technology, Stockholm, Sweden).
      6  1.1     elric  * All rights reserved.
      7  1.1     elric  *
      8  1.1     elric  * Redistribution and use in source and binary forms, with or without
      9  1.1     elric  * modification, are permitted provided that the following conditions
     10  1.1     elric  * are met:
     11  1.1     elric  *
     12  1.1     elric  * 1. Redistributions of source code must retain the above copyright
     13  1.1     elric  *    notice, this list of conditions and the following disclaimer.
     14  1.1     elric  *
     15  1.1     elric  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1     elric  *    notice, this list of conditions and the following disclaimer in the
     17  1.1     elric  *    documentation and/or other materials provided with the distribution.
     18  1.1     elric  *
     19  1.1     elric  * 3. Neither the name of the Institute nor the names of its contributors
     20  1.1     elric  *    may be used to endorse or promote products derived from this software
     21  1.1     elric  *    without specific prior written permission.
     22  1.1     elric  *
     23  1.1     elric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  1.1     elric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1     elric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1     elric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  1.1     elric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1     elric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1     elric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1     elric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1     elric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1     elric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1     elric  * SUCH DAMAGE.
     34  1.1     elric  */
     35  1.1     elric 
     36  1.1     elric #include "hx_locl.h"
     37  1.1     elric #ifdef HAVE_DLFCN_H
     38  1.1     elric #include <dlfcn.h>
     39  1.1     elric #endif
     40  1.1     elric 
     41  1.1     elric #ifdef HAVE_DLOPEN
     42  1.1     elric 
     43  1.2  christos #include "ref/pkcs11.h"
     44  1.1     elric 
     45  1.1     elric struct p11_slot {
     46  1.1     elric     int flags;
     47  1.1     elric #define P11_SESSION		1
     48  1.1     elric #define P11_SESSION_IN_USE	2
     49  1.1     elric #define P11_LOGIN_REQ		4
     50  1.1     elric #define P11_LOGIN_DONE		8
     51  1.1     elric #define P11_TOKEN_PRESENT	16
     52  1.1     elric     CK_SESSION_HANDLE session;
     53  1.1     elric     CK_SLOT_ID id;
     54  1.1     elric     CK_BBOOL token;
     55  1.1     elric     char *name;
     56  1.1     elric     hx509_certs certs;
     57  1.1     elric     char *pin;
     58  1.1     elric     struct {
     59  1.1     elric 	CK_MECHANISM_TYPE_PTR list;
     60  1.1     elric 	CK_ULONG num;
     61  1.1     elric 	CK_MECHANISM_INFO_PTR *infos;
     62  1.1     elric     } mechs;
     63  1.1     elric };
     64  1.1     elric 
     65  1.1     elric struct p11_module {
     66  1.1     elric     void *dl_handle;
     67  1.1     elric     CK_FUNCTION_LIST_PTR funcs;
     68  1.1     elric     CK_ULONG num_slots;
     69  1.1     elric     unsigned int ref;
     70  1.2  christos     unsigned int selected_slot;
     71  1.1     elric     struct p11_slot *slot;
     72  1.1     elric };
     73  1.1     elric 
     74  1.1     elric #define P11FUNC(module,f,args) (*(module)->funcs->C_##f)args
     75  1.1     elric 
     76  1.1     elric static int p11_get_session(hx509_context,
     77  1.1     elric 			   struct p11_module *,
     78  1.1     elric 			   struct p11_slot *,
     79  1.1     elric 			   hx509_lock,
     80  1.1     elric 			   CK_SESSION_HANDLE *);
     81  1.1     elric static int p11_put_session(struct p11_module *,
     82  1.1     elric 			   struct p11_slot *,
     83  1.1     elric 			   CK_SESSION_HANDLE);
     84  1.1     elric static void p11_release_module(struct p11_module *);
     85  1.1     elric 
     86  1.1     elric static int p11_list_keys(hx509_context,
     87  1.1     elric 			 struct p11_module *,
     88  1.1     elric 			 struct p11_slot *,
     89  1.1     elric 			 CK_SESSION_HANDLE,
     90  1.1     elric 			 hx509_lock,
     91  1.1     elric 			 hx509_certs *);
     92  1.1     elric 
     93  1.1     elric /*
     94  1.1     elric  *
     95  1.1     elric  */
     96  1.1     elric 
     97  1.1     elric struct p11_rsa {
     98  1.1     elric     struct p11_module *p;
     99  1.1     elric     struct p11_slot *slot;
    100  1.1     elric     CK_OBJECT_HANDLE private_key;
    101  1.1     elric     CK_OBJECT_HANDLE public_key;
    102  1.1     elric };
    103  1.1     elric 
    104  1.1     elric static int
    105  1.1     elric p11_rsa_public_encrypt(int flen,
    106  1.1     elric 		       const unsigned char *from,
    107  1.1     elric 		       unsigned char *to,
    108  1.1     elric 		       RSA *rsa,
    109  1.1     elric 		       int padding)
    110  1.1     elric {
    111  1.1     elric     return -1;
    112  1.1     elric }
    113  1.1     elric 
    114  1.1     elric static int
    115  1.1     elric p11_rsa_public_decrypt(int flen,
    116  1.1     elric 		       const unsigned char *from,
    117  1.1     elric 		       unsigned char *to,
    118  1.1     elric 		       RSA *rsa,
    119  1.1     elric 		       int padding)
    120  1.1     elric {
    121  1.1     elric     return -1;
    122  1.1     elric }
    123  1.1     elric 
    124  1.1     elric 
    125  1.1     elric static int
    126  1.1     elric p11_rsa_private_encrypt(int flen,
    127  1.1     elric 			const unsigned char *from,
    128  1.1     elric 			unsigned char *to,
    129  1.1     elric 			RSA *rsa,
    130  1.1     elric 			int padding)
    131  1.1     elric {
    132  1.1     elric     struct p11_rsa *p11rsa = RSA_get_app_data(rsa);
    133  1.1     elric     CK_OBJECT_HANDLE key = p11rsa->private_key;
    134  1.1     elric     CK_SESSION_HANDLE session;
    135  1.1     elric     CK_MECHANISM mechanism;
    136  1.1     elric     CK_ULONG ck_sigsize;
    137  1.1     elric     int ret;
    138  1.1     elric 
    139  1.1     elric     if (padding != RSA_PKCS1_PADDING)
    140  1.1     elric 	return -1;
    141  1.1     elric 
    142  1.1     elric     memset(&mechanism, 0, sizeof(mechanism));
    143  1.1     elric     mechanism.mechanism = CKM_RSA_PKCS;
    144  1.1     elric 
    145  1.1     elric     ck_sigsize = RSA_size(rsa);
    146  1.1     elric 
    147  1.1     elric     ret = p11_get_session(NULL, p11rsa->p, p11rsa->slot, NULL, &session);
    148  1.1     elric     if (ret)
    149  1.1     elric 	return -1;
    150  1.1     elric 
    151  1.1     elric     ret = P11FUNC(p11rsa->p, SignInit, (session, &mechanism, key));
    152  1.1     elric     if (ret != CKR_OK) {
    153  1.1     elric 	p11_put_session(p11rsa->p, p11rsa->slot, session);
    154  1.1     elric 	return -1;
    155  1.1     elric     }
    156  1.1     elric 
    157  1.1     elric     ret = P11FUNC(p11rsa->p, Sign,
    158  1.2  christos 		  (session, (CK_BYTE *)(intptr_t)from, flen, to, &ck_sigsize));
    159  1.1     elric     p11_put_session(p11rsa->p, p11rsa->slot, session);
    160  1.1     elric     if (ret != CKR_OK)
    161  1.1     elric 	return -1;
    162  1.1     elric 
    163  1.1     elric     return ck_sigsize;
    164  1.1     elric }
    165  1.1     elric 
    166  1.1     elric static int
    167  1.1     elric p11_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
    168  1.1     elric 			RSA * rsa, int padding)
    169  1.1     elric {
    170  1.1     elric     struct p11_rsa *p11rsa = RSA_get_app_data(rsa);
    171  1.1     elric     CK_OBJECT_HANDLE key = p11rsa->private_key;
    172  1.1     elric     CK_SESSION_HANDLE session;
    173  1.1     elric     CK_MECHANISM mechanism;
    174  1.1     elric     CK_ULONG ck_sigsize;
    175  1.1     elric     int ret;
    176  1.1     elric 
    177  1.1     elric     if (padding != RSA_PKCS1_PADDING)
    178  1.1     elric 	return -1;
    179  1.1     elric 
    180  1.1     elric     memset(&mechanism, 0, sizeof(mechanism));
    181  1.1     elric     mechanism.mechanism = CKM_RSA_PKCS;
    182  1.1     elric 
    183  1.1     elric     ck_sigsize = RSA_size(rsa);
    184  1.1     elric 
    185  1.1     elric     ret = p11_get_session(NULL, p11rsa->p, p11rsa->slot, NULL, &session);
    186  1.1     elric     if (ret)
    187  1.1     elric 	return -1;
    188  1.1     elric 
    189  1.1     elric     ret = P11FUNC(p11rsa->p, DecryptInit, (session, &mechanism, key));
    190  1.1     elric     if (ret != CKR_OK) {
    191  1.1     elric 	p11_put_session(p11rsa->p, p11rsa->slot, session);
    192  1.1     elric 	return -1;
    193  1.1     elric     }
    194  1.1     elric 
    195  1.1     elric     ret = P11FUNC(p11rsa->p, Decrypt,
    196  1.2  christos 		  (session, (CK_BYTE *)(intptr_t)from, flen, to, &ck_sigsize));
    197  1.1     elric     p11_put_session(p11rsa->p, p11rsa->slot, session);
    198  1.1     elric     if (ret != CKR_OK)
    199  1.1     elric 	return -1;
    200  1.1     elric 
    201  1.1     elric     return ck_sigsize;
    202  1.1     elric }
    203  1.1     elric 
    204  1.1     elric static int
    205  1.1     elric p11_rsa_init(RSA *rsa)
    206  1.1     elric {
    207  1.1     elric     return 1;
    208  1.1     elric }
    209  1.1     elric 
    210  1.1     elric static int
    211  1.1     elric p11_rsa_finish(RSA *rsa)
    212  1.1     elric {
    213  1.1     elric     struct p11_rsa *p11rsa = RSA_get_app_data(rsa);
    214  1.1     elric     p11_release_module(p11rsa->p);
    215  1.1     elric     free(p11rsa);
    216  1.1     elric     return 1;
    217  1.1     elric }
    218  1.1     elric 
    219  1.3  christos 
    220  1.3  christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL
    221  1.1     elric static const RSA_METHOD p11_rsa_pkcs1_method = {
    222  1.1     elric     "hx509 PKCS11 PKCS#1 RSA",
    223  1.1     elric     p11_rsa_public_encrypt,
    224  1.1     elric     p11_rsa_public_decrypt,
    225  1.1     elric     p11_rsa_private_encrypt,
    226  1.1     elric     p11_rsa_private_decrypt,
    227  1.1     elric     NULL,
    228  1.1     elric     NULL,
    229  1.1     elric     p11_rsa_init,
    230  1.1     elric     p11_rsa_finish,
    231  1.1     elric     0,
    232  1.1     elric     NULL,
    233  1.1     elric     NULL,
    234  1.2  christos     NULL,
    235  1.1     elric     NULL
    236  1.1     elric };
    237  1.3  christos #endif
    238  1.1     elric 
    239  1.1     elric /*
    240  1.1     elric  *
    241  1.1     elric  */
    242  1.1     elric 
    243  1.1     elric static int
    244  1.1     elric p11_mech_info(hx509_context context,
    245  1.1     elric 	      struct p11_module *p,
    246  1.1     elric 	      struct p11_slot *slot,
    247  1.1     elric 	      int num)
    248  1.1     elric {
    249  1.1     elric     CK_ULONG i;
    250  1.1     elric     int ret;
    251  1.1     elric 
    252  1.1     elric     ret = P11FUNC(p, GetMechanismList, (slot->id, NULL_PTR, &i));
    253  1.1     elric     if (ret) {
    254  1.1     elric 	hx509_set_error_string(context, 0, HX509_PKCS11_NO_MECH,
    255  1.1     elric 			       "Failed to get mech list count for slot %d",
    256  1.1     elric 			       num);
    257  1.1     elric 	return HX509_PKCS11_NO_MECH;
    258  1.1     elric     }
    259  1.1     elric     if (i == 0) {
    260  1.1     elric 	hx509_set_error_string(context, 0, HX509_PKCS11_NO_MECH,
    261  1.1     elric 			       "no mech supported for slot %d", num);
    262  1.1     elric 	return HX509_PKCS11_NO_MECH;
    263  1.1     elric     }
    264  1.1     elric     slot->mechs.list = calloc(i, sizeof(slot->mechs.list[0]));
    265  1.1     elric     if (slot->mechs.list == NULL) {
    266  1.1     elric 	hx509_set_error_string(context, 0, ENOMEM,
    267  1.1     elric 			       "out of memory");
    268  1.1     elric 	return ENOMEM;
    269  1.1     elric     }
    270  1.1     elric     slot->mechs.num = i;
    271  1.1     elric     ret = P11FUNC(p, GetMechanismList, (slot->id, slot->mechs.list, &i));
    272  1.1     elric     if (ret) {
    273  1.1     elric 	hx509_set_error_string(context, 0, HX509_PKCS11_NO_MECH,
    274  1.1     elric 			       "Failed to get mech list for slot %d",
    275  1.1     elric 			       num);
    276  1.1     elric 	return HX509_PKCS11_NO_MECH;
    277  1.1     elric     }
    278  1.1     elric     assert(i == slot->mechs.num);
    279  1.1     elric 
    280  1.1     elric     slot->mechs.infos = calloc(i, sizeof(*slot->mechs.infos));
    281  1.1     elric     if (slot->mechs.list == NULL) {
    282  1.1     elric 	hx509_set_error_string(context, 0, ENOMEM,
    283  1.1     elric 			       "out of memory");
    284  1.1     elric 	return ENOMEM;
    285  1.1     elric     }
    286  1.1     elric 
    287  1.1     elric     for (i = 0; i < slot->mechs.num; i++) {
    288  1.1     elric 	slot->mechs.infos[i] = calloc(1, sizeof(*(slot->mechs.infos[0])));
    289  1.1     elric 	if (slot->mechs.infos[i] == NULL) {
    290  1.1     elric 	    hx509_set_error_string(context, 0, ENOMEM,
    291  1.1     elric 				   "out of memory");
    292  1.1     elric 	    return ENOMEM;
    293  1.1     elric 	}
    294  1.1     elric 	ret = P11FUNC(p, GetMechanismInfo, (slot->id, slot->mechs.list[i],
    295  1.1     elric 					    slot->mechs.infos[i]));
    296  1.1     elric 	if (ret) {
    297  1.1     elric 	    hx509_set_error_string(context, 0, HX509_PKCS11_NO_MECH,
    298  1.1     elric 				   "Failed to get mech info for slot %d",
    299  1.1     elric 				   num);
    300  1.1     elric 	    return HX509_PKCS11_NO_MECH;
    301  1.1     elric 	}
    302  1.1     elric     }
    303  1.1     elric 
    304  1.1     elric     return 0;
    305  1.1     elric }
    306  1.1     elric 
    307  1.1     elric static int
    308  1.1     elric p11_init_slot(hx509_context context,
    309  1.1     elric 	      struct p11_module *p,
    310  1.1     elric 	      hx509_lock lock,
    311  1.1     elric 	      CK_SLOT_ID id,
    312  1.1     elric 	      int num,
    313  1.1     elric 	      struct p11_slot *slot)
    314  1.1     elric {
    315  1.1     elric     CK_SESSION_HANDLE session;
    316  1.1     elric     CK_SLOT_INFO slot_info;
    317  1.1     elric     CK_TOKEN_INFO token_info;
    318  1.1     elric     size_t i;
    319  1.1     elric     int ret;
    320  1.1     elric 
    321  1.1     elric     slot->certs = NULL;
    322  1.1     elric     slot->id = id;
    323  1.1     elric 
    324  1.1     elric     ret = P11FUNC(p, GetSlotInfo, (slot->id, &slot_info));
    325  1.1     elric     if (ret) {
    326  1.1     elric 	hx509_set_error_string(context, 0, HX509_PKCS11_TOKEN_CONFUSED,
    327  1.1     elric 			       "Failed to init PKCS11 slot %d",
    328  1.1     elric 			       num);
    329  1.1     elric 	return HX509_PKCS11_TOKEN_CONFUSED;
    330  1.1     elric     }
    331  1.1     elric 
    332  1.1     elric     for (i = sizeof(slot_info.slotDescription) - 1; i > 0; i--) {
    333  1.1     elric 	char c = slot_info.slotDescription[i];
    334  1.1     elric 	if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\0')
    335  1.1     elric 	    continue;
    336  1.1     elric 	i++;
    337  1.1     elric 	break;
    338  1.1     elric     }
    339  1.1     elric 
    340  1.2  christos     ret = asprintf(&slot->name, "%.*s", (int)i,
    341  1.2  christos 		   slot_info.slotDescription);
    342  1.2  christos     if (ret == -1)
    343  1.2  christos 	return ENOMEM;
    344  1.1     elric 
    345  1.1     elric     if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0)
    346  1.1     elric 	return 0;
    347  1.1     elric 
    348  1.1     elric     ret = P11FUNC(p, GetTokenInfo, (slot->id, &token_info));
    349  1.1     elric     if (ret) {
    350  1.1     elric 	hx509_set_error_string(context, 0, HX509_PKCS11_NO_TOKEN,
    351  1.1     elric 			       "Failed to init PKCS11 slot %d "
    352  1.2  christos 			       "with error 0x%08x",
    353  1.1     elric 			       num, ret);
    354  1.1     elric 	return HX509_PKCS11_NO_TOKEN;
    355  1.1     elric     }
    356  1.1     elric     slot->flags |= P11_TOKEN_PRESENT;
    357  1.1     elric 
    358  1.1     elric     if (token_info.flags & CKF_LOGIN_REQUIRED)
    359  1.1     elric 	slot->flags |= P11_LOGIN_REQ;
    360  1.1     elric 
    361  1.1     elric     ret = p11_get_session(context, p, slot, lock, &session);
    362  1.1     elric     if (ret)
    363  1.1     elric 	return ret;
    364  1.1     elric 
    365  1.1     elric     ret = p11_mech_info(context, p, slot, num);
    366  1.1     elric     if (ret)
    367  1.1     elric 	goto out;
    368  1.1     elric 
    369  1.1     elric     ret = p11_list_keys(context, p, slot, session, lock, &slot->certs);
    370  1.1     elric  out:
    371  1.1     elric     p11_put_session(p, slot, session);
    372  1.1     elric 
    373  1.1     elric     return ret;
    374  1.1     elric }
    375  1.1     elric 
    376  1.1     elric static int
    377  1.1     elric p11_get_session(hx509_context context,
    378  1.1     elric 		struct p11_module *p,
    379  1.1     elric 		struct p11_slot *slot,
    380  1.1     elric 		hx509_lock lock,
    381  1.1     elric 		CK_SESSION_HANDLE *psession)
    382  1.1     elric {
    383  1.1     elric     CK_RV ret;
    384  1.1     elric 
    385  1.1     elric     if (slot->flags & P11_SESSION_IN_USE)
    386  1.1     elric 	_hx509_abort("slot already in session");
    387  1.1     elric 
    388  1.1     elric     if (slot->flags & P11_SESSION) {
    389  1.1     elric 	slot->flags |= P11_SESSION_IN_USE;
    390  1.1     elric 	*psession = slot->session;
    391  1.1     elric 	return 0;
    392  1.1     elric     }
    393  1.1     elric 
    394  1.1     elric     ret = P11FUNC(p, OpenSession, (slot->id,
    395  1.1     elric 				   CKF_SERIAL_SESSION,
    396  1.1     elric 				   NULL,
    397  1.1     elric 				   NULL,
    398  1.1     elric 				   &slot->session));
    399  1.1     elric     if (ret != CKR_OK) {
    400  1.1     elric 	if (context)
    401  1.1     elric 	    hx509_set_error_string(context, 0, HX509_PKCS11_OPEN_SESSION,
    402  1.1     elric 				   "Failed to OpenSession for slot id %d "
    403  1.1     elric 				   "with error: 0x%08x",
    404  1.1     elric 				   (int)slot->id, ret);
    405  1.1     elric 	return HX509_PKCS11_OPEN_SESSION;
    406  1.1     elric     }
    407  1.1     elric 
    408  1.1     elric     slot->flags |= P11_SESSION;
    409  1.1     elric 
    410  1.1     elric     /*
    411  1.1     elric      * If we have have to login, and haven't tried before and have a
    412  1.1     elric      * prompter or known to work pin code.
    413  1.1     elric      *
    414  1.1     elric      * This code is very conversative and only uses the prompter in
    415  1.1     elric      * the hx509_lock, the reason is that it's bad to try many
    416  1.1     elric      * passwords on a pkcs11 token, it might lock up and have to be
    417  1.1     elric      * unlocked by a administrator.
    418  1.1     elric      *
    419  1.1     elric      * XXX try harder to not use pin several times on the same card.
    420  1.1     elric      */
    421  1.1     elric 
    422  1.1     elric     if (   (slot->flags & P11_LOGIN_REQ)
    423  1.1     elric 	&& (slot->flags & P11_LOGIN_DONE) == 0
    424  1.1     elric 	&& (lock || slot->pin))
    425  1.1     elric     {
    426  1.1     elric 	hx509_prompt prompt;
    427  1.1     elric 	char pin[20];
    428  1.1     elric 	char *str;
    429  1.1     elric 
    430  1.1     elric 	if (slot->pin == NULL) {
    431  1.1     elric 
    432  1.1     elric 	    memset(&prompt, 0, sizeof(prompt));
    433  1.1     elric 
    434  1.2  christos 	    ret = asprintf(&str, "PIN code for %s: ", slot->name);
    435  1.2  christos 	    if (ret == -1 || str == NULL) {
    436  1.2  christos 		if (context)
    437  1.2  christos 		    hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    438  1.2  christos 		return ENOMEM;
    439  1.2  christos 	    }
    440  1.1     elric 	    prompt.prompt = str;
    441  1.1     elric 	    prompt.type = HX509_PROMPT_TYPE_PASSWORD;
    442  1.1     elric 	    prompt.reply.data = pin;
    443  1.1     elric 	    prompt.reply.length = sizeof(pin);
    444  1.2  christos 
    445  1.1     elric 	    ret = hx509_lock_prompt(lock, &prompt);
    446  1.1     elric 	    if (ret) {
    447  1.1     elric 		free(str);
    448  1.1     elric 		if (context)
    449  1.1     elric 		    hx509_set_error_string(context, 0, ret,
    450  1.1     elric 					   "Failed to get pin code for slot "
    451  1.1     elric 					   "id %d with error: %d",
    452  1.1     elric 					   (int)slot->id, ret);
    453  1.1     elric 		return ret;
    454  1.1     elric 	    }
    455  1.1     elric 	    free(str);
    456  1.1     elric 	} else {
    457  1.1     elric 	    strlcpy(pin, slot->pin, sizeof(pin));
    458  1.1     elric 	}
    459  1.1     elric 
    460  1.1     elric 	ret = P11FUNC(p, Login, (slot->session, CKU_USER,
    461  1.1     elric 				 (unsigned char*)pin, strlen(pin)));
    462  1.1     elric 	if (ret != CKR_OK) {
    463  1.1     elric 	    if (context)
    464  1.1     elric 		hx509_set_error_string(context, 0, HX509_PKCS11_LOGIN,
    465  1.1     elric 				       "Failed to login on slot id %d "
    466  1.1     elric 				       "with error: 0x%08x",
    467  1.1     elric 				       (int)slot->id, ret);
    468  1.2  christos 	    switch(ret) {
    469  1.2  christos 	        case CKR_PIN_LOCKED:
    470  1.2  christos 	            return HX509_PKCS11_PIN_LOCKED;
    471  1.2  christos 	        case CKR_PIN_EXPIRED:
    472  1.2  christos 	            return HX509_PKCS11_PIN_EXPIRED;
    473  1.2  christos 	        case CKR_PIN_INCORRECT:
    474  1.2  christos 	            return HX509_PKCS11_PIN_INCORRECT;
    475  1.2  christos 	        case CKR_USER_PIN_NOT_INITIALIZED:
    476  1.2  christos 	            return HX509_PKCS11_PIN_NOT_INITIALIZED;
    477  1.2  christos 	        default:
    478  1.2  christos 	            return HX509_PKCS11_LOGIN;
    479  1.2  christos 	    }
    480  1.1     elric 	} else
    481  1.1     elric 	    slot->flags |= P11_LOGIN_DONE;
    482  1.1     elric 
    483  1.1     elric 	if (slot->pin == NULL) {
    484  1.1     elric 	    slot->pin = strdup(pin);
    485  1.1     elric 	    if (slot->pin == NULL) {
    486  1.1     elric 		if (context)
    487  1.1     elric 		    hx509_set_error_string(context, 0, ENOMEM,
    488  1.1     elric 					   "out of memory");
    489  1.1     elric 		return ENOMEM;
    490  1.1     elric 	    }
    491  1.1     elric 	}
    492  1.1     elric     } else
    493  1.1     elric 	slot->flags |= P11_LOGIN_DONE;
    494  1.1     elric 
    495  1.1     elric     slot->flags |= P11_SESSION_IN_USE;
    496  1.1     elric 
    497  1.1     elric     *psession = slot->session;
    498  1.1     elric 
    499  1.1     elric     return 0;
    500  1.1     elric }
    501  1.1     elric 
    502  1.1     elric static int
    503  1.1     elric p11_put_session(struct p11_module *p,
    504  1.1     elric 		struct p11_slot *slot,
    505  1.1     elric 		CK_SESSION_HANDLE session)
    506  1.1     elric {
    507  1.1     elric     if ((slot->flags & P11_SESSION_IN_USE) == 0)
    508  1.1     elric 	_hx509_abort("slot not in session");
    509  1.1     elric     slot->flags &= ~P11_SESSION_IN_USE;
    510  1.1     elric 
    511  1.1     elric     return 0;
    512  1.1     elric }
    513  1.1     elric 
    514  1.1     elric static int
    515  1.1     elric iterate_entries(hx509_context context,
    516  1.1     elric 		struct p11_module *p, struct p11_slot *slot,
    517  1.1     elric 		CK_SESSION_HANDLE session,
    518  1.1     elric 		CK_ATTRIBUTE *search_data, int num_search_data,
    519  1.1     elric 		CK_ATTRIBUTE *query, int num_query,
    520  1.1     elric 		int (*func)(hx509_context,
    521  1.1     elric 			    struct p11_module *, struct p11_slot *,
    522  1.1     elric 			    CK_SESSION_HANDLE session,
    523  1.1     elric 			    CK_OBJECT_HANDLE object,
    524  1.1     elric 			    void *, CK_ATTRIBUTE *, int), void *ptr)
    525  1.1     elric {
    526  1.1     elric     CK_OBJECT_HANDLE object;
    527  1.1     elric     CK_ULONG object_count;
    528  1.1     elric     int ret, ret2, i;
    529  1.1     elric 
    530  1.1     elric     ret = P11FUNC(p, FindObjectsInit, (session, search_data, num_search_data));
    531  1.1     elric     if (ret != CKR_OK) {
    532  1.1     elric 	return -1;
    533  1.1     elric     }
    534  1.1     elric     while (1) {
    535  1.1     elric 	ret = P11FUNC(p, FindObjects, (session, &object, 1, &object_count));
    536  1.1     elric 	if (ret != CKR_OK) {
    537  1.1     elric 	    return -1;
    538  1.1     elric 	}
    539  1.1     elric 	if (object_count == 0)
    540  1.1     elric 	    break;
    541  1.2  christos 
    542  1.1     elric 	for (i = 0; i < num_query; i++)
    543  1.1     elric 	    query[i].pValue = NULL;
    544  1.1     elric 
    545  1.1     elric 	ret = P11FUNC(p, GetAttributeValue,
    546  1.1     elric 		      (session, object, query, num_query));
    547  1.1     elric 	if (ret != CKR_OK) {
    548  1.1     elric 	    return -1;
    549  1.1     elric 	}
    550  1.1     elric 	for (i = 0; i < num_query; i++) {
    551  1.1     elric 	    query[i].pValue = malloc(query[i].ulValueLen);
    552  1.1     elric 	    if (query[i].pValue == NULL) {
    553  1.1     elric 		ret = ENOMEM;
    554  1.1     elric 		goto out;
    555  1.1     elric 	    }
    556  1.1     elric 	}
    557  1.1     elric 	ret = P11FUNC(p, GetAttributeValue,
    558  1.1     elric 		      (session, object, query, num_query));
    559  1.1     elric 	if (ret != CKR_OK) {
    560  1.1     elric 	    ret = -1;
    561  1.1     elric 	    goto out;
    562  1.1     elric 	}
    563  1.2  christos 
    564  1.1     elric 	ret = (*func)(context, p, slot, session, object, ptr, query, num_query);
    565  1.1     elric 	if (ret)
    566  1.1     elric 	    goto out;
    567  1.1     elric 
    568  1.1     elric 	for (i = 0; i < num_query; i++) {
    569  1.1     elric 	    if (query[i].pValue)
    570  1.1     elric 		free(query[i].pValue);
    571  1.1     elric 	    query[i].pValue = NULL;
    572  1.1     elric 	}
    573  1.1     elric     }
    574  1.1     elric  out:
    575  1.1     elric 
    576  1.1     elric     for (i = 0; i < num_query; i++) {
    577  1.1     elric 	if (query[i].pValue)
    578  1.1     elric 	    free(query[i].pValue);
    579  1.1     elric 	query[i].pValue = NULL;
    580  1.1     elric     }
    581  1.1     elric 
    582  1.1     elric     ret2 = P11FUNC(p, FindObjectsFinal, (session));
    583  1.1     elric     if (ret2 != CKR_OK) {
    584  1.1     elric 	return ret2;
    585  1.1     elric     }
    586  1.1     elric 
    587  1.1     elric     return ret;
    588  1.1     elric }
    589  1.2  christos 
    590  1.1     elric static BIGNUM *
    591  1.1     elric getattr_bn(struct p11_module *p,
    592  1.1     elric 	   struct p11_slot *slot,
    593  1.1     elric 	   CK_SESSION_HANDLE session,
    594  1.1     elric 	   CK_OBJECT_HANDLE object,
    595  1.1     elric 	   unsigned int type)
    596  1.1     elric {
    597  1.1     elric     CK_ATTRIBUTE query;
    598  1.1     elric     BIGNUM *bn;
    599  1.1     elric     int ret;
    600  1.1     elric 
    601  1.1     elric     query.type = type;
    602  1.1     elric     query.pValue = NULL;
    603  1.1     elric     query.ulValueLen = 0;
    604  1.1     elric 
    605  1.1     elric     ret = P11FUNC(p, GetAttributeValue,
    606  1.1     elric 		  (session, object, &query, 1));
    607  1.1     elric     if (ret != CKR_OK)
    608  1.1     elric 	return NULL;
    609  1.1     elric 
    610  1.1     elric     query.pValue = malloc(query.ulValueLen);
    611  1.1     elric 
    612  1.1     elric     ret = P11FUNC(p, GetAttributeValue,
    613  1.1     elric 		  (session, object, &query, 1));
    614  1.1     elric     if (ret != CKR_OK) {
    615  1.1     elric 	free(query.pValue);
    616  1.1     elric 	return NULL;
    617  1.1     elric     }
    618  1.1     elric     bn = BN_bin2bn(query.pValue, query.ulValueLen, NULL);
    619  1.1     elric     free(query.pValue);
    620  1.1     elric 
    621  1.1     elric     return bn;
    622  1.1     elric }
    623  1.1     elric 
    624  1.1     elric static int
    625  1.1     elric collect_private_key(hx509_context context,
    626  1.1     elric 		    struct p11_module *p, struct p11_slot *slot,
    627  1.1     elric 		    CK_SESSION_HANDLE session,
    628  1.1     elric 		    CK_OBJECT_HANDLE object,
    629  1.1     elric 		    void *ptr, CK_ATTRIBUTE *query, int num_query)
    630  1.1     elric {
    631  1.1     elric     struct hx509_collector *collector = ptr;
    632  1.1     elric     hx509_private_key key;
    633  1.1     elric     heim_octet_string localKeyId;
    634  1.1     elric     int ret;
    635  1.1     elric     RSA *rsa;
    636  1.1     elric     struct p11_rsa *p11rsa;
    637  1.1     elric 
    638  1.1     elric     localKeyId.data = query[0].pValue;
    639  1.1     elric     localKeyId.length = query[0].ulValueLen;
    640  1.1     elric 
    641  1.1     elric     ret = hx509_private_key_init(&key, NULL, NULL);
    642  1.1     elric     if (ret)
    643  1.1     elric 	return ret;
    644  1.1     elric 
    645  1.1     elric     rsa = RSA_new();
    646  1.1     elric     if (rsa == NULL)
    647  1.1     elric 	_hx509_abort("out of memory");
    648  1.1     elric 
    649  1.1     elric     /*
    650  1.1     elric      * The exponent and modulus should always be present according to
    651  1.1     elric      * the pkcs11 specification, but some smartcards leaves it out,
    652  1.1     elric      * let ignore any failure to fetch it.
    653  1.1     elric      */
    654  1.3  christos     BIGNUM *n = getattr_bn(p, slot, session, object, CKA_MODULUS);
    655  1.3  christos     BIGNUM *e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT);
    656  1.3  christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL
    657  1.3  christos     rsa->n = n;
    658  1.3  christos     rsa->e = e;
    659  1.3  christos #else
    660  1.3  christos     RSA_set0_key(rsa, n, e, NULL);
    661  1.3  christos #endif
    662  1.1     elric 
    663  1.1     elric     p11rsa = calloc(1, sizeof(*p11rsa));
    664  1.1     elric     if (p11rsa == NULL)
    665  1.1     elric 	_hx509_abort("out of memory");
    666  1.1     elric 
    667  1.1     elric     p11rsa->p = p;
    668  1.1     elric     p11rsa->slot = slot;
    669  1.1     elric     p11rsa->private_key = object;
    670  1.1     elric 
    671  1.1     elric     if (p->ref == 0)
    672  1.1     elric 	_hx509_abort("pkcs11 ref == 0 on alloc");
    673  1.1     elric     p->ref++;
    674  1.1     elric     if (p->ref == UINT_MAX)
    675  1.1     elric 	_hx509_abort("pkcs11 ref == UINT_MAX on alloc");
    676  1.1     elric 
    677  1.3  christos     RSA_METHOD *meth;
    678  1.3  christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL
    679  1.3  christos     meth = __UNCONST(&p11_rsa_pkcs1_method);
    680  1.3  christos #else
    681  1.3  christos     meth = RSA_meth_dup(RSA_get_default_method());
    682  1.3  christos     RSA_meth_set1_name(meth, "hx509 PKCS11 PKCS#1 RSA");
    683  1.3  christos     RSA_meth_set_pub_enc(meth, p11_rsa_public_encrypt);
    684  1.3  christos     RSA_meth_set_pub_dec(meth, p11_rsa_public_decrypt);
    685  1.3  christos     RSA_meth_set_priv_enc(meth, p11_rsa_private_encrypt);
    686  1.3  christos     RSA_meth_set_priv_dec(meth, p11_rsa_private_decrypt);
    687  1.3  christos     RSA_meth_set_init(meth, p11_rsa_init);
    688  1.3  christos     RSA_meth_set_finish(meth, p11_rsa_finish);
    689  1.3  christos #endif
    690  1.3  christos     RSA_set_method(rsa, meth);
    691  1.1     elric     ret = RSA_set_app_data(rsa, p11rsa);
    692  1.1     elric     if (ret != 1)
    693  1.1     elric 	_hx509_abort("RSA_set_app_data");
    694  1.1     elric 
    695  1.1     elric     hx509_private_key_assign_rsa(key, rsa);
    696  1.1     elric 
    697  1.1     elric     ret = _hx509_collector_private_key_add(context,
    698  1.1     elric 					   collector,
    699  1.1     elric 					   hx509_signature_rsa(),
    700  1.1     elric 					   key,
    701  1.1     elric 					   NULL,
    702  1.1     elric 					   &localKeyId);
    703  1.1     elric 
    704  1.1     elric     if (ret) {
    705  1.1     elric 	hx509_private_key_free(&key);
    706  1.1     elric 	return ret;
    707  1.1     elric     }
    708  1.1     elric     return 0;
    709  1.1     elric }
    710  1.1     elric 
    711  1.1     elric static void
    712  1.1     elric p11_cert_release(hx509_cert cert, void *ctx)
    713  1.1     elric {
    714  1.1     elric     struct p11_module *p = ctx;
    715  1.1     elric     p11_release_module(p);
    716  1.1     elric }
    717  1.1     elric 
    718  1.1     elric 
    719  1.1     elric static int
    720  1.1     elric collect_cert(hx509_context context,
    721  1.1     elric 	     struct p11_module *p, struct p11_slot *slot,
    722  1.1     elric 	     CK_SESSION_HANDLE session,
    723  1.1     elric 	     CK_OBJECT_HANDLE object,
    724  1.1     elric 	     void *ptr, CK_ATTRIBUTE *query, int num_query)
    725  1.1     elric {
    726  1.1     elric     struct hx509_collector *collector = ptr;
    727  1.2  christos     heim_error_t error = NULL;
    728  1.1     elric     hx509_cert cert;
    729  1.1     elric     int ret;
    730  1.1     elric 
    731  1.1     elric     if ((CK_LONG)query[0].ulValueLen == -1 ||
    732  1.1     elric 	(CK_LONG)query[1].ulValueLen == -1)
    733  1.1     elric     {
    734  1.1     elric 	return 0;
    735  1.1     elric     }
    736  1.1     elric 
    737  1.2  christos     cert = hx509_cert_init_data(context, query[1].pValue,
    738  1.2  christos 			       query[1].ulValueLen, &error);
    739  1.2  christos     if (cert == NULL) {
    740  1.2  christos 	ret = heim_error_get_code(error);
    741  1.2  christos 	heim_release(error);
    742  1.1     elric 	return ret;
    743  1.2  christos     }
    744  1.1     elric 
    745  1.1     elric     if (p->ref == 0)
    746  1.1     elric 	_hx509_abort("pkcs11 ref == 0 on alloc");
    747  1.1     elric     p->ref++;
    748  1.1     elric     if (p->ref == UINT_MAX)
    749  1.1     elric 	_hx509_abort("pkcs11 ref to high");
    750  1.1     elric 
    751  1.1     elric     _hx509_cert_set_release(cert, p11_cert_release, p);
    752  1.1     elric 
    753  1.1     elric     {
    754  1.1     elric 	heim_octet_string data;
    755  1.2  christos 
    756  1.1     elric 	data.data = query[0].pValue;
    757  1.1     elric 	data.length = query[0].ulValueLen;
    758  1.2  christos 
    759  1.1     elric 	_hx509_set_cert_attribute(context,
    760  1.1     elric 				  cert,
    761  1.1     elric 				  &asn1_oid_id_pkcs_9_at_localKeyId,
    762  1.1     elric 				  &data);
    763  1.1     elric     }
    764  1.1     elric 
    765  1.1     elric     if ((CK_LONG)query[2].ulValueLen != -1) {
    766  1.1     elric 	char *str;
    767  1.1     elric 
    768  1.2  christos 	ret = asprintf(&str, "%.*s",
    769  1.2  christos 		       (int)query[2].ulValueLen, (char *)query[2].pValue);
    770  1.2  christos 	if (ret != -1 && str) {
    771  1.1     elric 	    hx509_cert_set_friendly_name(cert, str);
    772  1.1     elric 	    free(str);
    773  1.1     elric 	}
    774  1.1     elric     }
    775  1.1     elric 
    776  1.1     elric     ret = _hx509_collector_certs_add(context, collector, cert);
    777  1.1     elric     hx509_cert_free(cert);
    778  1.1     elric 
    779  1.1     elric     return ret;
    780  1.1     elric }
    781  1.1     elric 
    782  1.1     elric 
    783  1.1     elric static int
    784  1.1     elric p11_list_keys(hx509_context context,
    785  1.1     elric 	      struct p11_module *p,
    786  1.1     elric 	      struct p11_slot *slot,
    787  1.1     elric 	      CK_SESSION_HANDLE session,
    788  1.1     elric 	      hx509_lock lock,
    789  1.1     elric 	      hx509_certs *certs)
    790  1.1     elric {
    791  1.1     elric     struct hx509_collector *collector;
    792  1.1     elric     CK_OBJECT_CLASS key_class;
    793  1.1     elric     CK_ATTRIBUTE search_data[] = {
    794  1.1     elric 	{CKA_CLASS, NULL, 0},
    795  1.1     elric     };
    796  1.1     elric     CK_ATTRIBUTE query_data[3] = {
    797  1.1     elric 	{CKA_ID, NULL, 0},
    798  1.1     elric 	{CKA_VALUE, NULL, 0},
    799  1.1     elric 	{CKA_LABEL, NULL, 0}
    800  1.1     elric     };
    801  1.1     elric     int ret;
    802  1.1     elric 
    803  1.1     elric     search_data[0].pValue = &key_class;
    804  1.1     elric     search_data[0].ulValueLen = sizeof(key_class);
    805  1.1     elric 
    806  1.1     elric     if (lock == NULL)
    807  1.1     elric 	lock = _hx509_empty_lock;
    808  1.1     elric 
    809  1.1     elric     ret = _hx509_collector_alloc(context, lock, &collector);
    810  1.1     elric     if (ret)
    811  1.1     elric 	return ret;
    812  1.1     elric 
    813  1.1     elric     key_class = CKO_PRIVATE_KEY;
    814  1.1     elric     ret = iterate_entries(context, p, slot, session,
    815  1.1     elric 			  search_data, 1,
    816  1.1     elric 			  query_data, 1,
    817  1.1     elric 			  collect_private_key, collector);
    818  1.1     elric     if (ret)
    819  1.1     elric 	goto out;
    820  1.1     elric 
    821  1.1     elric     key_class = CKO_CERTIFICATE;
    822  1.1     elric     ret = iterate_entries(context, p, slot, session,
    823  1.1     elric 			  search_data, 1,
    824  1.1     elric 			  query_data, 3,
    825  1.1     elric 			  collect_cert, collector);
    826  1.1     elric     if (ret)
    827  1.1     elric 	goto out;
    828  1.1     elric 
    829  1.1     elric     ret = _hx509_collector_collect_certs(context, collector, &slot->certs);
    830  1.1     elric 
    831  1.1     elric out:
    832  1.1     elric     _hx509_collector_free(collector);
    833  1.1     elric 
    834  1.1     elric     return ret;
    835  1.1     elric }
    836  1.1     elric 
    837  1.1     elric 
    838  1.1     elric static int
    839  1.1     elric p11_init(hx509_context context,
    840  1.1     elric 	 hx509_certs certs, void **data, int flags,
    841  1.1     elric 	 const char *residue, hx509_lock lock)
    842  1.1     elric {
    843  1.1     elric     CK_C_GetFunctionList getFuncs;
    844  1.1     elric     struct p11_module *p;
    845  1.1     elric     char *list, *str;
    846  1.1     elric     int ret;
    847  1.1     elric 
    848  1.1     elric     *data = NULL;
    849  1.1     elric 
    850  1.1     elric     list = strdup(residue);
    851  1.1     elric     if (list == NULL)
    852  1.1     elric 	return ENOMEM;
    853  1.1     elric 
    854  1.1     elric     p = calloc(1, sizeof(*p));
    855  1.1     elric     if (p == NULL) {
    856  1.1     elric 	free(list);
    857  1.1     elric 	return ENOMEM;
    858  1.1     elric     }
    859  1.1     elric 
    860  1.1     elric     p->ref = 1;
    861  1.2  christos     p->selected_slot = 0;
    862  1.1     elric 
    863  1.1     elric     str = strchr(list, ',');
    864  1.1     elric     if (str)
    865  1.1     elric 	*str++ = '\0';
    866  1.1     elric     while (str) {
    867  1.1     elric 	char *strnext;
    868  1.1     elric 	strnext = strchr(str, ',');
    869  1.1     elric 	if (strnext)
    870  1.1     elric 	    *strnext++ = '\0';
    871  1.1     elric 	if (strncasecmp(str, "slot=", 5) == 0)
    872  1.1     elric 	    p->selected_slot = atoi(str + 5);
    873  1.1     elric 	str = strnext;
    874  1.1     elric     }
    875  1.1     elric 
    876  1.1     elric     p->dl_handle = dlopen(list, RTLD_NOW);
    877  1.1     elric     if (p->dl_handle == NULL) {
    878  1.1     elric 	ret = HX509_PKCS11_LOAD;
    879  1.1     elric 	hx509_set_error_string(context, 0, ret,
    880  1.1     elric 			       "Failed to open %s: %s", list, dlerror());
    881  1.1     elric 	goto out;
    882  1.1     elric     }
    883  1.1     elric 
    884  1.1     elric     getFuncs = (CK_C_GetFunctionList) dlsym(p->dl_handle, "C_GetFunctionList");
    885  1.1     elric     if (getFuncs == NULL) {
    886  1.1     elric 	ret = HX509_PKCS11_LOAD;
    887  1.1     elric 	hx509_set_error_string(context, 0, ret,
    888  1.1     elric 			       "C_GetFunctionList missing in %s: %s",
    889  1.1     elric 			       list, dlerror());
    890  1.1     elric 	goto out;
    891  1.1     elric     }
    892  1.1     elric 
    893  1.1     elric     ret = (*getFuncs)(&p->funcs);
    894  1.1     elric     if (ret) {
    895  1.1     elric 	ret = HX509_PKCS11_LOAD;
    896  1.1     elric 	hx509_set_error_string(context, 0, ret,
    897  1.1     elric 			       "C_GetFunctionList failed in %s", list);
    898  1.1     elric 	goto out;
    899  1.1     elric     }
    900  1.1     elric 
    901  1.1     elric     ret = P11FUNC(p, Initialize, (NULL_PTR));
    902  1.1     elric     if (ret != CKR_OK) {
    903  1.1     elric 	ret = HX509_PKCS11_TOKEN_CONFUSED;
    904  1.1     elric 	hx509_set_error_string(context, 0, ret,
    905  1.1     elric 			       "Failed initialize the PKCS11 module");
    906  1.1     elric 	goto out;
    907  1.1     elric     }
    908  1.1     elric 
    909  1.1     elric     ret = P11FUNC(p, GetSlotList, (FALSE, NULL, &p->num_slots));
    910  1.1     elric     if (ret) {
    911  1.1     elric 	ret = HX509_PKCS11_TOKEN_CONFUSED;
    912  1.1     elric 	hx509_set_error_string(context, 0, ret,
    913  1.1     elric 			       "Failed to get number of PKCS11 slots");
    914  1.1     elric 	goto out;
    915  1.1     elric     }
    916  1.1     elric 
    917  1.1     elric    if (p->num_slots == 0) {
    918  1.1     elric 	ret = HX509_PKCS11_NO_SLOT;
    919  1.1     elric 	hx509_set_error_string(context, 0, ret,
    920  1.1     elric 			       "Selected PKCS11 module have no slots");
    921  1.1     elric 	goto out;
    922  1.1     elric    }
    923  1.1     elric 
    924  1.1     elric 
    925  1.1     elric     {
    926  1.1     elric 	CK_SLOT_ID_PTR slot_ids;
    927  1.2  christos 	int num_tokens = 0;
    928  1.2  christos 	size_t i;
    929  1.1     elric 
    930  1.1     elric 	slot_ids = malloc(p->num_slots * sizeof(*slot_ids));
    931  1.1     elric 	if (slot_ids == NULL) {
    932  1.1     elric 	    hx509_clear_error_string(context);
    933  1.1     elric 	    ret = ENOMEM;
    934  1.1     elric 	    goto out;
    935  1.1     elric 	}
    936  1.1     elric 
    937  1.1     elric 	ret = P11FUNC(p, GetSlotList, (FALSE, slot_ids, &p->num_slots));
    938  1.1     elric 	if (ret) {
    939  1.1     elric 	    free(slot_ids);
    940  1.1     elric 	    hx509_set_error_string(context, 0, HX509_PKCS11_TOKEN_CONFUSED,
    941  1.1     elric 				   "Failed getting slot-list from "
    942  1.1     elric 				   "PKCS11 module");
    943  1.1     elric 	    ret = HX509_PKCS11_TOKEN_CONFUSED;
    944  1.1     elric 	    goto out;
    945  1.1     elric 	}
    946  1.1     elric 
    947  1.1     elric 	p->slot = calloc(p->num_slots, sizeof(p->slot[0]));
    948  1.1     elric 	if (p->slot == NULL) {
    949  1.1     elric 	    free(slot_ids);
    950  1.1     elric 	    hx509_set_error_string(context, 0, ENOMEM,
    951  1.1     elric 				   "Failed to get memory for slot-list");
    952  1.1     elric 	    ret = ENOMEM;
    953  1.1     elric 	    goto out;
    954  1.1     elric 	}
    955  1.2  christos 
    956  1.1     elric 	for (i = 0; i < p->num_slots; i++) {
    957  1.2  christos 	    if ((p->selected_slot != 0) && (slot_ids[i] != (p->selected_slot - 1)))
    958  1.2  christos 		continue;
    959  1.1     elric 	    ret = p11_init_slot(context, p, lock, slot_ids[i], i, &p->slot[i]);
    960  1.2  christos 	    if (!ret) {
    961  1.2  christos 	        if (p->slot[i].flags & P11_TOKEN_PRESENT)
    962  1.2  christos 	            num_tokens++;
    963  1.2  christos 	    }
    964  1.1     elric 	}
    965  1.1     elric 	free(slot_ids);
    966  1.1     elric 	if (ret)
    967  1.1     elric 	    goto out;
    968  1.1     elric 	if (num_tokens == 0) {
    969  1.1     elric 	    ret = HX509_PKCS11_NO_TOKEN;
    970  1.1     elric 	    goto out;
    971  1.1     elric 	}
    972  1.1     elric     }
    973  1.1     elric 
    974  1.2  christos     free(list);
    975  1.2  christos 
    976  1.1     elric     *data = p;
    977  1.1     elric 
    978  1.1     elric     return 0;
    979  1.1     elric  out:
    980  1.2  christos     if (list)
    981  1.2  christos 	free(list);
    982  1.1     elric     p11_release_module(p);
    983  1.1     elric     return ret;
    984  1.1     elric }
    985  1.1     elric 
    986  1.1     elric static void
    987  1.1     elric p11_release_module(struct p11_module *p)
    988  1.1     elric {
    989  1.2  christos     size_t i;
    990  1.1     elric 
    991  1.1     elric     if (p->ref == 0)
    992  1.1     elric 	_hx509_abort("pkcs11 ref to low");
    993  1.1     elric     if (--p->ref > 0)
    994  1.1     elric 	return;
    995  1.1     elric 
    996  1.1     elric     for (i = 0; i < p->num_slots; i++) {
    997  1.1     elric 	if (p->slot[i].flags & P11_SESSION_IN_USE)
    998  1.1     elric 	    _hx509_abort("pkcs11 module release while session in use");
    999  1.1     elric 	if (p->slot[i].flags & P11_SESSION) {
   1000  1.1     elric 	    P11FUNC(p, CloseSession, (p->slot[i].session));
   1001  1.1     elric 	}
   1002  1.1     elric 
   1003  1.1     elric 	if (p->slot[i].name)
   1004  1.1     elric 	    free(p->slot[i].name);
   1005  1.1     elric 	if (p->slot[i].pin) {
   1006  1.1     elric 	    memset(p->slot[i].pin, 0, strlen(p->slot[i].pin));
   1007  1.1     elric 	    free(p->slot[i].pin);
   1008  1.1     elric 	}
   1009  1.1     elric 	if (p->slot[i].mechs.num) {
   1010  1.1     elric 	    free(p->slot[i].mechs.list);
   1011  1.1     elric 
   1012  1.1     elric 	    if (p->slot[i].mechs.infos) {
   1013  1.2  christos 		size_t j;
   1014  1.1     elric 
   1015  1.1     elric 		for (j = 0 ; j < p->slot[i].mechs.num ; j++)
   1016  1.1     elric 		    free(p->slot[i].mechs.infos[j]);
   1017  1.1     elric 		free(p->slot[i].mechs.infos);
   1018  1.1     elric 	    }
   1019  1.1     elric 	}
   1020  1.1     elric     }
   1021  1.1     elric     free(p->slot);
   1022  1.1     elric 
   1023  1.1     elric     if (p->funcs)
   1024  1.1     elric 	P11FUNC(p, Finalize, (NULL));
   1025  1.1     elric 
   1026  1.1     elric     if (p->dl_handle)
   1027  1.1     elric 	dlclose(p->dl_handle);
   1028  1.1     elric 
   1029  1.1     elric     memset(p, 0, sizeof(*p));
   1030  1.1     elric     free(p);
   1031  1.1     elric }
   1032  1.1     elric 
   1033  1.1     elric static int
   1034  1.1     elric p11_free(hx509_certs certs, void *data)
   1035  1.1     elric {
   1036  1.1     elric     struct p11_module *p = data;
   1037  1.2  christos     size_t i;
   1038  1.1     elric 
   1039  1.1     elric     for (i = 0; i < p->num_slots; i++) {
   1040  1.1     elric 	if (p->slot[i].certs)
   1041  1.1     elric 	    hx509_certs_free(&p->slot[i].certs);
   1042  1.1     elric     }
   1043  1.1     elric     p11_release_module(p);
   1044  1.1     elric     return 0;
   1045  1.1     elric }
   1046  1.1     elric 
   1047  1.1     elric struct p11_cursor {
   1048  1.1     elric     hx509_certs certs;
   1049  1.1     elric     void *cursor;
   1050  1.1     elric };
   1051  1.1     elric 
   1052  1.1     elric static int
   1053  1.1     elric p11_iter_start(hx509_context context,
   1054  1.1     elric 	       hx509_certs certs, void *data, void **cursor)
   1055  1.1     elric {
   1056  1.1     elric     struct p11_module *p = data;
   1057  1.1     elric     struct p11_cursor *c;
   1058  1.2  christos     int ret;
   1059  1.2  christos     size_t i;
   1060  1.1     elric 
   1061  1.1     elric     c = malloc(sizeof(*c));
   1062  1.1     elric     if (c == NULL) {
   1063  1.1     elric 	hx509_clear_error_string(context);
   1064  1.1     elric 	return ENOMEM;
   1065  1.1     elric     }
   1066  1.1     elric     ret = hx509_certs_init(context, "MEMORY:pkcs11-iter", 0, NULL, &c->certs);
   1067  1.1     elric     if (ret) {
   1068  1.1     elric 	free(c);
   1069  1.1     elric 	return ret;
   1070  1.1     elric     }
   1071  1.1     elric 
   1072  1.1     elric     for (i = 0 ; i < p->num_slots; i++) {
   1073  1.1     elric 	if (p->slot[i].certs == NULL)
   1074  1.1     elric 	    continue;
   1075  1.1     elric 	ret = hx509_certs_merge(context, c->certs, p->slot[i].certs);
   1076  1.1     elric 	if (ret) {
   1077  1.1     elric 	    hx509_certs_free(&c->certs);
   1078  1.1     elric 	    free(c);
   1079  1.1     elric 	    return ret;
   1080  1.1     elric 	}
   1081  1.1     elric     }
   1082  1.1     elric 
   1083  1.1     elric     ret = hx509_certs_start_seq(context, c->certs, &c->cursor);
   1084  1.1     elric     if (ret) {
   1085  1.1     elric 	hx509_certs_free(&c->certs);
   1086  1.1     elric 	free(c);
   1087  1.1     elric 	return 0;
   1088  1.1     elric     }
   1089  1.1     elric     *cursor = c;
   1090  1.1     elric 
   1091  1.1     elric     return 0;
   1092  1.1     elric }
   1093  1.1     elric 
   1094  1.1     elric static int
   1095  1.1     elric p11_iter(hx509_context context,
   1096  1.1     elric 	 hx509_certs certs, void *data, void *cursor, hx509_cert *cert)
   1097  1.1     elric {
   1098  1.1     elric     struct p11_cursor *c = cursor;
   1099  1.1     elric     return hx509_certs_next_cert(context, c->certs, c->cursor, cert);
   1100  1.1     elric }
   1101  1.1     elric 
   1102  1.1     elric static int
   1103  1.1     elric p11_iter_end(hx509_context context,
   1104  1.1     elric 	     hx509_certs certs, void *data, void *cursor)
   1105  1.1     elric {
   1106  1.1     elric     struct p11_cursor *c = cursor;
   1107  1.1     elric     int ret;
   1108  1.1     elric     ret = hx509_certs_end_seq(context, c->certs, c->cursor);
   1109  1.1     elric     hx509_certs_free(&c->certs);
   1110  1.1     elric     free(c);
   1111  1.1     elric     return ret;
   1112  1.1     elric }
   1113  1.1     elric 
   1114  1.1     elric #define MECHFLAG(x) { "unknown-flag-" #x, x }
   1115  1.1     elric static struct units mechflags[] = {
   1116  1.1     elric 	MECHFLAG(0x80000000),
   1117  1.1     elric 	MECHFLAG(0x40000000),
   1118  1.1     elric 	MECHFLAG(0x20000000),
   1119  1.1     elric 	MECHFLAG(0x10000000),
   1120  1.1     elric 	MECHFLAG(0x08000000),
   1121  1.1     elric 	MECHFLAG(0x04000000),
   1122  1.1     elric 	{"ec-compress",		0x2000000 },
   1123  1.1     elric 	{"ec-uncompress",	0x1000000 },
   1124  1.1     elric 	{"ec-namedcurve",	0x0800000 },
   1125  1.1     elric 	{"ec-ecparameters",	0x0400000 },
   1126  1.1     elric 	{"ec-f-2m",		0x0200000 },
   1127  1.1     elric 	{"ec-f-p",		0x0100000 },
   1128  1.1     elric 	{"derive",		0x0080000 },
   1129  1.1     elric 	{"unwrap",		0x0040000 },
   1130  1.1     elric 	{"wrap",		0x0020000 },
   1131  1.1     elric 	{"genereate-key-pair",	0x0010000 },
   1132  1.1     elric 	{"generate",		0x0008000 },
   1133  1.1     elric 	{"verify-recover",	0x0004000 },
   1134  1.1     elric 	{"verify",		0x0002000 },
   1135  1.1     elric 	{"sign-recover",	0x0001000 },
   1136  1.1     elric 	{"sign",		0x0000800 },
   1137  1.1     elric 	{"digest",		0x0000400 },
   1138  1.1     elric 	{"decrypt",		0x0000200 },
   1139  1.1     elric 	{"encrypt",		0x0000100 },
   1140  1.1     elric 	MECHFLAG(0x00080),
   1141  1.1     elric 	MECHFLAG(0x00040),
   1142  1.1     elric 	MECHFLAG(0x00020),
   1143  1.1     elric 	MECHFLAG(0x00010),
   1144  1.1     elric 	MECHFLAG(0x00008),
   1145  1.1     elric 	MECHFLAG(0x00004),
   1146  1.1     elric 	MECHFLAG(0x00002),
   1147  1.1     elric 	{"hw",			0x0000001 },
   1148  1.1     elric 	{ NULL,			0x0000000 }
   1149  1.1     elric };
   1150  1.1     elric #undef MECHFLAG
   1151  1.1     elric 
   1152  1.1     elric static int
   1153  1.1     elric p11_printinfo(hx509_context context,
   1154  1.1     elric 	      hx509_certs certs,
   1155  1.1     elric 	      void *data,
   1156  1.1     elric 	      int (*func)(void *, const char *),
   1157  1.1     elric 	      void *ctx)
   1158  1.1     elric {
   1159  1.1     elric     struct p11_module *p = data;
   1160  1.2  christos     size_t i, j;
   1161  1.1     elric 
   1162  1.1     elric     _hx509_pi_printf(func, ctx, "pkcs11 driver with %d slot%s",
   1163  1.1     elric 		     p->num_slots, p->num_slots > 1 ? "s" : "");
   1164  1.1     elric 
   1165  1.1     elric     for (i = 0; i < p->num_slots; i++) {
   1166  1.1     elric 	struct p11_slot *s = &p->slot[i];
   1167  1.1     elric 
   1168  1.1     elric 	_hx509_pi_printf(func, ctx, "slot %d: id: %d name: %s flags: %08x",
   1169  1.1     elric 			 i, (int)s->id, s->name, s->flags);
   1170  1.1     elric 
   1171  1.1     elric 	_hx509_pi_printf(func, ctx, "number of supported mechanisms: %lu",
   1172  1.1     elric 			 (unsigned long)s->mechs.num);
   1173  1.1     elric 	for (j = 0; j < s->mechs.num; j++) {
   1174  1.1     elric 	    const char *mechname = "unknown";
   1175  1.1     elric 	    char flags[256], unknownname[40];
   1176  1.1     elric #define MECHNAME(s,n) case s: mechname = n; break
   1177  1.1     elric 	    switch(s->mechs.list[j]) {
   1178  1.1     elric 		MECHNAME(CKM_RSA_PKCS_KEY_PAIR_GEN, "rsa-pkcs-key-pair-gen");
   1179  1.1     elric 		MECHNAME(CKM_RSA_PKCS, "rsa-pkcs");
   1180  1.1     elric 		MECHNAME(CKM_RSA_X_509, "rsa-x-509");
   1181  1.1     elric 		MECHNAME(CKM_MD5_RSA_PKCS, "md5-rsa-pkcs");
   1182  1.1     elric 		MECHNAME(CKM_SHA1_RSA_PKCS, "sha1-rsa-pkcs");
   1183  1.1     elric 		MECHNAME(CKM_SHA256_RSA_PKCS, "sha256-rsa-pkcs");
   1184  1.1     elric 		MECHNAME(CKM_SHA384_RSA_PKCS, "sha384-rsa-pkcs");
   1185  1.1     elric 		MECHNAME(CKM_SHA512_RSA_PKCS, "sha512-rsa-pkcs");
   1186  1.1     elric 		MECHNAME(CKM_RIPEMD160_RSA_PKCS, "ripemd160-rsa-pkcs");
   1187  1.1     elric 		MECHNAME(CKM_RSA_PKCS_OAEP, "rsa-pkcs-oaep");
   1188  1.1     elric 		MECHNAME(CKM_SHA512_HMAC, "sha512-hmac");
   1189  1.1     elric 		MECHNAME(CKM_SHA512, "sha512");
   1190  1.1     elric 		MECHNAME(CKM_SHA384_HMAC, "sha384-hmac");
   1191  1.1     elric 		MECHNAME(CKM_SHA384, "sha384");
   1192  1.1     elric 		MECHNAME(CKM_SHA256_HMAC, "sha256-hmac");
   1193  1.1     elric 		MECHNAME(CKM_SHA256, "sha256");
   1194  1.1     elric 		MECHNAME(CKM_SHA_1, "sha1");
   1195  1.1     elric 		MECHNAME(CKM_MD5, "md5");
   1196  1.1     elric 		MECHNAME(CKM_RIPEMD160, "ripemd-160");
   1197  1.1     elric 		MECHNAME(CKM_DES_ECB, "des-ecb");
   1198  1.1     elric 		MECHNAME(CKM_DES_CBC, "des-cbc");
   1199  1.1     elric 		MECHNAME(CKM_AES_ECB, "aes-ecb");
   1200  1.1     elric 		MECHNAME(CKM_AES_CBC, "aes-cbc");
   1201  1.1     elric 		MECHNAME(CKM_DH_PKCS_PARAMETER_GEN, "dh-pkcs-parameter-gen");
   1202  1.1     elric 	    default:
   1203  1.1     elric 		snprintf(unknownname, sizeof(unknownname),
   1204  1.1     elric 			 "unknown-mech-%lu",
   1205  1.1     elric 			 (unsigned long)s->mechs.list[j]);
   1206  1.1     elric 		mechname = unknownname;
   1207  1.1     elric 		break;
   1208  1.1     elric 	    }
   1209  1.1     elric #undef MECHNAME
   1210  1.1     elric 	    unparse_flags(s->mechs.infos[j]->flags, mechflags,
   1211  1.1     elric 			  flags, sizeof(flags));
   1212  1.1     elric 
   1213  1.1     elric 	    _hx509_pi_printf(func, ctx, "  %s: %s", mechname, flags);
   1214  1.1     elric 	}
   1215  1.1     elric     }
   1216  1.1     elric 
   1217  1.1     elric     return 0;
   1218  1.1     elric }
   1219  1.1     elric 
   1220  1.1     elric static struct hx509_keyset_ops keyset_pkcs11 = {
   1221  1.1     elric     "PKCS11",
   1222  1.1     elric     0,
   1223  1.1     elric     p11_init,
   1224  1.1     elric     NULL,
   1225  1.1     elric     p11_free,
   1226  1.1     elric     NULL,
   1227  1.1     elric     NULL,
   1228  1.1     elric     p11_iter_start,
   1229  1.1     elric     p11_iter,
   1230  1.1     elric     p11_iter_end,
   1231  1.2  christos     p11_printinfo,
   1232  1.2  christos     NULL,
   1233  1.2  christos     NULL
   1234  1.1     elric };
   1235  1.1     elric 
   1236  1.1     elric #endif /* HAVE_DLOPEN */
   1237  1.1     elric 
   1238  1.1     elric void
   1239  1.1     elric _hx509_ks_pkcs11_register(hx509_context context)
   1240  1.1     elric {
   1241  1.1     elric #ifdef HAVE_DLOPEN
   1242  1.1     elric     _hx509_ks_register(context, &keyset_pkcs11);
   1243  1.1     elric #endif
   1244  1.1     elric }
   1245