isc_result_t dst_key_buildinternal(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, void *data, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(data != NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, bits, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); key->keydata.generic = data; result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } *keyp = key; return (ISC_R_SUCCESS); }
isc_result_t dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(target != NULL); CHECKALG(key->key_alg); if (key->func->todns == NULL) return (DST_R_UNSUPPORTEDALG); if (isc_buffer_availablelength(target) < 4) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff)); isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto); isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg); if (key->key_flags & DNS_KEYFLAG_EXTENDED) { if (isc_buffer_availablelength(target) < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)((key->key_flags >> 16) & 0xffff)); } if (key->keydata.generic == NULL) /*%< NULL KEY */ return (ISC_R_SUCCESS); return (key->func->todns(key, target)); }
isc_result_t dst_key_getfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, isc_buffer_t *buf) { isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(buf != NULL); CHECKALG(alg); result = buildfilename(name, id, alg, type, directory, buf); if (result == ISC_R_SUCCESS) { if (isc_buffer_availablelength(buf) > 0) isc_buffer_putuint8(buf, 0); else result = ISC_R_NOSPACE; } return (result); }
isc_result_t dst_key_tofile(const dst_key_t *key, int type, const char *directory) { isc_result_t ret = ISC_R_SUCCESS; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); CHECKALG(key->key_alg); if (key->func->tofile == NULL) return (DST_R_UNSUPPORTEDALG); if (type & DST_TYPE_PUBLIC) { ret = write_public_key(key, type, directory); if (ret != ISC_R_SUCCESS) return (ret); } if ((type & DST_TYPE_PRIVATE) && (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) return (key->func->tofile(key, directory)); else return (ISC_R_SUCCESS); }
isc_result_t dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(target != NULL); CHECKALG(key->key_alg); if (key->func->todns == NULL) return (DST_R_UNSUPPORTEDALG); return (key->func->todns(key, target)); }
isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig) { REQUIRE(VALID_CTX(dctx)); REQUIRE(sig != NULL); CHECKALG(dctx->key->key_alg); if (dctx->key->keydata.generic == NULL) return (DST_R_NULLKEY); if (dctx->key->func->verify == NULL) return (DST_R_NOTPUBLICKEY); return (dctx->key->func->verify(dctx, sig)); }
isc_result_t dst_key_generate2(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int param, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp, void (*callback)(int)) { dst_key_t *key; isc_result_t ret; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, bits, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (bits == 0) { /*%< NULL KEY */ key->key_flags |= DNS_KEYTYPE_NOKEY; *keyp = key; return (ISC_R_SUCCESS); } if (key->func->generate == NULL) { dst_key_free(&key); return (DST_R_UNSUPPORTEDALG); } ret = key->func->generate(key, param, callback); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } ret = computeid(key); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } *keyp = key; return (ISC_R_SUCCESS); }
isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(pub) && VALID_KEY(priv)); REQUIRE(secret != NULL); CHECKALG(pub->key_alg); CHECKALG(priv->key_alg); if (pub->keydata.generic == NULL || priv->keydata.generic == NULL) return (DST_R_NULLKEY); if (pub->key_alg != priv->key_alg || pub->func->computesecret == NULL || priv->func->computesecret == NULL) return (DST_R_KEYCANNOTCOMPUTESECRET); if (dst_key_isprivate(priv) == ISC_FALSE) return (DST_R_NOTPRIVATEKEY); return (pub->func->computesecret(pub, priv, secret)); }
isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; char filename[ISC_DIR_NAMEMAX]; isc_buffer_t buf; dst_key_t *key; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); key = NULL; isc_buffer_init(&buf, filename, ISC_DIR_NAMEMAX); result = dst_key_getfilename(name, id, alg, type, NULL, mctx, &buf); if (result != ISC_R_SUCCESS) goto out; result = dst_key_fromnamedfile(filename, directory, type, mctx, &key); if (result != ISC_R_SUCCESS) goto out; result = computeid(key); if (result != ISC_R_SUCCESS) goto out; if (!dns_name_equal(name, key->key_name) || id != key->key_id || alg != key->key_alg) { result = DST_R_INVALIDPRIVATEKEY; goto out; } *keyp = key; result = ISC_R_SUCCESS; out: if ((key != NULL) && (result != ISC_R_SUCCESS)) dst_key_free(&key); return (result); }
isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp) { char filename[ISC_DIR_NAMEMAX]; isc_buffer_t b; dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); isc_buffer_init(&b, filename, sizeof(filename)); result = buildfilename(name, id, alg, type, directory, &b); if (result != ISC_R_SUCCESS) return (result); key = NULL; result = dst_key_fromnamedfile(filename, type, mctx, &key); if (result != ISC_R_SUCCESS) return (result); result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } if (!dns_name_equal(name, key->key_name) || id != key->key_id || alg != key->key_alg) { dst_key_free(&key); return (DST_R_INVALIDPRIVATEKEY); } key->key_id = id; *keyp = key; return (ISC_R_SUCCESS); }
isc_result_t dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key; REQUIRE(VALID_CTX(dctx)); REQUIRE(sig != NULL); key = dctx->key; CHECKALG(key->key_alg); if (key->opaque == NULL) return (DST_R_NULLKEY); if (key->func->sign == NULL) return (DST_R_NOTPRIVATEKEY); if (key->func->isprivate == NULL || key->func->isprivate(key) == ISC_FALSE) return (DST_R_NOTPRIVATEKEY); return (key->func->sign(dctx, sig)); }
isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(label != NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (key->func->fromlabel == NULL) { dst_key_free(&key); return (DST_R_UNSUPPORTEDALG); } result = key->func->fromlabel(key, engine, label, pin); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } *keyp = key; return (ISC_R_SUCCESS); }