static isc_result_t pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = {0, NULL, 0 }; CK_SLOT_ID slotid; pk11_context_t *pk11_ctx; pk11_object_t *ec = key->keydata.pkey; isc_result_t ret; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (dctx->key->key_alg == DST_ALG_ECDSA256) mech.mechanism = CKM_SHA256; else mech.mechanism = CKM_SHA384; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (ec->ontoken && (dctx->use == DO_SIGN)) slotid = ec->slot; else slotid = pk11_get_best_token(OP_EC); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ec->reqlogon, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; return (ISC_R_SUCCESS); err: pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, { CKA_PRIME_1, NULL, 0 }, { CKA_PRIME_2, NULL, 0 }, { CKA_EXPONENT_1, NULL, 0 }, { CKA_EXPONENT_2, NULL, 0 }, { CKA_COEFFICIENT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_SLOT_ID slotid; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (rsa->ontoken) slotid = rsa->slot; else slotid = pk11_get_best_token(OP_RSA); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = rsa->ontoken; pk11_ctx->object = rsa->object; goto token_key; } for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_PRIVATE_EXPONENT: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_1: INSIST(keyTemplate[9].type == attr->type); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_2: INSIST(keyTemplate[10].type == attr->type); keyTemplate[10].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[10].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[10].pValue, attr->pValue, attr->ulValueLen); keyTemplate[10].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_1: INSIST(keyTemplate[11].type == attr->type); keyTemplate[11].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[11].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[11].pValue, attr->pValue, attr->ulValueLen); keyTemplate[11].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_2: INSIST(keyTemplate[12].type == attr->type); keyTemplate[12].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[12].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[12].pValue, attr->pValue, attr->ulValueLen); keyTemplate[12].ulValueLen = attr->ulValueLen; break; case CKA_COEFFICIENT: INSIST(keyTemplate[13].type == attr->type); keyTemplate[13].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[13].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[13].pValue, attr->pValue, attr->ulValueLen); keyTemplate[13].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 14, &pk11_ctx->object), ISC_R_FAILURE); token_key: switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_ULONG bits = 0; CK_BYTE pubexp[5]; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if (exp == 0) { /* RSA_F4 0x10001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 1; pubTemplate[6].ulValueLen = 3; } else { /* F5 0x100000001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 0; pubexp[3] = 0; pubexp[4] = 1; pubTemplate[6].ulValueLen = 5; } PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); key->keydata.pkey = rsa; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 8); rsa->attrcnt = 8; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; attr[2].type = CKA_PRIVATE_EXPONENT; attr[3].type = CKA_PRIME_1; attr[4].type = CKA_PRIME_2; attr[5].type = CKA_EXPONENT_1; attr[6].type = CKA_EXPONENT_2; attr[7].type = CKA_COEFFICIENT; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); attr += 2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); for (i = 0; i <= 5; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 }; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); key->keydata.pkey = gost; gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (gost->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost->repr, 0, sizeof(*attr) * 2); gost->attrcnt = 2; attr = gost->repr; attr[0].type = CKA_VALUE; attr[1].type = CKA_VALUE2; attr = gost->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11gost_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, 0 }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; gost = key->keydata.pkey; if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = gost->ontoken; pk11_ctx->object = gost->object; goto token_key; } for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 8, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE; CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DH; CK_ULONG bits = 0; CK_ATTRIBUTE dTemplate[] = { { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) } }; CK_ATTRIBUTE pTemplate[] = { { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dh = NULL; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if ((generator == 0) && ((bits == 768) || (bits == 1024) || (bits == 1536))) { if (bits == 768) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn768)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn768, sizeof(pk11_dh_bn768)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768); } else if (bits == 1024) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1024, sizeof(pk11_dh_bn1024)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024); } else { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1536, sizeof(pk11_dh_bn1536)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536); } pubTemplate[5].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn2)); if (pubTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[5].pValue, pk11_dh_bn2, sizeof(pk11_dh_bn2)); pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2); } else { PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dTemplate, (CK_ULONG) 5, &domainparams), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pTemplate[0].pValue = isc_mem_get(key->mctx, pTemplate[0].ulValueLen); if (pTemplate[0].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); pTemplate[1].pValue = isc_mem_get(key->mctx, pTemplate[1].ulValueLen); if (pTemplate[1].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pubTemplate[4].pValue = pTemplate[0].pValue; pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen; pTemplate[0].pValue = NULL; pubTemplate[5].pValue = pTemplate[1].pValue; pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen; pTemplate[1].pValue = NULL; } mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh, 0, sizeof(*dh)); key->keydata.pkey = dh; dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dh->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh->repr, 0, sizeof(*attr) * 4); dh->attrcnt = 4; attr = dh->repr; attr[0].type = CKA_PRIME; attr[0].pValue = pubTemplate[4].pValue; attr[0].ulValueLen = pubTemplate[4].ulValueLen; pubTemplate[4].pValue = NULL; attr[1].type = CKA_BASE; attr[1].pValue = pubTemplate[5].pValue; attr[1].ulValueLen = pubTemplate[5].ulValueLen; pubTemplate[5].pValue =NULL; attr += 2; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dh_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (domainparams != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); if (pubTemplate[4].pValue != NULL) { memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen); isc_mem_put(key->mctx, pubTemplate[4].pValue, pubTemplate[4].ulValueLen); } if (pubTemplate[5].pValue != NULL) { memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen); isc_mem_put(key->mctx, pubTemplate[5].pValue, pubTemplate[5].ulValueLen); } if (pTemplate[0].pValue != NULL) { memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); isc_mem_put(key->mctx, pTemplate[0].pValue, pTemplate[0].ulValueLen); } if (pTemplate[1].pValue != NULL) { memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); isc_mem_put(key->mctx, pTemplate[1].pValue, pTemplate[1].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } }; CK_ATTRIBUTE *attr; pk11_object_t *ec; pk11_context_t *pk11_ctx; isc_result_t ret; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_EC)); if (ret != ISC_R_SUCCESS) goto err; ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); key->keydata.pkey = ec; ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); if (ec->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 3); ec->attrcnt = 3; attr = ec->repr; attr[0].type = CKA_EC_PARAMS; attr[1].type = CKA_EC_POINT; attr[2].type = CKA_VALUE; attr = &pubTemplate[5]; SETCURVE(); PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = &pubTemplate[5]; FREECURVE(); attr = ec->repr; SETCURVE(); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; return (ISC_R_SUCCESS); err: pkcs11ecdsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_ATTRIBUTE *attr; CK_ULONG secLen; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) } }; CK_ATTRIBUTE valTemplate[] = { { CKA_VALUE, NULL, 0 } }; CK_BYTE *secValue; pk11_context_t ctx; isc_result_t ret; unsigned int i; isc_region_t r; REQUIRE(pub->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey->repr != NULL); attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); REQUIRE(attr != NULL); secLen = attr->ulValueLen; attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) return (ret); mech.ulParameterLen = attr->ulValueLen; mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen); if (mech.pParameter == NULL) DST_RET(ISC_R_NOMEMORY); memmove(mech.pParameter, attr->pValue, mech.ulParameterLen); ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DeriveKey, (ctx.session, &mech, hKey, keyTemplate, (CK_ULONG) 6, &hDerived), DST_R_COMPUTESECRETFAILURE); attr = valTemplate; PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); /* strip leading zeros */ secValue = (CK_BYTE_PTR) attr->pValue; for (i = 0; i < attr->ulValueLen; i++) if (secValue[i] != 0) break; isc_buffer_availableregion(secret, &r); if (r.length < attr->ulValueLen - i) DST_RET(ISC_R_NOSPACE); memmove(r.base, secValue + i, attr->ulValueLen - i); isc_buffer_add(secret, attr->ulValueLen - i); ret = ISC_R_SUCCESS; err: if (hDerived != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx.session, hDerived); if (valTemplate[0].pValue != NULL) { memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen); isc_mem_put(pub->mctx, valTemplate[0].pValue, valTemplate[0].ulValueLen); } if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) (void) pkcs_C_DestroyObject(ctx.session, hKey); if (mech.pParameter != NULL) { memset(mech.pParameter, 0, mech.ulParameterLen); isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); } pk11_return_session(&ctx); return (ret); }
static isc_result_t pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_FALSE, rsa->reqlogon, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; if (pk11_numbits(attr->pValue, attr->ulValueLen) > maxbits && maxbits != 0) DST_RET(DST_R_VERIFYFAILURE); break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &pk11_ctx->object), ISC_R_FAILURE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_DSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; dsa = key->keydata.pkey; if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = dsa->ontoken; pk11_ctx->object = dsa->object; goto token_key; } for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_SUBPRIME: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_BASE: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_VALUE2: INSIST(keyTemplate[9].type == CKA_VALUE); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 10, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE; CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DSA; CK_ULONG bits = 0; CK_ATTRIBUTE dpTemplate[] = { { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }, }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp), DST_R_CRYPTOFAILURE); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); key->keydata.pkey = dsa; dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); if (dsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa->repr, 0, sizeof(*attr) * 5); dsa->attrcnt = 5; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[1].type = CKA_SUBPRIME; attr[2].type = CKA_BASE; attr[3].type = CKA_VALUE; attr[4].type = CKA_VALUE2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); for (i = 0; i <= 2; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); pubTemplate[5].pValue = attr[0].pValue; pubTemplate[5].ulValueLen = attr[0].ulValueLen; pubTemplate[6].pValue = attr[1].pValue; pubTemplate[6].ulValueLen = attr[1].ulValueLen; pubTemplate[7].pValue = attr[2].pValue; pubTemplate[7].ulValueLen = attr[2].ulValueLen; mech.mechanism = CKM_DSA_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 8, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = dsa->repr; attr += 3; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (dp != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
ATF_TC_BODY(isc_gost_private, tc) { isc_result_t result; unsigned char privraw[31] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; #ifdef HAVE_OPENSSL_GOST unsigned char rbuf[32]; unsigned char privasn1[70] = { 0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; unsigned char abuf[71]; unsigned char gost_dummy_key[71] = { 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b, 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 }; EVP_PKEY *pkey; EC_KEY *eckey; BIGNUM *privkey; const BIGNUM *privkey1; const unsigned char *p; int len; unsigned char *q; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* raw parse */ privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL); ATF_REQUIRE(privkey != NULL); p = gost_dummy_key; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(gost_dummy_key)) != NULL); ATF_REQUIRE(pkey != NULL); ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1); BN_clear_free(privkey); /* asn1 tofile */ len = i2d_PrivateKey(pkey, NULL); ATF_REQUIRE(len == 70); q = abuf; ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len); ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0); EVP_PKEY_free(pkey); /* asn1 parse */ p = privasn1; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) len) != NULL); ATF_REQUIRE(pkey != NULL); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); privkey1 = EC_KEY_get0_private_key(eckey); len = BN_num_bytes(privkey1); ATF_REQUIRE(len == 31); ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len); ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0); dns_test_end(); #else CK_BBOOL truevalue = TRUE; CK_BBOOL falsevalue = FALSE; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, privraw, sizeof(privraw) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_BYTE sig[64]; CK_ULONG siglen; pk11_context_t pk11_ctx; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* create the private key */ memset(&pk11_ctx, 0, sizeof(pk11_ctx)); ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)) == ISC_R_SUCCESS); pk11_ctx.object = CK_INVALID_HANDLE; pk11_ctx.ontoken = ISC_FALSE; ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate, (CK_ULONG) 9, &pk11_ctx.object) == CKR_OK); ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE); /* sign something */ ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech, pk11_ctx.object) == CKR_OK); siglen = 0; ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, NULL, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, sig, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); dns_test_end(); #endif };