static void pkcs11ecdsa_destroy(dst_key_t *key) { pk11_object_t *ec = key->keydata.pkey; CK_ATTRIBUTE *attr; if (ec == NULL) return; INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken); for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_LABEL: case CKA_ID: case CKA_EC_PARAMS: case CKA_EC_POINT: case CKA_VALUE: FREECURVE(); break; } if (ec->repr != NULL) { memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, ec->repr, ec->attrcnt * sizeof(*attr)); } memset(ec, 0, sizeof(*ec)); isc_mem_put(key->mctx, ec, sizeof(*ec)); key->keydata.pkey = NULL; }
static void pkcs11gost_destroy(dst_key_t *key) { pk11_object_t *gost = key->keydata.pkey; CK_ATTRIBUTE *attr; if (gost == NULL) return; INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken); for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: case CKA_VALUE2: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (gost->repr != NULL) { memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, gost->repr, gost->attrcnt * sizeof(*attr)); } memset(gost, 0, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); key->keydata.pkey = NULL; }
static isc_result_t pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *gost; isc_region_t r; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != ISC_GOST_PUBKEYLENGTH) return (DST_R_INVALIDPUBLICKEY); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) return (ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr)); if (gost->repr == NULL) goto nomemory; gost->attrcnt = 1; attr = gost->repr; attr->type = CKA_VALUE; attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH); if (attr->pValue == NULL) goto nomemory; memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH); attr->ulValueLen = ISC_GOST_PUBKEYLENGTH; isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH); key->keydata.pkey = gost; key->key_size = ISC_GOST_KEYSIZE; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (gost->repr != NULL) { memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, gost->repr, gost->attrcnt * sizeof(*attr)); } memset(gost, 0, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); return (ISC_R_NOMEMORY); }
CK_ATTRIBUTE * pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) { CK_ATTRIBUTE *attr; for(attr = pk11_attribute_first(obj); attr != NULL; attr = pk11_attribute_next(obj, attr)) if (attr->type == type) return (attr); return (NULL); }
static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *rsa; CK_ATTRIBUTE *attr; isc_region_t r; unsigned int e_bytes = 0, mod_bytes = 0; CK_BYTE *exponent = NULL, *modulus = NULL; REQUIRE(key->keydata.pkey != NULL); rsa = key->keydata.pkey; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_PUBLIC_EXPONENT: exponent = (CK_BYTE *) attr->pValue; e_bytes = (unsigned int) attr->ulValueLen; break; case CKA_MODULUS: modulus = (CK_BYTE *) attr->pValue; mod_bytes = (unsigned int) attr->ulValueLen; break; } REQUIRE((exponent != NULL) && (modulus != NULL)); isc_buffer_availableregion(data, &r); if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ if (r.length < 1) return (ISC_R_NOSPACE); isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); isc_region_consume(&r, 1); } else { if (r.length < 3) return (ISC_R_NOSPACE); isc_buffer_putuint8(data, 0); isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); isc_region_consume(&r, 3); } if (r.length < e_bytes + mod_bytes) return (ISC_R_NOSPACE); memmove(r.base, exponent, e_bytes); isc_region_consume(&r, e_bytes); memmove(r.base, modulus, mod_bytes); isc_buffer_add(data, e_bytes + mod_bytes); return (ISC_R_SUCCESS); }
static void pkcs11rsa_destroy(dst_key_t *key) { pk11_object_t *rsa = key->keydata.pkey; CK_ATTRIBUTE *attr; if (rsa == NULL) return; INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken); for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_LABEL: case CKA_ID: case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (rsa->repr != NULL) { memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); key->keydata.pkey = NULL; }
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 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 pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dsa; isc_region_t r; unsigned int t, p_bytes; CK_BYTE *prime, *subprime, *base, *pub_key; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) return (ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } subprime = r.base; isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); prime = r.base; isc_region_consume(&r, p_bytes); base = r.base; isc_region_consume(&r, p_bytes); pub_key = r.base; isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dsa->repr == NULL) goto nomemory; memset(dsa->repr, 0, sizeof(*attr) * 4); dsa->attrcnt = 4; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[0].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, prime, p_bytes); attr[0].ulValueLen = p_bytes; attr[1].type = CKA_SUBPRIME; attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH); attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH; attr[2].type = CKA_BASE; attr[2].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[2].pValue == NULL) goto nomemory; memmove(attr[2].pValue, base, p_bytes); attr[2].ulValueLen = p_bytes; attr[3].type = CKA_VALUE; attr[3].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[3].pValue == NULL) goto nomemory; memmove(attr[3].pValue, pub_key, p_bytes); attr[3].ulValueLen = p_bytes; key->keydata.pkey = dsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dsa->repr != NULL) { memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (ISC_R_NOMEMORY); }
static isc_result_t pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { CK_RV rv; CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; 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_EC_PARAMS, NULL, 0 }, { CKA_EC_POINT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; CK_ULONG dgstlen; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; dst_key_t *key = dctx->key; pk11_object_t *ec = key->keydata.pkey; isc_result_t ret = ISC_R_SUCCESS; unsigned int i; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (key->key_alg == DST_ALG_ECDSA256) dgstlen = ISC_SHA256_DIGESTLENGTH; else dgstlen = ISC_SHA384_DIGESTLENGTH; PK11_RET(pkcs_C_DigestFinal, (pk11_ctx->session, digest, &dgstlen), ISC_R_FAILURE); for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: 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_EC_POINT: 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; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_Verify, (pk11_ctx->session, digest, dgstlen, (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), DST_R_VERIFYFAILURE); err: if (hKey != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); 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)); dctx->ctxdata.pk11_ctx = NULL; return (ret); }
static isc_result_t pkcs11ecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { CK_RV rv; CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_EC; 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_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; CK_ULONG dgstlen; CK_ULONG siglen; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; dst_key_t *key = dctx->key; pk11_object_t *ec = key->keydata.pkey; isc_region_t r; isc_result_t ret = ISC_R_SUCCESS; unsigned int i; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (key->key_alg == DST_ALG_ECDSA256) { dgstlen = ISC_SHA256_DIGESTLENGTH; siglen = DNS_SIG_ECDSA256SIZE; } else { siglen = DNS_SIG_ECDSA384SIZE; dgstlen = ISC_SHA384_DIGESTLENGTH; } PK11_RET(pkcs_C_DigestFinal, (pk11_ctx->session, digest, &dgstlen), ISC_R_FAILURE); isc_buffer_availableregion(sig, &r); if (r.length < siglen) DST_RET(ISC_R_NOSPACE); if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = ec->ontoken; pk11_ctx->object = ec->object; goto token_key; } for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: 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_VALUE: 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; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &hKey), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->ontoken ? pk11_ctx->object : hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_Sign, (pk11_ctx->session, digest, dgstlen, (CK_BYTE_PTR) r.base, &siglen), DST_R_SIGNFAILURE); isc_buffer_add(sig, (unsigned int) siglen); err: if (hKey != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); 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)); dctx->ctxdata.pk11_ctx = NULL; 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_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; pk11_object_t *dsa; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL; CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL; dst_private_t priv; unsigned char bufs[5][128]; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } dsa = key->keydata.pkey; for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: prime = attr; break; case CKA_SUBPRIME: subprime = attr; break; case CKA_BASE: base = attr; break; case CKA_VALUE: pub_key = attr; break; case CKA_VALUE2: priv_key = attr; break; } if ((prime == NULL) || (subprime == NULL) || (base == NULL) || (pub_key == NULL) || (priv_key ==NULL)) return (DST_R_NULLKEY); priv.elements[cnt].tag = TAG_DSA_PRIME; priv.elements[cnt].length = (unsigned short) prime->ulValueLen; memmove(bufs[cnt], prime->pValue, prime->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_SUBPRIME; priv.elements[cnt].length = (unsigned short) subprime->ulValueLen; memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_BASE; priv.elements[cnt].length = (unsigned short) base->ulValueLen; memmove(bufs[cnt], base->pValue, base->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PRIVATE; priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen; memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PUBLIC; priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen; memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); }
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 pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *rsa; isc_region_t r; unsigned int e_bytes, mod_bytes; CK_BYTE *exponent = NULL, *modulus = NULL; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) return (ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); if (r.length < 1) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base++; r.length--; if (e_bytes == 0) { if (r.length < 2) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } e_bytes = ((*r.base++) << 8); e_bytes += *r.base++; r.length -= 2; } if (r.length < e_bytes) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } exponent = r.base; r.base += e_bytes; r.length -= e_bytes; modulus = r.base; mod_bytes = r.length; key->key_size = pk11_numbits(modulus, mod_bytes); isc_buffer_forward(data, r.length); rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) goto nomemory; memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, modulus, mod_bytes); attr[0].ulValueLen = (CK_ULONG) mod_bytes; attr[1].type = CKA_PUBLIC_EXPONENT; attr[1].pValue = isc_mem_get(key->mctx, e_bytes); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, exponent, e_bytes); attr[1].ulValueLen = (CK_ULONG) e_bytes; key->keydata.pkey = rsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (rsa->repr != NULL) { memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (ISC_R_NOMEMORY); }
static isc_result_t pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *ec; isc_region_t r; unsigned int len; CK_ATTRIBUTE *attr; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) len = DNS_KEY_ECDSA256SIZE; else len = DNS_KEY_ECDSA384SIZE; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != len) return (DST_R_INVALIDPUBLICKEY); ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) return (ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (ec->repr == NULL) goto nomemory; ec->attrcnt = 2; attr = ec->repr; attr->type = CKA_EC_PARAMS; if (key->key_alg == DST_ALG_ECDSA256) { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); attr->ulValueLen = sizeof(pk11_ecc_prime256v1); } else { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); attr->ulValueLen = sizeof(pk11_ecc_secp384r1); } attr++; attr->type = CKA_EC_POINT; attr->pValue = isc_mem_get(key->mctx, len + 3); if (attr->pValue == NULL) goto nomemory; ((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING; ((CK_BYTE_PTR) attr->pValue)[1] = len + 1; ((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED; memmove((CK_BYTE_PTR) attr->pValue + 3, r.base, len); attr->ulValueLen = len + 3; isc_buffer_forward(data, len); key->keydata.pkey = ec; key->key_size = len * 4; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: case CKA_EC_POINT: FREECURVE(); break; } if (ec->repr != NULL) { memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, ec->repr, ec->attrcnt * sizeof(*attr)); } memset(ec, 0, sizeof(*ec)); isc_mem_put(key->mctx, ec, sizeof(*ec)); return (ISC_R_NOMEMORY); }
static isc_result_t pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { int i; pk11_object_t *rsa; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; dst_private_t priv; unsigned char *bufs[10]; isc_result_t result; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } rsa = key->keydata.pkey; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: modulus = attr; break; case CKA_PUBLIC_EXPONENT: exponent = attr; break; case CKA_PRIVATE_EXPONENT: d = attr; break; case CKA_PRIME_1: p = attr; break; case CKA_PRIME_2: q = attr; break; case CKA_EXPONENT_1: dmp1 = attr; break; case CKA_EXPONENT_2: dmq1 = attr; break; case CKA_COEFFICIENT: iqmp = attr; break; } if ((modulus == NULL) || (exponent == NULL)) return (DST_R_NULLKEY); memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 10; i++) { bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } memset(bufs[i], 0, modulus->ulValueLen); } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = (unsigned short) modulus->ulValueLen; memmove(bufs[i], modulus->pValue, modulus->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = (unsigned short) exponent->ulValueLen; memmove(bufs[i], exponent->pValue, exponent->ulValueLen); priv.elements[i].data = bufs[i]; i++; if (d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = (unsigned short) d->ulValueLen; memmove(bufs[i], d->pValue, d->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = (unsigned short) p->ulValueLen; memmove(bufs[i], p->pValue, p->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = (unsigned short) q->ulValueLen; memmove(bufs[i], q->pValue, q->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = (unsigned short) dmp1->ulValueLen; memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = (unsigned short) dmq1->ulValueLen; memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = (unsigned short) iqmp->ulValueLen; memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: for (i = 0; i < 10; i++) { if (bufs[i] == NULL) break; memset(bufs[i], 0, modulus->ulValueLen); isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); } return (result); }
static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dsa; CK_ATTRIBUTE *attr; isc_region_t r; int dnslen; unsigned int t, p_bytes; CK_ATTRIBUTE *prime = NULL, *subprime = NULL; CK_ATTRIBUTE *base = NULL, *pub_key = NULL; CK_BYTE *cp; REQUIRE(key->keydata.pkey != NULL); dsa = key->keydata.pkey; for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: prime = attr; break; case CKA_SUBPRIME: subprime = attr; break; case CKA_BASE: base = attr; break; case CKA_VALUE: pub_key = attr; break; } REQUIRE((prime != NULL) && (subprime != NULL) && (base != NULL) && (pub_key != NULL)); isc_buffer_availableregion(data, &r); t = (prime->ulValueLen - 64) / 8; if (t > 8) return (DST_R_INVALIDPUBLICKEY); p_bytes = 64 + 8 * t; dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); memset(r.base, 0, dnslen); *r.base = t; isc_region_consume(&r, 1); cp = (CK_BYTE *) subprime->pValue; memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen, cp, subprime->ulValueLen); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); cp = (CK_BYTE *) prime->pValue; memmove(r.base + key->key_size/8 - prime->ulValueLen, cp, prime->ulValueLen); isc_region_consume(&r, p_bytes); cp = (CK_BYTE *) base->pValue; memmove(r.base + key->key_size/8 - base->ulValueLen, cp, base->ulValueLen); isc_region_consume(&r, p_bytes); cp = (CK_BYTE *) pub_key->pValue; memmove(r.base + key->key_size/8 - pub_key->ulValueLen, cp, pub_key->ulValueLen); isc_region_consume(&r, p_bytes); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); }