2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-28 21:17:54 +00:00

More dst updates:

- dst_lib_init()/dst_lib_destroy() allow dst to use a predefined
	  mctx and free all resources on exit.
	- dst_key_tofile() & dst_key/fromfile() take a directory parameter.
	- dst_key_parsefile() removed, replaced by dst_key_fromnamedfile()
	- more bug fixes and memory leak fixes
This commit is contained in:
Brian Wellington 2000-06-06 21:58:16 +00:00
parent 46734259ca
commit 4441bfbd6b
12 changed files with 414 additions and 268 deletions

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: bsafe_link.c,v 1.25 2000/06/06 16:35:59 tale Exp $ * $Id: bsafe_link.c,v 1.26 2000/06/06 21:58:03 bwelling Exp $
*/ */
#if defined(DNSSAFE) #if defined(DNSSAFE)
@ -619,7 +619,7 @@ dnssafersa_fromdns(dst_key_t *key, isc_buffer_t *data) {
} }
static isc_result_t static isc_result_t
dnssafersa_tofile(const dst_key_t *key) { dnssafersa_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0; int cnt = 0;
B_KEY_OBJ rkey; B_KEY_OBJ rkey;
A_PKCS_RSA_PRIVATE_KEY *private = NULL; A_PKCS_RSA_PRIVATE_KEY *private = NULL;
@ -665,11 +665,12 @@ dnssafersa_tofile(const dst_key_t *key) {
priv.elements[cnt++].length = private->coefficient.len; priv.elements[cnt++].length = private->coefficient.len;
priv.nelements = cnt; priv.nelements = cnt;
return (dst__privstruct_writefile(key, &priv)); return (dst__privstruct_writefile(key, &priv, directory));
} }
static isc_result_t static isc_result_t
dnssafersa_fromfile(dst_key_t *key, const isc_uint16_t id) { dnssafersa_fromfile(dst_key_t *key, const isc_uint16_t id,
const char *filename) {
dst_private_t priv; dst_private_t priv;
isc_result_t ret; isc_result_t ret;
isc_buffer_t b; isc_buffer_t b;
@ -685,7 +686,7 @@ dnssafersa_fromfile(dst_key_t *key, const isc_uint16_t id) {
/* /*
* Read private key file. * Read private key file.
*/ */
ret = dst__privstruct_parsefile(key, id, &priv, mctx); ret = dst__privstruct_parsefile(key, id, filename, mctx, &priv);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
/* /*
@ -809,10 +810,15 @@ static dst_func_t dnssafersa_functions = {
dnssafersa_fromfile, dnssafersa_fromfile,
}; };
void isc_result_t
dst__dnssafersa_init(dst_func_t **funcp) { dst__dnssafersa_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL && *funcp == NULL); REQUIRE(funcp != NULL && *funcp == NULL);
*funcp = &dnssafersa_functions; *funcp = &dnssafersa_functions;
return (ISC_R_SUCCESS);
}
void
dst__dnssafersa_destroy(void) {
} }
/* /*

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: dst_api.c,v 1.46 2000/06/03 00:43:46 bwelling Exp $ * $Id: dst_api.c,v 1.47 2000/06/06 21:58:04 bwelling Exp $
*/ */
#include <config.h> #include <config.h>
@ -36,6 +36,7 @@
#include <isc/time.h> #include <isc/time.h>
#include <isc/util.h> #include <isc/util.h>
#include <dns/fixedname.h>
#include <dns/name.h> #include <dns/name.h>
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/types.h> #include <dns/types.h>
@ -58,28 +59,57 @@ dst_key_t *dst_key_md5 = NULL;
static dst_func_t *dst_t_func[DST_MAX_ALGS]; static dst_func_t *dst_t_func[DST_MAX_ALGS];
static isc_mem_t *dst_memory_pool = NULL; static isc_mem_t *dst_memory_pool = NULL;
static isc_boolean_t dst_initialized = ISC_FALSE;
static isc_mutex_t mutex, random_lock;
static isc_once_t once = ISC_ONCE_INIT; static isc_once_t once = ISC_ONCE_INIT;
static isc_mutex_t random_lock;
/* Static functions */ /* Static functions */
static void initialize(void); static isc_result_t initialize(isc_mem_t *mctx);
static dst_key_t * get_key_struct(dns_name_t *name, static dst_key_t * get_key_struct(dns_name_t *name,
const unsigned int alg, const unsigned int alg,
const unsigned int flags, const unsigned int flags,
const unsigned int protocol, const unsigned int protocol,
const unsigned int bits, const unsigned int bits,
isc_mem_t *mctx); isc_mem_t *mctx);
static isc_result_t read_public_key(dns_name_t *name, static isc_result_t read_public_key(const char *filename,
const isc_uint16_t id,
const unsigned int alg,
isc_mem_t *mctx, isc_mem_t *mctx,
dst_key_t **keyp); dst_key_t **keyp);
static isc_result_t write_public_key(const dst_key_t *key); static isc_result_t write_public_key(const dst_key_t *key,
const char *directory);
static isc_result_t buildfilename(dns_name_t *name,
const unsigned int id,
const unsigned int alg,
const unsigned int type,
const char *directory,
isc_buffer_t *out);
isc_result_t
dst_lib_init(isc_mem_t *mctx) {
return (initialize(mctx));
}
void
dst_lib_destroy() {
RUNTIME_CHECK(dst_initialized == ISC_TRUE);
dst_initialized = ISC_FALSE;
dst__hmacmd5_destroy();
#ifdef DNSSAFE
dst__dnssafersa_destroy();
#endif
#ifdef OPENSSL
dst__openssldsa_destroy();
dst__openssldh_destroy();
dst__opensslmd5_destroy();
#endif
isc_mem_detach(&dst_memory_pool);
}
isc_boolean_t isc_boolean_t
dst_algorithm_supported(const unsigned int alg) { dst_algorithm_supported(const unsigned int alg) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
return (ISC_FALSE); return (ISC_FALSE);
return (ISC_TRUE); return (ISC_TRUE);
@ -90,9 +120,9 @@ dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
dst_context_t *dctx; dst_context_t *dctx;
isc_result_t result; isc_result_t result;
REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(mctx != NULL); REQUIRE(mctx != NULL);
REQUIRE(dctxp != NULL && *dctxp == NULL); REQUIRE(dctxp != NULL && *dctxp == NULL);
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
if (key->func->createctx == NULL) if (key->func->createctx == NULL)
return (DST_R_UNSUPPORTEDALG); return (DST_R_UNSUPPORTEDALG);
@ -182,7 +212,7 @@ isc_result_t
dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
isc_buffer_t *secret) isc_buffer_t *secret)
{ {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(pub) && VALID_KEY(priv)); REQUIRE(VALID_KEY(pub) && VALID_KEY(priv));
REQUIRE(secret != NULL); REQUIRE(secret != NULL);
@ -205,11 +235,12 @@ dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
} }
isc_result_t isc_result_t
dst_key_tofile(const dst_key_t *key, const int type) { dst_key_tofile(const dst_key_t *key, const int type, const char *directory) {
isc_result_t ret = ISC_R_SUCCESS; isc_result_t ret = ISC_R_SUCCESS;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
if (dst_algorithm_supported(key->key_alg) == ISC_FALSE) if (dst_algorithm_supported(key->key_alg) == ISC_FALSE)
return (DST_R_UNSUPPORTEDALG); return (DST_R_UNSUPPORTEDALG);
@ -217,59 +248,91 @@ dst_key_tofile(const dst_key_t *key, const int type) {
if (key->func->tofile == NULL) if (key->func->tofile == NULL)
return (DST_R_UNSUPPORTEDALG); return (DST_R_UNSUPPORTEDALG);
if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0)
return (DST_R_UNSUPPORTEDTYPE);
if (type & DST_TYPE_PUBLIC) { if (type & DST_TYPE_PUBLIC) {
ret = write_public_key(key); ret = write_public_key(key, directory);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
} }
if ((type & DST_TYPE_PRIVATE) && if ((type & DST_TYPE_PRIVATE) &&
(key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
return (key->func->tofile(key)); return (key->func->tofile(key, directory));
else else
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
isc_result_t isc_result_t
dst_key_fromfile(dns_name_t *name, const isc_uint16_t id, dst_key_fromfile(dns_name_t *name, const isc_uint16_t id,
const unsigned int alg, const int type, isc_mem_t *mctx, const unsigned int alg, const int type, const char *directory,
dst_key_t **keyp) isc_mem_t *mctx, dst_key_t **keyp)
{ {
dst_key_t *key = NULL, *pubkey = NULL; char filename[ISC_DIR_NAMEMAX];
isc_result_t ret; isc_buffer_t b;
dst_key_t *key;
isc_result_t result;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(dns_name_isabsolute(name)); REQUIRE(dns_name_isabsolute(name));
REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
REQUIRE(mctx != NULL); REQUIRE(mctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(keyp != NULL && *keyp == NULL);
if (dst_algorithm_supported(alg) == ISC_FALSE) if (dst_algorithm_supported(alg) == ISC_FALSE)
return (DST_R_UNSUPPORTEDALG); return (DST_R_UNSUPPORTEDALG);
if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0) isc_buffer_init(&b, filename, sizeof filename);
return (DST_R_UNSUPPORTEDTYPE); result = buildfilename(name, id, alg, type, directory, &b);
if (result != ISC_R_SUCCESS)
return (result);
ret = read_public_key(name, id, alg, mctx, &pubkey); key = NULL;
if (ret == ISC_R_NOTFOUND && (type & DST_TYPE_PUBLIC) == 0) result = dst_key_fromnamedfile(filename, type, mctx, &key);
key = get_key_struct(name, alg, 0, 0, 0, mctx); if (result != ISC_R_SUCCESS)
else if (ret != ISC_R_SUCCESS) return (result);
return (ret);
else {
if (type == DST_TYPE_PUBLIC ||
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) ==
DNS_KEYTYPE_NOKEY)
{
*keyp = pubkey;
return (ISC_R_SUCCESS);
}
key = get_key_struct(name, pubkey->key_alg, pubkey->key_flags, if (!dns_name_equal(name, key->key_name) ||
pubkey->key_proto, 0, mctx); id != key->key_id ||
dst_key_free(&pubkey); alg != key->key_alg)
{
dst_key_free(&key);
return (DST_R_INVALIDPUBLICKEY);
} }
*keyp = key;
return (ISC_R_SUCCESS);
}
isc_result_t
dst_key_fromnamedfile(const char *filename, const int type, isc_mem_t *mctx,
dst_key_t **keyp)
{
isc_result_t result;
dst_key_t *pubkey = NULL, *key = NULL;
isc_uint16_t id;
REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(filename != NULL);
REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
REQUIRE(mctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL);
result = read_public_key(filename, mctx, &pubkey);
if (result == ISC_R_NOTFOUND)
return (DST_R_INVALIDPUBLICKEY);
else if (result != ISC_R_SUCCESS)
return (result);
if (type == DST_TYPE_PUBLIC ||
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
{
*keyp = pubkey;
return (ISC_R_SUCCESS);
}
key = get_key_struct(pubkey->key_name, pubkey->key_alg,
pubkey->key_flags, pubkey->key_proto, 0, mctx);
id = pubkey->key_id;
dst_key_free(&pubkey);
if (key == NULL) if (key == NULL)
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
@ -279,10 +342,10 @@ dst_key_fromfile(dns_name_t *name, const isc_uint16_t id,
return (DST_R_UNSUPPORTEDALG); return (DST_R_UNSUPPORTEDALG);
} }
ret = key->func->fromfile(key, id); result = key->func->fromfile(key, id, filename);
if (ret != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
dst_key_free(&key); dst_key_free(&key);
return (ret); return (result);
} }
*keyp = key; *keyp = key;
@ -291,7 +354,7 @@ dst_key_fromfile(dns_name_t *name, const isc_uint16_t id,
isc_result_t isc_result_t
dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE(target != NULL); REQUIRE(target != NULL);
@ -328,7 +391,7 @@ dst_key_fromdns(dns_name_t *name, isc_buffer_t *source, isc_mem_t *mctx,
isc_uint8_t alg, proto; isc_uint8_t alg, proto;
isc_uint32_t flags, extflags; isc_uint32_t flags, extflags;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(dns_name_isabsolute(name)); REQUIRE(dns_name_isabsolute(name));
REQUIRE(source != NULL); REQUIRE(source != NULL);
REQUIRE(mctx != NULL); REQUIRE(mctx != NULL);
@ -362,7 +425,7 @@ dst_key_frombuffer(dns_name_t *name, const unsigned int alg,
dst_key_t *key; dst_key_t *key;
isc_result_t ret; isc_result_t ret;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(dns_name_isabsolute(name)); REQUIRE(dns_name_isabsolute(name));
REQUIRE(source != NULL); REQUIRE(source != NULL);
REQUIRE(mctx != NULL); REQUIRE(mctx != NULL);
@ -392,7 +455,7 @@ dst_key_frombuffer(dns_name_t *name, const unsigned int alg,
isc_result_t isc_result_t
dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) { dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE(target != NULL); REQUIRE(target != NULL);
@ -414,7 +477,7 @@ dst_key_generate(dns_name_t *name, const unsigned int alg,
dst_key_t *key; dst_key_t *key;
isc_result_t ret; isc_result_t ret;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(dns_name_isabsolute(name)); REQUIRE(dns_name_isabsolute(name));
REQUIRE(mctx != NULL); REQUIRE(mctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(keyp != NULL && *keyp == NULL);
@ -449,7 +512,7 @@ dst_key_generate(dns_name_t *name, const unsigned int alg,
isc_boolean_t isc_boolean_t
dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key1)); REQUIRE(VALID_KEY(key1));
REQUIRE(VALID_KEY(key2)); REQUIRE(VALID_KEY(key2));
@ -468,7 +531,7 @@ dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
isc_boolean_t isc_boolean_t
dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key1)); REQUIRE(VALID_KEY(key1));
REQUIRE(VALID_KEY(key2)); REQUIRE(VALID_KEY(key2));
@ -489,7 +552,7 @@ dst_key_free(dst_key_t **keyp) {
isc_mem_t *mctx; isc_mem_t *mctx;
dst_key_t *key; dst_key_t *key;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(keyp != NULL && VALID_KEY(*keyp)); REQUIRE(keyp != NULL && VALID_KEY(*keyp));
key = *keyp; key = *keyp;
@ -579,117 +642,20 @@ dst_key_isnullkey(const dst_key_t *key) {
} }
isc_result_t isc_result_t
dst_key_buildfilename(const dst_key_t *key, const int type, isc_buffer_t *out) dst_key_buildfilename(const dst_key_t *key, const int type,
{ const char *directory, isc_buffer_t *out) {
const char *suffix;
unsigned int len;
isc_result_t result;
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE(type == DST_TYPE_PRIVATE || type == DST_TYPE_PUBLIC || REQUIRE(type == DST_TYPE_PRIVATE || type == DST_TYPE_PUBLIC ||
type == 0); type == 0);
REQUIRE(out != NULL);
if (type == 0)
suffix = "";
else if (type == DST_TYPE_PRIVATE)
suffix = ".private";
else
suffix = ".key";
if (isc_buffer_availablelength(out) < 1)
return (ISC_R_NOSPACE);
isc_buffer_putstr(out, "K");
result = dns_name_totext(key->key_name, ISC_FALSE, out);
if (result != ISC_R_SUCCESS)
return (result);
len = 1 + 3 + 1 + 5 + strlen(suffix) + 1;
if (isc_buffer_availablelength(out) < len)
return (ISC_R_NOSPACE);
sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s",
key->key_alg, key->key_id, suffix);
isc_buffer_add(out, len);
return (ISC_R_SUCCESS);
}
isc_result_t return (buildfilename(key->key_name, key->key_id, key->key_alg,
dst_key_parsefilename(isc_buffer_t *source, isc_mem_t *mctx, dns_name_t *name, type, directory, out));
isc_uint16_t *id, unsigned int *alg, char **suffix)
{
isc_result_t result = ISC_R_SUCCESS;
char c, str[6], *p, *endp;
isc_region_t r;
isc_buffer_t b;
unsigned int length;
long l;
REQUIRE(source != NULL);
REQUIRE(mctx != NULL);
REQUIRE(dns_name_hasbuffer(name));
REQUIRE(id != NULL);
REQUIRE(alg != NULL);
REQUIRE(suffix == NULL || *suffix == NULL);
if (isc_buffer_remaininglength(source) < 1)
return (ISC_R_UNEXPECTEDEND);
c = (char) isc_buffer_getuint8(source);
if (c != 'K')
return (ISC_R_INVALIDFILE);
isc_buffer_remainingregion(source, &r);
p = (char *)r.base;
length = r.length;
while (length > 0 && *p != '+') {
length--;
p++;
}
if (length == 0)
return (ISC_R_UNEXPECTEDEND);
length = p - (char *)r.base;
isc_buffer_init(&b, r.base, length);
isc_buffer_add(&b, length);
result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_forward(source, length);
if (isc_buffer_remaininglength(source) < 1 + 3 + 1 + 5)
return (ISC_R_UNEXPECTEDEND);
c = (char) isc_buffer_getuint8(source);
if (c != '+')
return (ISC_R_INVALIDFILE);
isc_buffer_remainingregion(source, &r);
memcpy(str, r.base, 3);
str[3] = 0;
*alg = strtol(str, &endp, 10);
if (*endp != '\0')
return (ISC_R_INVALIDFILE);
isc_buffer_forward(source, 3);
c = (char) isc_buffer_getuint8(source);
if (c != '+')
return (ISC_R_INVALIDFILE);
isc_buffer_remainingregion(source, &r);
memcpy(str, r.base, 5);
str[5] = 0;
l = strtol(str, &endp, 10);
if (*endp != '\0' || l > (isc_uint16_t)-1)
return (ISC_R_INVALIDFILE);
*id = (isc_uint16_t)l;
isc_buffer_forward(source, 5);
if (suffix == NULL)
return (ISC_R_SUCCESS);
isc_buffer_remainingregion(source, &r);
*suffix = isc_mem_get(mctx, r.length + 1);
if (*suffix == NULL)
return (ISC_R_NOMEMORY);
if (r.length > 0)
memcpy(*suffix, r.base, r.length);
(*suffix)[r.length] = 0;
return (ISC_R_SUCCESS);
} }
isc_result_t isc_result_t
dst_key_sigsize(const dst_key_t *key, unsigned int *n) { dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE(n != NULL); REQUIRE(n != NULL);
@ -713,7 +679,7 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
isc_result_t isc_result_t
dst_key_secretsize(const dst_key_t *key, unsigned int *n) { dst_key_secretsize(const dst_key_t *key, unsigned int *n) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(VALID_KEY(key)); REQUIRE(VALID_KEY(key));
REQUIRE(n != NULL); REQUIRE(n != NULL);
@ -736,7 +702,7 @@ dst_random_get(const unsigned int wanted, isc_buffer_t *target) {
isc_region_t r; isc_region_t r;
int status; int status;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); REQUIRE(initialize(NULL) == ISC_R_SUCCESS);
REQUIRE(target != NULL); REQUIRE(target != NULL);
isc_buffer_availableregion(target, &r); isc_buffer_availableregion(target, &r);
@ -757,26 +723,59 @@ dst_random_get(const unsigned int wanted, isc_buffer_t *target) {
*** Static methods *** Static methods
***/ ***/
/* #define RETERR(x) do { \
* Initializes the Digital Signature Toolkit. result = (x); \
*/ if (result != ISC_R_SUCCESS) \
goto out; \
} while (0)
static void static void
initialize(void) { initialize_action(void) {
RUNTIME_CHECK(isc_mutex_init(&mutex) == ISC_R_SUCCESS);
}
static isc_result_t
initialize(isc_mem_t *mctx) {
isc_result_t result = ISC_R_SUCCESS;
isc_once_do(&once, initialize_action);
LOCK(&mutex);
if (mctx != NULL)
REQUIRE(dst_initialized == ISC_FALSE);
if (dst_initialized) {
UNLOCK(&mutex);
return (ISC_R_SUCCESS);
}
if (mctx != NULL)
isc_mem_attach(mctx, &dst_memory_pool);
else {
result = isc_mem_create(0, 0, &dst_memory_pool);
if (result != ISC_R_SUCCESS)
return (result);
}
dst_initialized = ISC_TRUE;
UNLOCK(&mutex);
memset(dst_t_func, 0, sizeof(dst_t_func)); memset(dst_t_func, 0, sizeof(dst_t_func));
RUNTIME_CHECK(isc_mem_create(0, 0, &dst_memory_pool) == ISC_R_SUCCESS); RETERR(isc_mutex_init(&random_lock));
RUNTIME_CHECK(isc_mutex_init(&random_lock) == ISC_R_SUCCESS);
dst_result_register(); dst_result_register();
dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5]); RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5]));
#ifdef DNSSAFE #ifdef DNSSAFE
dst__dnssafersa_init(&dst_t_func[DST_ALG_RSA]); RETERR(dst__dnssafersa_init(&dst_t_func[DST_ALG_RSA]));
#endif #endif
#ifdef OPENSSL #ifdef OPENSSL
dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]); RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
dst__openssldh_init(&dst_t_func[DST_ALG_DH]); RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH]));
dst__opensslmd5_init(&dst_t_func[DST_ALG_MD5]); RETERR(dst__opensslmd5_init(&dst_t_func[DST_ALG_MD5]));
memset(&md5key, 0, sizeof(dst_key_t)); memset(&md5key, 0, sizeof(dst_key_t));
md5key.magic = KEY_MAGIC; md5key.magic = KEY_MAGIC;
@ -808,6 +807,12 @@ initialize(void) {
isc_random_invalidate(&rctx); isc_random_invalidate(&rctx);
} }
#endif #endif
return (ISC_R_SUCCESS);
out:
dst_lib_destroy();
return (result);
} }
/* /*
@ -856,28 +861,29 @@ get_key_struct(dns_name_t *name, const unsigned int alg,
* Reads a public key from disk * Reads a public key from disk
*/ */
static isc_result_t static isc_result_t
read_public_key(dns_name_t *name, const isc_uint16_t id, const unsigned int alg, read_public_key(const char *filename, isc_mem_t *mctx, dst_key_t **keyp) {
isc_mem_t *mctx, dst_key_t **keyp)
{
char filename[ISC_DIR_NAMEMAX];
u_char rdatabuf[DST_KEY_MAXSIZE]; u_char rdatabuf[DST_KEY_MAXSIZE];
isc_buffer_t b; isc_buffer_t b;
dns_fixedname_t name;
isc_lex_t *lex = NULL; isc_lex_t *lex = NULL;
isc_token_t token; isc_token_t token;
isc_result_t ret; isc_result_t ret;
dns_rdata_t rdata; dns_rdata_t rdata;
unsigned int opt = ISC_LEXOPT_DNSMULTILINE; unsigned int opt = ISC_LEXOPT_DNSMULTILINE;
dst_key_t *tempkey; char *newfilename;
tempkey = get_key_struct(name, alg, 0, 0, 0, mctx); if (strlen(filename) < 8)
if (tempkey == NULL) return (DST_R_INVALIDPUBLICKEY);
newfilename = isc_mem_get(mctx, strlen(filename) + 5);
if (newfilename == NULL)
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
tempkey->key_id = id; strcpy(newfilename, filename);
isc_buffer_init(&b, filename, sizeof(filename));
ret = dst_key_buildfilename(tempkey, DST_TYPE_PUBLIC, &b); if (strcmp(filename + strlen(filename) - 8, ".private") == 0)
dst_key_free(&tempkey); sprintf(newfilename + strlen(filename) - 8, ".key");
if (ret != ISC_R_SUCCESS) else if (strcmp(filename + strlen(filename) - 4, ".key") != 0)
return (ret); sprintf(newfilename + strlen(filename), ".key");
/* /*
* Open the file and read its formatted contents * Open the file and read its formatted contents
@ -888,9 +894,9 @@ read_public_key(dns_name_t *name, const isc_uint16_t id, const unsigned int alg,
/* 1500 should be large enough for any key */ /* 1500 should be large enough for any key */
ret = isc_lex_create(mctx, 1500, &lex); ret = isc_lex_create(mctx, 1500, &lex);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY); goto cleanup;
ret = isc_lex_openfile(lex, filename); ret = isc_lex_openfile(lex, newfilename);
if (ret != ISC_R_SUCCESS) { if (ret != ISC_R_SUCCESS) {
if (ret == ISC_R_FILENOTFOUND) if (ret == ISC_R_FILENOTFOUND)
ret = ISC_R_NOTFOUND; ret = ISC_R_NOTFOUND;
@ -910,6 +916,16 @@ read_public_key(dns_name_t *name, const isc_uint16_t id, const unsigned int alg,
/* Read the domain name */ /* Read the domain name */
NEXTTOKEN(lex, opt, &token); NEXTTOKEN(lex, opt, &token);
if (token.type != isc_tokentype_string)
BADTOKEN();
dns_fixedname_init(&name);
isc_buffer_init(&b, token.value.as_pointer,
strlen(token.value.as_pointer));
isc_buffer_add(&b, strlen(token.value.as_pointer));
ret = dns_name_fromtext(dns_fixedname_name(&name), &b, dns_rootname,
ISC_FALSE, NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup;
/* Read the next word: either TTL, 'IN', or 'KEY' */ /* Read the next word: either TTL, 'IN', or 'KEY' */
NEXTTOKEN(lex, opt, &token); NEXTTOKEN(lex, opt, &token);
@ -936,12 +952,13 @@ read_public_key(dns_name_t *name, const isc_uint16_t id, const unsigned int alg,
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
goto cleanup; goto cleanup;
ret = dst_key_fromdns(name, &b, mctx, keyp); ret = dst_key_fromdns(dns_fixedname_name(&name), &b, mctx, keyp);
if (ret != ISC_R_SUCCESS || (*keyp)->key_alg != alg) if (ret != ISC_R_SUCCESS)
goto cleanup; goto cleanup;
isc_lex_close(lex); isc_lex_close(lex);
isc_lex_destroy(&lex); isc_lex_destroy(&lex);
isc_mem_put(mctx, newfilename, strlen(filename) + 5);
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@ -950,6 +967,7 @@ cleanup:
isc_lex_close(lex); isc_lex_close(lex);
isc_lex_destroy(&lex); isc_lex_destroy(&lex);
} }
isc_mem_put(mctx, newfilename, strlen(filename) + 5);
return (ret); return (ret);
} }
@ -957,7 +975,7 @@ cleanup:
* Writes a public key to disk in DNS format. * Writes a public key to disk in DNS format.
*/ */
static isc_result_t static isc_result_t
write_public_key(const dst_key_t *key) { write_public_key(const dst_key_t *key, const char *directory) {
FILE *fp; FILE *fp;
isc_buffer_t keyb, textb, fileb; isc_buffer_t keyb, textb, fileb;
isc_region_t r; isc_region_t r;
@ -992,7 +1010,7 @@ write_public_key(const dst_key_t *key) {
* Make the filename. * Make the filename.
*/ */
isc_buffer_init(&fileb, filename, sizeof(filename)); isc_buffer_init(&fileb, filename, sizeof(filename));
ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, &fileb); ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
@ -1013,6 +1031,42 @@ write_public_key(const dst_key_t *key) {
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
isc_result_t
buildfilename(dns_name_t *name, const unsigned int id,
const unsigned int alg, const unsigned int type,
const char *directory, isc_buffer_t *out)
{
const char *suffix = "";
unsigned int len;
isc_result_t result;
REQUIRE(out != NULL);
if ((type & DST_TYPE_PRIVATE) != 0)
suffix = ".private";
else if (type == DST_TYPE_PUBLIC)
suffix = ".key";
if (directory != NULL) {
if (isc_buffer_availablelength(out) < strlen(directory))
return (ISC_R_NOSPACE);
isc_buffer_putstr(out, directory);
if (strlen(directory) > 0 &&
directory[strlen(directory) - 1] != '/')
isc_buffer_putstr(out, "/");
}
if (isc_buffer_availablelength(out) < 1)
return (ISC_R_NOSPACE);
isc_buffer_putstr(out, "K");
result = dns_name_totext(name, ISC_FALSE, out);
if (result != ISC_R_SUCCESS)
return (result);
len = 1 + 3 + 1 + 5 + strlen(suffix) + 1;
if (isc_buffer_availablelength(out) < len)
return (ISC_R_NOSPACE);
sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s", alg, id, suffix);
isc_buffer_add(out, len);
return (ISC_R_SUCCESS);
}
void * void *
dst__mem_alloc(size_t size) { dst__mem_alloc(size_t size) {
INSIST(dst_memory_pool != NULL); INSIST(dst_memory_pool != NULL);

View File

@ -92,8 +92,9 @@ struct dst_func {
/* conversion functions */ /* conversion functions */
isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data); isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data);
isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data); isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data);
isc_result_t (*tofile)(const dst_key_t *key); isc_result_t (*tofile)(const dst_key_t *key, const char *directory);
isc_result_t (*fromfile)(dst_key_t *key, const isc_uint16_t id); isc_result_t (*fromfile)(dst_key_t *key, const isc_uint16_t id,
const char *filename);
}; };
#ifndef DST_HASH_SIZE #ifndef DST_HASH_SIZE
@ -103,16 +104,20 @@ struct dst_func {
/* /*
* Initializers * Initializers
*/ */
void isc_result_t dst__hmacmd5_init(struct dst_func **funcp);
dst__hmacmd5_init(struct dst_func **funcp); isc_result_t dst__dnssafersa_init(struct dst_func **funcp);
void isc_result_t dst__openssldsa_init(struct dst_func **funcp);
dst__dnssafersa_init(struct dst_func **funcp); isc_result_t dst__openssldh_init(struct dst_func **funcp);
void isc_result_t dst__opensslmd5_init(struct dst_func **funcp);
dst__openssldsa_init(struct dst_func **funcp);
void /*
dst__openssldh_init(struct dst_func **funcp); * Destructors
void */
dst__opensslmd5_init(struct dst_func **funcp); void dst__hmacmd5_destroy(void);
void dst__dnssafersa_destroy(void);
void dst__openssldsa_destroy(void);
void dst__openssldh_destroy(void);
void dst__opensslmd5_destroy(void);
/* /*
* Support functions. * Support functions.

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: dst_parse.c,v 1.19 2000/06/02 23:36:07 bwelling Exp $ * $Id: dst_parse.c,v 1.20 2000/06/06 21:58:07 bwelling Exp $
*/ */
#include <config.h> #include <config.h>
@ -188,31 +188,41 @@ dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) {
int int
dst__privstruct_parsefile(dst_key_t *key, const isc_uint16_t id, dst__privstruct_parsefile(dst_key_t *key, const isc_uint16_t id,
dst_private_t *priv, isc_mem_t *mctx) const char *filename, isc_mem_t *mctx,
dst_private_t *priv)
{ {
char filename[ISC_DIR_NAMEMAX];
int n = 0, ret, major, minor; int n = 0, ret, major, minor;
isc_buffer_t b; isc_buffer_t b;
isc_lex_t *lex = NULL; isc_lex_t *lex = NULL;
isc_token_t token; isc_token_t token;
unsigned int opt = ISC_LEXOPT_EOL; unsigned int opt = ISC_LEXOPT_EOL;
char *newfilename;
isc_result_t iret; isc_result_t iret;
REQUIRE(priv != NULL); REQUIRE(priv != NULL);
if (strlen(filename) < 8)
return (DST_R_INVALIDPUBLICKEY);
newfilename = isc_mem_get(mctx, strlen(filename) + 9);
if (newfilename == NULL)
return (ISC_R_NOMEMORY);
strcpy(newfilename, filename);
if (strcmp(filename + strlen(filename) - 4, ".key") == 0)
sprintf(newfilename + strlen(filename) - 4, ".private");
else if (strcmp(filename + strlen(filename) - 8, ".private") != 0)
sprintf(newfilename + strlen(filename), ".private");
priv->nelements = 0; priv->nelements = 0;
isc_buffer_init(&b, filename, sizeof(filename));
key->key_id = id; key->key_id = id;
ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, &b);
if (ret != ISC_R_SUCCESS)
return (ret);
iret = isc_lex_create(mctx, 1024, &lex); iret = isc_lex_create(mctx, 1024, &lex);
if (iret != ISC_R_SUCCESS) if (iret != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
iret = isc_lex_openfile(lex, filename); iret = isc_lex_openfile(lex, newfilename);
if (iret != ISC_R_SUCCESS) if (iret != ISC_R_SUCCESS)
goto fail; goto fail;
@ -308,6 +318,7 @@ dst__privstruct_parsefile(dst_key_t *key, const isc_uint16_t id,
isc_lex_close(lex); isc_lex_close(lex);
isc_lex_destroy(&lex); isc_lex_destroy(&lex);
isc_mem_put(mctx, newfilename, strlen(filename) + 9);
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@ -316,6 +327,7 @@ fail:
isc_lex_close(lex); isc_lex_close(lex);
isc_lex_destroy(&lex); isc_lex_destroy(&lex);
} }
isc_mem_put(mctx, newfilename, strlen(filename) + 9);
priv->nelements = n; priv->nelements = n;
dst__privstruct_free(priv, mctx); dst__privstruct_free(priv, mctx);
@ -323,7 +335,9 @@ fail:
} }
int int
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv) { dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory)
{
FILE *fp; FILE *fp;
int ret, i; int ret, i;
isc_result_t iret; isc_result_t iret;
@ -337,7 +351,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv) {
return (DST_R_INVALIDPRIVATEKEY); return (DST_R_INVALIDPRIVATEKEY);
isc_buffer_init(&b, filename, sizeof(filename)); isc_buffer_init(&b, filename, sizeof(filename));
ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, &b); ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);

