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