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); }
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); }