View File

@ -79,10 +79,12 @@ dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx);
int int
dst__privstruct_parsefile(dst_key_t *key, const isc_uint16_t id, dst__privstruct_parsefile(dst_key_t *key, const isc_uint16_t id,
dst_private_t *priv, isc_mem_t *mctx); const char *filename, isc_mem_t *mctx,
dst_private_t *priv);
int int
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv); dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory);
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS

View File

@ -17,7 +17,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: dst_result.c,v 1.10 2000/06/02 18:57:44 bwelling Exp $ * $Id: dst_result.c,v 1.11 2000/06/06 21:58:09 bwelling Exp $
*/ */
#include <config.h> #include <config.h>
@ -30,8 +30,8 @@
static const char *text[DST_R_NRESULTS] = { static const char *text[DST_R_NRESULTS] = {
"algorithm is unsupported", /* 0 */ "algorithm is unsupported", /* 0 */
"key type is unsupported", /* 1 */ "UNUSED1", /* 1 */
"signature mode is unsupported", /* 2 */ "UNUSED2", /* 2 */
"illegal operation for a null key", /* 3 */ "illegal operation for a null key", /* 3 */
"public key is invalid", /* 4 */ "public key is invalid", /* 4 */
"private key is invalid", /* 5 */ "private key is invalid", /* 5 */

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: hmac_link.c,v 1.31 2000/06/05 19:10:58 bwelling Exp $ * $Id: hmac_link.c,v 1.32 2000/06/06 21:58:10 bwelling Exp $
*/ */
#include <config.h> #include <config.h>
@ -276,7 +276,7 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
} }
static isc_result_t static isc_result_t
hmacmd5_tofile(const dst_key_t *key) { hmacmd5_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0; int cnt = 0;
HMAC_Key *hkey; HMAC_Key *hkey;
dst_private_t priv; dst_private_t priv;
@ -292,18 +292,18 @@ hmacmd5_tofile(const dst_key_t *key) {
priv.elements[cnt++].data = hkey->key; priv.elements[cnt++].data = hkey->key;
priv.nelements = cnt; priv.nelements = cnt;
return (dst__privstruct_writefile(key, &priv)); return (dst__privstruct_writefile(key, &priv, directory));
} }
static isc_result_t static isc_result_t
hmacmd5_fromfile(dst_key_t *key, const isc_uint16_t id) { hmacmd5_fromfile(dst_key_t *key, const isc_uint16_t id, const char *filename) {
dst_private_t priv; dst_private_t priv;
isc_result_t ret; isc_result_t ret;
isc_buffer_t b; isc_buffer_t b;
isc_mem_t *mctx = key->mctx; isc_mem_t *mctx = key->mctx;
/* read private key file */ /* read private key file */
ret = dst__privstruct_parsefile(key, id, &priv, mctx); ret = dst__privstruct_parsefile(key, id, filename, mctx, &priv);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
@ -333,8 +333,13 @@ static dst_func_t hmacmd5_functions = {
hmacmd5_fromfile, hmacmd5_fromfile,
}; };
void isc_result_t
dst__hmacmd5_init(dst_func_t **funcp) { dst__hmacmd5_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL && *funcp == NULL); REQUIRE(funcp != NULL && *funcp == NULL);
*funcp = &hmacmd5_functions; *funcp = &hmacmd5_functions;
return (ISC_R_SUCCESS);
}
void
dst__hmacmd5_destroy(void) {
} }

