isc_result_t dst_key_frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key = NULL; isc_result_t result; REQUIRE(dst_initialized); result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx, &key); if (result != ISC_R_SUCCESS) return (result); 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_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_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_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_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); }
isc_result_t dst_key_fromnamedfile(const char *filename, const char *dirname, int type, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; dst_key_t *pubkey = NULL, *key = NULL; char *newfilename = NULL; int newfilenamelen = 0; isc_lex_t *lex = NULL; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(filename != NULL); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); /* If an absolute path is specified, don't use the key directory */ #ifndef WIN32 if (filename[0] == '/') dirname = NULL; #else /* WIN32 */ if (filename[0] == '/' || filename[0] == '\\') dirname = NULL; #endif newfilenamelen = strlen(filename) + 5; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) return (ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".key"); INSIST(result == ISC_R_SUCCESS); result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; RETERR(result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { result = computeid(pubkey); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } *keyp = pubkey; return (ISC_R_SUCCESS); } result = algorithm_status(pubkey->key_alg); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } key = get_key_struct(pubkey->key_name, pubkey->key_alg, pubkey->key_flags, pubkey->key_proto, 0, pubkey->key_class, pubkey->key_ttl, mctx); if (key == NULL) { dst_key_free(&pubkey); return (ISC_R_NOMEMORY); } if (key->func->parse == NULL) RETERR(DST_R_UNSUPPORTEDALG); newfilenamelen = strlen(filename) + 9; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) RETERR(ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".private"); INSIST(result == ISC_R_SUCCESS); RETERR(isc_lex_create(mctx, 1500, &lex)); RETERR(isc_lex_openfile(lex, newfilename)); isc_mem_put(mctx, newfilename, newfilenamelen); RETERR(key->func->parse(key, lex, pubkey)); isc_lex_destroy(&lex); RETERR(computeid(key)); if (pubkey->key_id != key->key_id) RETERR(DST_R_INVALIDPRIVATEKEY); dst_key_free(&pubkey); *keyp = key; return (ISC_R_SUCCESS); out: if (pubkey != NULL) dst_key_free(&pubkey); if (newfilename != NULL) isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); if (key != NULL) dst_key_free(&key); return (result); }
/*% * Set the flags on a key, then recompute the key ID */ isc_result_t dst_key_setflags(dst_key_t *key, isc_uint32_t flags) { REQUIRE(VALID_KEY(key)); key->key_flags = flags; return (computeid(key)); }
isc_result_t dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; dst_key_t *pubkey = NULL, *key = NULL; dns_keytag_t id; char *newfilename = NULL; int newfilenamelen = 0; isc_lex_t *lex = NULL; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(filename != NULL); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); newfilenamelen = strlen(filename) + 5; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) return (ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, filename, ".key"); INSIST(result == ISC_R_SUCCESS); result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; if (result != ISC_R_SUCCESS) return (result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { result = computeid(pubkey); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } *keyp = pubkey; return (ISC_R_SUCCESS); } result = algorithm_status(pubkey->key_alg); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } key = get_key_struct(pubkey->key_name, pubkey->key_alg, pubkey->key_flags, pubkey->key_proto, 0, pubkey->key_class, mctx); id = pubkey->key_id; dst_key_free(&pubkey); if (key == NULL) return (ISC_R_NOMEMORY); if (key->func->parse == NULL) RETERR(DST_R_UNSUPPORTEDALG); newfilenamelen = strlen(filename) + 9; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) RETERR(ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, filename, ".private"); INSIST(result == ISC_R_SUCCESS); RETERR(isc_lex_create(mctx, 1500, &lex)); RETERR(isc_lex_openfile(lex, newfilename)); isc_mem_put(mctx, newfilename, newfilenamelen); RETERR(key->func->parse(key, lex)); isc_lex_destroy(&lex); RETERR(computeid(key)); if (id != key->key_id) RETERR(DST_R_INVALIDPRIVATEKEY); *keyp = key; return (ISC_R_SUCCESS); out: if (newfilename != NULL) isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); dst_key_free(&key); return (result); }