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