View File

@ -46,6 +46,30 @@ extern dst_key_t *dst_key_md5;
*** Functions *** Functions
***/ ***/
isc_result_t
dst_lib_init(isc_mem_t *mctx);
/*
* Initializes the DST subsystem. If this call is omitted, DST will allocate
* resources itself when the first library call is made (including its own
* memory context).
*
* Requires:
* "mctx" is a valid memory context
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_NOMEMORY
*
* Ensures:
* DST is properly initialized.
*/
void
dst_lib_destroy(void);
/*
* Releases all resources allocated by DST.
*/
isc_boolean_t isc_boolean_t
dst_algorithm_supported(const unsigned int alg); dst_algorithm_supported(const unsigned int alg);
/* /*
@ -176,16 +200,18 @@ dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
isc_result_t isc_result_t
dst_key_fromfile(dns_name_t *name, const isc_uint16_t id, dst_key_fromfile(dns_name_t *name, const isc_uint16_t id,
const unsigned int alg, const int type, const unsigned int alg, const int type,
isc_mem_t *mctx, dst_key_t **keyp); const char *directory, isc_mem_t *mctx, dst_key_t **keyp);
/* /*
* Reads a key from permanent storage. The key can either be a public or * Reads a key from permanent storage. The key can either be a public or
* key, and is specified by name, algorithm, and id. * private key, and is specified by name, algorithm, and id. If a private key
* is specified, the public key must also be present. If directory is NULL,
* the current directory is assumed.
* *
* Requires: * Requires:
* "name" is a valid absolute dns name. * "name" is a valid absolute dns name.
* "id" is a valid key tag identifier. * "id" is a valid key tag identifier.
* "alg" is a supported key algorithm. * "alg" is a supported key algorithm.
* "type" is either DST_TYPE_PUBLIC or DST_TYPE_PRIVATE. * "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
* "mctx" is a valid memory context. * "mctx" is a valid memory context.
* "keyp" is not NULL and "*keyp" is NULL. * "keyp" is not NULL and "*keyp" is NULL.
* *
@ -198,11 +224,34 @@ dst_key_fromfile(dns_name_t *name, const isc_uint16_t id,
*/ */
isc_result_t isc_result_t
dst_key_tofile(const dst_key_t *key, const int type); dst_key_fromnamedfile(const char *filename, const int type, isc_mem_t *mctx,
dst_key_t **keyp);
/*
* Reads a key from permanent storage. The key can either be a public or
* key, and is specified by filename. If a private key is specified, the
* public key must also be present.
*
* Requires:
* "filename" is not NULL
* "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
* "mctx" is a valid memory context
* "keyp" is not NULL and "*keyp" is NULL.
*
* Returns:
* ISC_R_SUCCESS
* any other result indicates failure
*
* Ensures:
* If successful, *keyp will contain a valid key.
*/
isc_result_t
dst_key_tofile(const dst_key_t *key, const int type, const char *directory);
/* /*
* Writes a key to permanent storage. The key can either be a public or * Writes a key to permanent storage. The key can either be a public or
* private key. Public keys are written in DNS format and private keys * private key. Public keys are written in DNS format and private keys
* are written as a set of base64 encoded values. * are written as a set of base64 encoded values. If directory is NULL,
* the current directory is assumed.
* *
* Requires: * Requires:
* "key" is a valid key. * "key" is a valid key.
@ -397,9 +446,11 @@ isc_boolean_t
dst_key_isnullkey(const dst_key_t *key); dst_key_isnullkey(const dst_key_t *key);
isc_result_t isc_result_t
dst_key_buildfilename(const dst_key_t *key, const int type, isc_buffer_t *out); dst_key_buildfilename(const dst_key_t *key, const int type,
const char *directory, isc_buffer_t *out);
/* /*
* Generates the filename used by dst to store the specified key. * Generates the filename used by dst to store the specified key.
* If directory is NULL, the current directory is assumed.
* *
* Requires: * Requires:
* "key" is a valid key * "key" is a valid key
@ -411,25 +462,6 @@ dst_key_buildfilename(const dst_key_t *key, const int type, isc_buffer_t *out);
* be advanced. * be advanced.
*/ */
isc_result_t
dst_key_parsefilename(isc_buffer_t *source, isc_mem_t *mctx, dns_name_t *name,
isc_uint16_t *id, unsigned int *alg, char **suffix);
/*
* Parses a dst key filename into its components.
*
* Requires:
* "source" is a valid buffer
* "mctx" is a valid memory context
* "name" is a valid name with a dedicated buffer
* "id" and "alg" are not NULL
* Either "suffix" is NULL or "suffix" is not NULL and "*suffix" is NULL
*
* Ensures:
* "*name" will point to allocated memory, as will "*suffix" if suffix
* is not NULL (strlen() + 1 bytes). The current pointer in source
* will be advanced.
*/
isc_result_t isc_result_t
dst_key_sigsize(const dst_key_t *key, unsigned int *n); dst_key_sigsize(const dst_key_t *key, unsigned int *n);
/* /*

View File

@ -30,8 +30,8 @@
#include <isc/result.h> /* Contractual promise. */ #include <isc/result.h> /* Contractual promise. */
#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) #define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0)
#define DST_R_UNSUPPORTEDTYPE (ISC_RESULTCLASS_DST + 1) /* 1 is unused */
#define DST_R_UNSUPPORTEDMODE (ISC_RESULTCLASS_DST + 2) /* 2 is unused */
#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) #define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3)
#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) #define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4)
#define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5) #define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5)

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: openssl_link.c,v 1.25 2000/06/02 23:36:12 bwelling Exp $ * $Id: openssl_link.c,v 1.26 2000/06/06 21:58:11 bwelling Exp $
*/ */
#if defined(OPENSSL) #if defined(OPENSSL)
@ -57,7 +57,11 @@ static void
openssldsa_destroyctx(dst_context_t *dctx) { openssldsa_destroyctx(dst_context_t *dctx) {
SHA_CTX *ctx = dctx->opaque; SHA_CTX *ctx = dctx->opaque;
isc_mem_put(dctx->mctx, ctx, sizeof(SHA_CTX)); if (ctx != NULL) {
unsigned char digest[SHA_DIGEST_LENGTH];
SHA1_Final(digest, ctx);
isc_mem_put(dctx->mctx, ctx, sizeof(SHA_CTX));
}
} }
static isc_result_t static isc_result_t
@ -95,6 +99,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
dsa = key->opaque; dsa = key->opaque;
SHA1_Final(digest, ctx); SHA1_Final(digest, ctx);
isc_mem_put(dctx->mctx, ctx, sizeof(SHA_CTX));
dctx->opaque = NULL;
dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa); dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa);
if (dsasig == NULL) if (dsasig == NULL)
@ -126,6 +132,8 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dsa = key->opaque; dsa = key->opaque;
SHA1_Final(digest, ctx); SHA1_Final(digest, ctx);
isc_mem_put(dctx->mctx, ctx, sizeof(SHA_CTX));
dctx->opaque = NULL;
if (sig->length < 2 * SHA_DIGEST_LENGTH + 1) if (sig->length < 2 * SHA_DIGEST_LENGTH + 1)
return (DST_R_VERIFYFAILURE); return (DST_R_VERIFYFAILURE);
@ -321,7 +329,7 @@ openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
static isc_result_t static isc_result_t
openssldsa_tofile(const dst_key_t *key) { openssldsa_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0; int cnt = 0;
DSA *dsa; DSA *dsa;
dst_private_t priv; dst_private_t priv;
@ -363,11 +371,12 @@ openssldsa_tofile(const dst_key_t *key) {
cnt++; cnt++;
priv.nelements = cnt; priv.nelements = cnt;
return (dst__privstruct_writefile(key, &priv)); return (dst__privstruct_writefile(key, &priv, directory));
} }
static isc_result_t static isc_result_t
openssldsa_fromfile(dst_key_t *key, const isc_uint16_t id) { openssldsa_fromfile(dst_key_t *key, const isc_uint16_t id, const char *filename)
{
dst_private_t priv; dst_private_t priv;
isc_result_t ret; isc_result_t ret;
isc_buffer_t dns; isc_buffer_t dns;
@ -379,7 +388,7 @@ openssldsa_fromfile(dst_key_t *key, const isc_uint16_t id) {
#define DST_RET(a) {ret = a; goto err;} #define DST_RET(a) {ret = a; goto err;}
/* read private key file */ /* read private key file */
ret = dst__privstruct_parsefile(key, id, &priv, mctx); ret = dst__privstruct_parsefile(key, id, filename, mctx, &priv);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
@ -454,12 +463,17 @@ static dst_func_t openssldsa_functions = {
openssldsa_fromfile, openssldsa_fromfile,
}; };
void isc_result_t
dst__openssldsa_init(dst_func_t **funcp) { dst__openssldsa_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL && *funcp == NULL); REQUIRE(funcp != NULL && *funcp == NULL);
CRYPTO_set_mem_functions(dst__mem_alloc, dst__mem_realloc, CRYPTO_set_mem_functions(dst__mem_alloc, dst__mem_realloc,
dst__mem_free); dst__mem_free);
*funcp = &openssldsa_functions; *funcp = &openssldsa_functions;
return (ISC_R_SUCCESS);
}
void
dst__openssldsa_destroy(void) {
} }
#endif /* OPENSSL */ #endif /* OPENSSL */

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: openssldh_link.c,v 1.19 2000/06/02 23:36:13 bwelling Exp $ * $Id: openssldh_link.c,v 1.20 2000/06/06 21:58:12 bwelling Exp $
*/ */
#if defined(OPENSSL) #if defined(OPENSSL)
@ -380,7 +380,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) {
} }
static isc_result_t static isc_result_t
openssldh_tofile(const dst_key_t *key) { openssldh_tofile(const dst_key_t *key, const char *directory) {
int cnt = 0; int cnt = 0;
DH *dh; DH *dh;
dst_private_t priv; dst_private_t priv;
@ -416,11 +416,12 @@ openssldh_tofile(const dst_key_t *key) {
cnt++; cnt++;
priv.nelements = cnt; priv.nelements = cnt;
return (dst__privstruct_writefile(key, &priv)); return (dst__privstruct_writefile(key, &priv, directory));
} }
static isc_result_t static isc_result_t
openssldh_fromfile(dst_key_t *key, const isc_uint16_t id) { openssldh_fromfile(dst_key_t *key, const isc_uint16_t id, const char *filename)
{
dst_private_t priv; dst_private_t priv;
isc_result_t ret; isc_result_t ret;
isc_buffer_t dns; isc_buffer_t dns;
@ -434,7 +435,7 @@ openssldh_fromfile(dst_key_t *key, const isc_uint16_t id) {
mctx = key->mctx; mctx = key->mctx;
/* read private key file */ /* read private key file */
ret = dst__privstruct_parsefile(key, id, &priv, mctx); ret = dst__privstruct_parsefile(key, id, filename, mctx, &priv);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
@ -549,7 +550,7 @@ static dst_func_t openssldh_functions = {
openssldh_fromfile, openssldh_fromfile,
}; };
void isc_result_t
dst__openssldh_init(dst_func_t **funcp) { dst__openssldh_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL && *funcp == NULL); REQUIRE(funcp != NULL && *funcp == NULL);
CRYPTO_set_mem_functions(dst__mem_alloc, dst__mem_realloc, CRYPTO_set_mem_functions(dst__mem_alloc, dst__mem_realloc,
@ -561,6 +562,14 @@ dst__openssldh_init(dst_func_t **funcp) {
BN_fromhex(&bn768, PRIME768); BN_fromhex(&bn768, PRIME768);
BN_fromhex(&bn1024, PRIME1024); BN_fromhex(&bn1024, PRIME1024);
*funcp = &openssldh_functions; *funcp = &openssldh_functions;
return (ISC_R_SUCCESS);
}
void
dst__openssldh_destroy() {
BN_free(&bn2);
BN_free(&bn768);
BN_free(&bn1024);
} }
#endif /* OPENSSL */ #endif /* OPENSSL */

View File

@ -19,7 +19,7 @@
/* /*
* Principal Author: Brian Wellington * Principal Author: Brian Wellington
* $Id: opensslmd5_link.c,v 1.9 2000/06/02 23:36:14 bwelling Exp $ * $Id: opensslmd5_link.c,v 1.10 2000/06/06 21:58:13 bwelling Exp $
*/ */
#if defined(OPENSSL) #if defined(OPENSSL)
@ -95,10 +95,15 @@ static dst_func_t opensslmd5_functions = {
NULL, /* fromfile */ NULL, /* fromfile */
}; };
void isc_result_t
dst__opensslmd5_init(dst_func_t **funcp) { dst__opensslmd5_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL && *funcp == NULL); REQUIRE(funcp != NULL && *funcp == NULL);
*funcp = &opensslmd5_functions; *funcp = &opensslmd5_functions;
return (ISC_R_SUCCESS);
}
void
dst__opensslmd5_destroy(void) {
} }
#endif /* OPENSSL */ #endif /* OPENSSL */