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