* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
#include <dns/dsdigest.h>
* The dst_key structure is opaque. Applications should use the accessor
* functions provided to retrieve key attributes. If an application needs
* to set attributes, new accessor functions will be written.
typedef struct dst_key dst_key_t;
typedef struct dst_context dst_context_t;
/* DST algorithm codes */
#define DST_ALG_UNKNOWN 0
#define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */
#define DST_ALG_RSASHA1 5
#define DST_ALG_NSEC3DSA 6
#define DST_ALG_NSEC3RSASHA1 7
#define DST_ALG_RSASHA256 8
#define DST_ALG_RSASHA512 10
#define DST_ALG_ECCGOST 12
#define DST_ALG_ECDSA256 13
#define DST_ALG_ECDSA384 14
#define DST_ALG_ED25519 15
#define DST_ALG_HMACMD5 157
#define DST_ALG_GSSAPI 160
#define DST_ALG_HMACSHA1 161 /* XXXMPA */
#define DST_ALG_HMACSHA224 162 /* XXXMPA */
#define DST_ALG_HMACSHA256 163 /* XXXMPA */
#define DST_ALG_HMACSHA384 164 /* XXXMPA */
#define DST_ALG_HMACSHA512 165 /* XXXMPA */
#define DST_ALG_INDIRECT 252
#define DST_ALG_PRIVATE 254
/*% A buffer of this size is large enough to hold any key */
#define DST_KEY_MAXSIZE 1280
* A buffer of this size is large enough to hold the textual representation
#define DST_KEY_MAXTEXTSIZE 2048
/*% 'Type' for dst_read_key() */
#define DST_TYPE_KEY 0x1000000 /* KEY key */
#define DST_TYPE_PRIVATE 0x2000000
#define DST_TYPE_PUBLIC 0x4000000
/* Key timing metadata definitions */
#define DST_TIME_CREATED 0
#define DST_TIME_PUBLISH 1
#define DST_TIME_ACTIVATE 2
#define DST_TIME_REVOKE 3
#define DST_TIME_INACTIVE 4
#define DST_TIME_DELETE 5
#define DST_TIME_DSPUBLISH 6
#define DST_TIME_SYNCPUBLISH 7
#define DST_TIME_SYNCDELETE 8
/* Numeric metadata definitions */
#define DST_NUM_PREDECESSOR 0
#define DST_NUM_SUCCESSOR 1
#define DST_NUM_ROLLPERIOD 3
#define DST_MAX_NUMERIC 3
* Current format version number of the private key parser.
* When parsing a key file with the same major number but a higher minor
* number, the key parser will ignore any fields it does not recognize.
* Thus, DST_MINOR_VERSION should be incremented whenever new
* fields are added to the private key file (such as new metadata).
* When rewriting these keys, those fields will be dropped, and the
* format version set back to the current one..
* When a key is seen with a higher major number, the key parser will
* reject it as invalid. Thus, DST_MAJOR_VERSION should be incremented
* and DST_MINOR_VERSION set to zero whenever there is a format change
* which is not backward compatible to previous versions of the dst_key
* parser, such as change in the syntax of an existing field, the removal
* of a currently mandatory field, or a new field added which would
* alter the functioning of the key if it were absent.
#define DST_MAJOR_VERSION 1
#define DST_MINOR_VERSION 3
dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags);
dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx,
const char *engine, unsigned int eflags);
* Initializes the DST subsystem.
* \li "mctx" is a valid memory context
* \li "ectx" is a valid entropy context
* \li DST is properly initialized.
* Releases all resources allocated by DST.
dst_random_getdata(void *data, unsigned int length,
unsigned int *returned, unsigned int flags);
* Gets random data from the random generator provided by the
* crypto library, if BIND was built with --enable-crypto-rand.
* See isc_entropy_getdata() for parameter usage. Normally when
* this function is available, it will be set up as a hook in the
* entropy context, so that isc_entropy_getdata() is a front-end to
* \li ISC_R_SUCCESS on success
* \li ISC_R_NOTIMPLEMENTED if BIND is built with --disable-crypto-rand
* \li DST_R_OPENSSLFAILURE, DST_R_CRYPTOFAILURE, or other codes on error
dst_algorithm_supported(unsigned int alg);
* Checks that a given algorithm is supported by DST.
dst_ds_digest_supported(unsigned int digest_type);
* Checks that a given digest algorithm is supported by DST.
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp);
dst_context_create2(dst_key_t *key, isc_mem_t *mctx,
isc_logcategory_t *category, dst_context_t **dctxp);
dst_context_create3(dst_key_t *key, isc_mem_t *mctx,
isc_logcategory_t *category, bool useforsigning,
dst_context_create4(dst_key_t *key, isc_mem_t *mctx,
isc_logcategory_t *category, bool useforsigning,
int maxbits, dst_context_t **dctxp);
* Creates a context to be used for a sign or verify operation.
* \li "key" is a valid key.
* \li "mctx" is a valid memory context.
* \li dctxp != NULL && *dctxp == NULL
* \li *dctxp will contain a usable context.
dst_context_destroy(dst_context_t **dctxp);
* Destroys all memory associated with a context.
* \li *dctxp != NULL && *dctxp == NULL
dst_context_adddata(dst_context_t *dctx, const isc_region_t *data);
* Incrementally adds data to the context to be used in a sign or verify
* \li "dctx" is a valid context
* \li "data" is a valid region
* \li all other errors indicate failure
dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig);
* Computes a signature using the data and key stored in the context.
* \li "dctx" is a valid context.
* \li "sig" is a valid buffer.
* \li DST_R_VERIFYFAILURE
* \li all other errors indicate failure
* \li "sig" will contain the signature
dst_context_verify(dst_context_t *dctx, isc_region_t *sig);
dst_context_verify2(dst_context_t *dctx, unsigned int maxbits,
* Verifies the signature using the data and key stored in the context.
* 'maxbits' specifies the maximum number of bits permitted in the RSA
* \li "dctx" is a valid context.
* \li "sig" is a valid region.
* \li all other errors indicate failure
* \li "sig" will contain the signature
dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
* Computes a shared secret from two (Diffie-Hellman) keys.
* \li "pub" is a valid key that can be used to derive a shared secret
* \li "priv" is a valid private key that can be used to derive a shared secret
* \li "secret" is a valid buffer
* \li any other result indicates failure
* \li If successful, secret will contain the derived shared secret.
dst_key_getfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg,
int type, const char *directory,
isc_mem_t *mctx, isc_buffer_t *buf);
* Generates a key filename for the name, algorithm, and
* id, and places it in the buffer 'buf'. If directory is NULL, the
* current directory is assumed.
* \li "name" is a valid absolute dns name.
* \li "id" is a valid key tag identifier.
* \li "alg" is a supported key algorithm.
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY
* \li "mctx" is a valid memory context.
* \li any other result indicates failure
dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type,
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
* 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.
* \li "name" is a valid absolute dns name.
* \li "id" is a valid key tag identifier.
* \li "alg" is a supported key algorithm.
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY
* \li "mctx" is a valid memory context.
* \li "keyp" is not NULL and "*keyp" is NULL.
* \li any other result indicates failure
* \li If successful, *keyp will contain a valid key.
dst_key_fromnamedfile(const char *filename, const char *dirname,
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.
* If 'dirname' is not NULL, and 'filename' is a relative path,
* then the file is looked up relative to the given directory.
* If 'filename' is an absolute path, 'dirname' is ignored.
* \li "filename" is not NULL
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY
* \li "mctx" is a valid memory context
* \li "keyp" is not NULL and "*keyp" is NULL.
* \li any other result indicates failure
* \li If successful, *keyp will contain a valid key.
dst_key_read_public(const char *filename, int type,
isc_mem_t *mctx, dst_key_t **keyp);
* Reads a public key from permanent storage. The key must be a public key.
* \li "filename" is not NULL
* \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY
* \li "mctx" is a valid memory context
* \li "keyp" is not NULL and "*keyp" is NULL.
* \li DST_R_BADKEYTYPE if the key type is not the expected one
* \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key
* \li any other result indicates failure
* \li If successful, *keyp will contain a valid key.
dst_key_tofile(const dst_key_t *key, int type, const char *directory);
* 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
* are written as a set of base64 encoded values. If directory is NULL,
* the current directory is assumed.
* \li "key" is a valid key.
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
* \li any other result indicates failure
dst_key_fromdns_ex(dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
* Converts a DNS KEY record into a DST key.
* \li "name" is a valid absolute dns name.
* \li "source" is a valid buffer. There must be at least 4 bytes available.
* \li "mctx" is a valid memory context.
* \li "keyp" is not NULL and "*keyp" is NULL.
* \li any other result indicates failure
* \li If successful, *keyp will contain a valid key, and the consumed
* pointer in data will be advanced.
dst_key_todns(const dst_key_t *key, isc_buffer_t *target);
* Converts a DST key into a DNS KEY record.
* \li "key" is a valid key.
* \li "target" is a valid buffer. There must be at least 4 bytes unused.
* \li any other result indicates failure
* \li If successful, the used pointer in 'target' is advanced by at least 4.
dst_key_frombuffer(dns_name_t *name, unsigned int alg,
unsigned int flags, unsigned int protocol,
dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
* Converts a buffer containing DNS KEY RDATA into a DST key.
*\li "name" is a valid absolute dns name.
*\li "alg" is a supported key algorithm.
*\li "source" is a valid buffer.
*\li "mctx" is a valid memory context.
*\li "keyp" is not NULL and "*keyp" is NULL.
* \li any other result indicates failure
*\li If successful, *keyp will contain a valid key, and the consumed
* pointer in source will be advanced.