1/*
2 *
3 * keys.h
4 *
5 * priv key definitions
6 *
7 * a Net::DNS like library for C
8 *
9 * (c) NLnet Labs, 2005-2006
10 *
11 * See the file LICENSE for the license
12 */
13
14/**
15 * \file
16 *
17 * Addendum to \ref dnssec.h, this module contains key and algorithm definitions and functions.
18 */
19
20
21#ifndef LDNS_KEYS_H
22#define LDNS_KEYS_H
23
24#include <ldns/common.h>
25#if LDNS_BUILD_CONFIG_HAVE_SSL
26#include <openssl/ssl.h>
27#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
28#include <ldns/util.h>
29#include <errno.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35extern ldns_lookup_table ldns_signing_algorithms[];
36
37#define LDNS_KEY_ZONE_KEY 0x0100   /* rfc 4034 */
38#define LDNS_KEY_SEP_KEY 0x0001    /* rfc 4034 */
39#define LDNS_KEY_REVOKE_KEY 0x0080 /* rfc 5011 */
40
41/**
42 * Algorithms used in dns
43 */
44enum ldns_enum_algorithm
45{
46        LDNS_RSAMD5             = 1,   /* RFC 4034,4035 */
47        LDNS_DH                 = 2,
48        LDNS_DSA                = 3,
49        LDNS_ECC                = 4,
50        LDNS_RSASHA1            = 5,
51        LDNS_DSA_NSEC3          = 6,
52        LDNS_RSASHA1_NSEC3      = 7,
53        LDNS_RSASHA256          = 8,   /* RFC 5702 */
54        LDNS_RSASHA512          = 10,  /* RFC 5702 */
55        LDNS_ECC_GOST           = 12,  /* RFC 5933 */
56        LDNS_ECDSAP256SHA256    = 13,  /* RFC 6605 */
57        LDNS_ECDSAP384SHA384    = 14,  /* RFC 6605 */
58        LDNS_INDIRECT           = 252,
59        LDNS_PRIVATEDNS         = 253,
60        LDNS_PRIVATEOID         = 254
61};
62typedef enum ldns_enum_algorithm ldns_algorithm;
63
64/**
65 * Hashing algorithms used in the DS record
66 */
67enum ldns_enum_hash
68{
69        LDNS_SHA1               = 1,  /* RFC 4034 */
70        LDNS_SHA256             = 2,  /* RFC 4509 */
71        LDNS_HASH_GOST          = 3,  /* RFC 5933 */
72        LDNS_SHA384             = 4   /* RFC 6605 */
73};
74typedef enum ldns_enum_hash ldns_hash;
75
76/**
77 * Algorithms used in dns for signing
78 */
79enum ldns_enum_signing_algorithm
80{
81	LDNS_SIGN_RSAMD5	 = LDNS_RSAMD5,
82	LDNS_SIGN_RSASHA1	 = LDNS_RSASHA1,
83	LDNS_SIGN_DSA		 = LDNS_DSA,
84	LDNS_SIGN_RSASHA1_NSEC3  = LDNS_RSASHA1_NSEC3,
85	LDNS_SIGN_RSASHA256	 = LDNS_RSASHA256,
86	LDNS_SIGN_RSASHA512	 = LDNS_RSASHA512,
87	LDNS_SIGN_DSA_NSEC3	 = LDNS_DSA_NSEC3,
88	LDNS_SIGN_ECC_GOST       = LDNS_ECC_GOST,
89        LDNS_SIGN_ECDSAP256SHA256 = LDNS_ECDSAP256SHA256,
90        LDNS_SIGN_ECDSAP384SHA384 = LDNS_ECDSAP384SHA384,
91	LDNS_SIGN_HMACMD5	 = 157,	/* not official! This type is for TSIG, not DNSSEC */
92	LDNS_SIGN_HMACSHA1	 = 158,	/* not official! This type is for TSIG, not DNSSEC */
93	LDNS_SIGN_HMACSHA256 = 159  /* ditto */
94};
95typedef enum ldns_enum_signing_algorithm ldns_signing_algorithm;
96
97/**
98 * General key structure, can contain all types of keys that
99 * are used in DNSSEC. Mostly used to store private keys, since
100 * public keys can also be stored in a \ref ldns_rr with type
101 * \ref LDNS_RR_TYPE_DNSKEY.
102 *
103 * This structure can also store some variables that influence the
104 * signatures generated by signing with this key, for instance the
105 * inception date.
106 */
107struct ldns_struct_key {
108	ldns_signing_algorithm _alg;
109	/** Whether to use this key when signing */
110	bool _use;
111	/** Storage pointers for the types of keys supported */
112	/* TODO remove unions? */
113	struct {
114#if LDNS_BUILD_CONFIG_HAVE_SSL
115#ifndef S_SPLINT_S
116		/* The key can be an OpenSSL EVP Key
117		 */
118		EVP_PKEY *key;
119#endif
120#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
121		/**
122		 * The key can be an HMAC key
123		 */
124		struct {
125			unsigned char *key;
126			size_t size;
127		} hmac;
128		/** the key structure can also just point to some external
129		 *  key data
130		 */
131		void *external_key;
132	} _key;
133	/** Depending on the key we can have extra data */
134	union {
135                /** Some values that influence generated signatures */
136		struct {
137			/** The TTL of the rrset that is currently signed */
138			uint32_t orig_ttl;
139			/** The inception date of signatures made with this key. */
140			uint32_t inception;
141			/** The expiration date of signatures made with this key. */
142			uint32_t expiration;
143			/** The keytag of this key. */
144			uint16_t keytag;
145			/** The dnssec key flags as specified in RFC4035, like ZSK and KSK */
146			uint16_t flags;
147		}  dnssec;
148	} _extra;
149	/** Owner name of the key */
150	ldns_rdf *_pubkey_owner;
151};
152typedef struct ldns_struct_key ldns_key;
153
154/**
155 * Same as rr_list, but now for keys
156 */
157struct ldns_struct_key_list
158{
159	size_t _key_count;
160	ldns_key **_keys;
161};
162typedef struct ldns_struct_key_list ldns_key_list;
163
164
165/**
166 * Creates a new empty key list
167 * \return a new ldns_key_list structure pointer
168 */
169ldns_key_list *ldns_key_list_new(void);
170
171/**
172 * Creates a new empty key structure
173 * \return a new ldns_key * structure
174 */
175ldns_key *ldns_key_new(void);
176
177/**
178 * Creates a new key based on the algorithm
179 *
180 * \param[in] a The algorithm to use
181 * \param[in] size the number of bytes for the keysize
182 * \return a new ldns_key structure with the key
183 */
184ldns_key *ldns_key_new_frm_algorithm(ldns_signing_algorithm a, uint16_t size);
185
186/**
187 * Creates a new priv key based on the
188 * contents of the file pointed by fp.
189 *
190 * The file should be in Private-key-format v1.x.
191 *
192 * \param[out] k the new ldns_key structure
193 * \param[in] fp the file pointer to use
194 * \return an error or LDNS_STATUS_OK
195 */
196ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
197
198/**
199 * Creates a new private key based on the
200 * contents of the file pointed by fp
201 *
202 * The file should be in Private-key-format v1.x.
203 *
204 * \param[out] k the new ldns_key structure
205 * \param[in] fp the file pointer to use
206 * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
207 * \return an error or LDNS_STATUS_OK
208 */
209ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
210
211#if LDNS_BUILD_CONFIG_HAVE_SSL
212/**
213 * Read the key with the given id from the given engine and store it
214 * in the given ldns_key structure. The algorithm type is set
215 */
216ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm);
217
218
219/**
220 * frm_fp helper function. This function parses the
221 * remainder of the (RSA) priv. key file generated from bind9
222 * \param[in] fp the file to parse
223 * \return NULL on failure otherwise a RSA structure
224 */
225RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
226#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
227
228#if LDNS_BUILD_CONFIG_HAVE_SSL
229/**
230 * frm_fp helper function. This function parses the
231 * remainder of the (RSA) priv. key file generated from bind9
232 * \param[in] fp the file to parse
233 * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
234 * \return NULL on failure otherwise a RSA structure
235 */
236RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
237#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
238
239#if LDNS_BUILD_CONFIG_HAVE_SSL
240/**
241 * frm_fp helper function. This function parses the
242 * remainder of the (DSA) priv. key file
243 * \param[in] fp the file to parse
244 * \return NULL on failure otherwise a RSA structure
245 */
246DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
247#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
248
249#if LDNS_BUILD_CONFIG_HAVE_SSL
250/**
251 * frm_fp helper function. This function parses the
252 * remainder of the (DSA) priv. key file
253 * \param[in] fp the file to parse
254 * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
255 * \return NULL on failure otherwise a RSA structure
256 */
257DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
258#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
259
260#if LDNS_BUILD_CONFIG_HAVE_SSL
261/**
262 * frm_fp helper function. This function parses the
263 * remainder of the (HMAC-MD5) key file
264 * This function allocated a buffer that needs to be freed
265 * \param[in] fp the file to parse
266 * \param[out] hmac_size the number of bits in the resulting buffer
267 * \return NULL on failure otherwise a newly allocated char buffer
268 */
269unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
270#endif
271
272#if LDNS_BUILD_CONFIG_HAVE_SSL
273/**
274 * frm_fp helper function. This function parses the
275 * remainder of the (HMAC-MD5) key file
276 * This function allocated a buffer that needs to be freed
277 * \param[in] fp the file to parse
278 * \param[in] line_nr pointer to an integer containing the current line number (for error reporting purposes)
279 * \param[out] hmac_size the number of bits in the resulting buffer
280 * \return NULL on failure otherwise a newly allocated char buffer
281 */
282unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_size);
283#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
284
285/* acces write functions */
286/**
287 * Set the key's algorithm
288 * \param[in] k the key
289 * \param[in] l the algorithm
290 */
291void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
292#if LDNS_BUILD_CONFIG_HAVE_SSL
293/**
294 * Set the key's evp key
295 * \param[in] k the key
296 * \param[in] e the evp key
297 */
298void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
299
300/**
301 * Set the key's rsa data.
302 * The rsa data should be freed by the user.
303 * \param[in] k the key
304 * \param[in] r the rsa data
305 */
306void ldns_key_set_rsa_key(ldns_key *k, RSA *r);
307
308/**
309 * Set the key's dsa data
310 * The dsa data should be freed by the user.
311 * \param[in] k the key
312 * \param[in] d the dsa data
313 */
314void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
315
316/**
317 * Assign the key's rsa data
318 * The rsa data will be freed automatically when the key is freed.
319 * \param[in] k the key
320 * \param[in] r the rsa data
321 */
322void ldns_key_assign_rsa_key(ldns_key *k, RSA *r);
323
324/**
325 * Assign the key's dsa data
326 * The dsa data will be freed automatically when the key is freed.
327 * \param[in] k the key
328 * \param[in] d the dsa data
329 */
330void ldns_key_assign_dsa_key(ldns_key *k, DSA *d);
331
332/**
333 * Get the PKEY id for GOST, loads GOST into openssl as a side effect.
334 * Only available if GOST is compiled into the library and openssl.
335 * \return the gost id for EVP_CTX creation.
336 */
337int ldns_key_EVP_load_gost_id(void);
338
339/** Release the engine reference held for the GOST engine. */
340void ldns_key_EVP_unload_gost(void);
341#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
342
343/**
344 * Set the key's hmac data
345 * \param[in] k the key
346 * \param[in] hmac the raw key data
347 */
348void ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac);
349
350/**
351 * Set the key id data. This is used if the key points to
352 * some externally stored key data
353 *
354 * Only the pointer is set, the data there is not copied,
355 * and must be freed manually; ldns_key_deep_free() does
356 * *not* free this data
357 * \param[in] key the key
358 * \param[in] external_key key id data
359 */
360void ldns_key_set_external_key(ldns_key *key, void *external_key);
361
362/**
363 * Set the key's hmac size
364 * \param[in] k the key
365 * \param[in] hmac_size the size of the hmac data
366 */
367void ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size);
368/**
369 * Set the key's original ttl
370 * \param[in] k the key
371 * \param[in] t the ttl
372 */
373void ldns_key_set_origttl(ldns_key *k, uint32_t t);
374/**
375 * Set the key's inception date (seconds after epoch)
376 * \param[in] k the key
377 * \param[in] i the inception
378 */
379void ldns_key_set_inception(ldns_key *k, uint32_t i);
380/**
381 * Set the key's expiration date (seconds after epoch)
382 * \param[in] k the key
383 * \param[in] e the expiration
384 */
385void ldns_key_set_expiration(ldns_key *k, uint32_t e);
386/**
387 * Set the key's pubkey owner
388 * \param[in] k the key
389 * \param[in] r the owner
390 */
391void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r);
392/**
393 * Set the key's key tag
394 * \param[in] k the key
395 * \param[in] tag the keytag
396 */
397void ldns_key_set_keytag(ldns_key *k, uint16_t tag);
398/**
399 * Set the key's flags
400 * \param[in] k the key
401 * \param[in] flags the flags
402 */
403void ldns_key_set_flags(ldns_key *k, uint16_t flags);
404/**
405 * Set the keylist's key count to count
406 * \param[in] key the key
407 * \param[in] count the cuont
408 */
409void ldns_key_list_set_key_count(ldns_key_list *key, size_t count);
410
411/**
412 * pushes a key to a keylist
413 * \param[in] key_list the key_list to push to
414 * \param[in] key the key to push
415 * \return false on error, otherwise true
416 */
417bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key);
418
419/**
420 * returns the number of keys in the key list
421 * \param[in] key_list the key_list
422 * \return the numbers of keys in the list
423 */
424size_t ldns_key_list_key_count(const ldns_key_list *key_list);
425
426/**
427 * returns a pointer to the key in the list at the given position
428 * \param[in] key the key
429 * \param[in] nr the position in the list
430 * \return the key
431 */
432ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
433
434#if LDNS_BUILD_CONFIG_HAVE_SSL
435/**
436 * returns the (openssl) RSA struct contained in the key
437 * \param[in] k the key to look in
438 * \return the RSA * structure in the key
439 */
440RSA *ldns_key_rsa_key(const ldns_key *k);
441/**
442 * returns the (openssl) EVP struct contained in the key
443 * \param[in] k the key to look in
444 * \return the RSA * structure in the key
445 */
446EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
447#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
448
449/**
450 * returns the (openssl) DSA struct contained in the key
451 */
452#if LDNS_BUILD_CONFIG_HAVE_SSL
453DSA *ldns_key_dsa_key(const ldns_key *k);
454#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
455
456/**
457 * return the signing alg of the key
458 * \param[in] k the key
459 * \return the algorithm
460 */
461ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k);
462/**
463 * set the use flag
464 * \param[in] k the key
465 * \param[in] v the boolean value to set the _use field to
466 */
467void ldns_key_set_use(ldns_key *k, bool v);
468/**
469 * return the use flag
470 * \param[in] k the key
471 * \return the boolean value of the _use field
472 */
473bool ldns_key_use(const ldns_key *k);
474/**
475 * return the hmac key data
476 * \param[in] k the key
477 * \return the hmac key data
478 */
479unsigned char *ldns_key_hmac_key(const ldns_key *k);
480/**
481 * return the key id key data
482 * \param[in] k the key
483 * \return the key id data
484 */
485void *ldns_key_external_key(const ldns_key *k);
486/**
487 * return the hmac key size
488 * \param[in] k the key
489 * \return the hmac key size
490 */
491size_t ldns_key_hmac_size(const ldns_key *k);
492/**
493 * return the original ttl of the key
494 * \param[in] k the key
495 * \return the original ttl
496 */
497uint32_t ldns_key_origttl(const ldns_key *k);
498/**
499 * return the key's inception date
500 * \param[in] k the key
501 * \return the inception date
502 */
503uint32_t ldns_key_inception(const ldns_key *k);
504/**
505 * return the key's expiration date
506 * \param[in] k the key
507 * \return the experiration date
508 */
509uint32_t ldns_key_expiration(const ldns_key *k);
510/**
511 * return the keytag
512 * \param[in] k the key
513 * \return the keytag
514 */
515uint16_t ldns_key_keytag(const ldns_key *k);
516/**
517 * return the public key's owner
518 * \param[in] k the key
519 * \return the owner
520 */
521ldns_rdf *ldns_key_pubkey_owner(const ldns_key *k);
522/**
523 * Set the 'use' flag for all keys in the list
524 * \param[in] keys The key_list
525 * \param[in] v The value to set the use flags to
526 */
527void
528ldns_key_list_set_use(ldns_key_list *keys, bool v);
529
530/**
531 * return the flag of the key
532 * \param[in] k the key
533 * \return the flag
534 */
535uint16_t ldns_key_flags(const ldns_key *k);
536
537/**
538 * pops the last rr from a keylist
539 * \param[in] key_list the rr_list to pop from
540 * \return NULL if nothing to pop. Otherwise the popped RR
541 */
542ldns_key *ldns_key_list_pop_key(ldns_key_list *key_list);
543
544/**
545 * converts a ldns_key to a public key rr
546 * If the key data exists at an external point, the corresponding
547 * rdata field must still be added with ldns_rr_rdf_push() to the
548 * result rr of this function
549 *
550 * \param[in] k the ldns_key to convert
551 * \return ldns_rr representation of the key
552 */
553ldns_rr *ldns_key2rr(const ldns_key *k);
554
555/**
556 * print a private key to the file ouput
557 *
558 * \param[in] output the FILE descriptor where to print to
559 * \param[in] k the ldns_key to print
560 */
561void ldns_key_print(FILE *output, const ldns_key *k);
562
563/**
564 * frees a key structure, but not its internal data structures
565 *
566 * \param[in] key the key object to free
567 */
568void ldns_key_free(ldns_key *key);
569
570/**
571 * frees a key structure and all its internal data structures, except
572 * the data set by ldns_key_set_external_key()
573 *
574 * \param[in] key the key object to free
575 */
576void ldns_key_deep_free(ldns_key *key);
577
578/**
579 * Frees a key list structure
580 * \param[in] key_list the key list object to free
581 */
582void ldns_key_list_free(ldns_key_list *key_list);
583
584/**
585 * Instantiates a DNSKEY or DS RR from file.
586 * \param[in] filename the file to read the record from
587 * \return the corresponding RR, or NULL if the parsing failed
588 */
589ldns_rr * ldns_read_anchor_file(const char *filename);
590
591/**
592 * Returns the 'default base name' for key files;
593 * IE. K\<zone\>+\<alg\>+\<keytag\>
594 * (without the .key or .private)
595 * The memory for this is allocated by this function,
596 * and should be freed by the caller
597 *
598 * \param[in] key the key to get the file name from
599 * \returns A string containing the file base name
600 */
601char *ldns_key_get_file_base_name(ldns_key *key);
602
603/**
604 * See if a key algorithm is supported
605 * \param[in] algo the signing algorithm number.
606 * \returns true if supported.
607 */
608int ldns_key_algo_supported(int algo);
609
610/**
611 * Get signing algorithm by name.  Comparison is case insensitive.
612 * \param[in] name string with the name.
613 * \returns 0 on parse failure or the algorithm number.
614 */
615ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name);
616
617#ifdef __cplusplus
618}
619#endif
620
621#endif /* LDNS_KEYS_H */
622