dst_api.c revision 016c0a82f1ce3fe4d362d7c9cf8de4377ffaf5a9
573d78f3d53859bc01ce5d5cebbaac9b8b90bfbaTinderbox User * Portions Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Portions Copyright (C) 1999-2003 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * Permission to use, copy, modify, and distribute this software for any
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Principal Author: Brian Wellington
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * $Id: dst_api.c,v 1.4 2005/06/17 02:22:43 marka Exp $
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt#define DST_AS_STR(t) ((t).value.as_textregion.base)
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrewsstatic unsigned int dst_entropy_flags = 0;
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrewsstatic isc_boolean_t dst_initialized = ISC_FALSE;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * Static functions.
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntstatic dst_key_t * get_key_struct(dns_name_t *name,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt unsigned int alg,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews unsigned int flags,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencestatic isc_result_t write_public_key(const dst_key_t *key, int type,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t buildfilename(dns_name_t *name,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence unsigned int alg,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence unsigned int type,
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic isc_result_t computeid(dst_key_t *key);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic isc_result_t frombuffer(dns_name_t *name,
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic isc_result_t algorithm_status(unsigned int alg);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic isc_result_t addsuffix(char *filename, unsigned int len,
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson const char *ofilename, const char *suffix);
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt } while (0); \
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Huntstatic void *
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssondst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * When using --with-openssl, there seems to be no good way of not
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * leaking memory due to the openssl error handling mechanism.
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * Avoid assertions by using a local memory context and not checking
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * for leaks on exit. Note: as there are leaks we cannot use
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * ISC_MEMFLAG_INTERNAL as it will free up memory still being used
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * by libcrypto.
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE);
cdbb3d27740fd052f18067b937097ebf35df356bAutomatic Updater memset(dst_t_func, 0, sizeof(dst_t_func));
28ad0be64ee756013c0f6a474fc447ee613ee0d1Evan Hunt RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#endif /* OPENSSL */
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]));
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt for (i = 0; i < DST_MAX_ALGS; i++)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (dst_t_func[i] != NULL && dst_t_func[i]->cleanup != NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntdst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
8bb77cd31b7518fb5d2a6a9d75e16e4abd59df61Andreas Gustafssondst_context_destroy(dst_context_t **dctxp) {
ba7ea2326d98edb4296098749fc9cf44b5157643David Lawrence isc_mem_put(dctx->mctx, dctx, sizeof(dst_context_t));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsdst_context_adddata(dst_context_t *dctx, const isc_region_t *data) {
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson return (dctx->key->func->adddata(dctx, data));
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafssondst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsdst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Huntdst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pub->opaque == NULL || priv->opaque == NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (pub->func->computesecret(pub, priv, secret));
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updaterdst_key_tofile(const dst_key_t *key, int type, const char *directory) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsdst_key_fromfile(dns_name_t *name, dns_keytag_t id,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews unsigned int alg, int type, const char *directory,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt result = buildfilename(name, id, alg, type, directory, &b);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt result = dst_key_fromnamedfile(filename, type, mctx, &key);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson if (!dns_name_equal(name, key->key_name) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsdst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews result = addsuffix(newfilename, newfilenamelen, filename, ".key");
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result = dst_key_read_public(newfilename, type, mctx, &pubkey);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(mctx, newfilename, newfilenamelen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews key = get_key_struct(pubkey->key_name, pubkey->key_alg,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson newfilename = isc_mem_get(mctx, newfilenamelen);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt result = addsuffix(newfilename, newfilenamelen, filename, ".private");
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson RETERR(isc_lex_create(mctx, 1500, &lex));
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson RETERR(isc_lex_openfile(lex, newfilename));
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson isc_mem_put(mctx, newfilename, newfilenamelen);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Huntdst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff));
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto);
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsdst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass,
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result = frombuffer(name, alg, flags, proto, rdclass, source,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrewsdst_key_frombuffer(dns_name_t *name, unsigned int alg,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews result = frombuffer(name, alg, flags, protocol, rdclass, source,
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssondst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntdst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson RETERR(isc_lex_create(key->mctx, 1500, &lex));
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Huntdst_key_fromgssapi(dns_name_t *name, void *opaque, isc_mem_t *mctx,
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC,
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafssondst_key_generate(dns_name_t *name, unsigned int alg,
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (DST_R_UNSUPPORTEDALG);
return (ret);
return (ret);
return (ISC_R_SUCCESS);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
type == 0);
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_DSA:
*n = DNS_SIG_DSASIGSIZE;
case DST_ALG_HMACMD5:
case DST_ALG_GSSAPI:
case DST_ALG_DH:
return (DST_R_UNSUPPORTEDALG);
return (ISC_R_SUCCESS);
return (DST_R_UNSUPPORTEDALG);
return (ISC_R_SUCCESS);
static dst_key_t *
return (NULL);
return (NULL);
return (NULL);
return (key);
isc_buffer_t b;
goto cleanup;
goto cleanup;
goto cleanup; \
#define BADTOKEN() { \
goto cleanup; \
BADTOKEN();
goto cleanup;
BADTOKEN();
BADTOKEN();
BADTOKEN();
goto cleanup;
goto cleanup;
keyp);
goto cleanup;
return (ret);
static isc_boolean_t
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_DSA:
case DST_ALG_DH:
return (ISC_FALSE);
case DST_ALG_HMACMD5:
case DST_ALG_GSSAPI:
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
isc_region_t r;
return (ret);
return (DST_R_INVALIDPUBLICKEY);
return (DST_R_INVALIDPUBLICKEY);
return (ret);
return (DST_R_WRITEERROR);
access = 0;
&access);
return (ret);
return (ISC_R_SUCCESS);
static isc_result_t
unsigned int len;
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
return (result);
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
static isc_result_t
isc_region_t r;
return (ret);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_NOMEMORY);
return (ret);
return (DST_R_UNSUPPORTEDALG);
return (ret);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_SUCCESS);
#ifndef OPENSSL
return (DST_R_NOCRYPTO);
return (DST_R_UNSUPPORTEDALG);
static isc_result_t
const char *suffix)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
if (pseudo)