1 /* $NetBSD: pkcs11rsa_link.c,v 1.1.1.5 2015/09/03 07:21:37 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* Id */ 20 21 #ifdef PKCS11CRYPTO 22 23 #include <config.h> 24 25 #include <isc/entropy.h> 26 #include <isc/md5.h> 27 #include <isc/sha1.h> 28 #include <isc/sha2.h> 29 #include <isc/mem.h> 30 #include <isc/string.h> 31 #include <isc/util.h> 32 33 #include <dst/result.h> 34 35 #include "dst_internal.h" 36 #include "dst_parse.h" 37 #include "dst_pkcs11.h" 38 39 #include <pk11/internal.h> 40 41 /* 42 * Limit the size of public exponents. 43 */ 44 #ifndef RSA_MAX_PUBEXP_BITS 45 #define RSA_MAX_PUBEXP_BITS 35 46 #endif 47 48 #define DST_RET(a) {ret = a; goto err;} 49 50 static CK_BBOOL truevalue = TRUE; 51 static CK_BBOOL falsevalue = FALSE; 52 53 static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data); 54 static void pkcs11rsa_destroy(dst_key_t *key); 55 static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, 56 const char *label, dst_key_t *pub); 57 58 static isc_result_t 59 pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { 60 CK_RV rv; 61 CK_MECHANISM mech = { 0, NULL, 0 }; 62 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; 63 CK_KEY_TYPE keyType = CKK_RSA; 64 CK_ATTRIBUTE keyTemplate[] = 65 { 66 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, 67 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 68 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 69 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 70 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 71 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, 72 { CKA_MODULUS, NULL, 0 }, 73 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 74 { CKA_PRIVATE_EXPONENT, NULL, 0 }, 75 { CKA_PRIME_1, NULL, 0 }, 76 { CKA_PRIME_2, NULL, 0 }, 77 { CKA_EXPONENT_1, NULL, 0 }, 78 { CKA_EXPONENT_2, NULL, 0 }, 79 { CKA_COEFFICIENT, NULL, 0 } 80 }; 81 CK_ATTRIBUTE *attr; 82 CK_SLOT_ID slotid; 83 pk11_object_t *rsa; 84 pk11_context_t *pk11_ctx; 85 isc_result_t ret; 86 unsigned int i; 87 88 REQUIRE(key->key_alg == DST_ALG_RSAMD5 || 89 key->key_alg == DST_ALG_RSASHA1 || 90 key->key_alg == DST_ALG_NSEC3RSASHA1 || 91 key->key_alg == DST_ALG_RSASHA256 || 92 key->key_alg == DST_ALG_RSASHA512); 93 94 rsa = key->keydata.pkey; 95 96 pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, 97 sizeof(*pk11_ctx)); 98 if (pk11_ctx == NULL) 99 return (ISC_R_NOMEMORY); 100 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 101 if (rsa->ontoken) 102 slotid = rsa->slot; 103 else 104 slotid = pk11_get_best_token(OP_RSA); 105 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, 106 rsa->reqlogon, NULL, slotid); 107 if (ret != ISC_R_SUCCESS) 108 goto err; 109 110 if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { 111 pk11_ctx->ontoken = rsa->ontoken; 112 pk11_ctx->object = rsa->object; 113 goto token_key; 114 } 115 116 for (attr = pk11_attribute_first(rsa); 117 attr != NULL; 118 attr = pk11_attribute_next(rsa, attr)) 119 switch (attr->type) { 120 case CKA_MODULUS: 121 INSIST(keyTemplate[6].type == attr->type); 122 keyTemplate[6].pValue = isc_mem_get(dctx->mctx, 123 attr->ulValueLen); 124 if (keyTemplate[6].pValue == NULL) 125 DST_RET(ISC_R_NOMEMORY); 126 memmove(keyTemplate[6].pValue, attr->pValue, 127 attr->ulValueLen); 128 keyTemplate[6].ulValueLen = attr->ulValueLen; 129 break; 130 case CKA_PUBLIC_EXPONENT: 131 INSIST(keyTemplate[7].type == attr->type); 132 keyTemplate[7].pValue = isc_mem_get(dctx->mctx, 133 attr->ulValueLen); 134 if (keyTemplate[7].pValue == NULL) 135 DST_RET(ISC_R_NOMEMORY); 136 memmove(keyTemplate[7].pValue, attr->pValue, 137 attr->ulValueLen); 138 keyTemplate[7].ulValueLen = attr->ulValueLen; 139 break; 140 case CKA_PRIVATE_EXPONENT: 141 INSIST(keyTemplate[8].type == attr->type); 142 keyTemplate[8].pValue = isc_mem_get(dctx->mctx, 143 attr->ulValueLen); 144 if (keyTemplate[8].pValue == NULL) 145 DST_RET(ISC_R_NOMEMORY); 146 memmove(keyTemplate[8].pValue, attr->pValue, 147 attr->ulValueLen); 148 keyTemplate[8].ulValueLen = attr->ulValueLen; 149 break; 150 case CKA_PRIME_1: 151 INSIST(keyTemplate[9].type == attr->type); 152 keyTemplate[9].pValue = isc_mem_get(dctx->mctx, 153 attr->ulValueLen); 154 if (keyTemplate[9].pValue == NULL) 155 DST_RET(ISC_R_NOMEMORY); 156 memmove(keyTemplate[9].pValue, attr->pValue, 157 attr->ulValueLen); 158 keyTemplate[9].ulValueLen = attr->ulValueLen; 159 break; 160 case CKA_PRIME_2: 161 INSIST(keyTemplate[10].type == attr->type); 162 keyTemplate[10].pValue = isc_mem_get(dctx->mctx, 163 attr->ulValueLen); 164 if (keyTemplate[10].pValue == NULL) 165 DST_RET(ISC_R_NOMEMORY); 166 memmove(keyTemplate[10].pValue, attr->pValue, 167 attr->ulValueLen); 168 keyTemplate[10].ulValueLen = attr->ulValueLen; 169 break; 170 case CKA_EXPONENT_1: 171 INSIST(keyTemplate[11].type == attr->type); 172 keyTemplate[11].pValue = isc_mem_get(dctx->mctx, 173 attr->ulValueLen); 174 if (keyTemplate[11].pValue == NULL) 175 DST_RET(ISC_R_NOMEMORY); 176 memmove(keyTemplate[11].pValue, attr->pValue, 177 attr->ulValueLen); 178 keyTemplate[11].ulValueLen = attr->ulValueLen; 179 break; 180 case CKA_EXPONENT_2: 181 INSIST(keyTemplate[12].type == attr->type); 182 keyTemplate[12].pValue = isc_mem_get(dctx->mctx, 183 attr->ulValueLen); 184 if (keyTemplate[12].pValue == NULL) 185 DST_RET(ISC_R_NOMEMORY); 186 memmove(keyTemplate[12].pValue, attr->pValue, 187 attr->ulValueLen); 188 keyTemplate[12].ulValueLen = attr->ulValueLen; 189 break; 190 case CKA_COEFFICIENT: 191 INSIST(keyTemplate[13].type == attr->type); 192 keyTemplate[13].pValue = isc_mem_get(dctx->mctx, 193 attr->ulValueLen); 194 if (keyTemplate[13].pValue == NULL) 195 DST_RET(ISC_R_NOMEMORY); 196 memmove(keyTemplate[13].pValue, attr->pValue, 197 attr->ulValueLen); 198 keyTemplate[13].ulValueLen = attr->ulValueLen; 199 break; 200 } 201 pk11_ctx->object = CK_INVALID_HANDLE; 202 pk11_ctx->ontoken = ISC_FALSE; 203 PK11_RET(pkcs_C_CreateObject, 204 (pk11_ctx->session, 205 keyTemplate, (CK_ULONG) 14, 206 &pk11_ctx->object), 207 ISC_R_FAILURE); 208 209 token_key: 210 211 switch (dctx->key->key_alg) { 212 case DST_ALG_RSAMD5: 213 mech.mechanism = CKM_MD5_RSA_PKCS; 214 break; 215 case DST_ALG_RSASHA1: 216 case DST_ALG_NSEC3RSASHA1: 217 mech.mechanism = CKM_SHA1_RSA_PKCS; 218 break; 219 case DST_ALG_RSASHA256: 220 mech.mechanism = CKM_SHA256_RSA_PKCS; 221 break; 222 case DST_ALG_RSASHA512: 223 mech.mechanism = CKM_SHA512_RSA_PKCS; 224 break; 225 default: 226 INSIST(0); 227 } 228 229 PK11_RET(pkcs_C_SignInit, 230 (pk11_ctx->session, &mech, pk11_ctx->object), 231 ISC_R_FAILURE); 232 233 dctx->ctxdata.pk11_ctx = pk11_ctx; 234 235 for (i = 6; i <= 13; i++) 236 if (keyTemplate[i].pValue != NULL) { 237 memset(keyTemplate[i].pValue, 0, 238 keyTemplate[i].ulValueLen); 239 isc_mem_put(dctx->mctx, 240 keyTemplate[i].pValue, 241 keyTemplate[i].ulValueLen); 242 } 243 244 return (ISC_R_SUCCESS); 245 246 err: 247 if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) 248 (void) pkcs_C_DestroyObject(pk11_ctx->session, 249 pk11_ctx->object); 250 for (i = 6; i <= 13; i++) 251 if (keyTemplate[i].pValue != NULL) { 252 memset(keyTemplate[i].pValue, 0, 253 keyTemplate[i].ulValueLen); 254 isc_mem_put(dctx->mctx, 255 keyTemplate[i].pValue, 256 keyTemplate[i].ulValueLen); 257 } 258 pk11_return_session(pk11_ctx); 259 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 260 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); 261 262 return (ret); 263 } 264 265 static isc_result_t 266 pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, 267 dst_context_t *dctx) { 268 CK_RV rv; 269 CK_MECHANISM mech = { 0, NULL, 0 }; 270 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; 271 CK_KEY_TYPE keyType = CKK_RSA; 272 CK_ATTRIBUTE keyTemplate[] = 273 { 274 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, 275 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 276 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 277 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 278 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, 279 { CKA_MODULUS, NULL, 0 }, 280 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 281 }; 282 CK_ATTRIBUTE *attr; 283 pk11_object_t *rsa; 284 pk11_context_t *pk11_ctx; 285 isc_result_t ret; 286 unsigned int i; 287 288 REQUIRE(key->key_alg == DST_ALG_RSAMD5 || 289 key->key_alg == DST_ALG_RSASHA1 || 290 key->key_alg == DST_ALG_NSEC3RSASHA1 || 291 key->key_alg == DST_ALG_RSASHA256 || 292 key->key_alg == DST_ALG_RSASHA512); 293 294 rsa = key->keydata.pkey; 295 296 pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, 297 sizeof(*pk11_ctx)); 298 if (pk11_ctx == NULL) 299 return (ISC_R_NOMEMORY); 300 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, 301 rsa->reqlogon, NULL, 302 pk11_get_best_token(OP_RSA)); 303 if (ret != ISC_R_SUCCESS) 304 goto err; 305 306 for (attr = pk11_attribute_first(rsa); 307 attr != NULL; 308 attr = pk11_attribute_next(rsa, attr)) 309 switch (attr->type) { 310 case CKA_MODULUS: 311 INSIST(keyTemplate[5].type == attr->type); 312 keyTemplate[5].pValue = isc_mem_get(dctx->mctx, 313 attr->ulValueLen); 314 if (keyTemplate[5].pValue == NULL) 315 DST_RET(ISC_R_NOMEMORY); 316 memmove(keyTemplate[5].pValue, attr->pValue, 317 attr->ulValueLen); 318 keyTemplate[5].ulValueLen = attr->ulValueLen; 319 break; 320 case CKA_PUBLIC_EXPONENT: 321 INSIST(keyTemplate[6].type == attr->type); 322 keyTemplate[6].pValue = isc_mem_get(dctx->mctx, 323 attr->ulValueLen); 324 if (keyTemplate[6].pValue == NULL) 325 DST_RET(ISC_R_NOMEMORY); 326 memmove(keyTemplate[6].pValue, attr->pValue, 327 attr->ulValueLen); 328 keyTemplate[6].ulValueLen = attr->ulValueLen; 329 if (pk11_numbits(attr->pValue, 330 attr->ulValueLen) > maxbits && 331 maxbits != 0) 332 DST_RET(DST_R_VERIFYFAILURE); 333 break; 334 } 335 pk11_ctx->object = CK_INVALID_HANDLE; 336 pk11_ctx->ontoken = ISC_FALSE; 337 PK11_RET(pkcs_C_CreateObject, 338 (pk11_ctx->session, 339 keyTemplate, (CK_ULONG) 7, 340 &pk11_ctx->object), 341 ISC_R_FAILURE); 342 343 switch (dctx->key->key_alg) { 344 case DST_ALG_RSAMD5: 345 mech.mechanism = CKM_MD5_RSA_PKCS; 346 break; 347 case DST_ALG_RSASHA1: 348 case DST_ALG_NSEC3RSASHA1: 349 mech.mechanism = CKM_SHA1_RSA_PKCS; 350 break; 351 case DST_ALG_RSASHA256: 352 mech.mechanism = CKM_SHA256_RSA_PKCS; 353 break; 354 case DST_ALG_RSASHA512: 355 mech.mechanism = CKM_SHA512_RSA_PKCS; 356 break; 357 default: 358 INSIST(0); 359 } 360 361 PK11_RET(pkcs_C_VerifyInit, 362 (pk11_ctx->session, &mech, pk11_ctx->object), 363 ISC_R_FAILURE); 364 365 dctx->ctxdata.pk11_ctx = pk11_ctx; 366 367 for (i = 5; i <= 6; i++) 368 if (keyTemplate[i].pValue != NULL) { 369 memset(keyTemplate[i].pValue, 0, 370 keyTemplate[i].ulValueLen); 371 isc_mem_put(dctx->mctx, 372 keyTemplate[i].pValue, 373 keyTemplate[i].ulValueLen); 374 } 375 376 return (ISC_R_SUCCESS); 377 378 err: 379 if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) 380 (void) pkcs_C_DestroyObject(pk11_ctx->session, 381 pk11_ctx->object); 382 for (i = 5; i <= 6; i++) 383 if (keyTemplate[i].pValue != NULL) { 384 memset(keyTemplate[i].pValue, 0, 385 keyTemplate[i].ulValueLen); 386 isc_mem_put(dctx->mctx, 387 keyTemplate[i].pValue, 388 keyTemplate[i].ulValueLen); 389 } 390 pk11_return_session(pk11_ctx); 391 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 392 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); 393 394 return (ret); 395 } 396 397 static isc_result_t 398 pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { 399 if (dctx->use == DO_SIGN) 400 return (pkcs11rsa_createctx_sign(key, dctx)); 401 else 402 return (pkcs11rsa_createctx_verify(key, 0U, dctx)); 403 } 404 405 static isc_result_t 406 pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) { 407 if (dctx->use == DO_SIGN) 408 return (pkcs11rsa_createctx_sign(key, dctx)); 409 else 410 return (pkcs11rsa_createctx_verify(key, 411 (unsigned) maxbits, dctx)); 412 } 413 414 static void 415 pkcs11rsa_destroyctx(dst_context_t *dctx) { 416 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; 417 418 if (pk11_ctx != NULL) { 419 if (!pk11_ctx->ontoken && 420 (pk11_ctx->object != CK_INVALID_HANDLE)) 421 (void) pkcs_C_DestroyObject(pk11_ctx->session, 422 pk11_ctx->object); 423 pk11_return_session(pk11_ctx); 424 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 425 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); 426 dctx->ctxdata.pk11_ctx = NULL; 427 } 428 } 429 430 static isc_result_t 431 pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) { 432 CK_RV rv; 433 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; 434 isc_result_t ret = ISC_R_SUCCESS; 435 436 if (dctx->use == DO_SIGN) 437 PK11_CALL(pkcs_C_SignUpdate, 438 (pk11_ctx->session, 439 (CK_BYTE_PTR) data->base, 440 (CK_ULONG) data->length), 441 ISC_R_FAILURE); 442 else 443 PK11_CALL(pkcs_C_VerifyUpdate, 444 (pk11_ctx->session, 445 (CK_BYTE_PTR) data->base, 446 (CK_ULONG) data->length), 447 ISC_R_FAILURE); 448 return (ret); 449 } 450 451 static isc_result_t 452 pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { 453 CK_RV rv; 454 CK_ULONG siglen = 0; 455 isc_region_t r; 456 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; 457 isc_result_t ret = ISC_R_SUCCESS; 458 459 PK11_RET(pkcs_C_SignFinal, 460 (pk11_ctx->session, NULL, &siglen), 461 DST_R_SIGNFAILURE); 462 463 isc_buffer_availableregion(sig, &r); 464 465 if (r.length < (unsigned int) siglen) 466 return (ISC_R_NOSPACE); 467 468 PK11_RET(pkcs_C_SignFinal, 469 (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), 470 DST_R_SIGNFAILURE); 471 472 isc_buffer_add(sig, (unsigned int) siglen); 473 474 err: 475 return (ret); 476 } 477 478 static isc_result_t 479 pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { 480 CK_RV rv; 481 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; 482 isc_result_t ret = ISC_R_SUCCESS; 483 484 PK11_CALL(pkcs_C_VerifyFinal, 485 (pk11_ctx->session, 486 (CK_BYTE_PTR) sig->base, 487 (CK_ULONG) sig->length), 488 DST_R_VERIFYFAILURE); 489 return (ret); 490 } 491 492 static isc_boolean_t 493 pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) { 494 pk11_object_t *rsa1, *rsa2; 495 CK_ATTRIBUTE *attr1, *attr2; 496 497 rsa1 = key1->keydata.pkey; 498 rsa2 = key2->keydata.pkey; 499 500 if ((rsa1 == NULL) && (rsa2 == NULL)) 501 return (ISC_TRUE); 502 else if ((rsa1 == NULL) || (rsa2 == NULL)) 503 return (ISC_FALSE); 504 505 attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS); 506 attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS); 507 if ((attr1 == NULL) && (attr2 == NULL)) 508 return (ISC_TRUE); 509 else if ((attr1 == NULL) || (attr2 == NULL) || 510 (attr1->ulValueLen != attr2->ulValueLen) || 511 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) 512 return (ISC_FALSE); 513 514 attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT); 515 attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT); 516 if ((attr1 == NULL) && (attr2 == NULL)) 517 return (ISC_TRUE); 518 else if ((attr1 == NULL) || (attr2 == NULL) || 519 (attr1->ulValueLen != attr2->ulValueLen) || 520 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) 521 return (ISC_FALSE); 522 523 attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT); 524 attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT); 525 if (((attr1 != NULL) || (attr2 != NULL)) && 526 ((attr1 == NULL) || (attr2 == NULL) || 527 (attr1->ulValueLen != attr2->ulValueLen) || 528 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) 529 return (ISC_FALSE); 530 531 if (!rsa1->ontoken && !rsa2->ontoken) 532 return (ISC_TRUE); 533 else if (rsa1->ontoken || rsa2->ontoken || 534 (rsa1->object != rsa2->object)) 535 return (ISC_FALSE); 536 537 return (ISC_TRUE); 538 } 539 540 static isc_result_t 541 pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { 542 CK_RV rv; 543 CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; 544 CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; 545 CK_ULONG bits = 0; 546 CK_BYTE pubexp[5]; 547 CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; 548 CK_KEY_TYPE keyType = CKK_RSA; 549 CK_ATTRIBUTE pubTemplate[] = 550 { 551 { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, 552 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 553 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 554 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 555 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, 556 { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, 557 { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } 558 }; 559 CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; 560 CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; 561 CK_ATTRIBUTE privTemplate[] = 562 { 563 { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, 564 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 565 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 566 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 567 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, 568 { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, 569 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, 570 }; 571 CK_ATTRIBUTE *attr; 572 pk11_object_t *rsa; 573 pk11_context_t *pk11_ctx; 574 isc_result_t ret; 575 unsigned int i; 576 577 UNUSED(callback); 578 579 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, 580 sizeof(*pk11_ctx)); 581 if (pk11_ctx == NULL) 582 return (ISC_R_NOMEMORY); 583 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, 584 ISC_FALSE, NULL, pk11_get_best_token(OP_RSA)); 585 if (ret != ISC_R_SUCCESS) 586 goto err; 587 588 bits = key->key_size; 589 if (exp == 0) { 590 /* RSA_F4 0x10001 */ 591 pubexp[0] = 1; 592 pubexp[1] = 0; 593 pubexp[2] = 1; 594 pubTemplate[6].ulValueLen = 3; 595 } else { 596 /* F5 0x100000001 */ 597 pubexp[0] = 1; 598 pubexp[1] = 0; 599 pubexp[2] = 0; 600 pubexp[3] = 0; 601 pubexp[4] = 1; 602 pubTemplate[6].ulValueLen = 5; 603 } 604 605 PK11_RET(pkcs_C_GenerateKeyPair, 606 (pk11_ctx->session, &mech, 607 pubTemplate, (CK_ULONG) 7, 608 privTemplate, (CK_ULONG) 7, 609 &pub, &priv), 610 DST_R_CRYPTOFAILURE); 611 612 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); 613 if (rsa == NULL) 614 DST_RET(ISC_R_NOMEMORY); 615 memset(rsa, 0, sizeof(*rsa)); 616 key->keydata.pkey = rsa; 617 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); 618 if (rsa->repr == NULL) 619 DST_RET(ISC_R_NOMEMORY); 620 memset(rsa->repr, 0, sizeof(*attr) * 8); 621 rsa->attrcnt = 8; 622 623 attr = rsa->repr; 624 attr[0].type = CKA_MODULUS; 625 attr[1].type = CKA_PUBLIC_EXPONENT; 626 attr[2].type = CKA_PRIVATE_EXPONENT; 627 attr[3].type = CKA_PRIME_1; 628 attr[4].type = CKA_PRIME_2; 629 attr[5].type = CKA_EXPONENT_1; 630 attr[6].type = CKA_EXPONENT_2; 631 attr[7].type = CKA_COEFFICIENT; 632 633 PK11_RET(pkcs_C_GetAttributeValue, 634 (pk11_ctx->session, pub, attr, 2), 635 DST_R_CRYPTOFAILURE); 636 for (i = 0; i <= 1; i++) { 637 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); 638 if (attr[i].pValue == NULL) 639 DST_RET(ISC_R_NOMEMORY); 640 memset(attr[i].pValue, 0, attr[i].ulValueLen); 641 } 642 PK11_RET(pkcs_C_GetAttributeValue, 643 (pk11_ctx->session, pub, attr, 2), 644 DST_R_CRYPTOFAILURE); 645 646 attr += 2; 647 PK11_RET(pkcs_C_GetAttributeValue, 648 (pk11_ctx->session, priv, attr, 6), 649 DST_R_CRYPTOFAILURE); 650 for (i = 0; i <= 5; i++) { 651 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); 652 if (attr[i].pValue == NULL) 653 DST_RET(ISC_R_NOMEMORY); 654 memset(attr[i].pValue, 0, attr[i].ulValueLen); 655 } 656 PK11_RET(pkcs_C_GetAttributeValue, 657 (pk11_ctx->session, priv, attr, 6), 658 DST_R_CRYPTOFAILURE); 659 660 (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); 661 (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); 662 pk11_return_session(pk11_ctx); 663 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 664 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 665 666 return (ISC_R_SUCCESS); 667 668 err: 669 pkcs11rsa_destroy(key); 670 if (priv != CK_INVALID_HANDLE) 671 (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); 672 if (pub != CK_INVALID_HANDLE) 673 (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); 674 pk11_return_session(pk11_ctx); 675 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 676 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 677 678 return (ret); 679 } 680 681 static isc_boolean_t 682 pkcs11rsa_isprivate(const dst_key_t *key) { 683 pk11_object_t *rsa = key->keydata.pkey; 684 CK_ATTRIBUTE *attr; 685 686 if (rsa == NULL) 687 return (ISC_FALSE); 688 attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT); 689 return (ISC_TF((attr != NULL) || rsa->ontoken)); 690 } 691 692 static void 693 pkcs11rsa_destroy(dst_key_t *key) { 694 pk11_object_t *rsa = key->keydata.pkey; 695 CK_ATTRIBUTE *attr; 696 697 if (rsa == NULL) 698 return; 699 700 INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken); 701 702 for (attr = pk11_attribute_first(rsa); 703 attr != NULL; 704 attr = pk11_attribute_next(rsa, attr)) 705 switch (attr->type) { 706 case CKA_LABEL: 707 case CKA_ID: 708 case CKA_MODULUS: 709 case CKA_PUBLIC_EXPONENT: 710 case CKA_PRIVATE_EXPONENT: 711 case CKA_PRIME_1: 712 case CKA_PRIME_2: 713 case CKA_EXPONENT_1: 714 case CKA_EXPONENT_2: 715 case CKA_COEFFICIENT: 716 if (attr->pValue != NULL) { 717 memset(attr->pValue, 0, attr->ulValueLen); 718 isc_mem_put(key->mctx, 719 attr->pValue, 720 attr->ulValueLen); 721 } 722 break; 723 } 724 if (rsa->repr != NULL) { 725 memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); 726 isc_mem_put(key->mctx, 727 rsa->repr, 728 rsa->attrcnt * sizeof(*attr)); 729 } 730 memset(rsa, 0, sizeof(*rsa)); 731 isc_mem_put(key->mctx, rsa, sizeof(*rsa)); 732 key->keydata.pkey = NULL; 733 } 734 735 static isc_result_t 736 pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) { 737 pk11_object_t *rsa; 738 CK_ATTRIBUTE *attr; 739 isc_region_t r; 740 unsigned int e_bytes = 0, mod_bytes = 0; 741 CK_BYTE *exponent = NULL, *modulus = NULL; 742 743 REQUIRE(key->keydata.pkey != NULL); 744 745 rsa = key->keydata.pkey; 746 747 for (attr = pk11_attribute_first(rsa); 748 attr != NULL; 749 attr = pk11_attribute_next(rsa, attr)) 750 switch (attr->type) { 751 case CKA_PUBLIC_EXPONENT: 752 exponent = (CK_BYTE *) attr->pValue; 753 e_bytes = (unsigned int) attr->ulValueLen; 754 break; 755 case CKA_MODULUS: 756 modulus = (CK_BYTE *) attr->pValue; 757 mod_bytes = (unsigned int) attr->ulValueLen; 758 break; 759 } 760 REQUIRE((exponent != NULL) && (modulus != NULL)); 761 762 isc_buffer_availableregion(data, &r); 763 764 if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ 765 if (r.length < 1) 766 return (ISC_R_NOSPACE); 767 isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); 768 isc_region_consume(&r, 1); 769 } else { 770 if (r.length < 3) 771 return (ISC_R_NOSPACE); 772 isc_buffer_putuint8(data, 0); 773 isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); 774 isc_region_consume(&r, 3); 775 } 776 777 if (r.length < e_bytes + mod_bytes) 778 return (ISC_R_NOSPACE); 779 780 memmove(r.base, exponent, e_bytes); 781 isc_region_consume(&r, e_bytes); 782 memmove(r.base, modulus, mod_bytes); 783 784 isc_buffer_add(data, e_bytes + mod_bytes); 785 786 return (ISC_R_SUCCESS); 787 } 788 789 static isc_result_t 790 pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { 791 pk11_object_t *rsa; 792 isc_region_t r; 793 unsigned int e_bytes, mod_bytes; 794 CK_BYTE *exponent = NULL, *modulus = NULL; 795 CK_ATTRIBUTE *attr; 796 unsigned int length; 797 798 isc_buffer_remainingregion(data, &r); 799 if (r.length == 0) 800 return (ISC_R_SUCCESS); 801 length = r.length; 802 803 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); 804 if (rsa == NULL) 805 return (ISC_R_NOMEMORY); 806 807 memset(rsa, 0, sizeof(*rsa)); 808 809 e_bytes = *r.base; 810 isc_region_consume(&r, 1); 811 812 if (e_bytes == 0) { 813 if (r.length < 2) { 814 memset(rsa, 0, sizeof(*rsa)); 815 isc_mem_put(key->mctx, rsa, sizeof(*rsa)); 816 return (DST_R_INVALIDPUBLICKEY); 817 } 818 e_bytes = (*r.base) << 8; 819 isc_region_consume(&r, 1); 820 e_bytes += *r.base; 821 isc_region_consume(&r, 1); 822 } 823 824 if (r.length < e_bytes) { 825 memset(rsa, 0, sizeof(*rsa)); 826 isc_mem_put(key->mctx, rsa, sizeof(*rsa)); 827 return (DST_R_INVALIDPUBLICKEY); 828 } 829 exponent = r.base; 830 isc_region_consume(&r, e_bytes); 831 modulus = r.base; 832 mod_bytes = r.length; 833 834 key->key_size = pk11_numbits(modulus, mod_bytes); 835 836 isc_buffer_forward(data, length); 837 838 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); 839 if (rsa->repr == NULL) 840 goto nomemory; 841 memset(rsa->repr, 0, sizeof(*attr) * 2); 842 rsa->attrcnt = 2; 843 attr = rsa->repr; 844 attr[0].type = CKA_MODULUS; 845 attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); 846 if (attr[0].pValue == NULL) 847 goto nomemory; 848 memmove(attr[0].pValue, modulus, mod_bytes); 849 attr[0].ulValueLen = (CK_ULONG) mod_bytes; 850 attr[1].type = CKA_PUBLIC_EXPONENT; 851 attr[1].pValue = isc_mem_get(key->mctx, e_bytes); 852 if (attr[1].pValue == NULL) 853 goto nomemory; 854 memmove(attr[1].pValue, exponent, e_bytes); 855 attr[1].ulValueLen = (CK_ULONG) e_bytes; 856 857 key->keydata.pkey = rsa; 858 859 return (ISC_R_SUCCESS); 860 861 nomemory: 862 for (attr = pk11_attribute_first(rsa); 863 attr != NULL; 864 attr = pk11_attribute_next(rsa, attr)) 865 switch (attr->type) { 866 case CKA_MODULUS: 867 case CKA_PUBLIC_EXPONENT: 868 if (attr->pValue != NULL) { 869 memset(attr->pValue, 0, attr->ulValueLen); 870 isc_mem_put(key->mctx, 871 attr->pValue, 872 attr->ulValueLen); 873 } 874 break; 875 } 876 if (rsa->repr != NULL) { 877 memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); 878 isc_mem_put(key->mctx, 879 rsa->repr, 880 rsa->attrcnt * sizeof(*attr)); 881 } 882 memset(rsa, 0, sizeof(*rsa)); 883 isc_mem_put(key->mctx, rsa, sizeof(*rsa)); 884 return (ISC_R_NOMEMORY); 885 } 886 887 static isc_result_t 888 pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { 889 int i; 890 pk11_object_t *rsa; 891 CK_ATTRIBUTE *attr; 892 CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; 893 CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; 894 CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; 895 dst_private_t priv; 896 unsigned char *bufs[10]; 897 isc_result_t result; 898 899 if (key->keydata.pkey == NULL) 900 return (DST_R_NULLKEY); 901 902 if (key->external) { 903 priv.nelements = 0; 904 return (dst__privstruct_writefile(key, &priv, directory)); 905 } 906 907 rsa = key->keydata.pkey; 908 909 for (attr = pk11_attribute_first(rsa); 910 attr != NULL; 911 attr = pk11_attribute_next(rsa, attr)) 912 switch (attr->type) { 913 case CKA_MODULUS: 914 modulus = attr; 915 break; 916 case CKA_PUBLIC_EXPONENT: 917 exponent = attr; 918 break; 919 case CKA_PRIVATE_EXPONENT: 920 d = attr; 921 break; 922 case CKA_PRIME_1: 923 p = attr; 924 break; 925 case CKA_PRIME_2: 926 q = attr; 927 break; 928 case CKA_EXPONENT_1: 929 dmp1 = attr; 930 break; 931 case CKA_EXPONENT_2: 932 dmq1 = attr; 933 break; 934 case CKA_COEFFICIENT: 935 iqmp = attr; 936 break; 937 } 938 if ((modulus == NULL) || (exponent == NULL)) 939 return (DST_R_NULLKEY); 940 941 memset(bufs, 0, sizeof(bufs)); 942 943 for (i = 0; i < 10; i++) { 944 bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); 945 if (bufs[i] == NULL) { 946 result = ISC_R_NOMEMORY; 947 goto fail; 948 } 949 memset(bufs[i], 0, modulus->ulValueLen); 950 } 951 952 i = 0; 953 954 priv.elements[i].tag = TAG_RSA_MODULUS; 955 priv.elements[i].length = (unsigned short) modulus->ulValueLen; 956 memmove(bufs[i], modulus->pValue, modulus->ulValueLen); 957 priv.elements[i].data = bufs[i]; 958 i++; 959 960 priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; 961 priv.elements[i].length = (unsigned short) exponent->ulValueLen; 962 memmove(bufs[i], exponent->pValue, exponent->ulValueLen); 963 priv.elements[i].data = bufs[i]; 964 i++; 965 966 if (d != NULL) { 967 priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; 968 priv.elements[i].length = (unsigned short) d->ulValueLen; 969 memmove(bufs[i], d->pValue, d->ulValueLen); 970 priv.elements[i].data = bufs[i]; 971 i++; 972 } 973 974 if (p != NULL) { 975 priv.elements[i].tag = TAG_RSA_PRIME1; 976 priv.elements[i].length = (unsigned short) p->ulValueLen; 977 memmove(bufs[i], p->pValue, p->ulValueLen); 978 priv.elements[i].data = bufs[i]; 979 i++; 980 } 981 982 if (q != NULL) { 983 priv.elements[i].tag = TAG_RSA_PRIME2; 984 priv.elements[i].length = (unsigned short) q->ulValueLen; 985 memmove(bufs[i], q->pValue, q->ulValueLen); 986 priv.elements[i].data = bufs[i]; 987 i++; 988 } 989 990 if (dmp1 != NULL) { 991 priv.elements[i].tag = TAG_RSA_EXPONENT1; 992 priv.elements[i].length = (unsigned short) dmp1->ulValueLen; 993 memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen); 994 priv.elements[i].data = bufs[i]; 995 i++; 996 } 997 998 if (dmq1 != NULL) { 999 priv.elements[i].tag = TAG_RSA_EXPONENT2; 1000 priv.elements[i].length = (unsigned short) dmq1->ulValueLen; 1001 memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen); 1002 priv.elements[i].data = bufs[i]; 1003 i++; 1004 } 1005 1006 if (iqmp != NULL) { 1007 priv.elements[i].tag = TAG_RSA_COEFFICIENT; 1008 priv.elements[i].length = (unsigned short) iqmp->ulValueLen; 1009 memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen); 1010 priv.elements[i].data = bufs[i]; 1011 i++; 1012 } 1013 1014 if (key->engine != NULL) { 1015 priv.elements[i].tag = TAG_RSA_ENGINE; 1016 priv.elements[i].length = strlen(key->engine) + 1; 1017 priv.elements[i].data = (unsigned char *)key->engine; 1018 i++; 1019 } 1020 1021 if (key->label != NULL) { 1022 priv.elements[i].tag = TAG_RSA_LABEL; 1023 priv.elements[i].length = strlen(key->label) + 1; 1024 priv.elements[i].data = (unsigned char *)key->label; 1025 i++; 1026 } 1027 1028 priv.nelements = i; 1029 result = dst__privstruct_writefile(key, &priv, directory); 1030 fail: 1031 for (i = 0; i < 10; i++) { 1032 if (bufs[i] == NULL) 1033 break; 1034 memset(bufs[i], 0, modulus->ulValueLen); 1035 isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); 1036 } 1037 return (result); 1038 } 1039 1040 static isc_result_t 1041 pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, 1042 dst_key_t *pub) 1043 { 1044 CK_RV rv; 1045 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; 1046 CK_KEY_TYPE keyType = CKK_RSA; 1047 CK_ATTRIBUTE searchTemplate[] = 1048 { 1049 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, 1050 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 1051 { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, 1052 { CKA_LABEL, NULL, 0 } 1053 }; 1054 CK_ULONG cnt; 1055 CK_ATTRIBUTE *attr; 1056 CK_ATTRIBUTE *pubattr; 1057 pk11_object_t *rsa; 1058 pk11_object_t *pubrsa; 1059 pk11_context_t *pk11_ctx = NULL; 1060 isc_result_t ret; 1061 1062 if (label == NULL) 1063 return (DST_R_NOENGINE); 1064 1065 rsa = key->keydata.pkey; 1066 pubrsa = pub->keydata.pkey; 1067 1068 rsa->object = CK_INVALID_HANDLE; 1069 rsa->ontoken = ISC_TRUE; 1070 rsa->reqlogon = ISC_TRUE; 1071 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); 1072 if (rsa->repr == NULL) 1073 return (ISC_R_NOMEMORY); 1074 memset(rsa->repr, 0, sizeof(*attr) * 2); 1075 rsa->attrcnt = 2; 1076 attr = rsa->repr; 1077 1078 attr->type = CKA_MODULUS; 1079 pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); 1080 attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); 1081 if (attr->pValue == NULL) 1082 DST_RET(ISC_R_NOMEMORY); 1083 memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); 1084 attr->ulValueLen = pubattr->ulValueLen; 1085 attr++; 1086 1087 attr->type = CKA_PUBLIC_EXPONENT; 1088 pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); 1089 attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); 1090 if (attr->pValue == NULL) 1091 DST_RET(ISC_R_NOMEMORY); 1092 memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); 1093 attr->ulValueLen = pubattr->ulValueLen; 1094 1095 ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); 1096 if (ret != ISC_R_SUCCESS) 1097 goto err; 1098 1099 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, 1100 sizeof(*pk11_ctx)); 1101 if (pk11_ctx == NULL) 1102 DST_RET(ISC_R_NOMEMORY); 1103 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, 1104 rsa->reqlogon, NULL, rsa->slot); 1105 if (ret != ISC_R_SUCCESS) 1106 goto err; 1107 1108 attr = pk11_attribute_bytype(rsa, CKA_LABEL); 1109 if (attr == NULL) { 1110 attr = pk11_attribute_bytype(rsa, CKA_ID); 1111 INSIST(attr != NULL); 1112 searchTemplate[3].type = CKA_ID; 1113 } 1114 searchTemplate[3].pValue = attr->pValue; 1115 searchTemplate[3].ulValueLen = attr->ulValueLen; 1116 1117 PK11_RET(pkcs_C_FindObjectsInit, 1118 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), 1119 DST_R_CRYPTOFAILURE); 1120 PK11_RET(pkcs_C_FindObjects, 1121 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), 1122 DST_R_CRYPTOFAILURE); 1123 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); 1124 if (cnt == 0) 1125 DST_RET(ISC_R_NOTFOUND); 1126 if (cnt > 1) 1127 DST_RET(ISC_R_EXISTS); 1128 1129 if (engine != NULL) { 1130 key->engine = isc_mem_strdup(key->mctx, engine); 1131 if (key->engine == NULL) 1132 DST_RET(ISC_R_NOMEMORY); 1133 } 1134 1135 key->label = isc_mem_strdup(key->mctx, label); 1136 if (key->label == NULL) 1137 DST_RET(ISC_R_NOMEMORY); 1138 1139 pk11_return_session(pk11_ctx); 1140 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 1141 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 1142 1143 attr = pk11_attribute_bytype(rsa, CKA_MODULUS); 1144 INSIST(attr != NULL); 1145 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); 1146 1147 return (ISC_R_SUCCESS); 1148 1149 err: 1150 if (pk11_ctx != NULL) { 1151 pk11_return_session(pk11_ctx); 1152 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 1153 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 1154 } 1155 1156 return (ret); 1157 } 1158 1159 static isc_result_t 1160 rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) { 1161 CK_ATTRIBUTE *pubattr, *privattr; 1162 CK_BYTE *priv_exp = NULL, *priv_mod = NULL; 1163 CK_BYTE *pub_exp = NULL, *pub_mod = NULL; 1164 unsigned int priv_explen = 0, priv_modlen = 0; 1165 unsigned int pub_explen = 0, pub_modlen = 0; 1166 1167 REQUIRE(rsa != NULL && pubrsa != NULL); 1168 1169 privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); 1170 INSIST(privattr != NULL); 1171 priv_exp = privattr->pValue; 1172 priv_explen = privattr->ulValueLen; 1173 1174 pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); 1175 INSIST(pubattr != NULL); 1176 pub_exp = pubattr->pValue; 1177 pub_explen = pubattr->ulValueLen; 1178 1179 if (priv_exp != NULL) { 1180 if (priv_explen != pub_explen) 1181 return (DST_R_INVALIDPRIVATEKEY); 1182 if (memcmp(priv_exp, pub_exp, pub_explen) != 0) 1183 return (DST_R_INVALIDPRIVATEKEY); 1184 } else { 1185 privattr->pValue = pub_exp; 1186 privattr->ulValueLen = pub_explen; 1187 pubattr->pValue = NULL; 1188 pubattr->ulValueLen = 0; 1189 } 1190 1191 if (privattr->pValue == NULL) 1192 return (DST_R_INVALIDPRIVATEKEY); 1193 1194 privattr = pk11_attribute_bytype(rsa, CKA_MODULUS); 1195 INSIST(privattr != NULL); 1196 priv_mod = privattr->pValue; 1197 priv_modlen = privattr->ulValueLen; 1198 1199 pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); 1200 INSIST(pubattr != NULL); 1201 pub_mod = pubattr->pValue; 1202 pub_modlen = pubattr->ulValueLen; 1203 1204 if (priv_mod != NULL) { 1205 if (priv_modlen != pub_modlen) 1206 return (DST_R_INVALIDPRIVATEKEY); 1207 if (memcmp(priv_mod, pub_mod, pub_modlen) != 0) 1208 return (DST_R_INVALIDPRIVATEKEY); 1209 } else { 1210 privattr->pValue = pub_mod; 1211 privattr->ulValueLen = pub_modlen; 1212 pubattr->pValue = NULL; 1213 pubattr->ulValueLen = 0; 1214 } 1215 1216 if (privattr->pValue == NULL) 1217 return (DST_R_INVALIDPRIVATEKEY); 1218 1219 return (ISC_R_SUCCESS); 1220 } 1221 1222 static isc_result_t 1223 pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 1224 dst_private_t priv; 1225 isc_result_t ret; 1226 int i; 1227 pk11_object_t *rsa; 1228 CK_ATTRIBUTE *attr; 1229 isc_mem_t *mctx = key->mctx; 1230 const char *engine = NULL, *label = NULL; 1231 1232 /* read private key file */ 1233 ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); 1234 if (ret != ISC_R_SUCCESS) 1235 return (ret); 1236 1237 if (key->external) { 1238 if (priv.nelements != 0) 1239 DST_RET(DST_R_INVALIDPRIVATEKEY); 1240 if (pub == NULL) 1241 DST_RET(DST_R_INVALIDPRIVATEKEY); 1242 1243 key->keydata.pkey = pub->keydata.pkey; 1244 pub->keydata.pkey = NULL; 1245 key->key_size = pub->key_size; 1246 1247 dst__privstruct_free(&priv, mctx); 1248 memset(&priv, 0, sizeof(priv)); 1249 1250 return (ISC_R_SUCCESS); 1251 } 1252 1253 for (i = 0; i < priv.nelements; i++) { 1254 switch (priv.elements[i].tag) { 1255 case TAG_RSA_ENGINE: 1256 engine = (char *)priv.elements[i].data; 1257 break; 1258 case TAG_RSA_LABEL: 1259 label = (char *)priv.elements[i].data; 1260 break; 1261 default: 1262 break; 1263 } 1264 } 1265 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); 1266 if (rsa == NULL) 1267 DST_RET(ISC_R_NOMEMORY); 1268 memset(rsa, 0, sizeof(*rsa)); 1269 key->keydata.pkey = rsa; 1270 1271 /* Is this key is stored in a HSM? See if we can fetch it. */ 1272 if ((label != NULL) || (engine != NULL)) { 1273 ret = pkcs11rsa_fetch(key, engine, label, pub); 1274 if (ret != ISC_R_SUCCESS) 1275 goto err; 1276 dst__privstruct_free(&priv, mctx); 1277 memset(&priv, 0, sizeof(priv)); 1278 return (ret); 1279 } 1280 1281 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); 1282 if (rsa->repr == NULL) 1283 DST_RET(ISC_R_NOMEMORY); 1284 memset(rsa->repr, 0, sizeof(*attr) * 8); 1285 rsa->attrcnt = 8; 1286 attr = rsa->repr; 1287 attr[0].type = CKA_MODULUS; 1288 attr[1].type = CKA_PUBLIC_EXPONENT; 1289 attr[2].type = CKA_PRIVATE_EXPONENT; 1290 attr[3].type = CKA_PRIME_1; 1291 attr[4].type = CKA_PRIME_2; 1292 attr[5].type = CKA_EXPONENT_1; 1293 attr[6].type = CKA_EXPONENT_2; 1294 attr[7].type = CKA_COEFFICIENT; 1295 1296 for (i = 0; i < priv.nelements; i++) { 1297 CK_BYTE *bn; 1298 1299 switch (priv.elements[i].tag) { 1300 case TAG_RSA_ENGINE: 1301 continue; 1302 case TAG_RSA_LABEL: 1303 continue; 1304 default: 1305 bn = isc_mem_get(key->mctx, priv.elements[i].length); 1306 if (bn == NULL) 1307 DST_RET(ISC_R_NOMEMORY); 1308 memmove(bn, priv.elements[i].data, 1309 priv.elements[i].length); 1310 } 1311 1312 switch (priv.elements[i].tag) { 1313 case TAG_RSA_MODULUS: 1314 attr = pk11_attribute_bytype(rsa, CKA_MODULUS); 1315 INSIST(attr != NULL); 1316 attr->pValue = bn; 1317 attr->ulValueLen = priv.elements[i].length; 1318 break; 1319 case TAG_RSA_PUBLICEXPONENT: 1320 attr = pk11_attribute_bytype(rsa, 1321 CKA_PUBLIC_EXPONENT); 1322 INSIST(attr != NULL); 1323 attr->pValue = bn; 1324 attr->ulValueLen = priv.elements[i].length; 1325 break; 1326 case TAG_RSA_PRIVATEEXPONENT: 1327 attr = pk11_attribute_bytype(rsa, 1328 CKA_PRIVATE_EXPONENT); 1329 INSIST(attr != NULL); 1330 attr->pValue = bn; 1331 attr->ulValueLen = priv.elements[i].length; 1332 break; 1333 case TAG_RSA_PRIME1: 1334 attr = pk11_attribute_bytype(rsa, CKA_PRIME_1); 1335 INSIST(attr != NULL); 1336 attr->pValue = bn; 1337 attr->ulValueLen = priv.elements[i].length; 1338 break; 1339 case TAG_RSA_PRIME2: 1340 attr = pk11_attribute_bytype(rsa, CKA_PRIME_2); 1341 INSIST(attr != NULL); 1342 attr->pValue = bn; 1343 attr->ulValueLen = priv.elements[i].length; 1344 break; 1345 case TAG_RSA_EXPONENT1: 1346 attr = pk11_attribute_bytype(rsa, 1347 CKA_EXPONENT_1); 1348 INSIST(attr != NULL); 1349 attr->pValue = bn; 1350 attr->ulValueLen = priv.elements[i].length; 1351 break; 1352 case TAG_RSA_EXPONENT2: 1353 attr = pk11_attribute_bytype(rsa, 1354 CKA_EXPONENT_2); 1355 INSIST(attr != NULL); 1356 attr->pValue = bn; 1357 attr->ulValueLen = priv.elements[i].length; 1358 break; 1359 case TAG_RSA_COEFFICIENT: 1360 attr = pk11_attribute_bytype(rsa, 1361 CKA_COEFFICIENT); 1362 INSIST(attr != NULL); 1363 attr->pValue = bn; 1364 attr->ulValueLen = priv.elements[i].length; 1365 break; 1366 } 1367 } 1368 1369 if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS) 1370 DST_RET(DST_R_INVALIDPRIVATEKEY); 1371 1372 attr = pk11_attribute_bytype(rsa, CKA_MODULUS); 1373 INSIST(attr != NULL); 1374 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); 1375 1376 attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); 1377 INSIST(attr != NULL); 1378 if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) 1379 DST_RET(ISC_R_RANGE); 1380 1381 dst__privstruct_free(&priv, mctx); 1382 memset(&priv, 0, sizeof(priv)); 1383 1384 return (ISC_R_SUCCESS); 1385 1386 err: 1387 pkcs11rsa_destroy(key); 1388 dst__privstruct_free(&priv, mctx); 1389 memset(&priv, 0, sizeof(priv)); 1390 return (ret); 1391 } 1392 1393 static isc_result_t 1394 pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, 1395 const char *pin) 1396 { 1397 CK_RV rv; 1398 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; 1399 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; 1400 CK_KEY_TYPE keyType = CKK_RSA; 1401 CK_ATTRIBUTE searchTemplate[] = 1402 { 1403 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, 1404 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, 1405 { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, 1406 { CKA_LABEL, NULL, 0 } 1407 }; 1408 CK_ULONG cnt; 1409 CK_ATTRIBUTE *attr; 1410 pk11_object_t *rsa; 1411 pk11_context_t *pk11_ctx = NULL; 1412 isc_result_t ret; 1413 unsigned int i; 1414 1415 UNUSED(pin); 1416 1417 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); 1418 if (rsa == NULL) 1419 return (ISC_R_NOMEMORY); 1420 memset(rsa, 0, sizeof(*rsa)); 1421 rsa->object = CK_INVALID_HANDLE; 1422 rsa->ontoken = ISC_TRUE; 1423 rsa->reqlogon = ISC_TRUE; 1424 key->keydata.pkey = rsa; 1425 1426 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); 1427 if (rsa->repr == NULL) 1428 DST_RET(ISC_R_NOMEMORY); 1429 memset(rsa->repr, 0, sizeof(*attr) * 2); 1430 rsa->attrcnt = 2; 1431 attr = rsa->repr; 1432 attr[0].type = CKA_MODULUS; 1433 attr[1].type = CKA_PUBLIC_EXPONENT; 1434 1435 ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); 1436 if (ret != ISC_R_SUCCESS) 1437 goto err; 1438 1439 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, 1440 sizeof(*pk11_ctx)); 1441 if (pk11_ctx == NULL) 1442 DST_RET(ISC_R_NOMEMORY); 1443 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, 1444 rsa->reqlogon, NULL, rsa->slot); 1445 if (ret != ISC_R_SUCCESS) 1446 goto err; 1447 1448 attr = pk11_attribute_bytype(rsa, CKA_LABEL); 1449 if (attr == NULL) { 1450 attr = pk11_attribute_bytype(rsa, CKA_ID); 1451 INSIST(attr != NULL); 1452 searchTemplate[3].type = CKA_ID; 1453 } 1454 searchTemplate[3].pValue = attr->pValue; 1455 searchTemplate[3].ulValueLen = attr->ulValueLen; 1456 1457 PK11_RET(pkcs_C_FindObjectsInit, 1458 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), 1459 DST_R_CRYPTOFAILURE); 1460 PK11_RET(pkcs_C_FindObjects, 1461 (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), 1462 DST_R_CRYPTOFAILURE); 1463 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); 1464 if (cnt == 0) 1465 DST_RET(ISC_R_NOTFOUND); 1466 if (cnt > 1) 1467 DST_RET(ISC_R_EXISTS); 1468 1469 attr = rsa->repr; 1470 PK11_RET(pkcs_C_GetAttributeValue, 1471 (pk11_ctx->session, hKey, attr, 2), 1472 DST_R_CRYPTOFAILURE); 1473 for (i = 0; i <= 1; i++) { 1474 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); 1475 if (attr[i].pValue == NULL) 1476 DST_RET(ISC_R_NOMEMORY); 1477 memset(attr[i].pValue, 0, attr[i].ulValueLen); 1478 } 1479 PK11_RET(pkcs_C_GetAttributeValue, 1480 (pk11_ctx->session, hKey, attr, 2), 1481 DST_R_CRYPTOFAILURE); 1482 1483 keyClass = CKO_PRIVATE_KEY; 1484 PK11_RET(pkcs_C_FindObjectsInit, 1485 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), 1486 DST_R_CRYPTOFAILURE); 1487 PK11_RET(pkcs_C_FindObjects, 1488 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), 1489 DST_R_CRYPTOFAILURE); 1490 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); 1491 if (cnt == 0) 1492 DST_RET(ISC_R_NOTFOUND); 1493 if (cnt > 1) 1494 DST_RET(ISC_R_EXISTS); 1495 1496 if (engine != NULL) { 1497 key->engine = isc_mem_strdup(key->mctx, engine); 1498 if (key->engine == NULL) 1499 DST_RET(ISC_R_NOMEMORY); 1500 } 1501 1502 key->label = isc_mem_strdup(key->mctx, label); 1503 if (key->label == NULL) 1504 DST_RET(ISC_R_NOMEMORY); 1505 1506 attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); 1507 INSIST(attr != NULL); 1508 if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) 1509 DST_RET(ISC_R_RANGE); 1510 1511 attr = pk11_attribute_bytype(rsa, CKA_MODULUS); 1512 INSIST(attr != NULL); 1513 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); 1514 1515 pk11_return_session(pk11_ctx); 1516 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 1517 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 1518 1519 return (ISC_R_SUCCESS); 1520 1521 err: 1522 pkcs11rsa_destroy(key); 1523 if (pk11_ctx != NULL) { 1524 pk11_return_session(pk11_ctx); 1525 memset(pk11_ctx, 0, sizeof(*pk11_ctx)); 1526 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); 1527 } 1528 1529 return (ret); 1530 } 1531 1532 static dst_func_t pkcs11rsa_functions = { 1533 pkcs11rsa_createctx, 1534 pkcs11rsa_createctx2, 1535 pkcs11rsa_destroyctx, 1536 pkcs11rsa_adddata, 1537 pkcs11rsa_sign, 1538 pkcs11rsa_verify, 1539 NULL, /*%< verify2 */ 1540 NULL, /*%< computesecret */ 1541 pkcs11rsa_compare, 1542 NULL, /*%< paramcompare */ 1543 pkcs11rsa_generate, 1544 pkcs11rsa_isprivate, 1545 pkcs11rsa_destroy, 1546 pkcs11rsa_todns, 1547 pkcs11rsa_fromdns, 1548 pkcs11rsa_tofile, 1549 pkcs11rsa_parse, 1550 NULL, /*%< cleanup */ 1551 pkcs11rsa_fromlabel, 1552 NULL, /*%< dump */ 1553 NULL, /*%< restore */ 1554 }; 1555 1556 isc_result_t 1557 dst__pkcs11rsa_init(dst_func_t **funcp) { 1558 REQUIRE(funcp != NULL); 1559 1560 if (*funcp == NULL) 1561 *funcp = &pkcs11rsa_functions; 1562 return (ISC_R_SUCCESS); 1563 } 1564 1565 #else /* PKCS11CRYPTO */ 1566 1567 #include <isc/util.h> 1568 1569 EMPTY_TRANSLATION_UNIT 1570 1571 #endif /* PKCS11CRYPTO */ 1572 /*! \file */ 1573