1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 #include <config.h>
13
14 #include <stdio.h>
15 #include <inttypes.h>
16 #include <stdbool.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <isc/log.h>
21 #include <isc/mem.h>
22 #include <isc/once.h>
23 #include <isc/platform.h>
24 #include <isc/print.h>
25 #include <isc/stdio.h>
26 #include <isc/string.h>
27 #include <isc/thread.h>
28 #include <isc/util.h>
29
30 #include <dst/result.h>
31
32 #include <pk11/pk11.h>
33 #include <pk11/internal.h>
34 #include <pk11/result.h>
35 #include <pk11/site.h>
36
37 #include <pkcs11/cryptoki.h>
38 #include <pkcs11/pkcs11.h>
39 #include <pkcs11/eddsa.h>
40
41 /* was 32 octets, Petr Spacek suggested 1024, SoftHSMv2 uses 256... */
42 #ifndef PINLEN
43 #define PINLEN 256
44 #endif
45
46 #ifndef PK11_NO_LOGERR
47 #define PK11_NO_LOGERR 1
48 #endif
49
50 LIBISC_EXTERNAL_DATA bool pk11_verbose_init = false;
51
52 static isc_once_t once = ISC_ONCE_INIT;
53 static isc_mem_t *pk11_mctx = NULL;
54 static int32_t allocsize = 0;
55 static bool initialized = false;
56
57 typedef struct pk11_session pk11_session_t;
58 typedef struct pk11_token pk11_token_t;
59 typedef ISC_LIST(pk11_session_t) pk11_sessionlist_t;
60
61 struct pk11_session {
62 unsigned int magic;
63 CK_SESSION_HANDLE session;
64 ISC_LINK(pk11_session_t) link;
65 pk11_token_t *token;
66 };
67
68 struct pk11_token {
69 unsigned int magic;
70 unsigned int operations;
71 ISC_LINK(pk11_token_t) link;
72 CK_SLOT_ID slotid;
73 pk11_sessionlist_t sessions;
74 bool logged;
75 char name[32];
76 char manuf[32];
77 char model[16];
78 char serial[16];
79 char pin[PINLEN + 1];
80 };
81 static ISC_LIST(pk11_token_t) tokens;
82
83 static pk11_token_t *rand_token;
84 static pk11_token_t *best_rsa_token;
85 static pk11_token_t *best_dsa_token;
86 static pk11_token_t *best_dh_token;
87 static pk11_token_t *digest_token;
88 static pk11_token_t *best_ec_token;
89 static pk11_token_t *best_gost_token;
90 static pk11_token_t *aes_token;
91
92 static isc_result_t free_all_sessions(void);
93 static isc_result_t free_session_list(pk11_sessionlist_t *slist);
94 static isc_result_t setup_session(pk11_session_t *sp,
95 pk11_token_t *token,
96 bool rw);
97 static void scan_slots(void);
98 static isc_result_t token_login(pk11_session_t *sp);
99 static char *percent_decode(char *x, size_t *len);
100 static bool pk11strcmp(const char *x, size_t lenx,
101 const char *y, size_t leny);
102 static CK_ATTRIBUTE *push_attribute(pk11_object_t *obj,
103 isc_mem_t *mctx,
104 size_t len);
105
106 static isc_mutex_t alloclock;
107 static isc_mutex_t sessionlock;
108
109 static pk11_sessionlist_t actives;
110
111 static CK_C_INITIALIZE_ARGS pk11_init_args = {
112 NULL_PTR, /* CreateMutex */
113 NULL_PTR, /* DestroyMutex */
114 NULL_PTR, /* LockMutex */
115 NULL_PTR, /* UnlockMutex */
116 CKF_OS_LOCKING_OK, /* flags */
117 NULL_PTR, /* pReserved */
118 };
119
120 #ifndef PK11_LIB_LOCATION
121 #define PK11_LIB_LOCATION "unknown_provider"
122 #endif
123
124 #ifndef WIN32
125 static const char *lib_name = PK11_LIB_LOCATION;
126 #else
127 static const char *lib_name = PK11_LIB_LOCATION ".dll";
128 #endif
129
130 void
pk11_set_lib_name(const char * name)131 pk11_set_lib_name(const char *name) {
132 lib_name = name;
133 }
134
135 const char *
pk11_get_lib_name(void)136 pk11_get_lib_name(void) {
137 return (lib_name);
138 }
139
140 static void
initialize(void)141 initialize(void) {
142 char *pk11_provider;
143
144 RUNTIME_CHECK(isc_mutex_init(&alloclock) == ISC_R_SUCCESS);
145 RUNTIME_CHECK(isc_mutex_init(&sessionlock) == ISC_R_SUCCESS);
146
147 pk11_provider = getenv("PKCS11_PROVIDER");
148 if (pk11_provider != NULL)
149 lib_name = pk11_provider;
150 }
151
152 void *
pk11_mem_get(size_t size)153 pk11_mem_get(size_t size) {
154 void *ptr;
155
156 LOCK(&alloclock);
157 if (pk11_mctx != NULL)
158 ptr = isc_mem_get(pk11_mctx, size);
159 else {
160 ptr = malloc(size);
161 if (ptr != NULL)
162 allocsize += (int)size;
163 }
164 UNLOCK(&alloclock);
165
166 if (ptr != NULL)
167 memset(ptr, 0, size);
168 return (ptr);
169 }
170
171 void
pk11_mem_put(void * ptr,size_t size)172 pk11_mem_put(void *ptr, size_t size) {
173 if (ptr != NULL)
174 memset(ptr, 0, size);
175 LOCK(&alloclock);
176 if (pk11_mctx != NULL)
177 isc_mem_put(pk11_mctx, ptr, size);
178 else {
179 if (ptr != NULL)
180 allocsize -= (int)size;
181 free(ptr);
182 }
183 UNLOCK(&alloclock);
184 }
185
186 isc_result_t
pk11_initialize(isc_mem_t * mctx,const char * engine)187 pk11_initialize(isc_mem_t *mctx, const char *engine) {
188 isc_result_t result = ISC_R_SUCCESS;
189 CK_RV rv;
190
191 RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
192
193 LOCK(&sessionlock);
194 LOCK(&alloclock);
195 if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0))
196 isc_mem_attach(mctx, &pk11_mctx);
197 UNLOCK(&alloclock);
198 if (initialized) {
199 goto unlock;
200 } else {
201 initialized = true;
202 }
203
204 ISC_LIST_INIT(tokens);
205 ISC_LIST_INIT(actives);
206
207 if (engine != NULL)
208 lib_name = engine;
209
210 /* Initialize the CRYPTOKI library */
211 rv = pkcs_C_Initialize((CK_VOID_PTR) &pk11_init_args);
212
213 if (rv == 0xfe) {
214 result = PK11_R_NOPROVIDER;
215 fprintf(stderr, "Can't load PKCS#11 provider: %s\n",
216 pk11_get_load_error_message());
217 goto unlock;
218 }
219 if (rv != CKR_OK) {
220 result = PK11_R_INITFAILED;
221 goto unlock;
222 }
223
224 scan_slots();
225 #ifdef PKCS11CRYPTO
226 if (rand_token == NULL) {
227 result = PK11_R_NORANDOMSERVICE;
228 goto unlock;
229 }
230 if (digest_token == NULL) {
231 result = PK11_R_NODIGESTSERVICE;
232 goto unlock;
233 }
234 #if defined(AES_CC)
235 if (aes_token == NULL) {
236 result = PK11_R_NOAESSERVICE;
237 goto unlock;
238 }
239 #endif
240 #endif /* PKCS11CRYPTO */
241 unlock:
242 UNLOCK(&sessionlock);
243 return (result);
244 }
245
246 isc_result_t
pk11_finalize(void)247 pk11_finalize(void) {
248 pk11_token_t *token, *next;
249 isc_result_t ret;
250
251 ret = free_all_sessions();
252 (void) pkcs_C_Finalize(NULL_PTR);
253 token = ISC_LIST_HEAD(tokens);
254 while (token != NULL) {
255 next = ISC_LIST_NEXT(token, link);
256 ISC_LIST_UNLINK(tokens, token, link);
257 if (token == rand_token)
258 rand_token = NULL;
259 if (token == best_rsa_token)
260 best_rsa_token = NULL;
261 if (token == best_dsa_token)
262 best_dsa_token = NULL;
263 if (token == best_dh_token)
264 best_dh_token = NULL;
265 if (token == digest_token)
266 digest_token = NULL;
267 if (token == best_ec_token)
268 best_ec_token = NULL;
269 if (token == best_gost_token)
270 best_gost_token = NULL;
271 if (token == aes_token)
272 aes_token = NULL;
273 pk11_mem_put(token, sizeof(*token));
274 token = next;
275 }
276 if (pk11_mctx != NULL)
277 isc_mem_detach(&pk11_mctx);
278 initialized = false;
279 return (ret);
280 }
281
282 isc_result_t
pk11_rand_bytes(unsigned char * buf,int num)283 pk11_rand_bytes(unsigned char *buf, int num) {
284 isc_result_t ret;
285 CK_RV rv;
286 pk11_context_t ctx;
287
288 ret = pk11_get_session(&ctx, OP_RAND, false, false,
289 false, NULL, 0);
290 if ((ret != ISC_R_SUCCESS) &&
291 (ret != PK11_R_NODIGESTSERVICE) &&
292 (ret != PK11_R_NOAESSERVICE))
293 return (ret);
294 RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
295 rv = pkcs_C_GenerateRandom(ctx.session,
296 (CK_BYTE_PTR) buf, (CK_ULONG) num);
297 pk11_return_session(&ctx);
298 if (rv == CKR_OK)
299 return (ISC_R_SUCCESS);
300 else
301 return (DST_R_CRYPTOFAILURE);
302 }
303
304 #define SEEDSIZE 1024
305
306 static CK_BYTE seed[SEEDSIZE];
307
308 void
pk11_rand_seed_fromfile(const char * randomfile)309 pk11_rand_seed_fromfile(const char *randomfile) {
310 pk11_context_t ctx;
311 FILE *stream = NULL;
312 size_t cc = 0;
313 isc_result_t ret;
314
315 ret = pk11_get_session(&ctx, OP_RAND, false, false,
316 false, NULL, 0);
317 if ((ret != ISC_R_SUCCESS) &&
318 (ret != PK11_R_NODIGESTSERVICE) &&
319 (ret != PK11_R_NOAESSERVICE))
320 return;
321 RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
322 ret = isc_stdio_open(randomfile, "r", &stream);
323 if (ret != ISC_R_SUCCESS)
324 goto cleanup;
325 ret = isc_stdio_read(seed, 1, SEEDSIZE, stream, &cc);
326 if (ret!= ISC_R_SUCCESS)
327 goto cleanup;
328 ret = isc_stdio_close(stream);
329 stream = NULL;
330 if (ret!= ISC_R_SUCCESS)
331 goto cleanup;
332 (void) pkcs_C_SeedRandom(ctx.session, seed, (CK_ULONG) cc);
333
334 cleanup:
335 if (stream != NULL)
336 (void) isc_stdio_close(stream);
337 pk11_return_session(&ctx);
338 }
339
340 isc_result_t
pk11_get_session(pk11_context_t * ctx,pk11_optype_t optype,bool need_services,bool rw,bool logon,const char * pin,CK_SLOT_ID slot)341 pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype,
342 bool need_services, bool rw,
343 bool logon, const char *pin, CK_SLOT_ID slot)
344 {
345 pk11_token_t *token = NULL;
346 pk11_sessionlist_t *freelist;
347 pk11_session_t *sp;
348 isc_result_t ret;
349 #ifdef PKCS11CRYPTO
350 isc_result_t service_ret = ISC_R_SUCCESS;
351 #else
352 UNUSED(need_services);
353 #endif
354
355 memset(ctx, 0, sizeof(pk11_context_t));
356 ctx->handle = NULL;
357 ctx->session = CK_INVALID_HANDLE;
358
359 ret = pk11_initialize(NULL, NULL);
360 #ifdef PKCS11CRYPTO
361 if (ret == PK11_R_NORANDOMSERVICE ||
362 ret == PK11_R_NODIGESTSERVICE ||
363 ret == PK11_R_NOAESSERVICE) {
364 if (need_services)
365 return (ret);
366 service_ret = ret;
367 }
368 else
369 #endif /* PKCS11CRYPTO */
370 if (ret != ISC_R_SUCCESS)
371 return (ret);
372
373 LOCK(&sessionlock);
374 /* wait for initialization to finish */
375 UNLOCK(&sessionlock);
376
377 switch(optype) {
378 #ifdef PKCS11CRYPTO
379 case OP_RAND:
380 token = rand_token;
381 break;
382 case OP_DIGEST:
383 token = digest_token;
384 break;
385 case OP_AES:
386 token = aes_token;
387 break;
388 case OP_ANY:
389 for (token = ISC_LIST_HEAD(tokens);
390 token != NULL;
391 token = ISC_LIST_NEXT(token, link))
392 if (token->slotid == slot)
393 break;
394 break;
395 #endif
396 default:
397 for (token = ISC_LIST_HEAD(tokens);
398 token != NULL;
399 token = ISC_LIST_NEXT(token, link))
400 if (token->slotid == slot)
401 break;
402 #ifdef PKCS11CRYPTO
403 if ((token == NULL) ||
404 ((token->operations & (1 << optype)) == 0))
405 return (ISC_R_NOTFOUND);
406 #endif
407 break;
408 }
409 if (token == NULL)
410 return (ISC_R_NOTFOUND);
411
412 /* Override the token's PIN */
413 if (logon && pin != NULL && *pin != '\0') {
414 if (strlen(pin) > PINLEN)
415 return (ISC_R_RANGE);
416 /*
417 * We want to zero out the old pin before
418 * overwriting with a new one.
419 */
420 memset(token->pin, 0, sizeof(token->pin));
421 strlcpy(token->pin, pin, sizeof(token->pin));
422 }
423
424 freelist = &token->sessions;
425
426 LOCK(&sessionlock);
427 sp = ISC_LIST_HEAD(*freelist);
428 if (sp != NULL) {
429 ISC_LIST_UNLINK(*freelist, sp, link);
430 ISC_LIST_APPEND(actives, sp, link);
431 UNLOCK(&sessionlock);
432 if (logon)
433 ret = token_login(sp);
434 ctx->handle = sp;
435 ctx->session = sp->session;
436 return (ret);
437 }
438 UNLOCK(&sessionlock);
439
440 sp = pk11_mem_get(sizeof(*sp));
441 if (sp == NULL)
442 return (ISC_R_NOMEMORY);
443 sp->magic = SES_MAGIC;
444 sp->token = token;
445 sp->session = CK_INVALID_HANDLE;
446 ISC_LINK_INIT(sp, link);
447 ret = setup_session(sp, token, rw);
448 if ((ret == ISC_R_SUCCESS) && logon)
449 ret = token_login(sp);
450 LOCK(&sessionlock);
451 ISC_LIST_APPEND(actives, sp, link);
452 UNLOCK(&sessionlock);
453 ctx->handle = sp;
454 ctx->session = sp->session;
455 #ifdef PKCS11CRYPTO
456 if (ret == ISC_R_SUCCESS)
457 ret = service_ret;
458 #endif
459 return (ret);
460 }
461
462 void
pk11_return_session(pk11_context_t * ctx)463 pk11_return_session(pk11_context_t *ctx) {
464 pk11_session_t *sp = (pk11_session_t *) ctx->handle;
465
466 if (sp == NULL)
467 return;
468 ctx->handle = NULL;
469 ctx->session = CK_INVALID_HANDLE;
470
471 LOCK(&sessionlock);
472 ISC_LIST_UNLINK(actives, sp, link);
473 UNLOCK(&sessionlock);
474 if (sp->session == CK_INVALID_HANDLE) {
475 pk11_mem_put(sp, sizeof(*sp));
476 return;
477 }
478
479 LOCK(&sessionlock);
480 ISC_LIST_APPEND(sp->token->sessions, sp, link);
481 UNLOCK(&sessionlock);
482 }
483
484 static isc_result_t
free_all_sessions(void)485 free_all_sessions(void) {
486 pk11_token_t *token;
487 isc_result_t ret = ISC_R_SUCCESS;
488 isc_result_t oret;
489
490 for (token = ISC_LIST_HEAD(tokens);
491 token != NULL;
492 token = ISC_LIST_NEXT(token, link)) {
493 oret = free_session_list(&token->sessions);
494 if (oret != ISC_R_SUCCESS)
495 ret = oret;
496 }
497 if (!ISC_LIST_EMPTY(actives)) {
498 ret = ISC_R_ADDRINUSE;
499 oret = free_session_list(&actives);
500 if (oret != ISC_R_SUCCESS)
501 ret = oret;
502 }
503 return (ret);
504 }
505
506 static isc_result_t
free_session_list(pk11_sessionlist_t * slist)507 free_session_list(pk11_sessionlist_t *slist) {
508 pk11_session_t *sp;
509 CK_RV rv;
510 isc_result_t ret;
511
512 ret = ISC_R_SUCCESS;
513 LOCK(&sessionlock);
514 while (!ISC_LIST_EMPTY(*slist)) {
515 sp = ISC_LIST_HEAD(*slist);
516 ISC_LIST_UNLINK(*slist, sp, link);
517 UNLOCK(&sessionlock);
518 if (sp->session != CK_INVALID_HANDLE) {
519 rv = pkcs_C_CloseSession(sp->session);
520 if (rv != CKR_OK)
521 ret = DST_R_CRYPTOFAILURE;
522 }
523 LOCK(&sessionlock);
524 pk11_mem_put(sp, sizeof(*sp));
525 }
526 UNLOCK(&sessionlock);
527
528 return (ret);
529 }
530
531 static isc_result_t
setup_session(pk11_session_t * sp,pk11_token_t * token,bool rw)532 setup_session(pk11_session_t *sp, pk11_token_t *token,
533 bool rw)
534 {
535 CK_RV rv;
536 CK_FLAGS flags = CKF_SERIAL_SESSION;
537
538 if (rw)
539 flags += CKF_RW_SESSION;
540
541 rv = pkcs_C_OpenSession(token->slotid, flags, NULL_PTR,
542 NULL_PTR, &sp->session);
543 if (rv != CKR_OK)
544 return (DST_R_CRYPTOFAILURE);
545 return (ISC_R_SUCCESS);
546 }
547
548 static isc_result_t
token_login(pk11_session_t * sp)549 token_login(pk11_session_t *sp) {
550 CK_RV rv;
551 pk11_token_t *token = sp->token;
552 isc_result_t ret = ISC_R_SUCCESS;
553
554 LOCK(&sessionlock);
555 if (!token->logged) {
556 rv = pkcs_C_Login(sp->session, CKU_USER,
557 (CK_UTF8CHAR_PTR) token->pin,
558 (CK_ULONG) strlen(token->pin));
559 if (rv != CKR_OK) {
560 ret = ISC_R_NOPERM;
561 #if PK11_NO_LOGERR
562 pk11_error_fatalcheck(__FILE__, __LINE__,
563 "pkcs_C_Login", rv);
564 #endif
565 } else
566 token->logged = true;
567 }
568 UNLOCK(&sessionlock);
569 return (ret);
570 }
571
572 #define PK11_TRACE(fmt) \
573 if (pk11_verbose_init) fprintf(stderr, fmt)
574 #define PK11_TRACE1(fmt, arg) \
575 if (pk11_verbose_init) fprintf(stderr, fmt, arg)
576 #define PK11_TRACE2(fmt, arg1, arg2) \
577 if (pk11_verbose_init) fprintf(stderr, fmt, arg1, arg2)
578 #define PK11_TRACEM(mech) \
579 if (pk11_verbose_init) fprintf(stderr, #mech ": 0x%lx\n", rv)
580
581 static void
scan_slots(void)582 scan_slots(void) {
583 CK_MECHANISM_INFO mechInfo;
584 CK_TOKEN_INFO tokenInfo;
585 CK_RV rv;
586 CK_SLOT_ID slot;
587 CK_SLOT_ID_PTR slotList;
588 CK_ULONG slotCount;
589 pk11_token_t *token;
590 unsigned int i;
591 bool bad;
592
593 slotCount = 0;
594 PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, NULL_PTR, &slotCount));
595 PK11_TRACE1("slotCount=%lu\n", slotCount);
596 /* it's not an error if we didn't find any providers */
597 if (slotCount == 0)
598 return;
599 slotList = pk11_mem_get(sizeof(CK_SLOT_ID) * slotCount);
600 RUNTIME_CHECK(slotList != NULL);
601 PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, slotList, &slotCount));
602
603 for (i = 0; i < slotCount; i++) {
604 slot = slotList[i];
605 PK11_TRACE2("slot#%u=0x%lx\n", i, slot);
606
607 rv = pkcs_C_GetTokenInfo(slot, &tokenInfo);
608 if (rv != CKR_OK)
609 continue;
610 token = pk11_mem_get(sizeof(*token));
611 RUNTIME_CHECK(token != NULL);
612 token->magic = TOK_MAGIC;
613 token->slotid = slot;
614 ISC_LINK_INIT(token, link);
615 ISC_LIST_INIT(token->sessions);
616 memmove(token->name, tokenInfo.label, 32);
617 memmove(token->manuf, tokenInfo.manufacturerID, 32);
618 memmove(token->model, tokenInfo.model, 16);
619 memmove(token->serial, tokenInfo.serialNumber, 16);
620 ISC_LIST_APPEND(tokens, token, link);
621 if ((tokenInfo.flags & CKF_RNG) == 0) {
622 PK11_TRACE("no CKF_RNG\n");
623 goto try_rsa;
624 }
625 token->operations |= 1 << OP_RAND;
626 if (rand_token == NULL)
627 rand_token = token;
628
629 try_rsa:
630 bad = false;
631 rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
632 &mechInfo);
633 if ((rv != CKR_OK) ||
634 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
635 bad = true;
636 PK11_TRACEM(CKM_RSA_PKCS_KEY_PAIR_GEN);
637 }
638 rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_RSA_PKCS,
639 &mechInfo);
640 if ((rv != CKR_OK) ||
641 ((mechInfo.flags & CKF_SIGN) == 0) ||
642 ((mechInfo.flags & CKF_VERIFY) == 0)) {
643 #if !defined(PK11_MD5_DISABLE) && !defined(PK11_RSA_PKCS_REPLACE)
644 bad = true;
645 #endif
646 PK11_TRACEM(CKM_MD5_RSA_PKCS);
647 }
648 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA1_RSA_PKCS,
649 &mechInfo);
650 if ((rv != CKR_OK) ||
651 ((mechInfo.flags & CKF_SIGN) == 0) ||
652 ((mechInfo.flags & CKF_VERIFY) == 0)) {
653 #ifndef PK11_RSA_PKCS_REPLACE
654 bad = true;
655 #endif
656 PK11_TRACEM(CKM_SHA1_RSA_PKCS);
657 }
658 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_RSA_PKCS,
659 &mechInfo);
660 if ((rv != CKR_OK) ||
661 ((mechInfo.flags & CKF_SIGN) == 0) ||
662 ((mechInfo.flags & CKF_VERIFY) == 0)) {
663 #ifndef PK11_RSA_PKCS_REPLACE
664 bad = true;
665 #endif
666 PK11_TRACEM(CKM_SHA256_RSA_PKCS);
667 }
668 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_RSA_PKCS,
669 &mechInfo);
670 if ((rv != CKR_OK) ||
671 ((mechInfo.flags & CKF_SIGN) == 0) ||
672 ((mechInfo.flags & CKF_VERIFY) == 0)) {
673 #ifndef PK11_RSA_PKCS_REPLACE
674 bad = true;
675 #endif
676 PK11_TRACEM(CKM_SHA512_RSA_PKCS);
677 }
678 rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS, &mechInfo);
679 if ((rv != CKR_OK) ||
680 ((mechInfo.flags & CKF_SIGN) == 0) ||
681 ((mechInfo.flags & CKF_VERIFY) == 0)) {
682 #ifdef PK11_RSA_PKCS_REPLACE
683 bad = true;
684 #endif
685 PK11_TRACEM(CKM_RSA_PKCS);
686 }
687 if (bad)
688 goto try_dsa;
689 token->operations |= 1 << OP_RSA;
690 if (best_rsa_token == NULL)
691 best_rsa_token = token;
692
693 try_dsa:
694 bad = false;
695 rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_PARAMETER_GEN,
696 &mechInfo);
697 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) {
698 #ifndef PK11_DSA_PARAMETER_GEN_SKIP
699 bad = true;
700 #endif
701 PK11_TRACEM(CKM_DSA_PARAMETER_GEN);
702 }
703 rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_KEY_PAIR_GEN,
704 &mechInfo);
705 if ((rv != CKR_OK) ||
706 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
707 bad = true;
708 PK11_TRACEM(CKM_DSA_PARAMETER_GEN);
709 }
710 rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_SHA1, &mechInfo);
711 if ((rv != CKR_OK) ||
712 ((mechInfo.flags & CKF_SIGN) == 0) ||
713 ((mechInfo.flags & CKF_VERIFY) == 0)) {
714 bad = true;
715 PK11_TRACEM(CKM_DSA_SHA1);
716 }
717 if (bad)
718 goto try_dh;
719 #ifndef PK11_DSA_DISABLE
720 token->operations |= 1 << OP_DSA;
721 if (best_dsa_token == NULL)
722 best_dsa_token = token;
723 #endif
724
725 try_dh:
726 bad = false;
727 rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_PARAMETER_GEN,
728 &mechInfo);
729 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) {
730 PK11_TRACEM(CKM_DH_PKCS_PARAMETER_GEN);
731 }
732 rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_KEY_PAIR_GEN,
733 &mechInfo);
734 if ((rv != CKR_OK) ||
735 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
736 #ifndef PK11_DH_PKCS_PARAMETER_GEN_SKIP
737 bad = true;
738 #endif
739 PK11_TRACEM(CKM_DH_PKCS_KEY_PAIR_GEN);
740 }
741 rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_DERIVE,
742 &mechInfo);
743 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DERIVE) == 0)) {
744 bad = true;
745 PK11_TRACEM(CKM_DH_PKCS_DERIVE);
746 }
747 if (bad)
748 goto try_digest;
749 #ifndef PK11_DH_DISABLE
750 token->operations |= 1 << OP_DH;
751 if (best_dh_token == NULL)
752 best_dh_token = token;
753 #endif
754
755 try_digest:
756 bad = false;
757 rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5, &mechInfo);
758 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
759 #ifndef PK11_MD5_DISABLE
760 bad = true;
761 #endif
762 PK11_TRACEM(CKM_MD5);
763 }
764 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1, &mechInfo);
765 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
766 bad = true;
767 PK11_TRACEM(CKM_SHA_1);
768 }
769 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224, &mechInfo);
770 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
771 bad = true;
772 PK11_TRACEM(CKM_SHA224);
773 }
774 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256, &mechInfo);
775 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
776 bad = true;
777 PK11_TRACEM(CKM_SHA256);
778 }
779 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384, &mechInfo);
780 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
781 bad = true;
782 PK11_TRACEM(CKM_SHA384);
783 }
784 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512, &mechInfo);
785 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
786 bad = true;
787 PK11_TRACEM(CKM_SHA512);
788 }
789 rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_HMAC, &mechInfo);
790 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
791 #if !defined(PK11_MD5_DISABLE) && !defined(PK11_MD5_HMAC_REPLACE)
792 bad = true;
793 #endif
794 PK11_TRACEM(CKM_MD5_HMAC);
795 }
796 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1_HMAC, &mechInfo);
797 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
798 #ifndef PK11_SHA_1_HMAC_REPLACE
799 bad = true;
800 #endif
801 PK11_TRACEM(CKM_SHA_1_HMAC);
802 }
803 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224_HMAC, &mechInfo);
804 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
805 #ifndef PK11_SHA224_HMAC_REPLACE
806 bad = true;
807 #endif
808 PK11_TRACEM(CKM_SHA224_HMAC);
809 }
810 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_HMAC, &mechInfo);
811 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
812 #ifndef PK11_SHA256_HMAC_REPLACE
813 bad = true;
814 #endif
815 PK11_TRACEM(CKM_SHA256_HMAC);
816 }
817 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384_HMAC, &mechInfo);
818 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
819 #ifndef PK11_SHA384_HMAC_REPLACE
820 bad = true;
821 #endif
822 PK11_TRACEM(CKM_SHA384_HMAC);
823 }
824 rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_HMAC, &mechInfo);
825 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) {
826 #ifndef PK11_SHA512_HMAC_REPLACE
827 bad = true;
828 #endif
829 PK11_TRACEM(CKM_SHA512_HMAC);
830 }
831 if (!bad) {
832 token->operations |= 1 << OP_DIGEST;
833 if (digest_token == NULL)
834 digest_token = token;
835 }
836
837 /* ECDSA requires digest */
838 rv = pkcs_C_GetMechanismInfo(slot, CKM_EC_KEY_PAIR_GEN,
839 &mechInfo);
840 if ((rv != CKR_OK) ||
841 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
842 bad = true;
843 PK11_TRACEM(CKM_EC_KEY_PAIR_GEN);
844 }
845 rv = pkcs_C_GetMechanismInfo(slot, CKM_ECDSA, &mechInfo);
846 if ((rv != CKR_OK) ||
847 ((mechInfo.flags & CKF_SIGN) == 0) ||
848 ((mechInfo.flags & CKF_VERIFY) == 0)) {
849 bad = true;
850 PK11_TRACEM(CKM_ECDSA);
851 }
852 if (bad)
853 goto try_gost;
854 token->operations |= 1 << OP_EC;
855 if (best_ec_token == NULL)
856 best_ec_token = token;
857
858 try_gost:
859 bad = false;
860 /* does GOST require digest too? */
861 rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3411, &mechInfo);
862 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) {
863 bad = true;
864 PK11_TRACEM(CKM_GOSTR3411);
865 }
866 rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3410_KEY_PAIR_GEN,
867 &mechInfo);
868 if ((rv != CKR_OK) ||
869 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
870 bad = true;
871 PK11_TRACEM(CKM_GOSTR3410_KEY_PAIR_GEN);
872 }
873 rv = pkcs_C_GetMechanismInfo(slot,
874 CKM_GOSTR3410_WITH_GOSTR3411,
875 &mechInfo);
876 if ((rv != CKR_OK) ||
877 ((mechInfo.flags & CKF_SIGN) == 0) ||
878 ((mechInfo.flags & CKF_VERIFY) == 0)) {
879 bad = true;
880 PK11_TRACEM(CKM_GOSTR3410_WITH_GOSTR3411);
881 }
882 if (bad)
883 goto try_eddsa;
884 token->operations |= 1 << OP_GOST;
885 if (best_gost_token == NULL)
886 best_gost_token = token;
887
888 try_eddsa:
889 #if defined(CKM_EDDSA_KEY_PAIR_GEN) && defined(CKM_EDDSA) && defined(CKK_EDDSA)
890 bad = false;
891 rv = pkcs_C_GetMechanismInfo(slot, CKM_EDDSA_KEY_PAIR_GEN,
892 &mechInfo);
893 if ((rv != CKR_OK) ||
894 ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) {
895 bad = true;
896 PK11_TRACEM(CKM_EDDSA_KEY_PAIR_GEN);
897 }
898 rv = pkcs_C_GetMechanismInfo(slot, CKM_EDDSA, &mechInfo);
899 if ((rv != CKR_OK) ||
900 ((mechInfo.flags & CKF_SIGN) == 0) ||
901 ((mechInfo.flags & CKF_VERIFY) == 0)) {
902 bad = true;
903 PK11_TRACEM(CKM_EDDSA);
904 }
905 if (bad)
906 goto try_aes;
907
908 try_aes:
909 #endif
910 bad = false;
911 rv = pkcs_C_GetMechanismInfo(slot, CKM_AES_ECB, &mechInfo);
912 if ((rv != CKR_OK) || ((mechInfo.flags & CKF_ENCRYPT) == 0)) {
913 bad = true;
914 PK11_TRACEM(CKM_AES_ECB);
915 }
916 if (bad)
917 continue;
918 token->operations |= 1 << OP_AES;
919 if (aes_token == NULL)
920 aes_token = token;
921 }
922
923 if (slotList != NULL) {
924 pk11_mem_put(slotList, sizeof(CK_SLOT_ID) * slotCount);
925 }
926 }
927
928 CK_SLOT_ID
pk11_get_best_token(pk11_optype_t optype)929 pk11_get_best_token(pk11_optype_t optype) {
930 pk11_token_t *token = NULL;
931
932 switch (optype) {
933 case OP_RAND:
934 token = rand_token;
935 break;
936 case OP_RSA:
937 token = best_rsa_token;
938 break;
939 case OP_DSA:
940 token = best_dsa_token;
941 break;
942 case OP_DH:
943 token = best_dh_token;
944 break;
945 case OP_DIGEST:
946 token = digest_token;
947 break;
948 case OP_EC:
949 token = best_ec_token;
950 break;
951 case OP_GOST:
952 token = best_gost_token;
953 break;
954 case OP_AES:
955 token = aes_token;
956 break;
957 default:
958 break;
959 }
960 if (token == NULL)
961 return (0);
962 return (token->slotid);
963 }
964
965 isc_result_t
pk11_numbits(CK_BYTE_PTR data,unsigned int bytecnt,unsigned int * bits)966 pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) {
967 unsigned int bitcnt, i;
968 CK_BYTE top;
969
970 if (bytecnt == 0) {
971 *bits = 0;
972 return (ISC_R_SUCCESS);
973 }
974 bitcnt = bytecnt * 8;
975 for (i = 0; i < bytecnt; i++) {
976 top = data[i];
977 if (top == 0) {
978 bitcnt -= 8;
979 continue;
980 }
981 if (top & 0x80) {
982 *bits = bitcnt;
983 return (ISC_R_SUCCESS);
984 }
985 if (top & 0x40) {
986 *bits = bitcnt - 1;
987 return (ISC_R_SUCCESS);
988 }
989 if (top & 0x20) {
990 *bits = bitcnt - 2;
991 return (ISC_R_SUCCESS);
992 }
993 if (top & 0x10) {
994 *bits = bitcnt - 3;
995 return (ISC_R_SUCCESS);
996 }
997 if (top & 0x08) {
998 *bits = bitcnt - 4;
999 return (ISC_R_SUCCESS);
1000 }
1001 if (top & 0x04) {
1002 *bits = bitcnt - 5;
1003 return (ISC_R_SUCCESS);
1004 }
1005 if (top & 0x02) {
1006 *bits = bitcnt - 6;
1007 return (ISC_R_SUCCESS);
1008 }
1009 if (top & 0x01) {
1010 *bits = bitcnt - 7;
1011 return (ISC_R_SUCCESS);
1012 }
1013 break;
1014 }
1015 return (ISC_R_RANGE);
1016 }
1017
1018 CK_ATTRIBUTE *
pk11_attribute_first(const pk11_object_t * obj)1019 pk11_attribute_first(const pk11_object_t *obj) {
1020 return (obj->repr);
1021 }
1022
1023 CK_ATTRIBUTE *
pk11_attribute_next(const pk11_object_t * obj,CK_ATTRIBUTE * attr)1024 pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr) {
1025 CK_ATTRIBUTE *next;
1026
1027 next = attr + 1;
1028 if ((next - obj->repr) >= obj->attrcnt)
1029 return (NULL);
1030 return (next);
1031 }
1032
1033 CK_ATTRIBUTE *
pk11_attribute_bytype(const pk11_object_t * obj,CK_ATTRIBUTE_TYPE type)1034 pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) {
1035 CK_ATTRIBUTE *attr;
1036
1037 for(attr = pk11_attribute_first(obj);
1038 attr != NULL;
1039 attr = pk11_attribute_next(obj, attr))
1040 if (attr->type == type)
1041 return (attr);
1042 return (NULL);
1043 }
1044
1045 static char *
percent_decode(char * x,size_t * len)1046 percent_decode(char *x, size_t *len) {
1047 char *p, *c;
1048 unsigned char v;
1049
1050 INSIST(len != NULL);
1051
1052 for (p = c = x; p[0] != '\0'; p++, c++) {
1053 switch (p[0]) {
1054 case '%':
1055 v = 0;
1056 switch (p[1]) {
1057 case '0':
1058 case '1':
1059 case '2':
1060 case '3':
1061 case '4':
1062 case '5':
1063 case '6':
1064 case '7':
1065 case '8':
1066 case '9':
1067 v = (p[1] - '0') << 4;
1068 break;
1069 case 'A':
1070 case 'B':
1071 case 'C':
1072 case 'D':
1073 case 'E':
1074 case 'F':
1075 v = (p[1] - 'A' + 10) << 4;
1076 break;
1077 case 'a':
1078 case 'b':
1079 case 'c':
1080 case 'd':
1081 case 'e':
1082 case 'f':
1083 v = (p[1] - 'a' + 10) << 4;
1084 break;
1085 default:
1086 return (NULL);
1087 }
1088 switch (p[2]) {
1089 case '0':
1090 case '1':
1091 case '2':
1092 case '3':
1093 case '4':
1094 case '5':
1095 case '6':
1096 case '7':
1097 case '8':
1098 case '9':
1099 v |= (p[2] - '0') & 0x0f;
1100 break;
1101 case 'A':
1102 case 'B':
1103 case 'C':
1104 case 'D':
1105 case 'E':
1106 case 'F':
1107 v = (p[2] - 'A' + 10) & 0x0f;
1108 break;
1109 case 'a':
1110 case 'b':
1111 case 'c':
1112 case 'd':
1113 case 'e':
1114 case 'f':
1115 v = (p[2] - 'a' + 10) & 0x0f;
1116 break;
1117 default:
1118 return (NULL);
1119 }
1120 p += 2;
1121 *c = (char) v;
1122 (*len)++;
1123 break;
1124 default:
1125 *c = *p;
1126 (*len)++;
1127 }
1128 }
1129 return (x);
1130 }
1131
1132 static bool
pk11strcmp(const char * x,size_t lenx,const char * y,size_t leny)1133 pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny) {
1134 char buf[32];
1135
1136 INSIST((leny == 32) || (leny == 16));
1137
1138 memset(buf, ' ', 32);
1139 if (lenx > leny)
1140 lenx = leny;
1141 memmove(buf, x, lenx);
1142 return (memcmp(buf, y, leny) == 0);
1143 }
1144
1145 static CK_ATTRIBUTE *
push_attribute(pk11_object_t * obj,isc_mem_t * mctx,size_t len)1146 push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len) {
1147 CK_ATTRIBUTE *old = obj->repr;
1148 CK_ATTRIBUTE *attr;
1149 CK_BYTE cnt = obj->attrcnt;
1150
1151 REQUIRE(old != NULL || cnt == 0);
1152
1153 obj->repr = isc_mem_get(mctx, (cnt + 1) * sizeof(*attr));
1154 if (obj->repr == NULL) {
1155 obj->repr = old;
1156 return (NULL);
1157 }
1158 memset(obj->repr, 0, (cnt + 1) * sizeof(*attr));
1159 if (old != NULL) {
1160 memmove(obj->repr, old, cnt * sizeof(*attr));
1161 }
1162 attr = obj->repr + cnt;
1163 attr->ulValueLen = (CK_ULONG) len;
1164 attr->pValue = isc_mem_get(mctx, len);
1165 if (attr->pValue == NULL) {
1166 memset(obj->repr, 0, (cnt + 1) * sizeof(*attr));
1167 isc_mem_put(mctx, obj->repr, (cnt + 1) * sizeof(*attr));
1168 obj->repr = old;
1169 return (NULL);
1170 }
1171 memset(attr->pValue, 0, len);
1172 if (old != NULL) {
1173 memset(old, 0, cnt * sizeof(*attr));
1174 isc_mem_put(mctx, old, cnt * sizeof(*attr));
1175 }
1176 obj->attrcnt++;
1177 return (attr);
1178 }
1179
1180 #define DST_RET(a) { ret = a; goto err; }
1181
1182 isc_result_t
pk11_parse_uri(pk11_object_t * obj,const char * label,isc_mem_t * mctx,pk11_optype_t optype)1183 pk11_parse_uri(pk11_object_t *obj, const char *label,
1184 isc_mem_t *mctx, pk11_optype_t optype)
1185 {
1186 CK_ATTRIBUTE *attr;
1187 pk11_token_t *token = NULL;
1188 char *uri, *p, *a, *na, *v;
1189 size_t len, l;
1190 FILE *stream = NULL;
1191 char pin[PINLEN + 1];
1192 bool gotpin = false;
1193 isc_result_t ret;
1194
1195 /* get values to work on */
1196 len = strlen(label) + 1;
1197 uri = isc_mem_get(mctx, len);
1198 if (uri == NULL)
1199 return (ISC_R_NOMEMORY);
1200 memmove(uri, label, len);
1201
1202 /* get the URI scheme */
1203 p = strchr(uri, ':');
1204 if (p == NULL)
1205 DST_RET(PK11_R_NOPROVIDER);
1206 *p++ = '\0';
1207 if (strcmp(uri, "pkcs11") != 0)
1208 DST_RET(PK11_R_NOPROVIDER);
1209
1210 /* get attributes */
1211 for (na = p; na != NULL;) {
1212 a = na;
1213 p = strchr(a, ';');
1214 if (p == NULL) {
1215 /* last attribute */
1216 na = NULL;
1217 } else {
1218 *p++ = '\0';
1219 na = p;
1220 }
1221 p = strchr(a, '=');
1222 if (p != NULL) {
1223 *p++ = '\0';
1224 v = p;
1225 } else
1226 v = a;
1227 l = 0;
1228 v = percent_decode(v, &l);
1229 if (v == NULL)
1230 DST_RET(PK11_R_NOPROVIDER);
1231 if ((a == v) || (strcmp(a, "object") == 0)) {
1232 /* object: CKA_LABEL */
1233 attr = pk11_attribute_bytype(obj, CKA_LABEL);
1234 if (attr != NULL)
1235 DST_RET(PK11_R_NOPROVIDER);
1236 attr = push_attribute(obj, mctx, l);
1237 if (attr == NULL)
1238 DST_RET(ISC_R_NOMEMORY);
1239 attr->type = CKA_LABEL;
1240 memmove(attr->pValue, v, l);
1241 } else if (strcmp(a, "token") == 0) {
1242 /* token: CK_TOKEN_INFO label */
1243 if (token == NULL)
1244 for (token = ISC_LIST_HEAD(tokens);
1245 token != NULL;
1246 token = ISC_LIST_NEXT(token, link))
1247 if (pk11strcmp(v, l, token->name, 32))
1248 break;
1249 } else if (strcmp(a, "manufacturer") == 0) {
1250 /* manufacturer: CK_TOKEN_INFO manufacturerID */
1251 if (token == NULL)
1252 for (token = ISC_LIST_HEAD(tokens);
1253 token != NULL;
1254 token = ISC_LIST_NEXT(token, link))
1255 if (pk11strcmp(v, l, token->manuf, 32))
1256 break;
1257 } else if (strcmp(a, "serial") == 0) {
1258 /* serial: CK_TOKEN_INFO serialNumber */
1259 if (token == NULL)
1260 for (token = ISC_LIST_HEAD(tokens);
1261 token != NULL;
1262 token = ISC_LIST_NEXT(token, link))
1263 if (pk11strcmp(v, l, token->serial, 16))
1264 break;
1265 } else if (strcmp(a, "model") == 0) {
1266 /* model: CK_TOKEN_INFO model */
1267 if (token == NULL)
1268 for (token = ISC_LIST_HEAD(tokens);
1269 token != NULL;
1270 token = ISC_LIST_NEXT(token, link))
1271 if (pk11strcmp(v, l, token->model, 16))
1272 break;
1273 } else if (strcmp(a, "library-manufacturer") == 0) {
1274 /* ignored */
1275 } else if (strcmp(a, "library-description") == 0) {
1276 /* ignored */
1277 } else if (strcmp(a, "library-version") == 0) {
1278 /* ignored */
1279 } else if (strcmp(a, "object-type") == 0) {
1280 /* object-type: CKA_CLASS */
1281 /* only private makes sense */
1282 if (strcmp(v, "private") != 0)
1283 DST_RET(PK11_R_NOPROVIDER);
1284 } else if (strcmp(a, "id") == 0) {
1285 /* id: CKA_ID */
1286 attr = pk11_attribute_bytype(obj, CKA_ID);
1287 if (attr != NULL)
1288 DST_RET(PK11_R_NOPROVIDER);
1289 attr = push_attribute(obj, mctx, l);
1290 if (attr == NULL)
1291 DST_RET(ISC_R_NOMEMORY);
1292 attr->type = CKA_ID;
1293 memmove(attr->pValue, v, l);
1294 } else if (strcmp(a, "pin-source") == 0) {
1295 /* pin-source: PIN */
1296 ret = isc_stdio_open(v, "r", &stream);
1297 if (ret != ISC_R_SUCCESS)
1298 goto err;
1299 memset(pin, 0, PINLEN + 1);
1300 ret = isc_stdio_read(pin, 1, PINLEN + 1, stream, &l);
1301 if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF))
1302 goto err;
1303 if (l > PINLEN)
1304 DST_RET(ISC_R_RANGE);
1305 ret = isc_stdio_close(stream);
1306 stream = NULL;
1307 if (ret != ISC_R_SUCCESS)
1308 goto err;
1309 gotpin = true;
1310 } else
1311 DST_RET(PK11_R_NOPROVIDER);
1312 }
1313
1314 if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) &&
1315 (pk11_attribute_bytype(obj, CKA_ID) == NULL))
1316 DST_RET(ISC_R_NOTFOUND);
1317
1318 if (token == NULL) {
1319 if (optype == OP_RSA)
1320 token = best_rsa_token;
1321 else if (optype == OP_DSA)
1322 token = best_dsa_token;
1323 else if (optype == OP_DH)
1324 token = best_dh_token;
1325 else if (optype == OP_EC)
1326 token = best_ec_token;
1327 }
1328 if (token == NULL)
1329 DST_RET(ISC_R_NOTFOUND);
1330 obj->slot = token->slotid;
1331 if (gotpin) {
1332 memmove(token->pin, pin, PINLEN + 1);
1333 obj->reqlogon = true;
1334 }
1335
1336 ret = ISC_R_SUCCESS;
1337
1338 err:
1339 if (stream != NULL)
1340 (void) isc_stdio_close(stream);
1341 isc_mem_put(mctx, uri, len);
1342 return (ret);
1343 }
1344
1345 void
pk11_error_fatalcheck(const char * file,int line,const char * funcname,CK_RV rv)1346 pk11_error_fatalcheck(const char *file, int line,
1347 const char *funcname, CK_RV rv)
1348 {
1349 isc_error_fatal(file, line, "%s: Error = 0x%.8lX\n", funcname, rv);
1350 }
1351
1352 void
pk11_dump_tokens(void)1353 pk11_dump_tokens(void) {
1354 pk11_token_t *token;
1355 bool first;
1356
1357 printf("DEFAULTS\n");
1358 printf("\trand_token=%p\n", rand_token);
1359 printf("\tbest_rsa_token=%p\n", best_rsa_token);
1360 printf("\tbest_dsa_token=%p\n", best_dsa_token);
1361 printf("\tbest_dh_token=%p\n", best_dh_token);
1362 printf("\tdigest_token=%p\n", digest_token);
1363 printf("\tbest_ec_token=%p\n", best_ec_token);
1364 printf("\tbest_gost_token=%p\n", best_gost_token);
1365 printf("\taes_token=%p\n", aes_token);
1366
1367 for (token = ISC_LIST_HEAD(tokens);
1368 token != NULL;
1369 token = ISC_LIST_NEXT(token, link)) {
1370 printf("\nTOKEN\n");
1371 printf("\taddress=%p\n", token);
1372 printf("\tslotID=%lu\n", token->slotid);
1373 printf("\tlabel=%.32s\n", token->name);
1374 printf("\tmanufacturerID=%.32s\n", token->manuf);
1375 printf("\tmodel=%.16s\n", token->model);
1376 printf("\tserialNumber=%.16s\n", token->serial);
1377 printf("\tsupported operations=0x%x (", token->operations);
1378 first = true;
1379 if (token->operations & (1 << OP_RAND)) {
1380 if (!first)
1381 printf(",");
1382 first = false;
1383 printf("RAND");
1384 }
1385 if (token->operations & (1 << OP_RSA)) {
1386 first = false;
1387 printf("RSA");
1388 }
1389 if (token->operations & (1 << OP_DSA)) {
1390 if (!first)
1391 printf(",");
1392 first = false;
1393 printf("DSA");
1394 }
1395 if (token->operations & (1 << OP_DH)) {
1396 if (!first)
1397 printf(",");
1398 first = false;
1399 printf("DH");
1400 }
1401 if (token->operations & (1 << OP_DIGEST)) {
1402 if (!first)
1403 printf(",");
1404 first = false;
1405 printf("DIGEST");
1406 }
1407 if (token->operations & (1 << OP_EC)) {
1408 if (!first)
1409 printf(",");
1410 first = false;
1411 printf("EC");
1412 }
1413 if (token->operations & (1 << OP_AES)) {
1414 if (!first)
1415 printf(",");
1416 first = false;
1417 UNUSED(first);
1418 printf("AES");
1419 }
1420 printf(")\n");
1421 }
1422 }
1423