dst.h revision 245163
1105197Ssam/* 2105197Ssam * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") 3105197Ssam * Copyright (C) 2000-2002 Internet Software Consortium. 4139823Simp * 5105197Ssam * Permission to use, copy, modify, and/or distribute this software for any 6105197Ssam * purpose with or without fee is hereby granted, provided that the above 7105197Ssam * copyright notice and this permission notice appear in all copies. 8105197Ssam * 9105197Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10105197Ssam * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11105197Ssam * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12105197Ssam * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13105197Ssam * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14105197Ssam * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15105197Ssam * PERFORMANCE OF THIS SOFTWARE. 16105197Ssam */ 17105197Ssam 18105197Ssam/* $Id$ */ 19105197Ssam 20105197Ssam#ifndef DST_DST_H 21105197Ssam#define DST_DST_H 1 22105197Ssam 23105197Ssam/*! \file dst/dst.h */ 24105197Ssam 25105197Ssam#include <isc/lang.h> 26105197Ssam#include <isc/stdtime.h> 27105197Ssam 28105197Ssam#include <dns/types.h> 29105197Ssam#include <dns/name.h> 30105197Ssam#include <dns/secalg.h> 31105197Ssam 32105197Ssam#include <dst/gssapi.h> 33105197Ssam 34105197SsamISC_LANG_BEGINDECLS 35105197Ssam 36105197Ssam/*** 37105197Ssam *** Types 38105197Ssam ***/ 39105197Ssam 40105197Ssam/*% 41105197Ssam * The dst_key structure is opaque. Applications should use the accessor 42105197Ssam * functions provided to retrieve key attributes. If an application needs 43105197Ssam * to set attributes, new accessor functions will be written. 44105197Ssam */ 45119643Ssam 46119643Ssamtypedef struct dst_key dst_key_t; 47105197Ssamtypedef struct dst_context dst_context_t; 48105197Ssam 49105197Ssam/* DST algorithm codes */ 50105197Ssam#define DST_ALG_UNKNOWN 0 51105197Ssam#define DST_ALG_RSAMD5 1 52105197Ssam#define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */ 53105197Ssam#define DST_ALG_DH 2 54105197Ssam#define DST_ALG_DSA 3 55105197Ssam#define DST_ALG_ECC 4 56105197Ssam#define DST_ALG_RSASHA1 5 57158767Spjd#define DST_ALG_NSEC3DSA 6 58105197Ssam#define DST_ALG_NSEC3RSASHA1 7 59105197Ssam#define DST_ALG_RSASHA256 8 60105197Ssam#define DST_ALG_RSASHA512 10 61105197Ssam#define DST_ALG_ECCGOST 12 62105197Ssam#define DST_ALG_ECDSA256 13 63105197Ssam#define DST_ALG_ECDSA384 14 64105197Ssam#define DST_ALG_HMACMD5 157 65105197Ssam#define DST_ALG_GSSAPI 160 66105197Ssam#define DST_ALG_HMACSHA1 161 /* XXXMPA */ 67105197Ssam#define DST_ALG_HMACSHA224 162 /* XXXMPA */ 68105197Ssam#define DST_ALG_HMACSHA256 163 /* XXXMPA */ 69105197Ssam#define DST_ALG_HMACSHA384 164 /* XXXMPA */ 70105197Ssam#define DST_ALG_HMACSHA512 165 /* XXXMPA */ 71105197Ssam#define DST_ALG_PRIVATE 254 72105197Ssam#define DST_ALG_EXPAND 255 73105197Ssam#define DST_MAX_ALGS 255 74105197Ssam 75105197Ssam/*% A buffer of this size is large enough to hold any key */ 76105197Ssam#define DST_KEY_MAXSIZE 1280 77105197Ssam 78105197Ssam/*% 79105197Ssam * A buffer of this size is large enough to hold the textual representation 80105197Ssam * of any key 81105197Ssam */ 82105197Ssam#define DST_KEY_MAXTEXTSIZE 2048 83105197Ssam 84105197Ssam/*% 'Type' for dst_read_key() */ 85105197Ssam#define DST_TYPE_KEY 0x1000000 /* KEY key */ 86105197Ssam#define DST_TYPE_PRIVATE 0x2000000 87105197Ssam#define DST_TYPE_PUBLIC 0x4000000 88105197Ssam 89105197Ssam/* Key timing metadata definitions */ 90105197Ssam#define DST_TIME_CREATED 0 91105197Ssam#define DST_TIME_PUBLISH 1 92105197Ssam#define DST_TIME_ACTIVATE 2 93105197Ssam#define DST_TIME_REVOKE 3 94105197Ssam#define DST_TIME_INACTIVE 4 95105197Ssam#define DST_TIME_DELETE 5 96105197Ssam#define DST_TIME_DSPUBLISH 6 97105197Ssam#define DST_MAX_TIMES 6 98105197Ssam 99105197Ssam/* Numeric metadata definitions */ 100105197Ssam#define DST_NUM_PREDECESSOR 0 101105197Ssam#define DST_NUM_SUCCESSOR 1 102105197Ssam#define DST_NUM_MAXTTL 2 103105197Ssam#define DST_NUM_ROLLPERIOD 3 104105197Ssam#define DST_MAX_NUMERIC 3 105105197Ssam 106105197Ssam/* 107105197Ssam * Current format version number of the private key parser. 108105197Ssam * 109105197Ssam * When parsing a key file with the same major number but a higher minor 110105197Ssam * number, the key parser will ignore any fields it does not recognize. 111105197Ssam * Thus, DST_MINOR_VERSION should be incremented whenever new 112105197Ssam * fields are added to the private key file (such as new metadata). 113105197Ssam * 114105197Ssam * When rewriting these keys, those fields will be dropped, and the 115105197Ssam * format version set back to the current one.. 116105197Ssam * 117105197Ssam * When a key is seen with a higher major number, the key parser will 118105197Ssam * reject it as invalid. Thus, DST_MAJOR_VERSION should be incremented 119105197Ssam * and DST_MINOR_VERSION set to zero whenever there is a format change 120105197Ssam * which is not backward compatible to previous versions of the dst_key 121105197Ssam * parser, such as change in the syntax of an existing field, the removal 122105197Ssam * of a currently mandatory field, or a new field added which would 123125876Sguido * alter the functioning of the key if it were absent. 124105197Ssam */ 125105197Ssam#define DST_MAJOR_VERSION 1 126105197Ssam#define DST_MINOR_VERSION 3 127105197Ssam 128119643Ssam/*** 129120585Ssam *** Functions 130120585Ssam ***/ 131120585Ssam 132120585Ssamisc_result_t 133120585Ssamdst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags); 134120585Ssam 135120585Ssamisc_result_t 136120585Ssamdst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, 137105197Ssam const char *engine, unsigned int eflags); 138119643Ssam/*%< 139120585Ssam * Initializes the DST subsystem. 140120585Ssam * 141120585Ssam * Requires: 142120585Ssam * \li "mctx" is a valid memory context 143120585Ssam * \li "ectx" is a valid entropy context 144120585Ssam * 145120585Ssam * Returns: 146120585Ssam * \li ISC_R_SUCCESS 147119643Ssam * \li ISC_R_NOMEMORY 148105197Ssam * \li DST_R_NOENGINE 149119643Ssam * 150120585Ssam * Ensures: 151120585Ssam * \li DST is properly initialized. 152120585Ssam */ 153120585Ssam 154120585Ssamvoid 155120585Ssamdst_lib_destroy(void); 156120585Ssam/*%< 157105197Ssam * Releases all resources allocated by DST. 158119643Ssam */ 159120585Ssam 160120585Ssamisc_boolean_t 161120585Ssamdst_algorithm_supported(unsigned int alg); 162120585Ssam/*%< 163120585Ssam * Checks that a given algorithm is supported by DST. 164120585Ssam * 165120585Ssam * Returns: 166105197Ssam * \li ISC_TRUE 167119643Ssam * \li ISC_FALSE 168120585Ssam */ 169120585Ssam 170120585Ssamisc_result_t 171120585Ssamdst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp); 172120585Ssam/*%< 173120585Ssam * Creates a context to be used for a sign or verify operation. 174120585Ssam * 175105197Ssam * Requires: 176105197Ssam * \li "key" is a valid key. 177128856Ssam * \li "mctx" is a valid memory context. 178105197Ssam * \li dctxp != NULL && *dctxp == NULL 179105197Ssam * 180128856Ssam * Returns: 181128856Ssam * \li ISC_R_SUCCESS 182128856Ssam * \li ISC_R_NOMEMORY 183105197Ssam * 184105197Ssam * Ensures: 185105197Ssam * \li *dctxp will contain a usable context. 186105197Ssam */ 187105197Ssam 188105197Ssamvoid 189105197Ssamdst_context_destroy(dst_context_t **dctxp); 190105197Ssam/*%< 191105197Ssam * Destroys all memory associated with a context. 192105197Ssam * 193105197Ssam * Requires: 194105197Ssam * \li *dctxp != NULL && *dctxp == NULL 195105197Ssam * 196105197Ssam * Ensures: 197105197Ssam * \li *dctxp == NULL 198105197Ssam */ 199105197Ssam 200105197Ssamisc_result_t 201105197Ssamdst_context_adddata(dst_context_t *dctx, const isc_region_t *data); 202105197Ssam/*%< 203105197Ssam * Incrementally adds data to the context to be used in a sign or verify 204105197Ssam * operation. 205105197Ssam * 206105197Ssam * Requires: 207105197Ssam * \li "dctx" is a valid context 208105197Ssam * \li "data" is a valid region 209105197Ssam * 210105197Ssam * Returns: 211105197Ssam * \li ISC_R_SUCCESS 212105197Ssam * \li DST_R_SIGNFAILURE 213105197Ssam * \li all other errors indicate failure 214105197Ssam */ 215105197Ssam 216105197Ssamisc_result_t 217105197Ssamdst_context_sign(dst_context_t *dctx, isc_buffer_t *sig); 218105197Ssam/*%< 219105197Ssam * Computes a signature using the data and key stored in the context. 220105197Ssam * 221105197Ssam * Requires: 222105197Ssam * \li "dctx" is a valid context. 223105197Ssam * \li "sig" is a valid buffer. 224105197Ssam * 225105197Ssam * Returns: 226105197Ssam * \li ISC_R_SUCCESS 227105197Ssam * \li DST_R_VERIFYFAILURE 228105197Ssam * \li all other errors indicate failure 229105197Ssam * 230105197Ssam * Ensures: 231105197Ssam * \li "sig" will contain the signature 232105197Ssam */ 233105197Ssam 234105197Ssamisc_result_t 235105197Ssamdst_context_verify(dst_context_t *dctx, isc_region_t *sig); 236105197Ssam/*%< 237105197Ssam * Verifies the signature using the data and key stored in the context. 238105197Ssam * 239105197Ssam * Requires: 240105197Ssam * \li "dctx" is a valid context. 241105197Ssam * \li "sig" is a valid region. 242105197Ssam * 243105197Ssam * Returns: 244105197Ssam * \li ISC_R_SUCCESS 245105197Ssam * \li all other errors indicate failure 246105197Ssam * 247105197Ssam * Ensures: 248105197Ssam * \li "sig" will contain the signature 249105197Ssam */ 250105197Ssam 251105197Ssamisc_result_t 252105197Ssamdst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, 253105197Ssam isc_buffer_t *secret); 254105197Ssam/*%< 255105197Ssam * Computes a shared secret from two (Diffie-Hellman) keys. 256105197Ssam * 257105197Ssam * Requires: 258105197Ssam * \li "pub" is a valid key that can be used to derive a shared secret 259105197Ssam * \li "priv" is a valid private key that can be used to derive a shared secret 260105197Ssam * \li "secret" is a valid buffer 261105197Ssam * 262105197Ssam * Returns: 263105197Ssam * \li ISC_R_SUCCESS 264105197Ssam * \li any other result indicates failure 265105197Ssam * 266105197Ssam * Ensures: 267105197Ssam * \li If successful, secret will contain the derived shared secret. 268105197Ssam */ 269105197Ssam 270105197Ssamisc_result_t 271105197Ssamdst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, 272105197Ssam const char *directory, isc_mem_t *mctx, dst_key_t **keyp); 273105197Ssam/*%< 274105197Ssam * Reads a key from permanent storage. The key can either be a public or 275105197Ssam * private key, and is specified by name, algorithm, and id. If a private key 276105197Ssam * is specified, the public key must also be present. If directory is NULL, 277105197Ssam * the current directory is assumed. 278105197Ssam * 279105197Ssam * Requires: 280105197Ssam * \li "name" is a valid absolute dns name. 281105197Ssam * \li "id" is a valid key tag identifier. 282105197Ssam * \li "alg" is a supported key algorithm. 283105197Ssam * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. 284105197Ssam * DST_TYPE_KEY look for a KEY record otherwise DNSKEY 285105197Ssam * \li "mctx" is a valid memory context. 286105197Ssam * \li "keyp" is not NULL and "*keyp" is NULL. 287105197Ssam * 288105197Ssam * Returns: 289125876Sguido * \li ISC_R_SUCCESS 290125876Sguido * \li any other result indicates failure 291105197Ssam * 292105197Ssam * Ensures: 293105197Ssam * \li If successful, *keyp will contain a valid key. 294105197Ssam */ 295105197Ssam 296105197Ssamisc_result_t 297105197Ssamdst_key_fromnamedfile(const char *filename, const char *dirname, 298105197Ssam int type, isc_mem_t *mctx, dst_key_t **keyp); 299105197Ssam/*%< 300105197Ssam * Reads a key from permanent storage. The key can either be a public or 301105197Ssam * key, and is specified by filename. If a private key is specified, the 302105197Ssam * public key must also be present. 303105197Ssam * 304105197Ssam * If 'dirname' is not NULL, and 'filename' is a relative path, 305105197Ssam * then the file is looked up relative to the given directory. 306105197Ssam * If 'filename' is an absolute path, 'dirname' is ignored. 307105197Ssam * 308105197Ssam * Requires: 309105197Ssam * \li "filename" is not NULL 310105197Ssam * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union 311105197Ssam * DST_TYPE_KEY look for a KEY record otherwise DNSKEY 312105197Ssam * \li "mctx" is a valid memory context 313105197Ssam * \li "keyp" is not NULL and "*keyp" is NULL. 314105197Ssam * 315105197Ssam * Returns: 316105197Ssam * \li ISC_R_SUCCESS 317105197Ssam * \li any other result indicates failure 318105197Ssam * 319105197Ssam * Ensures: 320105197Ssam * \li If successful, *keyp will contain a valid key. 321105197Ssam */ 322105197Ssam 323105197Ssam 324119643Ssamisc_result_t 325119643Ssamdst_key_read_public(const char *filename, int type, 326119643Ssam isc_mem_t *mctx, dst_key_t **keyp); 327119643Ssam/*%< 328119643Ssam * Reads a public key from permanent storage. The key must be a public key. 329119643Ssam * 330119643Ssam * Requires: 331105197Ssam * \li "filename" is not NULL 332105197Ssam * \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY 333105197Ssam * \li "mctx" is a valid memory context 334105197Ssam * \li "keyp" is not NULL and "*keyp" is NULL. 335105197Ssam * 336105197Ssam * Returns: 337105197Ssam * \li ISC_R_SUCCESS 338105197Ssam * \li DST_R_BADKEYTYPE if the key type is not the expected one 339105197Ssam * \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key 340105197Ssam * \li any other result indicates failure 341105197Ssam * 342105197Ssam * Ensures: 343105197Ssam * \li If successful, *keyp will contain a valid key. 344105197Ssam */ 345105197Ssam 346105197Ssamisc_result_t 347105197Ssamdst_key_tofile(const dst_key_t *key, int type, const char *directory); 348105197Ssam/*%< 349105197Ssam * Writes a key to permanent storage. The key can either be a public or 350105197Ssam * private key. Public keys are written in DNS format and private keys 351105197Ssam * are written as a set of base64 encoded values. If directory is NULL, 352105197Ssam * the current directory is assumed. 353105197Ssam * 354105197Ssam * Requires: 355105197Ssam * \li "key" is a valid key. 356105197Ssam * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union 357105197Ssam * 358105197Ssam * Returns: 359105197Ssam * \li ISC_R_SUCCESS 360105197Ssam * \li any other result indicates failure 361105197Ssam */ 362105197Ssam 363105197Ssamisc_result_t 364105197Ssamdst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, 365105197Ssam isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); 366105197Ssam/*%< 367105197Ssam * Converts a DNS KEY record into a DST key. 368105197Ssam * 369105197Ssam * Requires: 370105197Ssam * \li "name" is a valid absolute dns name. 371105197Ssam * \li "source" is a valid buffer. There must be at least 4 bytes available. 372105197Ssam * \li "mctx" is a valid memory context. 373105197Ssam * \li "keyp" is not NULL and "*keyp" is NULL. 374105197Ssam * 375105197Ssam * Returns: 376105197Ssam * \li ISC_R_SUCCESS 377105197Ssam * \li any other result indicates failure 378119643Ssam * 379105197Ssam * Ensures: 380105197Ssam * \li If successful, *keyp will contain a valid key, and the consumed 381105197Ssam * pointer in data will be advanced. 382105197Ssam */ 383105197Ssam 384105197Ssamisc_result_t 385105197Ssamdst_key_todns(const dst_key_t *key, isc_buffer_t *target); 386105197Ssam/*%< 387105197Ssam * Converts a DST key into a DNS KEY record. 388105197Ssam * 389105197Ssam * Requires: 390105197Ssam * \li "key" is a valid key. 391105197Ssam * \li "target" is a valid buffer. There must be at least 4 bytes unused. 392105197Ssam * 393105197Ssam * Returns: 394105197Ssam * \li ISC_R_SUCCESS 395105197Ssam * \li any other result indicates failure 396105197Ssam * 397105197Ssam * Ensures: 398105197Ssam * \li If successful, the used pointer in 'target' is advanced by at least 4. 399105197Ssam */ 400105197Ssam 401105197Ssamisc_result_t 402105197Ssamdst_key_frombuffer(dns_name_t *name, unsigned int alg, 403105197Ssam unsigned int flags, unsigned int protocol, 404105197Ssam dns_rdataclass_t rdclass, 405105197Ssam isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); 406105197Ssam/*%< 407105197Ssam * Converts a buffer containing DNS KEY RDATA into a DST key. 408105197Ssam * 409105197Ssam * Requires: 410105197Ssam *\li "name" is a valid absolute dns name. 411105197Ssam *\li "alg" is a supported key algorithm. 412105197Ssam *\li "source" is a valid buffer. 413105197Ssam *\li "mctx" is a valid memory context. 414105197Ssam *\li "keyp" is not NULL and "*keyp" is NULL. 415105197Ssam * 416105197Ssam * Returns: 417105197Ssam *\li ISC_R_SUCCESS 418105197Ssam * \li any other result indicates failure 419105197Ssam * 420105197Ssam * Ensures: 421105197Ssam *\li If successful, *keyp will contain a valid key, and the consumed 422105197Ssam * pointer in source will be advanced. 423105197Ssam */ 424157123Sgnn 425157123Sgnnisc_result_t 426157123Sgnndst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target); 427157123Sgnn/*%< 428105197Ssam * Converts a DST key into DNS KEY RDATA format. 429105197Ssam * 430105197Ssam * Requires: 431105197Ssam *\li "key" is a valid key. 432105197Ssam *\li "target" is a valid buffer. 433105197Ssam * 434105197Ssam * Returns: 435105197Ssam *\li ISC_R_SUCCESS 436105197Ssam * \li any other result indicates failure 437105197Ssam * 438105197Ssam * Ensures: 439105197Ssam *\li If successful, the used pointer in 'target' is advanced. 440105197Ssam */ 441105197Ssam 442105197Ssamisc_result_t 443105197Ssamdst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer); 444105197Ssam/*%< 445105197Ssam * Converts a public key into a private key, reading the private key 446105197Ssam * information from the buffer. The buffer should contain the same data 447105197Ssam * as the .private key file would. 448105197Ssam * 449105197Ssam * Requires: 450105197Ssam *\li "key" is a valid public key. 451105197Ssam *\li "buffer" is not NULL. 452105197Ssam * 453105197Ssam * Returns: 454105197Ssam *\li ISC_R_SUCCESS 455105197Ssam * \li any other result indicates failure 456105197Ssam * 457105197Ssam * Ensures: 458105197Ssam *\li If successful, key will contain a valid private key. 459105197Ssam */ 460105197Ssam 461105197Ssamgss_ctx_id_t 462105197Ssamdst_key_getgssctx(const dst_key_t *key); 463105197Ssam/*%< 464105197Ssam * Returns the opaque key data. 465105197Ssam * Be cautions when using this value unless you know what you are doing. 466105197Ssam * 467105197Ssam * Requires: 468105197Ssam *\li "key" is not NULL. 469105197Ssam * 470105197Ssam * Returns: 471105197Ssam *\li gssctx key data, possibly NULL. 472105197Ssam */ 473105197Ssam 474105197Ssamisc_result_t 475105197Ssamdst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, 476105197Ssam dst_key_t **keyp, isc_region_t *intoken); 477105197Ssam/*%< 478105197Ssam * Converts a GSSAPI opaque context id into a DST key. 479105197Ssam * 480105197Ssam * Requires: 481105197Ssam *\li "name" is a valid absolute dns name. 482105197Ssam *\li "gssctx" is a GSSAPI context id. 483105197Ssam *\li "mctx" is a valid memory context. 484105197Ssam *\li "keyp" is not NULL and "*keyp" is NULL. 485105197Ssam * 486105197Ssam * Returns: 487105197Ssam *\li ISC_R_SUCCESS 488105197Ssam * \li any other result indicates failure 489105197Ssam * 490105197Ssam * Ensures: 491105197Ssam *\li If successful, *keyp will contain a valid key and be responsible for 492105197Ssam * the context id. 493105197Ssam */ 494105197Ssam 495157123Sgnnisc_result_t 496157123Sgnndst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, 497157123Sgnn unsigned int protocol, dns_rdataclass_t rdclass, 498157123Sgnn const char *engine, const char *label, const char *pin, 499105197Ssam isc_mem_t *mctx, dst_key_t **keyp); 500105197Ssam 501105197Ssamisc_result_t 502105197Ssamdst_key_generate(dns_name_t *name, unsigned int alg, 503105197Ssam unsigned int bits, unsigned int param, 504105197Ssam unsigned int flags, unsigned int protocol, 505105197Ssam dns_rdataclass_t rdclass, 506158767Spjd isc_mem_t *mctx, dst_key_t **keyp); 507158767Spjd 508158767Spjdisc_result_t 509105197Ssamdst_key_generate2(dns_name_t *name, unsigned int alg, 510158767Spjd unsigned int bits, unsigned int param, 511158767Spjd unsigned int flags, unsigned int protocol, 512158767Spjd dns_rdataclass_t rdclass, 513158767Spjd isc_mem_t *mctx, dst_key_t **keyp, 514158767Spjd void (*callback)(int)); 515158767Spjd/*%< 516158767Spjd * Generate a DST key (or keypair) with the supplied parameters. The 517158767Spjd * interpretation of the "param" field depends on the algorithm: 518158767Spjd * \code 519158767Spjd * RSA: exponent 520158767Spjd * 0 use exponent 3 521158767Spjd * !0 use Fermat4 (2^16 + 1) 522158767Spjd * DH: generator 523158767Spjd * 0 default - use well known prime if bits == 768 or 1024, 524158767Spjd * otherwise use 2 as the generator. 525158767Spjd * !0 use this value as the generator. 526158767Spjd * DSA: unused 527105197Ssam * HMACMD5: entropy 528105197Ssam * 0 default - require good entropy 529120585Ssam * !0 lack of good entropy is ok 530105197Ssam *\endcode 531105197Ssam * 532120585Ssam * Requires: 533105197Ssam *\li "name" is a valid absolute dns name. 534105197Ssam *\li "keyp" is not NULL and "*keyp" is NULL. 535135947Ssam * 536105197Ssam * Returns: 537105197Ssam *\li ISC_R_SUCCESS 538135947Ssam * \li any other result indicates failure 539135947Ssam * 540135947Ssam * Ensures: 541135947Ssam *\li If successful, *keyp will contain a valid key. 542135947Ssam */ 543135947Ssam 544135947Ssamisc_boolean_t 545135947Ssamdst_key_compare(const dst_key_t *key1, const dst_key_t *key2); 546135947Ssam/*%< 547135947Ssam * Compares two DST keys. Returns true if they match, false otherwise. 548135947Ssam * 549105197Ssam * Keys ARE NOT considered to match if one of them is the revoked version 550105197Ssam * of the other. 551105197Ssam * 552105197Ssam * Requires: 553105197Ssam *\li "key1" is a valid key. 554105197Ssam *\li "key2" is a valid key. 555105197Ssam * 556105197Ssam * Returns: 557105197Ssam *\li ISC_TRUE 558105197Ssam * \li ISC_FALSE 559105197Ssam */ 560105197Ssam 561105197Ssamisc_boolean_t 562105197Ssamdst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2, 563105197Ssam isc_boolean_t match_revoked_key); 564105197Ssam/*%< 565105197Ssam * Compares only the public portions of two DST keys. Returns true 566105197Ssam * if they match, false otherwise. This allows us, for example, to 567105197Ssam * determine whether a public key found in a zone matches up with a 568105197Ssam * key pair found on disk. 569105197Ssam * 570105197Ssam * If match_revoked_key is TRUE, then keys ARE considered to match if one 571105197Ssam * of them is the revoked version of the other. Otherwise, they are not. 572120585Ssam * 573120585Ssam * Requires: 574120585Ssam *\li "key1" is a valid key. 575105197Ssam *\li "key2" is a valid key. 576105197Ssam * 577120585Ssam * Returns: 578105197Ssam *\li ISC_TRUE 579105197Ssam * \li ISC_FALSE 580105197Ssam */ 581105197Ssam 582105197Ssamisc_boolean_t 583105197Ssamdst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2); 584120585Ssam/*%< 585105197Ssam * Compares the parameters of two DST keys. This is used to determine if 586105197Ssam * two (Diffie-Hellman) keys can be used to derive a shared secret. 587105197Ssam * 588105197Ssam * Requires: 589105197Ssam *\li "key1" is a valid key. 590105197Ssam *\li "key2" is a valid key. 591105197Ssam * 592105197Ssam * Returns: 593105197Ssam *\li ISC_TRUE 594105197Ssam * \li ISC_FALSE 595105197Ssam */ 596105197Ssam 597105197Ssamvoid 598105197Ssamdst_key_attach(dst_key_t *source, dst_key_t **target); 599120585Ssam/* 600105197Ssam * Attach to a existing key increasing the reference count. 601105197Ssam * 602105197Ssam * Requires: 603105197Ssam *\li 'source' to be a valid key. 604105197Ssam *\li 'target' to be non-NULL and '*target' to be NULL. 605120585Ssam */ 606105197Ssam 607105197Ssamvoid 608120585Ssamdst_key_free(dst_key_t **keyp); 609105197Ssam/*%< 610105197Ssam * Decrement the key's reference counter and, when it reaches zero, 611105197Ssam * release all memory associated with the key. 612105197Ssam * 613105197Ssam * Requires: 614105197Ssam *\li "keyp" is not NULL and "*keyp" is a valid key. 615105197Ssam *\li reference counter greater than zero. 616105197Ssam * 617105197Ssam * Ensures: 618105197Ssam *\li All memory associated with "*keyp" will be freed. 619105197Ssam *\li *keyp == NULL 620105197Ssam */ 621105197Ssam 622105197Ssam/*%< 623105197Ssam * Accessor functions to obtain key fields. 624105197Ssam * 625105197Ssam * Require: 626105197Ssam *\li "key" is a valid key. 627105197Ssam */ 628120585Ssamdns_name_t * 629120585Ssamdst_key_name(const dst_key_t *key); 630120585Ssam 631105197Ssamunsigned int 632105197Ssamdst_key_size(const dst_key_t *key); 633120585Ssam 634105197Ssamunsigned int 635105197Ssamdst_key_proto(const dst_key_t *key); 636105197Ssam 637105197Ssamunsigned int 638105197Ssamdst_key_alg(const dst_key_t *key); 639105197Ssam 640105197Ssamisc_uint32_t 641120585Ssamdst_key_flags(const dst_key_t *key); 642105197Ssam 643105197Ssamdns_keytag_t 644105197Ssamdst_key_id(const dst_key_t *key); 645105197Ssam 646105197Ssamdns_keytag_t 647105197Ssamdst_key_rid(const dst_key_t *key); 648105197Ssam 649105197Ssamdns_rdataclass_t 650105197Ssamdst_key_class(const dst_key_t *key); 651105197Ssam 652105197Ssamisc_boolean_t 653105197Ssamdst_key_isprivate(const dst_key_t *key); 654105197Ssam 655105197Ssamisc_boolean_t 656105197Ssamdst_key_iszonekey(const dst_key_t *key); 657105197Ssam 658105197Ssamisc_boolean_t 659105197Ssamdst_key_isnullkey(const dst_key_t *key); 660105197Ssam 661105197Ssamisc_result_t 662120585Ssamdst_key_buildfilename(const dst_key_t *key, int type, 663105197Ssam const char *directory, isc_buffer_t *out); 664105197Ssam/*%< 665105197Ssam * Generates the filename used by dst to store the specified key. 666105197Ssam * If directory is NULL, the current directory is assumed. 667105197Ssam * 668120585Ssam * Requires: 669105197Ssam *\li "key" is a valid key 670105197Ssam *\li "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix. 671120585Ssam *\li "out" is a valid buffer 672105197Ssam * 673105197Ssam * Ensures: 674105197Ssam *\li the file name will be written to "out", and the used pointer will 675105197Ssam * be advanced. 676105197Ssam */ 677105197Ssam 678105197Ssamisc_result_t 679105197Ssamdst_key_sigsize(const dst_key_t *key, unsigned int *n); 680105197Ssam/*%< 681105197Ssam * Computes the size of a signature generated by the given key. 682105197Ssam * 683105197Ssam * Requires: 684105197Ssam *\li "key" is a valid key. 685105197Ssam *\li "n" is not NULL 686105197Ssam * 687105197Ssam * Returns: 688105197Ssam *\li #ISC_R_SUCCESS 689105197Ssam *\li DST_R_UNSUPPORTEDALG 690105197Ssam * 691105197Ssam * Ensures: 692105197Ssam *\li "n" stores the size of a generated signature 693120585Ssam */ 694105197Ssam 695105197Ssamisc_result_t 696120585Ssamdst_key_secretsize(const dst_key_t *key, unsigned int *n); 697120585Ssam/*%< 698105197Ssam * Computes the size of a shared secret generated by the given key. 699105197Ssam * 700105197Ssam * Requires: 701105197Ssam *\li "key" is a valid key. 702120585Ssam *\li "n" is not NULL 703105197Ssam * 704105197Ssam * Returns: 705105197Ssam *\li #ISC_R_SUCCESS 706105197Ssam *\li DST_R_UNSUPPORTEDALG 707105197Ssam * 708105197Ssam * Ensures: 709105197Ssam *\li "n" stores the size of a generated shared secret 710105197Ssam */ 711105197Ssam 712105197Ssamisc_uint16_t 713105197Ssamdst_region_computeid(const isc_region_t *source, unsigned int alg); 714105197Ssamisc_uint16_t 715105197Ssamdst_region_computerid(const isc_region_t *source, unsigned int alg); 716105197Ssam/*%< 717105197Ssam * Computes the (revoked) key id of the key stored in the provided 718105197Ssam * region with the given algorithm. 719105197Ssam * 720105197Ssam * Requires: 721105197Ssam *\li "source" contains a valid, non-NULL region. 722105197Ssam * 723105197Ssam * Returns: 724105197Ssam *\li the key id 725105197Ssam */ 726105197Ssam 727105197Ssamisc_uint16_t 728105197Ssamdst_key_getbits(const dst_key_t *key); 729105197Ssam/*%< 730105197Ssam * Get the number of digest bits required (0 == MAX). 731105197Ssam * 732105197Ssam * Requires: 733105197Ssam * "key" is a valid key. 734105197Ssam */ 735105197Ssam 736105197Ssamvoid 737105197Ssamdst_key_setbits(dst_key_t *key, isc_uint16_t bits); 738105197Ssam/*%< 739105197Ssam * Set the number of digest bits required (0 == MAX). 740105197Ssam * 741105197Ssam * Requires: 742105197Ssam * "key" is a valid key. 743105197Ssam */ 744120585Ssam 745105197Ssamisc_result_t 746105197Ssamdst_key_setflags(dst_key_t *key, isc_uint32_t flags); 747120585Ssam/* 748105197Ssam * Set the key flags, and recompute the key ID. 749105197Ssam * 750105197Ssam * Requires: 751105197Ssam * "key" is a valid key. 752105197Ssam */ 753105197Ssam 754105197Ssamisc_result_t 755105197Ssamdst_key_getnum(const dst_key_t *key, int type, isc_uint32_t *valuep); 756105197Ssam/*%< 757105197Ssam * Get a member of the numeric metadata array and place it in '*valuep'. 758105197Ssam * 759105197Ssam * Requires: 760105197Ssam * "key" is a valid key. 761105197Ssam * "type" is no larger than DST_MAX_NUMERIC 762105197Ssam * "timep" is not null. 763105197Ssam */ 764120585Ssam 765120585Ssamvoid 766120585Ssamdst_key_setnum(dst_key_t *key, int type, isc_uint32_t value); 767105197Ssam/*%< 768120585Ssam * Set a member of the numeric metadata array. 769105197Ssam * 770105197Ssam * Requires: 771105197Ssam * "key" is a valid key. 772105197Ssam * "type" is no larger than DST_MAX_NUMERIC 773105197Ssam */ 774105197Ssam 775105197Ssamvoid 776120585Ssamdst_key_unsetnum(dst_key_t *key, int type); 777119643Ssam/*%< 778119643Ssam * Flag a member of the numeric metadata array as "not set". 779119643Ssam * 780105197Ssam * Requires: 781105197Ssam * "key" is a valid key. 782105197Ssam * "type" is no larger than DST_MAX_NUMERIC 783105197Ssam */ 784105197Ssam 785105197Ssamisc_result_t 786105197Ssamdst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep); 787120585Ssam/*%< 788105197Ssam * Get a member of the timing metadata array and place it in '*timep'. 789105197Ssam * 790105197Ssam * Requires: 791105197Ssam * "key" is a valid key. 792105197Ssam * "type" is no larger than DST_MAX_TIMES 793105197Ssam * "timep" is not null. 794105197Ssam */ 795105197Ssam 796105197Ssamvoid 797105197Ssamdst_key_settime(dst_key_t *key, int type, isc_stdtime_t when); 798105197Ssam/*%< 799105197Ssam * Set a member of the timing metadata array. 800105197Ssam * 801105197Ssam * Requires: 802105197Ssam * "key" is a valid key. 803105197Ssam * "type" is no larger than DST_MAX_TIMES 804105197Ssam */ 805105197Ssam 806105197Ssamvoid 807105197Ssamdst_key_unsettime(dst_key_t *key, int type); 808105197Ssam/*%< 809105197Ssam * Flag a member of the timing metadata array as "not set". 810105197Ssam * 811105197Ssam * Requires: 812105197Ssam * "key" is a valid key. 813105197Ssam * "type" is no larger than DST_MAX_TIMES 814105197Ssam */ 815105197Ssam 816105197Ssamisc_result_t 817105197Ssamdst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp); 818105197Ssam/*%< 819105197Ssam * Get the private key format version number. (If the key does not have 820105197Ssam * a private key associated with it, the version will be 0.0.) The major 821105197Ssam * version number is placed in '*majorp', and the minor version number in 822105197Ssam * '*minorp'. 823105197Ssam * 824105197Ssam * Requires: 825105197Ssam * "key" is a valid key. 826105197Ssam * "majorp" is not NULL. 827105197Ssam * "minorp" is not NULL. 828105197Ssam */ 829105197Ssam 830105197Ssamvoid 831105197Ssamdst_key_setprivateformat(dst_key_t *key, int major, int minor); 832120585Ssam/*%< 833120585Ssam * Set the private key format version number. 834105197Ssam * 835105197Ssam * Requires: 836105197Ssam * "key" is a valid key. 837105197Ssam */ 838105197Ssam 839120585Ssam#define DST_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + 7) 840105197Ssam 841105197Ssamvoid 842105197Ssamdst_key_format(const dst_key_t *key, char *cp, unsigned int size); 843105197Ssam/*%< 844105197Ssam * Write the uniquely identifying information about the key (name, 845105197Ssam * algorithm, key ID) into a string 'cp' of size 'size'. 846105197Ssam */ 847105197Ssam 848105197Ssam 849105197Ssamisc_buffer_t * 850105197Ssamdst_key_tkeytoken(const dst_key_t *key); 851105197Ssam/*%< 852105197Ssam * Return the token from the TKEY request, if any. If this key was 853105197Ssam * not negotiated via TKEY, return NULL. 854105197Ssam * 855128856Ssam * Requires: 856105197Ssam * "key" is a valid key. 857105197Ssam */ 858128856Ssam 859128856Ssam 860105197Ssamisc_result_t 861120585Ssamdst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length); 862105197Ssam/*%< 863105197Ssam * Allocate 'buffer' and dump the key into it in base64 format. The buffer 864105197Ssam * is not NUL terminated. The length of the buffer is returned in *length. 865119643Ssam * 866128856Ssam * 'buffer' needs to be freed using isc_mem_put(mctx, buffer, length); 867128856Ssam * 868128856Ssam * Requires: 869128856Ssam * 'buffer' to be non NULL and *buffer to be NULL. 870128856Ssam * 'length' to be non NULL and *length to be zero. 871128856Ssam * 872128856Ssam * Returns: 873120585Ssam * ISC_R_SUCCESS 874105197Ssam * ISC_R_NOMEMORY 875119643Ssam * ISC_R_NOTIMPLEMENTED 876105197Ssam * others. 877120585Ssam */ 878105197Ssam 879105197Ssamisc_result_t 880105197Ssamdst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, 881105197Ssam unsigned int protocol, dns_rdataclass_t rdclass, 882105197Ssam isc_mem_t *mctx, const char *keystr, dst_key_t **keyp); 883128856Ssam 884128856Ssam 885105197SsamISC_LANG_ENDDECLS 886105197Ssam 887105197Ssam#endif /* DST_DST_H */ 888105197Ssam