dst_api.c revision e672951ed28b2e9cc7a19c3d7fa4a258382f981c
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Portions Copyright (C) 1999-2003 Internet Software Consortium.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Permission to use, copy, modify, and/or distribute this software for any
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * purpose with or without fee is hereby granted, provided that the above
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * copyright notice and this permission notice appear in all copies.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
f97d56e757b9a293ffbaa915ca4d792ae84ba85aTinderbox User * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * purpose with or without fee is hereby granted, provided that the above
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * copyright notice and this permission notice appear in all copies.
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Principal Author: Brian Wellington
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * $Id: dst_api.c,v 1.14 2008/04/01 23:47:10 tbox Exp $
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt#define DST_AS_STR(t) ((t).value.as_textregion.base)
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverstatic isc_entropy_t *dst_entropy_pool = NULL;
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverstatic unsigned int dst_entropy_flags = 0;
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrewsstatic isc_boolean_t dst_initialized = ISC_FALSE;
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryvervoid gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver * Static functions.
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverstatic dst_key_t * get_key_struct(dns_name_t *name,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews unsigned int alg,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews unsigned int flags,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews unsigned int protocol,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews unsigned int bits,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrewsstatic isc_result_t write_public_key(const dst_key_t *key, int type,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverstatic isc_result_t buildfilename(dns_name_t *name,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver unsigned int alg,
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt unsigned int type,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverstatic isc_result_t computeid(dst_key_t *key);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver unsigned int alg,
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt unsigned int flags,
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryverstatic isc_result_t algorithm_status(unsigned int alg);
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryverstatic isc_result_t addsuffix(char *filename, unsigned int len,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver } while (0); \
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverdst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * When using --with-openssl, there seems to be no good way of not
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * leaking memory due to the openssl error handling mechanism.
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt * Avoid assertions by using a local memory context and not checking
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt * for leaks on exit. Note: as there are leaks we cannot use
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt * ISC_MEMFLAG_INTERNAL as it will free up memory still being used
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt * by libcrypto.
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver isc_mem_setname(dst__memory_pool, "dst", NULL);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver isc_entropy_attach(ectx, &dst_entropy_pool);
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256]));
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512]));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5]));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1]));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver#endif /* OPENSSL */
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver for (i = 0; i < DST_MAX_ALGS; i++)
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver if (dst_t_func[i] != NULL && dst_t_func[i]->cleanup != NULL)
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverdst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver dctx = isc_mem_get(mctx, sizeof(dst_context_t));
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver isc_mem_put(mctx, dctx, sizeof(dst_context_t));
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver INSIST(dctx->key->func->destroyctx != NULL);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver isc_mem_put(dctx->mctx, dctx, sizeof(dst_context_t));
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Huntdst_context_adddata(dst_context_t *dctx, const isc_region_t *data) {
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Huntdst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) {
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryverdst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver return (dctx->key->func->verify(dctx, sig));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Huntdst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt if (pub->keydata.generic == NULL || priv->keydata.generic == NULL)
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver return (pub->func->computesecret(pub, priv, secret));
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryverdst_key_tofile(const dst_key_t *key, int type, const char *directory) {
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
df0892aea6bfd20a01c3abf2b756625d23830390Mark Andrews (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
df0892aea6bfd20a01c3abf2b756625d23830390Mark Andrewsdst_key_fromfile(dns_name_t *name, dns_keytag_t id,
df0892aea6bfd20a01c3abf2b756625d23830390Mark Andrews unsigned int alg, int type, const char *directory,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews isc_buffer_init(&b, filename, sizeof(filename));
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = buildfilename(name, id, alg, type, directory, &b);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver result = dst_key_fromnamedfile(filename, type, mctx, &key);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver if (!dns_name_equal(name, key->key_name) || id != key->key_id ||
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Huntdst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt result = addsuffix(newfilename, newfilenamelen, filename, ".key");
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = dst_key_read_public(newfilename, type, mctx, &pubkey);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC ||
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver key = get_key_struct(pubkey->key_name, pubkey->key_alg,
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver newfilename = isc_mem_get(mctx, newfilenamelen);
9fee08f655527a5dd849b171daeeee1dbbccca76Vernon Schryver result = addsuffix(newfilename, newfilenamelen, filename, ".private");
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Huntdst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
afaa290bb6acc504e93a0adbf20b6dd6c64e6d63Vernon Schryver isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff));
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto);
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Hunt isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg);
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt if (key->keydata.generic == NULL) /*%< NULL KEY */
421d4a06479e61fbdc35087f3c4abc9fe65ad72aEvan Huntdst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass,
94315060c2b0d9deafabe72d6a0482405fd9d377Evan Hunt isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
return (result);
return (ISC_R_SUCCESS);
return (result);
return (result);
return (ISC_R_SUCCESS);
return (DST_R_UNSUPPORTEDALG);
out:
return (result);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (DST_R_UNSUPPORTEDALG);
return (result);
return (result);
return (ISC_R_SUCCESS);
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_HMACSHA1:
*n = ISC_SHA1_DIGESTLENGTH;
case DST_ALG_HMACSHA224:
*n = ISC_SHA224_DIGESTLENGTH;
case DST_ALG_HMACSHA256:
*n = ISC_SHA256_DIGESTLENGTH;
case DST_ALG_HMACSHA384:
*n = ISC_SHA384_DIGESTLENGTH;
case DST_ALG_HMACSHA512:
*n = ISC_SHA512_DIGESTLENGTH;
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);
suffix);
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)
dst__entropy_status(void) {