00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef PKCS11CRYPTO
00020
00021 #include <config.h>
00022
00023 #include <isc/entropy.h>
00024 #include <isc/md5.h>
00025 #include <isc/sha1.h>
00026 #include <isc/sha2.h>
00027 #include <isc/mem.h>
00028 #include <isc/string.h>
00029 #include <isc/util.h>
00030
00031 #include <dst/result.h>
00032
00033 #include "dst_internal.h"
00034 #include "dst_parse.h"
00035 #include "dst_pkcs11.h"
00036
00037 #include <pk11/internal.h>
00038
00039
00040
00041
00042 #ifndef RSA_MAX_PUBEXP_BITS
00043 #define RSA_MAX_PUBEXP_BITS 35
00044 #endif
00045
00046 #define DST_RET(a) {ret = a; goto err;}
00047
00048 static CK_BBOOL truevalue = TRUE;
00049 static CK_BBOOL falsevalue = FALSE;
00050
00051 static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data);
00052 static void pkcs11rsa_destroy(dst_key_t *key);
00053 static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine,
00054 const char *label, dst_key_t *pub);
00055
00056 static isc_result_t
00057 pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
00058 CK_RV rv;
00059 CK_MECHANISM mech = { 0, NULL, 0 };
00060 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
00061 CK_KEY_TYPE keyType = CKK_RSA;
00062 CK_ATTRIBUTE keyTemplate[] =
00063 {
00064 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00065 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00066 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00067 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00068 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00069 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00070 { CKA_MODULUS, NULL, 0 },
00071 { CKA_PUBLIC_EXPONENT, NULL, 0 },
00072 { CKA_PRIVATE_EXPONENT, NULL, 0 },
00073 { CKA_PRIME_1, NULL, 0 },
00074 { CKA_PRIME_2, NULL, 0 },
00075 { CKA_EXPONENT_1, NULL, 0 },
00076 { CKA_EXPONENT_2, NULL, 0 },
00077 { CKA_COEFFICIENT, NULL, 0 }
00078 };
00079 CK_ATTRIBUTE *attr;
00080 CK_SLOT_ID slotid;
00081 pk11_object_t *rsa;
00082 pk11_context_t *pk11_ctx;
00083 isc_result_t ret;
00084 unsigned int i;
00085
00086 REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
00087 key->key_alg == DST_ALG_RSASHA1 ||
00088 key->key_alg == DST_ALG_NSEC3RSASHA1 ||
00089 key->key_alg == DST_ALG_RSASHA256 ||
00090 key->key_alg == DST_ALG_RSASHA512);
00091
00092 rsa = key->keydata.pkey;
00093
00094 pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
00095 sizeof(*pk11_ctx));
00096 if (pk11_ctx == NULL)
00097 return (ISC_R_NOMEMORY);
00098 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00099 if (rsa->ontoken)
00100 slotid = rsa->slot;
00101 else
00102 slotid = pk11_get_best_token(OP_RSA);
00103 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
00104 rsa->reqlogon, NULL, slotid);
00105 if (ret != ISC_R_SUCCESS)
00106 goto err;
00107
00108 if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
00109 pk11_ctx->ontoken = rsa->ontoken;
00110 pk11_ctx->object = rsa->object;
00111 goto token_key;
00112 }
00113
00114 for (attr = pk11_attribute_first(rsa);
00115 attr != NULL;
00116 attr = pk11_attribute_next(rsa, attr))
00117 switch (attr->type) {
00118 case CKA_MODULUS:
00119 INSIST(keyTemplate[6].type == attr->type);
00120 keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
00121 attr->ulValueLen);
00122 if (keyTemplate[6].pValue == NULL)
00123 DST_RET(ISC_R_NOMEMORY);
00124 memmove(keyTemplate[6].pValue, attr->pValue,
00125 attr->ulValueLen);
00126 keyTemplate[6].ulValueLen = attr->ulValueLen;
00127 break;
00128 case CKA_PUBLIC_EXPONENT:
00129 INSIST(keyTemplate[7].type == attr->type);
00130 keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
00131 attr->ulValueLen);
00132 if (keyTemplate[7].pValue == NULL)
00133 DST_RET(ISC_R_NOMEMORY);
00134 memmove(keyTemplate[7].pValue, attr->pValue,
00135 attr->ulValueLen);
00136 keyTemplate[7].ulValueLen = attr->ulValueLen;
00137 break;
00138 case CKA_PRIVATE_EXPONENT:
00139 INSIST(keyTemplate[8].type == attr->type);
00140 keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
00141 attr->ulValueLen);
00142 if (keyTemplate[8].pValue == NULL)
00143 DST_RET(ISC_R_NOMEMORY);
00144 memmove(keyTemplate[8].pValue, attr->pValue,
00145 attr->ulValueLen);
00146 keyTemplate[8].ulValueLen = attr->ulValueLen;
00147 break;
00148 case CKA_PRIME_1:
00149 INSIST(keyTemplate[9].type == attr->type);
00150 keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
00151 attr->ulValueLen);
00152 if (keyTemplate[9].pValue == NULL)
00153 DST_RET(ISC_R_NOMEMORY);
00154 memmove(keyTemplate[9].pValue, attr->pValue,
00155 attr->ulValueLen);
00156 keyTemplate[9].ulValueLen = attr->ulValueLen;
00157 break;
00158 case CKA_PRIME_2:
00159 INSIST(keyTemplate[10].type == attr->type);
00160 keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
00161 attr->ulValueLen);
00162 if (keyTemplate[10].pValue == NULL)
00163 DST_RET(ISC_R_NOMEMORY);
00164 memmove(keyTemplate[10].pValue, attr->pValue,
00165 attr->ulValueLen);
00166 keyTemplate[10].ulValueLen = attr->ulValueLen;
00167 break;
00168 case CKA_EXPONENT_1:
00169 INSIST(keyTemplate[11].type == attr->type);
00170 keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
00171 attr->ulValueLen);
00172 if (keyTemplate[11].pValue == NULL)
00173 DST_RET(ISC_R_NOMEMORY);
00174 memmove(keyTemplate[11].pValue, attr->pValue,
00175 attr->ulValueLen);
00176 keyTemplate[11].ulValueLen = attr->ulValueLen;
00177 break;
00178 case CKA_EXPONENT_2:
00179 INSIST(keyTemplate[12].type == attr->type);
00180 keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
00181 attr->ulValueLen);
00182 if (keyTemplate[12].pValue == NULL)
00183 DST_RET(ISC_R_NOMEMORY);
00184 memmove(keyTemplate[12].pValue, attr->pValue,
00185 attr->ulValueLen);
00186 keyTemplate[12].ulValueLen = attr->ulValueLen;
00187 break;
00188 case CKA_COEFFICIENT:
00189 INSIST(keyTemplate[13].type == attr->type);
00190 keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
00191 attr->ulValueLen);
00192 if (keyTemplate[13].pValue == NULL)
00193 DST_RET(ISC_R_NOMEMORY);
00194 memmove(keyTemplate[13].pValue, attr->pValue,
00195 attr->ulValueLen);
00196 keyTemplate[13].ulValueLen = attr->ulValueLen;
00197 break;
00198 }
00199 pk11_ctx->object = CK_INVALID_HANDLE;
00200 pk11_ctx->ontoken = ISC_FALSE;
00201 PK11_RET(pkcs_C_CreateObject,
00202 (pk11_ctx->session,
00203 keyTemplate, (CK_ULONG) 14,
00204 &pk11_ctx->object),
00205 ISC_R_FAILURE);
00206
00207 token_key:
00208
00209 switch (dctx->key->key_alg) {
00210 case DST_ALG_RSAMD5:
00211 mech.mechanism = CKM_MD5_RSA_PKCS;
00212 break;
00213 case DST_ALG_RSASHA1:
00214 case DST_ALG_NSEC3RSASHA1:
00215 mech.mechanism = CKM_SHA1_RSA_PKCS;
00216 break;
00217 case DST_ALG_RSASHA256:
00218 mech.mechanism = CKM_SHA256_RSA_PKCS;
00219 break;
00220 case DST_ALG_RSASHA512:
00221 mech.mechanism = CKM_SHA512_RSA_PKCS;
00222 break;
00223 default:
00224 INSIST(0);
00225 }
00226
00227 PK11_RET(pkcs_C_SignInit,
00228 (pk11_ctx->session, &mech, pk11_ctx->object),
00229 ISC_R_FAILURE);
00230
00231 dctx->ctxdata.pk11_ctx = pk11_ctx;
00232
00233 for (i = 6; i <= 13; i++)
00234 if (keyTemplate[i].pValue != NULL) {
00235 memset(keyTemplate[i].pValue, 0,
00236 keyTemplate[i].ulValueLen);
00237 isc_mem_put(dctx->mctx,
00238 keyTemplate[i].pValue,
00239 keyTemplate[i].ulValueLen);
00240 }
00241
00242 return (ISC_R_SUCCESS);
00243
00244 err:
00245 if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
00246 (void) pkcs_C_DestroyObject(pk11_ctx->session,
00247 pk11_ctx->object);
00248 for (i = 6; i <= 13; i++)
00249 if (keyTemplate[i].pValue != NULL) {
00250 memset(keyTemplate[i].pValue, 0,
00251 keyTemplate[i].ulValueLen);
00252 isc_mem_put(dctx->mctx,
00253 keyTemplate[i].pValue,
00254 keyTemplate[i].ulValueLen);
00255 }
00256 pk11_return_session(pk11_ctx);
00257 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00258 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00259
00260 return (ret);
00261 }
00262
00263 static isc_result_t
00264 pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
00265 dst_context_t *dctx) {
00266 CK_RV rv;
00267 CK_MECHANISM mech = { 0, NULL, 0 };
00268 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
00269 CK_KEY_TYPE keyType = CKK_RSA;
00270 CK_ATTRIBUTE keyTemplate[] =
00271 {
00272 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00273 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00274 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00275 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00276 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
00277 { CKA_MODULUS, NULL, 0 },
00278 { CKA_PUBLIC_EXPONENT, NULL, 0 },
00279 };
00280 CK_ATTRIBUTE *attr;
00281 pk11_object_t *rsa;
00282 pk11_context_t *pk11_ctx;
00283 isc_result_t ret;
00284 unsigned int i;
00285
00286 REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
00287 key->key_alg == DST_ALG_RSASHA1 ||
00288 key->key_alg == DST_ALG_NSEC3RSASHA1 ||
00289 key->key_alg == DST_ALG_RSASHA256 ||
00290 key->key_alg == DST_ALG_RSASHA512);
00291
00292 rsa = key->keydata.pkey;
00293
00294 pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
00295 sizeof(*pk11_ctx));
00296 if (pk11_ctx == NULL)
00297 return (ISC_R_NOMEMORY);
00298 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
00299 rsa->reqlogon, NULL,
00300 pk11_get_best_token(OP_RSA));
00301 if (ret != ISC_R_SUCCESS)
00302 goto err;
00303
00304 for (attr = pk11_attribute_first(rsa);
00305 attr != NULL;
00306 attr = pk11_attribute_next(rsa, attr))
00307 switch (attr->type) {
00308 case CKA_MODULUS:
00309 INSIST(keyTemplate[5].type == attr->type);
00310 keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
00311 attr->ulValueLen);
00312 if (keyTemplate[5].pValue == NULL)
00313 DST_RET(ISC_R_NOMEMORY);
00314 memmove(keyTemplate[5].pValue, attr->pValue,
00315 attr->ulValueLen);
00316 keyTemplate[5].ulValueLen = attr->ulValueLen;
00317 break;
00318 case CKA_PUBLIC_EXPONENT:
00319 INSIST(keyTemplate[6].type == attr->type);
00320 keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
00321 attr->ulValueLen);
00322 if (keyTemplate[6].pValue == NULL)
00323 DST_RET(ISC_R_NOMEMORY);
00324 memmove(keyTemplate[6].pValue, attr->pValue,
00325 attr->ulValueLen);
00326 keyTemplate[6].ulValueLen = attr->ulValueLen;
00327 if (pk11_numbits(attr->pValue,
00328 attr->ulValueLen) > maxbits &&
00329 maxbits != 0)
00330 DST_RET(DST_R_VERIFYFAILURE);
00331 break;
00332 }
00333 pk11_ctx->object = CK_INVALID_HANDLE;
00334 pk11_ctx->ontoken = ISC_FALSE;
00335 PK11_RET(pkcs_C_CreateObject,
00336 (pk11_ctx->session,
00337 keyTemplate, (CK_ULONG) 7,
00338 &pk11_ctx->object),
00339 ISC_R_FAILURE);
00340
00341 switch (dctx->key->key_alg) {
00342 case DST_ALG_RSAMD5:
00343 mech.mechanism = CKM_MD5_RSA_PKCS;
00344 break;
00345 case DST_ALG_RSASHA1:
00346 case DST_ALG_NSEC3RSASHA1:
00347 mech.mechanism = CKM_SHA1_RSA_PKCS;
00348 break;
00349 case DST_ALG_RSASHA256:
00350 mech.mechanism = CKM_SHA256_RSA_PKCS;
00351 break;
00352 case DST_ALG_RSASHA512:
00353 mech.mechanism = CKM_SHA512_RSA_PKCS;
00354 break;
00355 default:
00356 INSIST(0);
00357 }
00358
00359 PK11_RET(pkcs_C_VerifyInit,
00360 (pk11_ctx->session, &mech, pk11_ctx->object),
00361 ISC_R_FAILURE);
00362
00363 dctx->ctxdata.pk11_ctx = pk11_ctx;
00364
00365 for (i = 5; i <= 6; i++)
00366 if (keyTemplate[i].pValue != NULL) {
00367 memset(keyTemplate[i].pValue, 0,
00368 keyTemplate[i].ulValueLen);
00369 isc_mem_put(dctx->mctx,
00370 keyTemplate[i].pValue,
00371 keyTemplate[i].ulValueLen);
00372 }
00373
00374 return (ISC_R_SUCCESS);
00375
00376 err:
00377 if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
00378 (void) pkcs_C_DestroyObject(pk11_ctx->session,
00379 pk11_ctx->object);
00380 for (i = 5; i <= 6; i++)
00381 if (keyTemplate[i].pValue != NULL) {
00382 memset(keyTemplate[i].pValue, 0,
00383 keyTemplate[i].ulValueLen);
00384 isc_mem_put(dctx->mctx,
00385 keyTemplate[i].pValue,
00386 keyTemplate[i].ulValueLen);
00387 }
00388 pk11_return_session(pk11_ctx);
00389 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00390 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00391
00392 return (ret);
00393 }
00394
00395 static isc_result_t
00396 pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) {
00397 if (dctx->use == DO_SIGN)
00398 return (pkcs11rsa_createctx_sign(key, dctx));
00399 else
00400 return (pkcs11rsa_createctx_verify(key, 0U, dctx));
00401 }
00402
00403 static isc_result_t
00404 pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) {
00405 if (dctx->use == DO_SIGN)
00406 return (pkcs11rsa_createctx_sign(key, dctx));
00407 else
00408 return (pkcs11rsa_createctx_verify(key,
00409 (unsigned) maxbits, dctx));
00410 }
00411
00412 static void
00413 pkcs11rsa_destroyctx(dst_context_t *dctx) {
00414 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00415
00416 if (pk11_ctx != NULL) {
00417 if (!pk11_ctx->ontoken &&
00418 (pk11_ctx->object != CK_INVALID_HANDLE))
00419 (void) pkcs_C_DestroyObject(pk11_ctx->session,
00420 pk11_ctx->object);
00421 pk11_return_session(pk11_ctx);
00422 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00423 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00424 dctx->ctxdata.pk11_ctx = NULL;
00425 }
00426 }
00427
00428 static isc_result_t
00429 pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
00430 CK_RV rv;
00431 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00432 isc_result_t ret = ISC_R_SUCCESS;
00433
00434 if (dctx->use == DO_SIGN)
00435 PK11_CALL(pkcs_C_SignUpdate,
00436 (pk11_ctx->session,
00437 (CK_BYTE_PTR) data->base,
00438 (CK_ULONG) data->length),
00439 ISC_R_FAILURE);
00440 else
00441 PK11_CALL(pkcs_C_VerifyUpdate,
00442 (pk11_ctx->session,
00443 (CK_BYTE_PTR) data->base,
00444 (CK_ULONG) data->length),
00445 ISC_R_FAILURE);
00446 return (ret);
00447 }
00448
00449 static isc_result_t
00450 pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00451 CK_RV rv;
00452 CK_ULONG siglen = 0;
00453 isc_region_t r;
00454 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00455 isc_result_t ret = ISC_R_SUCCESS;
00456
00457 PK11_RET(pkcs_C_SignFinal,
00458 (pk11_ctx->session, NULL, &siglen),
00459 DST_R_SIGNFAILURE);
00460
00461 isc_buffer_availableregion(sig, &r);
00462
00463 if (r.length < (unsigned int) siglen)
00464 return (ISC_R_NOSPACE);
00465
00466 PK11_RET(pkcs_C_SignFinal,
00467 (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen),
00468 DST_R_SIGNFAILURE);
00469
00470 isc_buffer_add(sig, (unsigned int) siglen);
00471
00472 err:
00473 return (ret);
00474 }
00475
00476 static isc_result_t
00477 pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
00478 CK_RV rv;
00479 pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00480 isc_result_t ret = ISC_R_SUCCESS;
00481
00482 PK11_CALL(pkcs_C_VerifyFinal,
00483 (pk11_ctx->session,
00484 (CK_BYTE_PTR) sig->base,
00485 (CK_ULONG) sig->length),
00486 DST_R_VERIFYFAILURE);
00487 return (ret);
00488 }
00489
00490 static isc_boolean_t
00491 pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
00492 pk11_object_t *rsa1, *rsa2;
00493 CK_ATTRIBUTE *attr1, *attr2;
00494
00495 rsa1 = key1->keydata.pkey;
00496 rsa2 = key2->keydata.pkey;
00497
00498 if ((rsa1 == NULL) && (rsa2 == NULL))
00499 return (ISC_TRUE);
00500 else if ((rsa1 == NULL) || (rsa2 == NULL))
00501 return (ISC_FALSE);
00502
00503 attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS);
00504 attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS);
00505 if ((attr1 == NULL) && (attr2 == NULL))
00506 return (ISC_TRUE);
00507 else if ((attr1 == NULL) || (attr2 == NULL) ||
00508 (attr1->ulValueLen != attr2->ulValueLen) ||
00509 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00510 return (ISC_FALSE);
00511
00512 attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT);
00513 attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT);
00514 if ((attr1 == NULL) && (attr2 == NULL))
00515 return (ISC_TRUE);
00516 else if ((attr1 == NULL) || (attr2 == NULL) ||
00517 (attr1->ulValueLen != attr2->ulValueLen) ||
00518 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00519 return (ISC_FALSE);
00520
00521 attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT);
00522 attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT);
00523 if (((attr1 != NULL) || (attr2 != NULL)) &&
00524 ((attr1 == NULL) || (attr2 == NULL) ||
00525 (attr1->ulValueLen != attr2->ulValueLen) ||
00526 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)))
00527 return (ISC_FALSE);
00528
00529 if (!rsa1->ontoken && !rsa2->ontoken)
00530 return (ISC_TRUE);
00531 else if (rsa1->ontoken || rsa2->ontoken ||
00532 (rsa1->object != rsa2->object))
00533 return (ISC_FALSE);
00534
00535 return (ISC_TRUE);
00536 }
00537
00538 static isc_result_t
00539 pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
00540 CK_RV rv;
00541 CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 };
00542 CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
00543 CK_ULONG bits = 0;
00544 CK_BYTE pubexp[5];
00545 CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
00546 CK_KEY_TYPE keyType = CKK_RSA;
00547 CK_ATTRIBUTE pubTemplate[] =
00548 {
00549 { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
00550 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00551 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00552 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00553 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
00554 { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) },
00555 { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) }
00556 };
00557 CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
00558 CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
00559 CK_ATTRIBUTE privTemplate[] =
00560 {
00561 { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
00562 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00563 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00564 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00565 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00566 { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
00567 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00568 };
00569 CK_ATTRIBUTE *attr;
00570 pk11_object_t *rsa;
00571 pk11_context_t *pk11_ctx;
00572 isc_result_t ret;
00573 unsigned int i;
00574
00575 UNUSED(callback);
00576
00577 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
00578 sizeof(*pk11_ctx));
00579 if (pk11_ctx == NULL)
00580 return (ISC_R_NOMEMORY);
00581 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
00582 ISC_FALSE, NULL, pk11_get_best_token(OP_RSA));
00583 if (ret != ISC_R_SUCCESS)
00584 goto err;
00585
00586 bits = key->key_size;
00587 if (exp == 0) {
00588
00589 pubexp[0] = 1;
00590 pubexp[1] = 0;
00591 pubexp[2] = 1;
00592 pubTemplate[6].ulValueLen = 3;
00593 } else {
00594
00595 pubexp[0] = 1;
00596 pubexp[1] = 0;
00597 pubexp[2] = 0;
00598 pubexp[3] = 0;
00599 pubexp[4] = 1;
00600 pubTemplate[6].ulValueLen = 5;
00601 }
00602
00603 PK11_RET(pkcs_C_GenerateKeyPair,
00604 (pk11_ctx->session, &mech,
00605 pubTemplate, (CK_ULONG) 7,
00606 privTemplate, (CK_ULONG) 7,
00607 &pub, &priv),
00608 DST_R_CRYPTOFAILURE);
00609
00610 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
00611 if (rsa == NULL)
00612 DST_RET(ISC_R_NOMEMORY);
00613 memset(rsa, 0, sizeof(*rsa));
00614 key->keydata.pkey = rsa;
00615 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
00616 if (rsa->repr == NULL)
00617 DST_RET(ISC_R_NOMEMORY);
00618 memset(rsa->repr, 0, sizeof(*attr) * 8);
00619 rsa->attrcnt = 8;
00620
00621 attr = rsa->repr;
00622 attr[0].type = CKA_MODULUS;
00623 attr[1].type = CKA_PUBLIC_EXPONENT;
00624 attr[2].type = CKA_PRIVATE_EXPONENT;
00625 attr[3].type = CKA_PRIME_1;
00626 attr[4].type = CKA_PRIME_2;
00627 attr[5].type = CKA_EXPONENT_1;
00628 attr[6].type = CKA_EXPONENT_2;
00629 attr[7].type = CKA_COEFFICIENT;
00630
00631 PK11_RET(pkcs_C_GetAttributeValue,
00632 (pk11_ctx->session, pub, attr, 2),
00633 DST_R_CRYPTOFAILURE);
00634 for (i = 0; i <= 1; i++) {
00635 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
00636 if (attr[i].pValue == NULL)
00637 DST_RET(ISC_R_NOMEMORY);
00638 memset(attr[i].pValue, 0, attr[i].ulValueLen);
00639 }
00640 PK11_RET(pkcs_C_GetAttributeValue,
00641 (pk11_ctx->session, pub, attr, 2),
00642 DST_R_CRYPTOFAILURE);
00643
00644 attr += 2;
00645 PK11_RET(pkcs_C_GetAttributeValue,
00646 (pk11_ctx->session, priv, attr, 6),
00647 DST_R_CRYPTOFAILURE);
00648 for (i = 0; i <= 5; i++) {
00649 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
00650 if (attr[i].pValue == NULL)
00651 DST_RET(ISC_R_NOMEMORY);
00652 memset(attr[i].pValue, 0, attr[i].ulValueLen);
00653 }
00654 PK11_RET(pkcs_C_GetAttributeValue,
00655 (pk11_ctx->session, priv, attr, 6),
00656 DST_R_CRYPTOFAILURE);
00657
00658 (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
00659 (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
00660 pk11_return_session(pk11_ctx);
00661 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00662 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
00663
00664 return (ISC_R_SUCCESS);
00665
00666 err:
00667 pkcs11rsa_destroy(key);
00668 if (priv != CK_INVALID_HANDLE)
00669 (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
00670 if (pub != CK_INVALID_HANDLE)
00671 (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
00672 pk11_return_session(pk11_ctx);
00673 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00674 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
00675
00676 return (ret);
00677 }
00678
00679 static isc_boolean_t
00680 pkcs11rsa_isprivate(const dst_key_t *key) {
00681 pk11_object_t *rsa = key->keydata.pkey;
00682 CK_ATTRIBUTE *attr;
00683
00684 if (rsa == NULL)
00685 return (ISC_FALSE);
00686 attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT);
00687 return (ISC_TF((attr != NULL) || rsa->ontoken));
00688 }
00689
00690 static void
00691 pkcs11rsa_destroy(dst_key_t *key) {
00692 pk11_object_t *rsa = key->keydata.pkey;
00693 CK_ATTRIBUTE *attr;
00694
00695 if (rsa == NULL)
00696 return;
00697
00698 INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken);
00699
00700 for (attr = pk11_attribute_first(rsa);
00701 attr != NULL;
00702 attr = pk11_attribute_next(rsa, attr))
00703 switch (attr->type) {
00704 case CKA_LABEL:
00705 case CKA_ID:
00706 case CKA_MODULUS:
00707 case CKA_PUBLIC_EXPONENT:
00708 case CKA_PRIVATE_EXPONENT:
00709 case CKA_PRIME_1:
00710 case CKA_PRIME_2:
00711 case CKA_EXPONENT_1:
00712 case CKA_EXPONENT_2:
00713 case CKA_COEFFICIENT:
00714 if (attr->pValue != NULL) {
00715 memset(attr->pValue, 0, attr->ulValueLen);
00716 isc_mem_put(key->mctx,
00717 attr->pValue,
00718 attr->ulValueLen);
00719 }
00720 break;
00721 }
00722 if (rsa->repr != NULL) {
00723 memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
00724 isc_mem_put(key->mctx,
00725 rsa->repr,
00726 rsa->attrcnt * sizeof(*attr));
00727 }
00728 memset(rsa, 0, sizeof(*rsa));
00729 isc_mem_put(key->mctx, rsa, sizeof(*rsa));
00730 key->keydata.pkey = NULL;
00731 }
00732
00733 static isc_result_t
00734 pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) {
00735 pk11_object_t *rsa;
00736 CK_ATTRIBUTE *attr;
00737 isc_region_t r;
00738 unsigned int e_bytes = 0, mod_bytes = 0;
00739 CK_BYTE *exponent = NULL, *modulus = NULL;
00740
00741 REQUIRE(key->keydata.pkey != NULL);
00742
00743 rsa = key->keydata.pkey;
00744
00745 for (attr = pk11_attribute_first(rsa);
00746 attr != NULL;
00747 attr = pk11_attribute_next(rsa, attr))
00748 switch (attr->type) {
00749 case CKA_PUBLIC_EXPONENT:
00750 exponent = (CK_BYTE *) attr->pValue;
00751 e_bytes = (unsigned int) attr->ulValueLen;
00752 break;
00753 case CKA_MODULUS:
00754 modulus = (CK_BYTE *) attr->pValue;
00755 mod_bytes = (unsigned int) attr->ulValueLen;
00756 break;
00757 }
00758 REQUIRE((exponent != NULL) && (modulus != NULL));
00759
00760 isc_buffer_availableregion(data, &r);
00761
00762 if (e_bytes < 256) {
00763 if (r.length < 1)
00764 return (ISC_R_NOSPACE);
00765 isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
00766 isc_region_consume(&r, 1);
00767 } else {
00768 if (r.length < 3)
00769 return (ISC_R_NOSPACE);
00770 isc_buffer_putuint8(data, 0);
00771 isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
00772 isc_region_consume(&r, 3);
00773 }
00774
00775 if (r.length < e_bytes + mod_bytes)
00776 return (ISC_R_NOSPACE);
00777
00778 memmove(r.base, exponent, e_bytes);
00779 isc_region_consume(&r, e_bytes);
00780 memmove(r.base, modulus, mod_bytes);
00781
00782 isc_buffer_add(data, e_bytes + mod_bytes);
00783
00784 return (ISC_R_SUCCESS);
00785 }
00786
00787 static isc_result_t
00788 pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
00789 pk11_object_t *rsa;
00790 isc_region_t r;
00791 unsigned int e_bytes, mod_bytes;
00792 CK_BYTE *exponent = NULL, *modulus = NULL;
00793 CK_ATTRIBUTE *attr;
00794
00795 isc_buffer_remainingregion(data, &r);
00796 if (r.length == 0)
00797 return (ISC_R_SUCCESS);
00798
00799 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
00800 if (rsa == NULL)
00801 return (ISC_R_NOMEMORY);
00802 memset(rsa, 0, sizeof(*rsa));
00803
00804 if (r.length < 1) {
00805 memset(rsa, 0, sizeof(*rsa));
00806 isc_mem_put(key->mctx, rsa, sizeof(*rsa));
00807 return (DST_R_INVALIDPUBLICKEY);
00808 }
00809 e_bytes = *r.base++;
00810 r.length--;
00811
00812 if (e_bytes == 0) {
00813 if (r.length < 2) {
00814 memset(rsa, 0, sizeof(*rsa));
00815 isc_mem_put(key->mctx, rsa, sizeof(*rsa));
00816 return (DST_R_INVALIDPUBLICKEY);
00817 }
00818 e_bytes = ((*r.base++) << 8);
00819 e_bytes += *r.base++;
00820 r.length -= 2;
00821 }
00822
00823 if (r.length < e_bytes) {
00824 memset(rsa, 0, sizeof(*rsa));
00825 isc_mem_put(key->mctx, rsa, sizeof(*rsa));
00826 return (DST_R_INVALIDPUBLICKEY);
00827 }
00828 exponent = r.base;
00829 r.base += e_bytes;
00830 r.length -= e_bytes;
00831 modulus = r.base;
00832 mod_bytes = r.length;
00833
00834 key->key_size = pk11_numbits(modulus, mod_bytes);
00835
00836 isc_buffer_forward(data, r.length);
00837
00838 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
00839 if (rsa->repr == NULL)
00840 goto nomemory;
00841 memset(rsa->repr, 0, sizeof(*attr) * 2);
00842 rsa->attrcnt = 2;
00843 attr = rsa->repr;
00844 attr[0].type = CKA_MODULUS;
00845 attr[0].pValue = isc_mem_get(key->mctx, mod_bytes);
00846 if (attr[0].pValue == NULL)
00847 goto nomemory;
00848 memmove(attr[0].pValue, modulus, mod_bytes);
00849 attr[0].ulValueLen = (CK_ULONG) mod_bytes;
00850 attr[1].type = CKA_PUBLIC_EXPONENT;
00851 attr[1].pValue = isc_mem_get(key->mctx, e_bytes);
00852 if (attr[1].pValue == NULL)
00853 goto nomemory;
00854 memmove(attr[1].pValue, exponent, e_bytes);
00855 attr[1].ulValueLen = (CK_ULONG) e_bytes;
00856
00857 key->keydata.pkey = rsa;
00858
00859 return (ISC_R_SUCCESS);
00860
00861 nomemory:
00862 for (attr = pk11_attribute_first(rsa);
00863 attr != NULL;
00864 attr = pk11_attribute_next(rsa, attr))
00865 switch (attr->type) {
00866 case CKA_MODULUS:
00867 case CKA_PUBLIC_EXPONENT:
00868 if (attr->pValue != NULL) {
00869 memset(attr->pValue, 0, attr->ulValueLen);
00870 isc_mem_put(key->mctx,
00871 attr->pValue,
00872 attr->ulValueLen);
00873 }
00874 break;
00875 }
00876 if (rsa->repr != NULL) {
00877 memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
00878 isc_mem_put(key->mctx,
00879 rsa->repr,
00880 rsa->attrcnt * sizeof(*attr));
00881 }
00882 memset(rsa, 0, sizeof(*rsa));
00883 isc_mem_put(key->mctx, rsa, sizeof(*rsa));
00884 return (ISC_R_NOMEMORY);
00885 }
00886
00887 static isc_result_t
00888 pkcs11rsa_tofile(const dst_key_t *key, const char *directory) {
00889 int i;
00890 pk11_object_t *rsa;
00891 CK_ATTRIBUTE *attr;
00892 CK_ATTRIBUTE *modulus = NULL, *exponent = NULL;
00893 CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL;
00894 CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
00895 dst_private_t priv;
00896 unsigned char *bufs[10];
00897 isc_result_t result;
00898
00899 if (key->keydata.pkey == NULL)
00900 return (DST_R_NULLKEY);
00901
00902 if (key->external) {
00903 priv.nelements = 0;
00904 return (dst__privstruct_writefile(key, &priv, directory));
00905 }
00906
00907 rsa = key->keydata.pkey;
00908
00909 for (attr = pk11_attribute_first(rsa);
00910 attr != NULL;
00911 attr = pk11_attribute_next(rsa, attr))
00912 switch (attr->type) {
00913 case CKA_MODULUS:
00914 modulus = attr;
00915 break;
00916 case CKA_PUBLIC_EXPONENT:
00917 exponent = attr;
00918 break;
00919 case CKA_PRIVATE_EXPONENT:
00920 d = attr;
00921 break;
00922 case CKA_PRIME_1:
00923 p = attr;
00924 break;
00925 case CKA_PRIME_2:
00926 q = attr;
00927 break;
00928 case CKA_EXPONENT_1:
00929 dmp1 = attr;
00930 break;
00931 case CKA_EXPONENT_2:
00932 dmq1 = attr;
00933 break;
00934 case CKA_COEFFICIENT:
00935 iqmp = attr;
00936 break;
00937 }
00938 if ((modulus == NULL) || (exponent == NULL))
00939 return (DST_R_NULLKEY);
00940
00941 memset(bufs, 0, sizeof(bufs));
00942
00943 for (i = 0; i < 10; i++) {
00944 bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen);
00945 if (bufs[i] == NULL) {
00946 result = ISC_R_NOMEMORY;
00947 goto fail;
00948 }
00949 memset(bufs[i], 0, modulus->ulValueLen);
00950 }
00951
00952 i = 0;
00953
00954 priv.elements[i].tag = TAG_RSA_MODULUS;
00955 priv.elements[i].length = (unsigned short) modulus->ulValueLen;
00956 memmove(bufs[i], modulus->pValue, modulus->ulValueLen);
00957 priv.elements[i].data = bufs[i];
00958 i++;
00959
00960 priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
00961 priv.elements[i].length = (unsigned short) exponent->ulValueLen;
00962 memmove(bufs[i], exponent->pValue, exponent->ulValueLen);
00963 priv.elements[i].data = bufs[i];
00964 i++;
00965
00966 if (d != NULL) {
00967 priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
00968 priv.elements[i].length = (unsigned short) d->ulValueLen;
00969 memmove(bufs[i], d->pValue, d->ulValueLen);
00970 priv.elements[i].data = bufs[i];
00971 i++;
00972 }
00973
00974 if (p != NULL) {
00975 priv.elements[i].tag = TAG_RSA_PRIME1;
00976 priv.elements[i].length = (unsigned short) p->ulValueLen;
00977 memmove(bufs[i], p->pValue, p->ulValueLen);
00978 priv.elements[i].data = bufs[i];
00979 i++;
00980 }
00981
00982 if (q != NULL) {
00983 priv.elements[i].tag = TAG_RSA_PRIME2;
00984 priv.elements[i].length = (unsigned short) q->ulValueLen;
00985 memmove(bufs[i], q->pValue, q->ulValueLen);
00986 priv.elements[i].data = bufs[i];
00987 i++;
00988 }
00989
00990 if (dmp1 != NULL) {
00991 priv.elements[i].tag = TAG_RSA_EXPONENT1;
00992 priv.elements[i].length = (unsigned short) dmp1->ulValueLen;
00993 memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen);
00994 priv.elements[i].data = bufs[i];
00995 i++;
00996 }
00997
00998 if (dmq1 != NULL) {
00999 priv.elements[i].tag = TAG_RSA_EXPONENT2;
01000 priv.elements[i].length = (unsigned short) dmq1->ulValueLen;
01001 memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen);
01002 priv.elements[i].data = bufs[i];
01003 i++;
01004 }
01005
01006 if (iqmp != NULL) {
01007 priv.elements[i].tag = TAG_RSA_COEFFICIENT;
01008 priv.elements[i].length = (unsigned short) iqmp->ulValueLen;
01009 memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen);
01010 priv.elements[i].data = bufs[i];
01011 i++;
01012 }
01013
01014 if (key->engine != NULL) {
01015 priv.elements[i].tag = TAG_RSA_ENGINE;
01016 priv.elements[i].length =
01017 (unsigned short)strlen(key->engine) + 1;
01018 priv.elements[i].data = (unsigned char *)key->engine;
01019 i++;
01020 }
01021
01022 if (key->label != NULL) {
01023 priv.elements[i].tag = TAG_RSA_LABEL;
01024 priv.elements[i].length =
01025 (unsigned short)strlen(key->label) + 1;
01026 priv.elements[i].data = (unsigned char *)key->label;
01027 i++;
01028 }
01029
01030 priv.nelements = i;
01031 result = dst__privstruct_writefile(key, &priv, directory);
01032 fail:
01033 for (i = 0; i < 10; i++) {
01034 if (bufs[i] == NULL)
01035 break;
01036 memset(bufs[i], 0, modulus->ulValueLen);
01037 isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen);
01038 }
01039 return (result);
01040 }
01041
01042 static isc_result_t
01043 pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
01044 dst_key_t *pub)
01045 {
01046 CK_RV rv;
01047 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
01048 CK_KEY_TYPE keyType = CKK_RSA;
01049 CK_ATTRIBUTE searchTemplate[] =
01050 {
01051 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
01052 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
01053 { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
01054 { CKA_LABEL, NULL, 0 }
01055 };
01056 CK_ULONG cnt;
01057 CK_ATTRIBUTE *attr;
01058 CK_ATTRIBUTE *pubattr;
01059 pk11_object_t *rsa;
01060 pk11_object_t *pubrsa;
01061 pk11_context_t *pk11_ctx = NULL;
01062 isc_result_t ret;
01063
01064 if (label == NULL)
01065 return (DST_R_NOENGINE);
01066
01067 rsa = key->keydata.pkey;
01068 pubrsa = pub->keydata.pkey;
01069
01070 rsa->object = CK_INVALID_HANDLE;
01071 rsa->ontoken = ISC_TRUE;
01072 rsa->reqlogon = ISC_TRUE;
01073 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
01074 if (rsa->repr == NULL)
01075 return (ISC_R_NOMEMORY);
01076 memset(rsa->repr, 0, sizeof(*attr) * 2);
01077 rsa->attrcnt = 2;
01078 attr = rsa->repr;
01079
01080 attr->type = CKA_MODULUS;
01081 pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
01082 attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
01083 if (attr->pValue == NULL)
01084 DST_RET(ISC_R_NOMEMORY);
01085 memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
01086 attr->ulValueLen = pubattr->ulValueLen;
01087 attr++;
01088
01089 attr->type = CKA_PUBLIC_EXPONENT;
01090 pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
01091 attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
01092 if (attr->pValue == NULL)
01093 DST_RET(ISC_R_NOMEMORY);
01094 memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
01095 attr->ulValueLen = pubattr->ulValueLen;
01096
01097 ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
01098 if (ret != ISC_R_SUCCESS)
01099 goto err;
01100
01101 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
01102 sizeof(*pk11_ctx));
01103 if (pk11_ctx == NULL)
01104 DST_RET(ISC_R_NOMEMORY);
01105 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
01106 rsa->reqlogon, NULL, rsa->slot);
01107 if (ret != ISC_R_SUCCESS)
01108 goto err;
01109
01110 attr = pk11_attribute_bytype(rsa, CKA_LABEL);
01111 if (attr == NULL) {
01112 attr = pk11_attribute_bytype(rsa, CKA_ID);
01113 INSIST(attr != NULL);
01114 searchTemplate[3].type = CKA_ID;
01115 }
01116 searchTemplate[3].pValue = attr->pValue;
01117 searchTemplate[3].ulValueLen = attr->ulValueLen;
01118
01119 PK11_RET(pkcs_C_FindObjectsInit,
01120 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
01121 DST_R_CRYPTOFAILURE);
01122 PK11_RET(pkcs_C_FindObjects,
01123 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
01124 DST_R_CRYPTOFAILURE);
01125 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
01126 if (cnt == 0)
01127 DST_RET(ISC_R_NOTFOUND);
01128 if (cnt > 1)
01129 DST_RET(ISC_R_EXISTS);
01130
01131 if (engine != NULL) {
01132 key->engine = isc_mem_strdup(key->mctx, engine);
01133 if (key->engine == NULL)
01134 DST_RET(ISC_R_NOMEMORY);
01135 }
01136
01137 key->label = isc_mem_strdup(key->mctx, label);
01138 if (key->label == NULL)
01139 DST_RET(ISC_R_NOMEMORY);
01140
01141 pk11_return_session(pk11_ctx);
01142 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
01143 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
01144
01145 attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
01146 INSIST(attr != NULL);
01147 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
01148
01149 return (ISC_R_SUCCESS);
01150
01151 err:
01152 if (pk11_ctx != NULL) {
01153 pk11_return_session(pk11_ctx);
01154 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
01155 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
01156 }
01157
01158 return (ret);
01159 }
01160
01161 static isc_result_t
01162 rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) {
01163 CK_ATTRIBUTE *pubattr, *privattr;
01164 CK_BYTE *priv_exp = NULL, *priv_mod = NULL;
01165 CK_BYTE *pub_exp = NULL, *pub_mod = NULL;
01166 unsigned int priv_explen = 0, priv_modlen = 0;
01167 unsigned int pub_explen = 0, pub_modlen = 0;
01168
01169 REQUIRE(rsa != NULL && pubrsa != NULL);
01170
01171 privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
01172 INSIST(privattr != NULL);
01173 priv_exp = privattr->pValue;
01174 priv_explen = privattr->ulValueLen;
01175
01176 pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
01177 INSIST(pubattr != NULL);
01178 pub_exp = pubattr->pValue;
01179 pub_explen = pubattr->ulValueLen;
01180
01181 if (priv_exp != NULL) {
01182 if (priv_explen != pub_explen)
01183 return (DST_R_INVALIDPRIVATEKEY);
01184 if (memcmp(priv_exp, pub_exp, pub_explen) != 0)
01185 return (DST_R_INVALIDPRIVATEKEY);
01186 } else {
01187 privattr->pValue = pub_exp;
01188 privattr->ulValueLen = pub_explen;
01189 pubattr->pValue = NULL;
01190 pubattr->ulValueLen = 0;
01191 }
01192
01193 if (privattr->pValue == NULL)
01194 return (DST_R_INVALIDPRIVATEKEY);
01195
01196 privattr = pk11_attribute_bytype(rsa, CKA_MODULUS);
01197 INSIST(privattr != NULL);
01198 priv_mod = privattr->pValue;
01199 priv_modlen = privattr->ulValueLen;
01200
01201 pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
01202 INSIST(pubattr != NULL);
01203 pub_mod = pubattr->pValue;
01204 pub_modlen = pubattr->ulValueLen;
01205
01206 if (priv_mod != NULL) {
01207 if (priv_modlen != pub_modlen)
01208 return (DST_R_INVALIDPRIVATEKEY);
01209 if (memcmp(priv_mod, pub_mod, pub_modlen) != 0)
01210 return (DST_R_INVALIDPRIVATEKEY);
01211 } else {
01212 privattr->pValue = pub_mod;
01213 privattr->ulValueLen = pub_modlen;
01214 pubattr->pValue = NULL;
01215 pubattr->ulValueLen = 0;
01216 }
01217
01218 if (privattr->pValue == NULL)
01219 return (DST_R_INVALIDPRIVATEKEY);
01220
01221 return (ISC_R_SUCCESS);
01222 }
01223
01224 static isc_result_t
01225 pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
01226 dst_private_t priv;
01227 isc_result_t ret;
01228 int i;
01229 pk11_object_t *rsa;
01230 CK_ATTRIBUTE *attr;
01231 isc_mem_t *mctx = key->mctx;
01232 const char *engine = NULL, *label = NULL;
01233
01234
01235 ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
01236 if (ret != ISC_R_SUCCESS)
01237 return (ret);
01238
01239 if (key->external) {
01240 if (priv.nelements != 0)
01241 DST_RET(DST_R_INVALIDPRIVATEKEY);
01242 if (pub == NULL)
01243 DST_RET(DST_R_INVALIDPRIVATEKEY);
01244
01245 key->keydata.pkey = pub->keydata.pkey;
01246 pub->keydata.pkey = NULL;
01247 key->key_size = pub->key_size;
01248
01249 dst__privstruct_free(&priv, mctx);
01250 memset(&priv, 0, sizeof(priv));
01251
01252 return (ISC_R_SUCCESS);
01253 }
01254
01255 for (i = 0; i < priv.nelements; i++) {
01256 switch (priv.elements[i].tag) {
01257 case TAG_RSA_ENGINE:
01258 engine = (char *)priv.elements[i].data;
01259 break;
01260 case TAG_RSA_LABEL:
01261 label = (char *)priv.elements[i].data;
01262 break;
01263 default:
01264 break;
01265 }
01266 }
01267 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
01268 if (rsa == NULL)
01269 DST_RET(ISC_R_NOMEMORY);
01270 memset(rsa, 0, sizeof(*rsa));
01271 key->keydata.pkey = rsa;
01272
01273
01274 if ((label != NULL) || (engine != NULL)) {
01275 ret = pkcs11rsa_fetch(key, engine, label, pub);
01276 if (ret != ISC_R_SUCCESS)
01277 goto err;
01278 dst__privstruct_free(&priv, mctx);
01279 memset(&priv, 0, sizeof(priv));
01280 return (ret);
01281 }
01282
01283 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
01284 if (rsa->repr == NULL)
01285 DST_RET(ISC_R_NOMEMORY);
01286 memset(rsa->repr, 0, sizeof(*attr) * 8);
01287 rsa->attrcnt = 8;
01288 attr = rsa->repr;
01289 attr[0].type = CKA_MODULUS;
01290 attr[1].type = CKA_PUBLIC_EXPONENT;
01291 attr[2].type = CKA_PRIVATE_EXPONENT;
01292 attr[3].type = CKA_PRIME_1;
01293 attr[4].type = CKA_PRIME_2;
01294 attr[5].type = CKA_EXPONENT_1;
01295 attr[6].type = CKA_EXPONENT_2;
01296 attr[7].type = CKA_COEFFICIENT;
01297
01298 for (i = 0; i < priv.nelements; i++) {
01299 CK_BYTE *bn;
01300
01301 switch (priv.elements[i].tag) {
01302 case TAG_RSA_ENGINE:
01303 continue;
01304 case TAG_RSA_LABEL:
01305 continue;
01306 default:
01307 bn = isc_mem_get(key->mctx, priv.elements[i].length);
01308 if (bn == NULL)
01309 DST_RET(ISC_R_NOMEMORY);
01310 memmove(bn, priv.elements[i].data,
01311 priv.elements[i].length);
01312 }
01313
01314 switch (priv.elements[i].tag) {
01315 case TAG_RSA_MODULUS:
01316 attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
01317 INSIST(attr != NULL);
01318 attr->pValue = bn;
01319 attr->ulValueLen = priv.elements[i].length;
01320 break;
01321 case TAG_RSA_PUBLICEXPONENT:
01322 attr = pk11_attribute_bytype(rsa,
01323 CKA_PUBLIC_EXPONENT);
01324 INSIST(attr != NULL);
01325 attr->pValue = bn;
01326 attr->ulValueLen = priv.elements[i].length;
01327 break;
01328 case TAG_RSA_PRIVATEEXPONENT:
01329 attr = pk11_attribute_bytype(rsa,
01330 CKA_PRIVATE_EXPONENT);
01331 INSIST(attr != NULL);
01332 attr->pValue = bn;
01333 attr->ulValueLen = priv.elements[i].length;
01334 break;
01335 case TAG_RSA_PRIME1:
01336 attr = pk11_attribute_bytype(rsa, CKA_PRIME_1);
01337 INSIST(attr != NULL);
01338 attr->pValue = bn;
01339 attr->ulValueLen = priv.elements[i].length;
01340 break;
01341 case TAG_RSA_PRIME2:
01342 attr = pk11_attribute_bytype(rsa, CKA_PRIME_2);
01343 INSIST(attr != NULL);
01344 attr->pValue = bn;
01345 attr->ulValueLen = priv.elements[i].length;
01346 break;
01347 case TAG_RSA_EXPONENT1:
01348 attr = pk11_attribute_bytype(rsa,
01349 CKA_EXPONENT_1);
01350 INSIST(attr != NULL);
01351 attr->pValue = bn;
01352 attr->ulValueLen = priv.elements[i].length;
01353 break;
01354 case TAG_RSA_EXPONENT2:
01355 attr = pk11_attribute_bytype(rsa,
01356 CKA_EXPONENT_2);
01357 INSIST(attr != NULL);
01358 attr->pValue = bn;
01359 attr->ulValueLen = priv.elements[i].length;
01360 break;
01361 case TAG_RSA_COEFFICIENT:
01362 attr = pk11_attribute_bytype(rsa,
01363 CKA_COEFFICIENT);
01364 INSIST(attr != NULL);
01365 attr->pValue = bn;
01366 attr->ulValueLen = priv.elements[i].length;
01367 break;
01368 }
01369 }
01370
01371 if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS)
01372 DST_RET(DST_R_INVALIDPRIVATEKEY);
01373
01374 attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
01375 INSIST(attr != NULL);
01376 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
01377
01378 attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
01379 INSIST(attr != NULL);
01380 if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
01381 DST_RET(ISC_R_RANGE);
01382
01383 dst__privstruct_free(&priv, mctx);
01384 memset(&priv, 0, sizeof(priv));
01385
01386 return (ISC_R_SUCCESS);
01387
01388 err:
01389 pkcs11rsa_destroy(key);
01390 dst__privstruct_free(&priv, mctx);
01391 memset(&priv, 0, sizeof(priv));
01392 return (ret);
01393 }
01394
01395 static isc_result_t
01396 pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
01397 const char *pin)
01398 {
01399 CK_RV rv;
01400 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
01401 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
01402 CK_KEY_TYPE keyType = CKK_RSA;
01403 CK_ATTRIBUTE searchTemplate[] =
01404 {
01405 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
01406 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
01407 { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
01408 { CKA_LABEL, NULL, 0 }
01409 };
01410 CK_ULONG cnt;
01411 CK_ATTRIBUTE *attr;
01412 pk11_object_t *rsa;
01413 pk11_context_t *pk11_ctx = NULL;
01414 isc_result_t ret;
01415 unsigned int i;
01416
01417 UNUSED(pin);
01418
01419 rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
01420 if (rsa == NULL)
01421 return (ISC_R_NOMEMORY);
01422 memset(rsa, 0, sizeof(*rsa));
01423 rsa->object = CK_INVALID_HANDLE;
01424 rsa->ontoken = ISC_TRUE;
01425 rsa->reqlogon = ISC_TRUE;
01426 key->keydata.pkey = rsa;
01427
01428 rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
01429 if (rsa->repr == NULL)
01430 DST_RET(ISC_R_NOMEMORY);
01431 memset(rsa->repr, 0, sizeof(*attr) * 2);
01432 rsa->attrcnt = 2;
01433 attr = rsa->repr;
01434 attr[0].type = CKA_MODULUS;
01435 attr[1].type = CKA_PUBLIC_EXPONENT;
01436
01437 ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
01438 if (ret != ISC_R_SUCCESS)
01439 goto err;
01440
01441 pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
01442 sizeof(*pk11_ctx));
01443 if (pk11_ctx == NULL)
01444 DST_RET(ISC_R_NOMEMORY);
01445 ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
01446 rsa->reqlogon, NULL, rsa->slot);
01447 if (ret != ISC_R_SUCCESS)
01448 goto err;
01449
01450 attr = pk11_attribute_bytype(rsa, CKA_LABEL);
01451 if (attr == NULL) {
01452 attr = pk11_attribute_bytype(rsa, CKA_ID);
01453 INSIST(attr != NULL);
01454 searchTemplate[3].type = CKA_ID;
01455 }
01456 searchTemplate[3].pValue = attr->pValue;
01457 searchTemplate[3].ulValueLen = attr->ulValueLen;
01458
01459 PK11_RET(pkcs_C_FindObjectsInit,
01460 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
01461 DST_R_CRYPTOFAILURE);
01462 PK11_RET(pkcs_C_FindObjects,
01463 (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt),
01464 DST_R_CRYPTOFAILURE);
01465 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
01466 if (cnt == 0)
01467 DST_RET(ISC_R_NOTFOUND);
01468 if (cnt > 1)
01469 DST_RET(ISC_R_EXISTS);
01470
01471 attr = rsa->repr;
01472 PK11_RET(pkcs_C_GetAttributeValue,
01473 (pk11_ctx->session, hKey, attr, 2),
01474 DST_R_CRYPTOFAILURE);
01475 for (i = 0; i <= 1; i++) {
01476 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
01477 if (attr[i].pValue == NULL)
01478 DST_RET(ISC_R_NOMEMORY);
01479 memset(attr[i].pValue, 0, attr[i].ulValueLen);
01480 }
01481 PK11_RET(pkcs_C_GetAttributeValue,
01482 (pk11_ctx->session, hKey, attr, 2),
01483 DST_R_CRYPTOFAILURE);
01484
01485 keyClass = CKO_PRIVATE_KEY;
01486 PK11_RET(pkcs_C_FindObjectsInit,
01487 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
01488 DST_R_CRYPTOFAILURE);
01489 PK11_RET(pkcs_C_FindObjects,
01490 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
01491 DST_R_CRYPTOFAILURE);
01492 (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
01493 if (cnt == 0)
01494 DST_RET(ISC_R_NOTFOUND);
01495 if (cnt > 1)
01496 DST_RET(ISC_R_EXISTS);
01497
01498 if (engine != NULL) {
01499 key->engine = isc_mem_strdup(key->mctx, engine);
01500 if (key->engine == NULL)
01501 DST_RET(ISC_R_NOMEMORY);
01502 }
01503
01504 key->label = isc_mem_strdup(key->mctx, label);
01505 if (key->label == NULL)
01506 DST_RET(ISC_R_NOMEMORY);
01507
01508 attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
01509 INSIST(attr != NULL);
01510 if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
01511 DST_RET(ISC_R_RANGE);
01512
01513 attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
01514 INSIST(attr != NULL);
01515 key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
01516
01517 pk11_return_session(pk11_ctx);
01518 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
01519 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
01520
01521 return (ISC_R_SUCCESS);
01522
01523 err:
01524 pkcs11rsa_destroy(key);
01525 if (pk11_ctx != NULL) {
01526 pk11_return_session(pk11_ctx);
01527 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
01528 isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
01529 }
01530
01531 return (ret);
01532 }
01533
01534 static dst_func_t pkcs11rsa_functions = {
01535 pkcs11rsa_createctx,
01536 pkcs11rsa_createctx2,
01537 pkcs11rsa_destroyctx,
01538 pkcs11rsa_adddata,
01539 pkcs11rsa_sign,
01540 pkcs11rsa_verify,
01541 NULL,
01542 NULL,
01543 pkcs11rsa_compare,
01544 NULL,
01545 pkcs11rsa_generate,
01546 pkcs11rsa_isprivate,
01547 pkcs11rsa_destroy,
01548 pkcs11rsa_todns,
01549 pkcs11rsa_fromdns,
01550 pkcs11rsa_tofile,
01551 pkcs11rsa_parse,
01552 NULL,
01553 pkcs11rsa_fromlabel,
01554 NULL,
01555 NULL,
01556 };
01557
01558 isc_result_t
01559 dst__pkcs11rsa_init(dst_func_t **funcp) {
01560 REQUIRE(funcp != NULL);
01561
01562 if (*funcp == NULL)
01563 *funcp = &pkcs11rsa_functions;
01564 return (ISC_R_SUCCESS);
01565 }
01566
01567 #else
01568
01569 #include <isc/util.h>
01570
01571 EMPTY_TRANSLATION_UNIT
01572
01573 #endif
01574