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