dst_api.c revision 65c4736d9c0ebc6d9b1d991593b55566909da9cd
1599ac12be522feb3f0cf8dab9fdde695a93a03fTinderbox User * Portions Copyright (c) 1995-1999 by Network Associates, Inc.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Principal Author: Brian Wellington
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * $Id: dst_api.c,v 1.1 1999/07/12 20:08:28 bwelling Exp $
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt#define VALID_KEY(key) (key != NULL && key->magic == KEY_MAGIC)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer/* Static functions */
3d711f2f75cb9a9ddcbf1fca9b2de192e75340e6Mark Andrewsstatic void initialize(void);
3d711f2f75cb9a9ddcbf1fca9b2de192e75340e6Mark Andrewsstatic dst_key_t * get_key_struct(const char *name, const int alg,
0e0e575ec135a983a53c501cf48734b823361ab4Brian Wellingtonstatic dst_result_t read_public_key(const char *name,
0e0e575ec135a983a53c501cf48734b823361ab4Brian Wellingtonstatic dst_result_t write_public_key(const dst_key_t *key);
0e0e575ec135a983a53c501cf48734b823361ab4Brian Wellington * dst_supported_algorithm
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * This function determines if the crypto system for the specified
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer * algorithm is present.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * alg The algorithm to test
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * ISC_TRUE The algorithm is available.
da5d1cf1b1aa29ae53a0427be49291b04bd60549Mark Andrews * ISC_FALSE The algorithm is not available.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * An incremental signing function. Data is signed in steps.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * First the context must be initialized (DST_SIG_MODE_INIT).
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Then data is hashed (DST_SIG_MODE_UPDATE). Finally the signature
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer * itself is created (DST_SIG_MODE_FINAL). This function can be called
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * once with DST_SIG_MODE_ALL set, or it can be called separately
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * for each step. The UPDATE step may be repeated.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * mode A bit mask specifying operation(s) to be performed.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * DST_SIG_MODE_INIT Initialize digest
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * DST_SIG_MODE_UPDATE Add data to digest
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * DST_SIG_MODE_FINAL Generate signature
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * DST_SIG_MODE_ALL Perform all operations
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * key The private key used to sign the data
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * context The state of the operation
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * data The data to be signed.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * sig The buffer to which the signature will be written.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * mctx Memory context used for allocations
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * DST_R_SUCCESS Success
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * !DST_R_SUCCESS Failure
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdst_sign(const int mode, dst_key_t *key, void **context,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington REQUIRE(data != NULL && data->base != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (key->func->sign(mode, key, context, data, sig, mctx));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * An incremental verify function. Data is verified in steps.
066cb385cd8f801dd3757db2922c9b1f343e65edAndreas Gustafsson * First the context must be initialized (DST_SIG_MODE_INIT).
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Then data is hashed (DST_SIG_MODE_UPDATE). Finally the signature
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington * is verified (DST_SIG_MODE_FINAL). This function can be called
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington * once with DST_SIG_MODE_ALL set, or it can be called separately
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington * for each step. The UPDATE step may be repeated.
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * mode A bit mask specifying operation(s) to be performed.
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * DST_SIG_MODE_INIT Initialize digest
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * DST_SIG_MODE_UPDATE Add data to digest
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * DST_SIG_MODE_FINAL Verify signature
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * DST_SIG_MODE_ALL Perform all operations
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * key The public key used to verify the signature.
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * context The state of the operation
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * data The data to be digested.
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * sig The signature.
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * mctx Memory context used for allocations
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * DST_R_SUCCESS Success
d302a620e0d49811874b9555ac2e4c6e05861a6bFrancis Dupont * !DST_R_SUCCESS Failure
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerdst_verify(const int mode, dst_key_t *key, void **context,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington REQUIRE(data != NULL && data->base != NULL);
cc48bb397fa6ba889f25157840492e68114dec8fBrian Wellington if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington return (key->func->verify(mode, key, context, data, sig, mctx));
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * dst_key_tofile
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * Writes a key to disk. The key can either be a public or private key.
c38b92000c0f1a95daaad5468777e165b8047de9Mark Andrews * key The key to be written.
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * type Either DST_PUBLIC or DST_PRIVATE, or both
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * DST_R_SUCCESS Success
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * !DST_R_SUCCESS Failure
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellingtondst_key_tofile(const dst_key_t *key, const int type) {
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0)
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington if ((ret = write_public_key(key)) != DST_R_SUCCESS)
1ae75c1024eb0475c2be352b8707772e16332ad0Mark Andrews (key->key_flags & NS_KEY_TYPEMASK) != NS_KEY_TYPE_NO_KEY)
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * dst_key_fromfile
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * Reads a key from disk. The key can either be a public or private
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * key, and is specified by name, algorithm, and id.
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * name The key name.
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * id The id of the key.
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * alg The algorithm of the key.
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * type Either DST_PUBLIC or DST_PRIVATE
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * mctx Memory context used to allocate key structure
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * keyp Returns the new key
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * DST_R_SUCCESS Success
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * !DST_R_SUCCESS Failure
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellingtondst_key_fromfile(const char *name, const isc_uint16_t id, const int alg,
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington const int type, isc_mem_t *mctx, dst_key_t **keyp)
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (dst_supported_algorithm(alg) == ISC_FALSE)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews ret = read_public_key(name, id, alg, mctx, &pubkey);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer (pubkey->key_flags & NS_KEY_TYPEMASK) == NS_KEY_TYPE_NO_KEY)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer key = get_key_struct(name, pubkey->key_alg, pubkey->key_flags,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer /* Fill in private key and some fields in the general key structure */
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * dst_key_todns
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * Function to encode a public key into DNS KEY format
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * key Key structure to encode.
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson * target Buffer to write the encoded key into.
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson * DST_R_SUCCESS Success
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * !DST_R_SUCCESS Failure
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint16(target, key->key_flags & 0xffff);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (key->key_flags & NS_KEY_EXTENDED_FLAGS) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(target, (key->key_flags >> 16) & 0xffff);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * dst_key_fromdns
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer * This function converts the contents of a DNS KEY RR into a key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * name Name of the new key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * source A buffer containing the KEY RR
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * mctx The memory context used to allocate the key
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * keyp Returns the new key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * DST_R_SUCCESS Success
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * !DST_R_SUCCESS Failure
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerdst_key_fromdns(const char *name, isc_buffer_t *source, isc_mem_t *mctx,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (r.length < 4) /* 2 bytes of flags, 1 proto, 1 alg */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer *keyp = get_key_struct(name, alg, flags, proto, 0, mctx);
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson ret = (*keyp)->func->from_dns(*keyp, source, mctx);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * dst_key_frombuffer
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * Function to convert raw data into a public key. The raw data format
e56101fa6876c876d9957c23784b6493cdb05e09Brian Wellington * is basically DNS KEY rdata format.
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews * name The key name
4b30598fb908755c4fd04f51cf3ce1f550434bf3Mark Andrews * alg The algorithm
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * flags The key's flags
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * protocol The key's protocol
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * source A buffer containing the key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * mctx The memory context used to allocate the key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * keyp Returns the new key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * DST_R_SUCCESS Success
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * !DST_R_SUCCESS Failure
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerdst_key_frombuffer(const char *name, const int alg, const int flags,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer const int protocol, isc_buffer_t *source, isc_mem_t *mctx,
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson if (dst_supported_algorithm(alg) == ISC_FALSE)
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson *keyp = get_key_struct(name, alg, flags, protocol, 0, mctx);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer ret = (*keyp)->func->from_dns((*keyp), source, mctx);
3f79a8b6f1b50f8e1bc2f274bcfe91d6af74f161Mark Andrews * dst_key_tobuffer
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson * Function to convert a public key into raw data. The raw data format
96eeb9496c09114c116132d5a493ef5eb88e3192Automatic Updater * is basically DNS KEY rdata format.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * key The key
20b6f1e657d049d9fdb251a0846465bff9b95948Andreas Gustafsson * target The buffer to be written into.
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * DST_R_SUCCESS Success
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * !DST_R_SUCCESS Failure
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerdst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
04e5f9812cb02d5d86b542dfa9a394f074ff5621Evan Hunt * dst_key_generate
04e5f9812cb02d5d86b542dfa9a394f074ff5621Evan Hunt * Generate and store a public/private keypair.
04e5f9812cb02d5d86b542dfa9a394f074ff5621Evan Hunt * Keys will be stored in formatted files.
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson * name Name of the new key. Used to create key files
b4876b6ddf706977153954507b498baf79a23442Andreas Gustafsson * K<name>+<alg>+<id>.public
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * K<name>+<alg>+<id>.private
7804502532d6e2eee80083431a22eb5d957f52a0Michael Sawyer * alg The algorithm to use
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * bits Size of the new key in bits
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * param Algorithm specific (currently RSA only)
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * 0 use exponent 3
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * !0 use Fermat4 (2^16 + 1)
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * flags The default value of the DNS Key flags.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * protocol Default value of the DNS Key protocol field.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * mctx The memory context used to allocate the key
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * keyp Returns the new key
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * DST_R_SUCCESS Success
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * !DST_R_SUCCESS Failure
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdst_key_generate(const char *name, const int alg, const int bits,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer const int exp, const int flags, const int protocol,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (dst_supported_algorithm(alg) == ISC_FALSE)
46e349e515e0b992ecafdc9597f9d5ee0cf81b2aBrian Wellington *keyp = get_key_struct(name, alg, flags, protocol, bits, mctx);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = (*keyp)->func->generate(*keyp, exp, mctx);
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * dst_key_compare
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * Compares two keys for equality.
8afea636ab0c07399aa3e2410b2cfbd41099df98Mark Andrews * Parameters
8afea636ab0c07399aa3e2410b2cfbd41099df98Mark Andrews * key1, key2 Two keys to be compared.
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * ISC_TRUE The keys are equal.
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * ISC_FALSE The keys are not equal.
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafssondst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * dst_key_free
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * Release all data structures pointed to by a key structure.
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer * key Key structure to be freed.
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * mctx The memory context used to allocate the key
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyerdst_key_free(dst_key_t *key, isc_mem_t *mctx) {
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
67d01dcacb2051a03377c8ec5c0e36604c17aea5Evan Hunt * dst_sig_size
67d01dcacb2051a03377c8ec5c0e36604c17aea5Evan Hunt * Computes the maximum size of a signature generated by the given key
67d01dcacb2051a03377c8ec5c0e36604c17aea5Evan Hunt * Parameters
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * key The DST key
32e783c745299f838dd7cf8ffe2032775a80f1d0Andreas Gustafsson * n The number of bytes necessary to hold a signature with the key.
0a92db42c6be6a158cd41ff863831a8d2d257935Mark Andrews RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer REQUIRE(dst_supported_algorithm(key->key_alg) == ISC_TRUE);
0a92db42c6be6a158cd41ff863831a8d2d257935Mark Andrews return (20);
0a92db42c6be6a158cd41ff863831a8d2d257935Mark Andrews return (-1);
7f20fd8ebb0cabc8f935381d958f8371990c9212Mark Andrews * dst_random
0a92db42c6be6a158cd41ff863831a8d2d257935Mark Andrews * a random number generator that can generate different levels of
0a92db42c6be6a158cd41ff863831a8d2d257935Mark Andrews * Parameters
20b6f1e657d049d9fdb251a0846465bff9b95948Andreas Gustafsson * mode selects the random number generator
8e61de2efdc23d1248cff0abf4cadec3325a929cMichael Sawyer * wanted the number of random bytes requested
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * target the buffer to store the random data
688a4c50c2025a683d8d2bf5bb53a591556df4fcAndreas Gustafsson * DST_R_SUCCESS Success
8e61de2efdc23d1248cff0abf4cadec3325a929cMichael Sawyer * !DST_R_SUCCESS Failure
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdst_random(const unsigned int wanted, isc_buffer_t *target) {
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer RUNTIME_CHECK(isc_mutex_lock((&random_lock)) == ISC_R_SUCCESS);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer RUNTIME_CHECK(isc_mutex_unlock((&random_lock)) == ISC_R_SUCCESS);
96eeb9496c09114c116132d5a493ef5eb88e3192Automatic Updater *** Static methods
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * This function initializes the Digital Signature Toolkit.
824cb6567555af556d0963d961798483d252eb5fMark Andrews * Parameters
aa2c453d3c6e416b56b29247bedd9a0af2721e93Mark Andrews RUNTIME_CHECK(isc_mem_create(0, 0, &dst_memory_pool) == ISC_R_SUCCESS);
9a762177e6a0aff3ea5c00f87568c8ae3cd0e6c7Andreas Gustafsson RUNTIME_CHECK(isc_mutex_init(&random_lock) == ISC_R_SUCCESS);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * get_key_struct
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * This function allocates key structure and fills in some of the
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * fields of the structure.
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * Parameters:
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * name the name of the key
5d20773abcdf9ff3afe14a349413174f94594188Michael Sawyer * alg the algorithm number
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * flags the dns flags of the key
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * protocol the dns protocol of the key
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * bits the size of the key
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * mctx the memory context to allocate from
32e783c745299f838dd7cf8ffe2032775a80f1d0Andreas Gustafsson * valid pointer otherwise
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyerget_key_struct(const char *name, const int alg, const int flags,
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer const int protocol, const int bits, isc_mem_t *mctx)
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer REQUIRE(dst_supported_algorithm(alg) != ISC_FALSE);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * dst_read_public_key
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Read a public key from disk
0e0e575ec135a983a53c501cf48734b823361ab4Brian Wellington * name The name
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer * alg The algorithm
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * mctx The memory context used to allocate the key
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * keyp Returns the new key
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * DST_R_SUCCESS Success
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * !DST_R_SUCCESS Failure
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerread_public_key(const char *name, const isc_uint16_t id, int alg,
5f01e77fc23fe9665fa2b8acd0a0c5bfbf61d61dBrian Wellington if (dst_s_build_filename(filename, name, id, alg, PUBLIC_KEY,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Open the file and read its formatted contents
f900be21902d02418c2c71ffed754fb3f9f54cffMichael Sawyer * File format:
f900be21902d02418c2c71ffed754fb3f9f54cffMichael Sawyer * domain.name [ttl] [IN] KEY <flags> <protocol> <algorithm> <key>
715361d0c3800e5ad886e5df971936ce6cd1ca89Mark Andrews /* 540 should be large enough for a 1024 bit DSA key */
5f01e77fc23fe9665fa2b8acd0a0c5bfbf61d61dBrian Wellington iret = isc_lex_gettoken(lex, opt, token); \
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt /* Read the domain name */
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt /* Read the next word: either TTL, 'IN', or 'KEY' */
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt /* If it's a TTL, read the next one */
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt if (strcasecmp(token.value.as_pointer, "IN") == 0)
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt if (strcasecmp(token.value.as_pointer, "KEY") != 0)
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf), ISC_BUFFERTYPE_BINARY);
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt dret = dns_rdata_fromtext(&rdata, dns_rdataclass_in, dns_rdatatype_key,
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt if (ret != DST_R_SUCCESS || (*keyp)->key_alg != alg)
67d01dcacb2051a03377c8ec5c0e36604c17aea5Evan Hunt * write_public_key
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Write a key to disk in DNS format.
67d01dcacb2051a03377c8ec5c0e36604c17aea5Evan Hunt * Parameters
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer * key A DST key
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer * DST_R_SUCCESS Success
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer * !DST_R_SUCCESS Failure
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&keyb, key_array, sizeof(key_array),
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&textb, text_array, sizeof(text_array),
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_fromregion(&rdata, dns_rdataclass_in, dns_rdatatype_key, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dnsret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Make the filename */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (dst_s_build_filename(filename, key->key_name, key->key_id,
e715e011788a529446b8013239c33599542ece32Michael Sawyer /* create public key file */