17b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 27b5038d7SDag-Erling Smørgrav 37b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 47b5038d7SDag-Erling Smørgrav 57b5038d7SDag-Erling Smørgrav #include <ldns/dnssec.h> 67b5038d7SDag-Erling Smørgrav #include <ldns/dnssec_sign.h> 77b5038d7SDag-Erling Smørgrav 87b5038d7SDag-Erling Smørgrav #include <strings.h> 97b5038d7SDag-Erling Smørgrav #include <time.h> 107b5038d7SDag-Erling Smørgrav 117b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 127b5038d7SDag-Erling Smørgrav /* this entire file is rather useless when you don't have 137b5038d7SDag-Erling Smørgrav * crypto... 147b5038d7SDag-Erling Smørgrav */ 157b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h> 167b5038d7SDag-Erling Smørgrav #include <openssl/evp.h> 177b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 187b5038d7SDag-Erling Smørgrav #include <openssl/err.h> 197b5038d7SDag-Erling Smørgrav #include <openssl/md5.h> 207b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 217b5038d7SDag-Erling Smørgrav 227b5038d7SDag-Erling Smørgrav ldns_rr * 237b5038d7SDag-Erling Smørgrav ldns_create_empty_rrsig(ldns_rr_list *rrset, 247b5038d7SDag-Erling Smørgrav ldns_key *current_key) 257b5038d7SDag-Erling Smørgrav { 267b5038d7SDag-Erling Smørgrav uint32_t orig_ttl; 277b5038d7SDag-Erling Smørgrav ldns_rr_class orig_class; 287b5038d7SDag-Erling Smørgrav time_t now; 297b5038d7SDag-Erling Smørgrav ldns_rr *current_sig; 307b5038d7SDag-Erling Smørgrav uint8_t label_count; 317b5038d7SDag-Erling Smørgrav ldns_rdf *signame; 327b5038d7SDag-Erling Smørgrav 337b5038d7SDag-Erling Smørgrav label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset, 347b5038d7SDag-Erling Smørgrav 0))); 357b5038d7SDag-Erling Smørgrav /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */ 367b5038d7SDag-Erling Smørgrav if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)))) 377b5038d7SDag-Erling Smørgrav label_count --; 387b5038d7SDag-Erling Smørgrav 397b5038d7SDag-Erling Smørgrav current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG); 407b5038d7SDag-Erling Smørgrav 417b5038d7SDag-Erling Smørgrav /* set the type on the new signature */ 427b5038d7SDag-Erling Smørgrav orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)); 437b5038d7SDag-Erling Smørgrav orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0)); 447b5038d7SDag-Erling Smørgrav 457b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(current_sig, orig_ttl); 467b5038d7SDag-Erling Smørgrav ldns_rr_set_class(current_sig, orig_class); 477b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(current_sig, 487b5038d7SDag-Erling Smørgrav ldns_rdf_clone( 497b5038d7SDag-Erling Smørgrav ldns_rr_owner( 507b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrset, 517b5038d7SDag-Erling Smørgrav 0)))); 527b5038d7SDag-Erling Smørgrav 537b5038d7SDag-Erling Smørgrav /* fill in what we know of the signature */ 547b5038d7SDag-Erling Smørgrav 557b5038d7SDag-Erling Smørgrav /* set the orig_ttl */ 567b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_origttl( 577b5038d7SDag-Erling Smørgrav current_sig, 587b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 597b5038d7SDag-Erling Smørgrav orig_ttl)); 607b5038d7SDag-Erling Smørgrav /* the signers name */ 617b5038d7SDag-Erling Smørgrav signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key)); 627b5038d7SDag-Erling Smørgrav ldns_dname2canonical(signame); 637b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_signame( 647b5038d7SDag-Erling Smørgrav current_sig, 657b5038d7SDag-Erling Smørgrav signame); 667b5038d7SDag-Erling Smørgrav /* label count - get it from the first rr in the rr_list */ 677b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_labels( 687b5038d7SDag-Erling Smørgrav current_sig, 697b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 707b5038d7SDag-Erling Smørgrav label_count)); 717b5038d7SDag-Erling Smørgrav /* inception, expiration */ 727b5038d7SDag-Erling Smørgrav now = time(NULL); 737b5038d7SDag-Erling Smørgrav if (ldns_key_inception(current_key) != 0) { 747b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_inception( 757b5038d7SDag-Erling Smørgrav current_sig, 767b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32( 777b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME, 787b5038d7SDag-Erling Smørgrav ldns_key_inception(current_key))); 797b5038d7SDag-Erling Smørgrav } else { 807b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_inception( 817b5038d7SDag-Erling Smørgrav current_sig, 827b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now)); 837b5038d7SDag-Erling Smørgrav } 847b5038d7SDag-Erling Smørgrav if (ldns_key_expiration(current_key) != 0) { 857b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_expiration( 867b5038d7SDag-Erling Smørgrav current_sig, 877b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32( 887b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME, 897b5038d7SDag-Erling Smørgrav ldns_key_expiration(current_key))); 907b5038d7SDag-Erling Smørgrav } else { 917b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_expiration( 927b5038d7SDag-Erling Smørgrav current_sig, 937b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32( 947b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME, 957b5038d7SDag-Erling Smørgrav now + LDNS_DEFAULT_EXP_TIME)); 967b5038d7SDag-Erling Smørgrav } 977b5038d7SDag-Erling Smørgrav 987b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_keytag( 997b5038d7SDag-Erling Smørgrav current_sig, 1007b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 1017b5038d7SDag-Erling Smørgrav ldns_key_keytag(current_key))); 1027b5038d7SDag-Erling Smørgrav 1037b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_algorithm( 1047b5038d7SDag-Erling Smørgrav current_sig, 1057b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8( 1067b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, 1077b5038d7SDag-Erling Smørgrav ldns_key_algorithm(current_key))); 1087b5038d7SDag-Erling Smørgrav 1097b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_typecovered( 1107b5038d7SDag-Erling Smørgrav current_sig, 1117b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16( 1127b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TYPE, 1137b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(rrset, 1147b5038d7SDag-Erling Smørgrav 0)))); 1157b5038d7SDag-Erling Smørgrav return current_sig; 1167b5038d7SDag-Erling Smørgrav } 1177b5038d7SDag-Erling Smørgrav 1187b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1197b5038d7SDag-Erling Smørgrav ldns_rdf * 1207b5038d7SDag-Erling Smørgrav ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key) 1217b5038d7SDag-Erling Smørgrav { 1227b5038d7SDag-Erling Smørgrav ldns_rdf *b64rdf = NULL; 1237b5038d7SDag-Erling Smørgrav 1247b5038d7SDag-Erling Smørgrav switch(ldns_key_algorithm(current_key)) { 1257b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 1267b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 1277b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1287b5038d7SDag-Erling Smørgrav sign_buf, 1297b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1307b5038d7SDag-Erling Smørgrav EVP_dss1()); 1317b5038d7SDag-Erling Smørgrav break; 1327b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 1337b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 1347b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1357b5038d7SDag-Erling Smørgrav sign_buf, 1367b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1377b5038d7SDag-Erling Smørgrav EVP_sha1()); 1387b5038d7SDag-Erling Smørgrav break; 1397b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 1407b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 1417b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1427b5038d7SDag-Erling Smørgrav sign_buf, 1437b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1447b5038d7SDag-Erling Smørgrav EVP_sha256()); 1457b5038d7SDag-Erling Smørgrav break; 1467b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 1477b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1487b5038d7SDag-Erling Smørgrav sign_buf, 1497b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1507b5038d7SDag-Erling Smørgrav EVP_sha512()); 1517b5038d7SDag-Erling Smørgrav break; 1527b5038d7SDag-Erling Smørgrav #endif /* USE_SHA2 */ 1537b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1547b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 1557b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1567b5038d7SDag-Erling Smørgrav sign_buf, 1577b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1587b5038d7SDag-Erling Smørgrav EVP_get_digestbyname("md_gost94")); 1597b5038d7SDag-Erling Smørgrav break; 1607b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */ 1617b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1627b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 1637b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1647b5038d7SDag-Erling Smørgrav sign_buf, 1657b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1667b5038d7SDag-Erling Smørgrav EVP_sha256()); 1677b5038d7SDag-Erling Smørgrav break; 1687b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 1697b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1707b5038d7SDag-Erling Smørgrav sign_buf, 1717b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1727b5038d7SDag-Erling Smørgrav EVP_sha384()); 1737b5038d7SDag-Erling Smørgrav break; 1747b5038d7SDag-Erling Smørgrav #endif 1757b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 1767b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp( 1777b5038d7SDag-Erling Smørgrav sign_buf, 1787b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key), 1797b5038d7SDag-Erling Smørgrav EVP_md5()); 1807b5038d7SDag-Erling Smørgrav break; 1817b5038d7SDag-Erling Smørgrav default: 1827b5038d7SDag-Erling Smørgrav /* do _you_ know this alg? */ 1837b5038d7SDag-Erling Smørgrav printf("unknown algorithm, "); 1847b5038d7SDag-Erling Smørgrav printf("is the one used available on this system?\n"); 1857b5038d7SDag-Erling Smørgrav break; 1867b5038d7SDag-Erling Smørgrav } 1877b5038d7SDag-Erling Smørgrav 1887b5038d7SDag-Erling Smørgrav return b64rdf; 1897b5038d7SDag-Erling Smørgrav } 1907b5038d7SDag-Erling Smørgrav 1917b5038d7SDag-Erling Smørgrav /** 1927b5038d7SDag-Erling Smørgrav * use this function to sign with a public/private key alg 1937b5038d7SDag-Erling Smørgrav * return the created signatures 1947b5038d7SDag-Erling Smørgrav */ 1957b5038d7SDag-Erling Smørgrav ldns_rr_list * 1967b5038d7SDag-Erling Smørgrav ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys) 1977b5038d7SDag-Erling Smørgrav { 1987b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures; 1997b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone; 2007b5038d7SDag-Erling Smørgrav ldns_rr *current_sig; 2017b5038d7SDag-Erling Smørgrav ldns_rdf *b64rdf; 2027b5038d7SDag-Erling Smørgrav ldns_key *current_key; 2037b5038d7SDag-Erling Smørgrav size_t key_count; 2047b5038d7SDag-Erling Smørgrav uint16_t i; 2057b5038d7SDag-Erling Smørgrav ldns_buffer *sign_buf; 2067b5038d7SDag-Erling Smørgrav ldns_rdf *new_owner; 2077b5038d7SDag-Erling Smørgrav 2087b5038d7SDag-Erling Smørgrav if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) { 2097b5038d7SDag-Erling Smørgrav return NULL; 2107b5038d7SDag-Erling Smørgrav } 2117b5038d7SDag-Erling Smørgrav 2127b5038d7SDag-Erling Smørgrav new_owner = NULL; 2137b5038d7SDag-Erling Smørgrav 2147b5038d7SDag-Erling Smørgrav signatures = ldns_rr_list_new(); 2157b5038d7SDag-Erling Smørgrav 2167b5038d7SDag-Erling Smørgrav /* prepare a signature and add all the know data 2177b5038d7SDag-Erling Smørgrav * prepare the rrset. Sign this together. */ 2187b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset); 2197b5038d7SDag-Erling Smørgrav if (!rrset_clone) { 2207b5038d7SDag-Erling Smørgrav return NULL; 2217b5038d7SDag-Erling Smørgrav } 2227b5038d7SDag-Erling Smørgrav 2237b5038d7SDag-Erling Smørgrav /* make it canonical */ 2247b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) { 2257b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), 2267b5038d7SDag-Erling Smørgrav ldns_rr_ttl(ldns_rr_list_rr(rrset, 0))); 2277b5038d7SDag-Erling Smørgrav ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i)); 2287b5038d7SDag-Erling Smørgrav } 2297b5038d7SDag-Erling Smørgrav /* sort */ 2307b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(rrset_clone); 2317b5038d7SDag-Erling Smørgrav 2327b5038d7SDag-Erling Smørgrav for (key_count = 0; 2337b5038d7SDag-Erling Smørgrav key_count < ldns_key_list_key_count(keys); 2347b5038d7SDag-Erling Smørgrav key_count++) { 2357b5038d7SDag-Erling Smørgrav if (!ldns_key_use(ldns_key_list_key(keys, key_count))) { 2367b5038d7SDag-Erling Smørgrav continue; 2377b5038d7SDag-Erling Smørgrav } 2387b5038d7SDag-Erling Smørgrav sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 2397b5038d7SDag-Erling Smørgrav if (!sign_buf) { 2407b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rrset_clone); 2417b5038d7SDag-Erling Smørgrav ldns_rr_list_free(signatures); 2427b5038d7SDag-Erling Smørgrav ldns_rdf_free(new_owner); 2437b5038d7SDag-Erling Smørgrav return NULL; 2447b5038d7SDag-Erling Smørgrav } 2457b5038d7SDag-Erling Smørgrav b64rdf = NULL; 2467b5038d7SDag-Erling Smørgrav 2477b5038d7SDag-Erling Smørgrav current_key = ldns_key_list_key(keys, key_count); 2487b5038d7SDag-Erling Smørgrav /* sign all RRs with keys that have ZSKbit, !SEPbit. 2497b5038d7SDag-Erling Smørgrav sign DNSKEY RRs with keys that have ZSKbit&SEPbit */ 2507b5038d7SDag-Erling Smørgrav if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) { 2517b5038d7SDag-Erling Smørgrav current_sig = ldns_create_empty_rrsig(rrset_clone, 2527b5038d7SDag-Erling Smørgrav current_key); 2537b5038d7SDag-Erling Smørgrav 2547b5038d7SDag-Erling Smørgrav /* right now, we have: a key, a semi-sig and an rrset. For 2557b5038d7SDag-Erling Smørgrav * which we can create the sig and base64 encode that and 2567b5038d7SDag-Erling Smørgrav * add that to the signature */ 2577b5038d7SDag-Erling Smørgrav 2587b5038d7SDag-Erling Smørgrav if (ldns_rrsig2buffer_wire(sign_buf, current_sig) 2597b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2607b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf); 2617b5038d7SDag-Erling Smørgrav /* ERROR */ 2627b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 263*2787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig); 264*2787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures); 2657b5038d7SDag-Erling Smørgrav return NULL; 2667b5038d7SDag-Erling Smørgrav } 2677b5038d7SDag-Erling Smørgrav 2687b5038d7SDag-Erling Smørgrav /* add the rrset in sign_buf */ 2697b5038d7SDag-Erling Smørgrav if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone) 2707b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) { 2717b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf); 2727b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 273*2787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig); 274*2787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures); 2757b5038d7SDag-Erling Smørgrav return NULL; 2767b5038d7SDag-Erling Smørgrav } 2777b5038d7SDag-Erling Smørgrav 2787b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_buffer(sign_buf, current_key); 2797b5038d7SDag-Erling Smørgrav 2807b5038d7SDag-Erling Smørgrav if (!b64rdf) { 2817b5038d7SDag-Erling Smørgrav /* signing went wrong */ 2827b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 283*2787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig); 284*2787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures); 2857b5038d7SDag-Erling Smørgrav return NULL; 2867b5038d7SDag-Erling Smørgrav } 2877b5038d7SDag-Erling Smørgrav 2887b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_set_sig(current_sig, b64rdf); 2897b5038d7SDag-Erling Smørgrav 2907b5038d7SDag-Erling Smørgrav /* push the signature to the signatures list */ 2917b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(signatures, current_sig); 2927b5038d7SDag-Erling Smørgrav } 2937b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf); /* restart for the next key */ 2947b5038d7SDag-Erling Smørgrav } 2957b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone); 2967b5038d7SDag-Erling Smørgrav 2977b5038d7SDag-Erling Smørgrav return signatures; 2987b5038d7SDag-Erling Smørgrav } 2997b5038d7SDag-Erling Smørgrav 3007b5038d7SDag-Erling Smørgrav /** 3017b5038d7SDag-Erling Smørgrav * Sign data with DSA 3027b5038d7SDag-Erling Smørgrav * 3037b5038d7SDag-Erling Smørgrav * \param[in] to_sign The ldns_buffer containing raw data that is 3047b5038d7SDag-Erling Smørgrav * to be signed 3057b5038d7SDag-Erling Smørgrav * \param[in] key The DSA key structure to sign with 3067b5038d7SDag-Erling Smørgrav * \return ldns_rdf for the RRSIG ldns_rr 3077b5038d7SDag-Erling Smørgrav */ 3087b5038d7SDag-Erling Smørgrav ldns_rdf * 3097b5038d7SDag-Erling Smørgrav ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) 3107b5038d7SDag-Erling Smørgrav { 3117b5038d7SDag-Erling Smørgrav unsigned char *sha1_hash; 3127b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf; 3137b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig; 3147b5038d7SDag-Erling Smørgrav 3157b5038d7SDag-Erling Smørgrav DSA_SIG *sig; 3167b5038d7SDag-Erling Smørgrav uint8_t *data; 3177b5038d7SDag-Erling Smørgrav size_t pad; 3187b5038d7SDag-Erling Smørgrav 3197b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 3207b5038d7SDag-Erling Smørgrav if (!b64sig) { 3217b5038d7SDag-Erling Smørgrav return NULL; 3227b5038d7SDag-Erling Smørgrav } 3237b5038d7SDag-Erling Smørgrav 3247b5038d7SDag-Erling Smørgrav sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), 3257b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL); 3267b5038d7SDag-Erling Smørgrav if (!sha1_hash) { 3277b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 3287b5038d7SDag-Erling Smørgrav return NULL; 3297b5038d7SDag-Erling Smørgrav } 3307b5038d7SDag-Erling Smørgrav 3317b5038d7SDag-Erling Smørgrav sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key); 3327b5038d7SDag-Erling Smørgrav if(!sig) { 3337b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 3347b5038d7SDag-Erling Smørgrav return NULL; 3357b5038d7SDag-Erling Smørgrav } 3367b5038d7SDag-Erling Smørgrav 3377b5038d7SDag-Erling Smørgrav data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH); 3387b5038d7SDag-Erling Smørgrav if(!data) { 3397b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 3407b5038d7SDag-Erling Smørgrav DSA_SIG_free(sig); 3417b5038d7SDag-Erling Smørgrav return NULL; 3427b5038d7SDag-Erling Smørgrav } 3437b5038d7SDag-Erling Smørgrav 3447b5038d7SDag-Erling Smørgrav data[0] = 1; 3457b5038d7SDag-Erling Smørgrav pad = 20 - (size_t) BN_num_bytes(sig->r); 3467b5038d7SDag-Erling Smørgrav if (pad > 0) { 3477b5038d7SDag-Erling Smørgrav memset(data + 1, 0, pad); 3487b5038d7SDag-Erling Smørgrav } 3497b5038d7SDag-Erling Smørgrav BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad); 3507b5038d7SDag-Erling Smørgrav 3517b5038d7SDag-Erling Smørgrav pad = 20 - (size_t) BN_num_bytes(sig->s); 3527b5038d7SDag-Erling Smørgrav if (pad > 0) { 3537b5038d7SDag-Erling Smørgrav memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad); 3547b5038d7SDag-Erling Smørgrav } 3557b5038d7SDag-Erling Smørgrav BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad)); 3567b5038d7SDag-Erling Smørgrav 3577b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, 3587b5038d7SDag-Erling Smørgrav 1 + 2 * SHA_DIGEST_LENGTH, 3597b5038d7SDag-Erling Smørgrav data); 3607b5038d7SDag-Erling Smørgrav 3617b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 3627b5038d7SDag-Erling Smørgrav LDNS_FREE(data); 3637b5038d7SDag-Erling Smørgrav DSA_SIG_free(sig); 3647b5038d7SDag-Erling Smørgrav 3657b5038d7SDag-Erling Smørgrav return sigdata_rdf; 3667b5038d7SDag-Erling Smørgrav } 3677b5038d7SDag-Erling Smørgrav 3687b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 3697b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 3707b5038d7SDag-Erling Smørgrav static int 3717b5038d7SDag-Erling Smørgrav ldns_pkey_is_ecdsa(EVP_PKEY* pkey) 3727b5038d7SDag-Erling Smørgrav { 3737b5038d7SDag-Erling Smørgrav EC_KEY* ec; 3747b5038d7SDag-Erling Smørgrav const EC_GROUP* g; 3757b5038d7SDag-Erling Smørgrav if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) 3767b5038d7SDag-Erling Smørgrav return 0; 3777b5038d7SDag-Erling Smørgrav ec = EVP_PKEY_get1_EC_KEY(pkey); 3787b5038d7SDag-Erling Smørgrav g = EC_KEY_get0_group(ec); 3797b5038d7SDag-Erling Smørgrav if(!g) { 3807b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 3817b5038d7SDag-Erling Smørgrav return 0; 3827b5038d7SDag-Erling Smørgrav } 3837b5038d7SDag-Erling Smørgrav if(EC_GROUP_get_curve_name(g) == NID_secp224r1 || 3847b5038d7SDag-Erling Smørgrav EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 || 3857b5038d7SDag-Erling Smørgrav EC_GROUP_get_curve_name(g) == NID_secp384r1) { 3867b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 3877b5038d7SDag-Erling Smørgrav return 1; 3887b5038d7SDag-Erling Smørgrav } 3897b5038d7SDag-Erling Smørgrav /* downref the eckey, the original is still inside the pkey */ 3907b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 3917b5038d7SDag-Erling Smørgrav return 0; 3927b5038d7SDag-Erling Smørgrav } 3937b5038d7SDag-Erling Smørgrav #endif /* splint */ 3947b5038d7SDag-Erling Smørgrav #endif /* USE_ECDSA */ 3957b5038d7SDag-Erling Smørgrav 3967b5038d7SDag-Erling Smørgrav ldns_rdf * 3977b5038d7SDag-Erling Smørgrav ldns_sign_public_evp(ldns_buffer *to_sign, 3987b5038d7SDag-Erling Smørgrav EVP_PKEY *key, 3997b5038d7SDag-Erling Smørgrav const EVP_MD *digest_type) 4007b5038d7SDag-Erling Smørgrav { 4017b5038d7SDag-Erling Smørgrav unsigned int siglen; 4027b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf; 4037b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig; 4047b5038d7SDag-Erling Smørgrav EVP_MD_CTX ctx; 4057b5038d7SDag-Erling Smørgrav const EVP_MD *md_type; 4067b5038d7SDag-Erling Smørgrav int r; 4077b5038d7SDag-Erling Smørgrav 4087b5038d7SDag-Erling Smørgrav siglen = 0; 4097b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 4107b5038d7SDag-Erling Smørgrav if (!b64sig) { 4117b5038d7SDag-Erling Smørgrav return NULL; 4127b5038d7SDag-Erling Smørgrav } 4137b5038d7SDag-Erling Smørgrav 4147b5038d7SDag-Erling Smørgrav /* initializes a signing context */ 4157b5038d7SDag-Erling Smørgrav md_type = digest_type; 4167b5038d7SDag-Erling Smørgrav if(!md_type) { 4177b5038d7SDag-Erling Smørgrav /* unknown message difest */ 4187b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4197b5038d7SDag-Erling Smørgrav return NULL; 4207b5038d7SDag-Erling Smørgrav } 4217b5038d7SDag-Erling Smørgrav 4227b5038d7SDag-Erling Smørgrav EVP_MD_CTX_init(&ctx); 4237b5038d7SDag-Erling Smørgrav r = EVP_SignInit(&ctx, md_type); 4247b5038d7SDag-Erling Smørgrav if(r == 1) { 4257b5038d7SDag-Erling Smørgrav r = EVP_SignUpdate(&ctx, (unsigned char*) 4267b5038d7SDag-Erling Smørgrav ldns_buffer_begin(to_sign), 4277b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign)); 4287b5038d7SDag-Erling Smørgrav } else { 4297b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4307b5038d7SDag-Erling Smørgrav return NULL; 4317b5038d7SDag-Erling Smørgrav } 4327b5038d7SDag-Erling Smørgrav if(r == 1) { 4337b5038d7SDag-Erling Smørgrav r = EVP_SignFinal(&ctx, (unsigned char*) 4347b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig), &siglen, key); 4357b5038d7SDag-Erling Smørgrav } else { 4367b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4377b5038d7SDag-Erling Smørgrav return NULL; 4387b5038d7SDag-Erling Smørgrav } 4397b5038d7SDag-Erling Smørgrav if(r != 1) { 4407b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4417b5038d7SDag-Erling Smørgrav return NULL; 4427b5038d7SDag-Erling Smørgrav } 4437b5038d7SDag-Erling Smørgrav 4447b5038d7SDag-Erling Smørgrav /* unfortunately, OpenSSL output is differenct from DNS DSA format */ 4457b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 4467b5038d7SDag-Erling Smørgrav if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) { 4477b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen); 4487b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 4497b5038d7SDag-Erling Smørgrav } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC && 4507b5038d7SDag-Erling Smørgrav ldns_pkey_is_ecdsa(key)) { 4517b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen); 4527b5038d7SDag-Erling Smørgrav #endif 4537b5038d7SDag-Erling Smørgrav } else { 4547b5038d7SDag-Erling Smørgrav /* ok output for other types is the same */ 4557b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 4567b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig)); 4577b5038d7SDag-Erling Smørgrav } 4587b5038d7SDag-Erling Smørgrav #endif /* splint */ 4597b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4607b5038d7SDag-Erling Smørgrav EVP_MD_CTX_cleanup(&ctx); 4617b5038d7SDag-Erling Smørgrav return sigdata_rdf; 4627b5038d7SDag-Erling Smørgrav } 4637b5038d7SDag-Erling Smørgrav 4647b5038d7SDag-Erling Smørgrav ldns_rdf * 4657b5038d7SDag-Erling Smørgrav ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key) 4667b5038d7SDag-Erling Smørgrav { 4677b5038d7SDag-Erling Smørgrav unsigned char *sha1_hash; 4687b5038d7SDag-Erling Smørgrav unsigned int siglen; 4697b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf; 4707b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig; 4717b5038d7SDag-Erling Smørgrav int result; 4727b5038d7SDag-Erling Smørgrav 4737b5038d7SDag-Erling Smørgrav siglen = 0; 4747b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 4757b5038d7SDag-Erling Smørgrav if (!b64sig) { 4767b5038d7SDag-Erling Smørgrav return NULL; 4777b5038d7SDag-Erling Smørgrav } 4787b5038d7SDag-Erling Smørgrav 4797b5038d7SDag-Erling Smørgrav sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), 4807b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL); 4817b5038d7SDag-Erling Smørgrav if (!sha1_hash) { 4827b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 4837b5038d7SDag-Erling Smørgrav return NULL; 4847b5038d7SDag-Erling Smørgrav } 4857b5038d7SDag-Erling Smørgrav 4867b5038d7SDag-Erling Smørgrav result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH, 4877b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(b64sig), 4887b5038d7SDag-Erling Smørgrav &siglen, key); 4897b5038d7SDag-Erling Smørgrav if (result != 1) { 490*2787e39aSDag-Erling Smørgrav ldns_buffer_free(b64sig); 4917b5038d7SDag-Erling Smørgrav return NULL; 4927b5038d7SDag-Erling Smørgrav } 4937b5038d7SDag-Erling Smørgrav 4947b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 4957b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig)); 4967b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); /* can't free this buffer ?? */ 4977b5038d7SDag-Erling Smørgrav return sigdata_rdf; 4987b5038d7SDag-Erling Smørgrav } 4997b5038d7SDag-Erling Smørgrav 5007b5038d7SDag-Erling Smørgrav ldns_rdf * 5017b5038d7SDag-Erling Smørgrav ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key) 5027b5038d7SDag-Erling Smørgrav { 5037b5038d7SDag-Erling Smørgrav unsigned char *md5_hash; 5047b5038d7SDag-Erling Smørgrav unsigned int siglen; 5057b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf; 5067b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig; 5077b5038d7SDag-Erling Smørgrav 5087b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 5097b5038d7SDag-Erling Smørgrav if (!b64sig) { 5107b5038d7SDag-Erling Smørgrav return NULL; 5117b5038d7SDag-Erling Smørgrav } 5127b5038d7SDag-Erling Smørgrav 5137b5038d7SDag-Erling Smørgrav md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign), 5147b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL); 5157b5038d7SDag-Erling Smørgrav if (!md5_hash) { 5167b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 5177b5038d7SDag-Erling Smørgrav return NULL; 5187b5038d7SDag-Erling Smørgrav } 5197b5038d7SDag-Erling Smørgrav 5207b5038d7SDag-Erling Smørgrav RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH, 5217b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(b64sig), 5227b5038d7SDag-Erling Smørgrav &siglen, key); 5237b5038d7SDag-Erling Smørgrav 5247b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 5257b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig)); 5267b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); 5277b5038d7SDag-Erling Smørgrav return sigdata_rdf; 5287b5038d7SDag-Erling Smørgrav } 5297b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 5307b5038d7SDag-Erling Smørgrav 5317b5038d7SDag-Erling Smørgrav /** 5327b5038d7SDag-Erling Smørgrav * Pushes all rrs from the rrsets of type A and AAAA on gluelist. 5337b5038d7SDag-Erling Smørgrav */ 5347b5038d7SDag-Erling Smørgrav static ldns_status 5357b5038d7SDag-Erling Smørgrav ldns_dnssec_addresses_on_glue_list( 5367b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrset, 5377b5038d7SDag-Erling Smørgrav ldns_rr_list *glue_list) 5387b5038d7SDag-Erling Smørgrav { 5397b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rrs; 5407b5038d7SDag-Erling Smørgrav while (cur_rrset) { 5417b5038d7SDag-Erling Smørgrav if (cur_rrset->type == LDNS_RR_TYPE_A 5427b5038d7SDag-Erling Smørgrav || cur_rrset->type == LDNS_RR_TYPE_AAAA) { 5437b5038d7SDag-Erling Smørgrav for (cur_rrs = cur_rrset->rrs; 5447b5038d7SDag-Erling Smørgrav cur_rrs; 5457b5038d7SDag-Erling Smørgrav cur_rrs = cur_rrs->next) { 5467b5038d7SDag-Erling Smørgrav if (cur_rrs->rr) { 5477b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(glue_list, 5487b5038d7SDag-Erling Smørgrav cur_rrs->rr)) { 5497b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 5507b5038d7SDag-Erling Smørgrav /* ldns_rr_list_push_rr() 5517b5038d7SDag-Erling Smørgrav * returns false when unable 5527b5038d7SDag-Erling Smørgrav * to increase the capacity 5537b5038d7SDag-Erling Smørgrav * of the ldsn_rr_list 5547b5038d7SDag-Erling Smørgrav */ 5557b5038d7SDag-Erling Smørgrav } 5567b5038d7SDag-Erling Smørgrav } 5577b5038d7SDag-Erling Smørgrav } 5587b5038d7SDag-Erling Smørgrav } 5597b5038d7SDag-Erling Smørgrav cur_rrset = cur_rrset->next; 5607b5038d7SDag-Erling Smørgrav } 5617b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 5627b5038d7SDag-Erling Smørgrav } 5637b5038d7SDag-Erling Smørgrav 5647b5038d7SDag-Erling Smørgrav /** 5657b5038d7SDag-Erling Smørgrav * Marks the names in the zone that are occluded. Those names will be skipped 5667b5038d7SDag-Erling Smørgrav * when walking the tree with the ldns_dnssec_name_node_next_nonglue() 5677b5038d7SDag-Erling Smørgrav * function. But watch out! Names that are partially occluded (like glue with 5687b5038d7SDag-Erling Smørgrav * the same name as the delegation) will not be marked and should specifically 5697b5038d7SDag-Erling Smørgrav * be taken into account seperately. 5707b5038d7SDag-Erling Smørgrav * 5717b5038d7SDag-Erling Smørgrav * When glue_list is given (not NULL), in the process of marking the names, all 5727b5038d7SDag-Erling Smørgrav * glue resource records will be pushed to that list, even glue at delegation names. 5737b5038d7SDag-Erling Smørgrav * 5747b5038d7SDag-Erling Smørgrav * \param[in] zone the zone in which to mark the names 5757b5038d7SDag-Erling Smørgrav * \param[in] glue_list the list to which to push the glue rrs 5767b5038d7SDag-Erling Smørgrav * \return LDNS_STATUS_OK on success, an error code otherwise 5777b5038d7SDag-Erling Smørgrav */ 5787b5038d7SDag-Erling Smørgrav ldns_status 5797b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 5807b5038d7SDag-Erling Smørgrav ldns_rr_list *glue_list) 5817b5038d7SDag-Erling Smørgrav { 5827b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node; 5837b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name; 5847b5038d7SDag-Erling Smørgrav ldns_rdf *owner; 5857b5038d7SDag-Erling Smørgrav ldns_rdf *cut = NULL; /* keeps track of zone cuts */ 5867b5038d7SDag-Erling Smørgrav /* When the cut is caused by a delegation, below_delegation will be 1. 5877b5038d7SDag-Erling Smørgrav * When caused by a DNAME, below_delegation will be 0. 5887b5038d7SDag-Erling Smørgrav */ 5897b5038d7SDag-Erling Smørgrav int below_delegation = -1; /* init suppresses comiler warning */ 5907b5038d7SDag-Erling Smørgrav ldns_status s; 5917b5038d7SDag-Erling Smørgrav 5927b5038d7SDag-Erling Smørgrav if (!zone || !zone->names) { 5937b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 5947b5038d7SDag-Erling Smørgrav } 5957b5038d7SDag-Erling Smørgrav for (node = ldns_rbtree_first(zone->names); 5967b5038d7SDag-Erling Smørgrav node != LDNS_RBTREE_NULL; 5977b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node)) { 5987b5038d7SDag-Erling Smørgrav name = (ldns_dnssec_name *) node->data; 5997b5038d7SDag-Erling Smørgrav owner = ldns_dnssec_name_name(name); 6007b5038d7SDag-Erling Smørgrav 6017b5038d7SDag-Erling Smørgrav if (cut) { 6027b5038d7SDag-Erling Smørgrav /* The previous node was a zone cut, or a subdomain 6037b5038d7SDag-Erling Smørgrav * below a zone cut. Is this node (still) a subdomain 6047b5038d7SDag-Erling Smørgrav * below the cut? Then the name is occluded. Unless 6057b5038d7SDag-Erling Smørgrav * the name contains a SOA, after which we are 6067b5038d7SDag-Erling Smørgrav * authoritative again. 6077b5038d7SDag-Erling Smørgrav * 6087b5038d7SDag-Erling Smørgrav * FIXME! If there are labels in between the SOA and 6097b5038d7SDag-Erling Smørgrav * the cut, going from the authoritative space (below 6107b5038d7SDag-Erling Smørgrav * the SOA) up into occluded space again, will not be 6117b5038d7SDag-Erling Smørgrav * detected with the contruct below! 6127b5038d7SDag-Erling Smørgrav */ 6137b5038d7SDag-Erling Smørgrav if (ldns_dname_is_subdomain(owner, cut) && 6147b5038d7SDag-Erling Smørgrav !ldns_dnssec_rrsets_contains_type( 6157b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_SOA)) { 6167b5038d7SDag-Erling Smørgrav 6177b5038d7SDag-Erling Smørgrav if (below_delegation && glue_list) { 6187b5038d7SDag-Erling Smørgrav s = ldns_dnssec_addresses_on_glue_list( 6197b5038d7SDag-Erling Smørgrav name->rrsets, glue_list); 6207b5038d7SDag-Erling Smørgrav if (s != LDNS_STATUS_OK) { 6217b5038d7SDag-Erling Smørgrav return s; 6227b5038d7SDag-Erling Smørgrav } 6237b5038d7SDag-Erling Smørgrav } 6247b5038d7SDag-Erling Smørgrav name->is_glue = true; /* Mark occluded name! */ 6257b5038d7SDag-Erling Smørgrav continue; 6267b5038d7SDag-Erling Smørgrav } else { 6277b5038d7SDag-Erling Smørgrav cut = NULL; 6287b5038d7SDag-Erling Smørgrav } 6297b5038d7SDag-Erling Smørgrav } 6307b5038d7SDag-Erling Smørgrav 6317b5038d7SDag-Erling Smørgrav /* The node is not below a zone cut. Is it a zone cut itself? 6327b5038d7SDag-Erling Smørgrav * Everything below a SOA is authoritative of course; Except 6337b5038d7SDag-Erling Smørgrav * when the name also contains a DNAME :). 6347b5038d7SDag-Erling Smørgrav */ 6357b5038d7SDag-Erling Smørgrav if (ldns_dnssec_rrsets_contains_type( 6367b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_NS) 6377b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type( 6387b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_SOA)) { 6397b5038d7SDag-Erling Smørgrav cut = owner; 6407b5038d7SDag-Erling Smørgrav below_delegation = 1; 6417b5038d7SDag-Erling Smørgrav if (glue_list) { /* record glue on the zone cut */ 6427b5038d7SDag-Erling Smørgrav s = ldns_dnssec_addresses_on_glue_list( 6437b5038d7SDag-Erling Smørgrav name->rrsets, glue_list); 6447b5038d7SDag-Erling Smørgrav if (s != LDNS_STATUS_OK) { 6457b5038d7SDag-Erling Smørgrav return s; 6467b5038d7SDag-Erling Smørgrav } 6477b5038d7SDag-Erling Smørgrav } 6487b5038d7SDag-Erling Smørgrav } else if (ldns_dnssec_rrsets_contains_type( 6497b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_DNAME)) { 6507b5038d7SDag-Erling Smørgrav cut = owner; 6517b5038d7SDag-Erling Smørgrav below_delegation = 0; 6527b5038d7SDag-Erling Smørgrav } 6537b5038d7SDag-Erling Smørgrav } 6547b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 6557b5038d7SDag-Erling Smørgrav } 6567b5038d7SDag-Erling Smørgrav 6577b5038d7SDag-Erling Smørgrav /** 6587b5038d7SDag-Erling Smørgrav * Marks the names in the zone that are occluded. Those names will be skipped 6597b5038d7SDag-Erling Smørgrav * when walking the tree with the ldns_dnssec_name_node_next_nonglue() 6607b5038d7SDag-Erling Smørgrav * function. But watch out! Names that are partially occluded (like glue with 6617b5038d7SDag-Erling Smørgrav * the same name as the delegation) will not be marked and should specifically 6627b5038d7SDag-Erling Smørgrav * be taken into account seperately. 6637b5038d7SDag-Erling Smørgrav * 6647b5038d7SDag-Erling Smørgrav * \param[in] zone the zone in which to mark the names 6657b5038d7SDag-Erling Smørgrav * \return LDNS_STATUS_OK on success, an error code otherwise 6667b5038d7SDag-Erling Smørgrav */ 6677b5038d7SDag-Erling Smørgrav ldns_status 6687b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone) 6697b5038d7SDag-Erling Smørgrav { 6707b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_mark_and_get_glue(zone, NULL); 6717b5038d7SDag-Erling Smørgrav } 6727b5038d7SDag-Erling Smørgrav 6737b5038d7SDag-Erling Smørgrav ldns_rbnode_t * 6747b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node) 6757b5038d7SDag-Erling Smørgrav { 6767b5038d7SDag-Erling Smørgrav ldns_rbnode_t *next_node = NULL; 6777b5038d7SDag-Erling Smørgrav ldns_dnssec_name *next_name = NULL; 6787b5038d7SDag-Erling Smørgrav bool done = false; 6797b5038d7SDag-Erling Smørgrav 6807b5038d7SDag-Erling Smørgrav if (node == LDNS_RBTREE_NULL) { 6817b5038d7SDag-Erling Smørgrav return NULL; 6827b5038d7SDag-Erling Smørgrav } 6837b5038d7SDag-Erling Smørgrav next_node = node; 6847b5038d7SDag-Erling Smørgrav while (!done) { 6857b5038d7SDag-Erling Smørgrav if (next_node == LDNS_RBTREE_NULL) { 6867b5038d7SDag-Erling Smørgrav return NULL; 6877b5038d7SDag-Erling Smørgrav } else { 6887b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)next_node->data; 6897b5038d7SDag-Erling Smørgrav if (!next_name->is_glue) { 6907b5038d7SDag-Erling Smørgrav done = true; 6917b5038d7SDag-Erling Smørgrav } else { 6927b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(next_node); 6937b5038d7SDag-Erling Smørgrav } 6947b5038d7SDag-Erling Smørgrav } 6957b5038d7SDag-Erling Smørgrav } 6967b5038d7SDag-Erling Smørgrav return next_node; 6977b5038d7SDag-Erling Smørgrav } 6987b5038d7SDag-Erling Smørgrav 6997b5038d7SDag-Erling Smørgrav ldns_status 7007b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone, 7017b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs) 7027b5038d7SDag-Erling Smørgrav { 7037b5038d7SDag-Erling Smørgrav 7047b5038d7SDag-Erling Smørgrav ldns_rbnode_t *first_node, *cur_node, *next_node; 7057b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name, *next_name; 7067b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr; 7077b5038d7SDag-Erling Smørgrav uint32_t nsec_ttl; 7087b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *soa; 7097b5038d7SDag-Erling Smørgrav 7107b5038d7SDag-Erling Smørgrav /* the TTL of NSEC rrs should be set to the minimum TTL of 7117b5038d7SDag-Erling Smørgrav * the zone SOA (RFC4035 Section 2.3) 7127b5038d7SDag-Erling Smørgrav */ 7137b5038d7SDag-Erling Smørgrav soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); 7147b5038d7SDag-Erling Smørgrav 7157b5038d7SDag-Erling Smørgrav /* did the caller actually set it? if not, 7167b5038d7SDag-Erling Smørgrav * fall back to default ttl 7177b5038d7SDag-Erling Smørgrav */ 7187b5038d7SDag-Erling Smørgrav if (soa && soa->rrs && soa->rrs->rr 7197b5038d7SDag-Erling Smørgrav && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) { 7207b5038d7SDag-Erling Smørgrav nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6)); 7217b5038d7SDag-Erling Smørgrav } else { 7227b5038d7SDag-Erling Smørgrav nsec_ttl = LDNS_DEFAULT_TTL; 7237b5038d7SDag-Erling Smørgrav } 7247b5038d7SDag-Erling Smørgrav 7257b5038d7SDag-Erling Smørgrav first_node = ldns_dnssec_name_node_next_nonglue( 7267b5038d7SDag-Erling Smørgrav ldns_rbtree_first(zone->names)); 7277b5038d7SDag-Erling Smørgrav cur_node = first_node; 7287b5038d7SDag-Erling Smørgrav if (cur_node) { 7297b5038d7SDag-Erling Smørgrav next_node = ldns_dnssec_name_node_next_nonglue( 7307b5038d7SDag-Erling Smørgrav ldns_rbtree_next(cur_node)); 7317b5038d7SDag-Erling Smørgrav } else { 7327b5038d7SDag-Erling Smørgrav next_node = NULL; 7337b5038d7SDag-Erling Smørgrav } 7347b5038d7SDag-Erling Smørgrav 7357b5038d7SDag-Erling Smørgrav while (cur_node && next_node) { 7367b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *)cur_node->data; 7377b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)next_node->data; 7387b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec(cur_name, 7397b5038d7SDag-Erling Smørgrav next_name, 7407b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC); 7417b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl); 7427b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){ 7437b5038d7SDag-Erling Smørgrav ldns_rr_free(nsec_rr); 7447b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 7457b5038d7SDag-Erling Smørgrav } 7467b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr); 7477b5038d7SDag-Erling Smørgrav cur_node = next_node; 7487b5038d7SDag-Erling Smørgrav if (cur_node) { 7497b5038d7SDag-Erling Smørgrav next_node = ldns_dnssec_name_node_next_nonglue( 7507b5038d7SDag-Erling Smørgrav ldns_rbtree_next(cur_node)); 7517b5038d7SDag-Erling Smørgrav } 7527b5038d7SDag-Erling Smørgrav } 7537b5038d7SDag-Erling Smørgrav 7547b5038d7SDag-Erling Smørgrav if (cur_node && !next_node) { 7557b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *)cur_node->data; 7567b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)first_node->data; 7577b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec(cur_name, 7587b5038d7SDag-Erling Smørgrav next_name, 7597b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC); 7607b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl); 7617b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){ 7627b5038d7SDag-Erling Smørgrav ldns_rr_free(nsec_rr); 7637b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 7647b5038d7SDag-Erling Smørgrav } 7657b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr); 7667b5038d7SDag-Erling Smørgrav } else { 7677b5038d7SDag-Erling Smørgrav printf("error\n"); 7687b5038d7SDag-Erling Smørgrav } 7697b5038d7SDag-Erling Smørgrav 7707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 7717b5038d7SDag-Erling Smørgrav } 7727b5038d7SDag-Erling Smørgrav 7737b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 7747b5038d7SDag-Erling Smørgrav /* in dnssec_zone.c */ 7757b5038d7SDag-Erling Smørgrav extern int ldns_dname_compare_v(const void *a, const void *b); 7767b5038d7SDag-Erling Smørgrav 7777b5038d7SDag-Erling Smørgrav static ldns_status 7787b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone, 7797b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 7807b5038d7SDag-Erling Smørgrav uint8_t algorithm, 7817b5038d7SDag-Erling Smørgrav uint8_t flags, 7827b5038d7SDag-Erling Smørgrav uint16_t iterations, 7837b5038d7SDag-Erling Smørgrav uint8_t salt_length, 7847b5038d7SDag-Erling Smørgrav uint8_t *salt, 7857b5038d7SDag-Erling Smørgrav ldns_rbtree_t **map) 7867b5038d7SDag-Erling Smørgrav { 7877b5038d7SDag-Erling Smørgrav ldns_rbnode_t *first_name_node; 7887b5038d7SDag-Erling Smørgrav ldns_rbnode_t *current_name_node; 7897b5038d7SDag-Erling Smørgrav ldns_dnssec_name *current_name; 7907b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 7917b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr; 7927b5038d7SDag-Erling Smørgrav ldns_rr_list *nsec3_list; 7937b5038d7SDag-Erling Smørgrav uint32_t nsec_ttl; 7947b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *soa; 7957b5038d7SDag-Erling Smørgrav ldns_rbnode_t *hashmap_node; 7967b5038d7SDag-Erling Smørgrav 7977b5038d7SDag-Erling Smørgrav if (!zone || !new_rrs || !zone->names) { 7987b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 7997b5038d7SDag-Erling Smørgrav } 8007b5038d7SDag-Erling Smørgrav 8017b5038d7SDag-Erling Smørgrav /* the TTL of NSEC rrs should be set to the minimum TTL of 8027b5038d7SDag-Erling Smørgrav * the zone SOA (RFC4035 Section 2.3) 8037b5038d7SDag-Erling Smørgrav */ 8047b5038d7SDag-Erling Smørgrav soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); 8057b5038d7SDag-Erling Smørgrav 8067b5038d7SDag-Erling Smørgrav /* did the caller actually set it? if not, 8077b5038d7SDag-Erling Smørgrav * fall back to default ttl 8087b5038d7SDag-Erling Smørgrav */ 8097b5038d7SDag-Erling Smørgrav if (soa && soa->rrs && soa->rrs->rr 8107b5038d7SDag-Erling Smørgrav && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) { 8117b5038d7SDag-Erling Smørgrav nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6)); 8127b5038d7SDag-Erling Smørgrav } else { 8137b5038d7SDag-Erling Smørgrav nsec_ttl = LDNS_DEFAULT_TTL; 8147b5038d7SDag-Erling Smørgrav } 8157b5038d7SDag-Erling Smørgrav 8167b5038d7SDag-Erling Smørgrav if (map) { 8177b5038d7SDag-Erling Smørgrav if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 8187b5038d7SDag-Erling Smørgrav == NULL) { 8197b5038d7SDag-Erling Smørgrav map = NULL; 8207b5038d7SDag-Erling Smørgrav }; 8217b5038d7SDag-Erling Smørgrav } 8227b5038d7SDag-Erling Smørgrav nsec3_list = ldns_rr_list_new(); 8237b5038d7SDag-Erling Smørgrav 8247b5038d7SDag-Erling Smørgrav first_name_node = ldns_dnssec_name_node_next_nonglue( 8257b5038d7SDag-Erling Smørgrav ldns_rbtree_first(zone->names)); 8267b5038d7SDag-Erling Smørgrav 8277b5038d7SDag-Erling Smørgrav current_name_node = first_name_node; 8287b5038d7SDag-Erling Smørgrav 8297b5038d7SDag-Erling Smørgrav while (current_name_node && 8307b5038d7SDag-Erling Smørgrav current_name_node != LDNS_RBTREE_NULL) { 8317b5038d7SDag-Erling Smørgrav current_name = (ldns_dnssec_name *) current_name_node->data; 8327b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec3(current_name, 8337b5038d7SDag-Erling Smørgrav NULL, 8347b5038d7SDag-Erling Smørgrav zone->soa->name, 8357b5038d7SDag-Erling Smørgrav algorithm, 8367b5038d7SDag-Erling Smørgrav flags, 8377b5038d7SDag-Erling Smørgrav iterations, 8387b5038d7SDag-Erling Smørgrav salt_length, 8397b5038d7SDag-Erling Smørgrav salt); 8407b5038d7SDag-Erling Smørgrav /* by default, our nsec based generator adds rrsigs 8417b5038d7SDag-Erling Smørgrav * remove the bitmap for empty nonterminals */ 8427b5038d7SDag-Erling Smørgrav if (!current_name->rrsets) { 8437b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr)); 8447b5038d7SDag-Erling Smørgrav } 8457b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl); 8467b5038d7SDag-Erling Smørgrav result = ldns_dnssec_name_add_rr(current_name, nsec_rr); 8477b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr); 8487b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(nsec3_list, nsec_rr); 8497b5038d7SDag-Erling Smørgrav if (map) { 8507b5038d7SDag-Erling Smørgrav hashmap_node = LDNS_MALLOC(ldns_rbnode_t); 8517b5038d7SDag-Erling Smørgrav if (hashmap_node && ldns_rr_owner(nsec_rr)) { 8527b5038d7SDag-Erling Smørgrav hashmap_node->key = ldns_dname_label( 8537b5038d7SDag-Erling Smørgrav ldns_rr_owner(nsec_rr), 0); 8547b5038d7SDag-Erling Smørgrav if (hashmap_node->key) { 8557b5038d7SDag-Erling Smørgrav hashmap_node->data = current_name->name; 8567b5038d7SDag-Erling Smørgrav (void) ldns_rbtree_insert( 8577b5038d7SDag-Erling Smørgrav *map, hashmap_node); 8587b5038d7SDag-Erling Smørgrav } 8597b5038d7SDag-Erling Smørgrav } 8607b5038d7SDag-Erling Smørgrav } 8617b5038d7SDag-Erling Smørgrav current_name_node = ldns_dnssec_name_node_next_nonglue( 8627b5038d7SDag-Erling Smørgrav ldns_rbtree_next(current_name_node)); 8637b5038d7SDag-Erling Smørgrav } 8647b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 865*2787e39aSDag-Erling Smørgrav ldns_rr_list_free(nsec3_list); 8667b5038d7SDag-Erling Smørgrav return result; 8677b5038d7SDag-Erling Smørgrav } 8687b5038d7SDag-Erling Smørgrav 8697b5038d7SDag-Erling Smørgrav ldns_rr_list_sort_nsec3(nsec3_list); 8707b5038d7SDag-Erling Smørgrav result = ldns_dnssec_chain_nsec3_list(nsec3_list); 8717b5038d7SDag-Erling Smørgrav ldns_rr_list_free(nsec3_list); 872*2787e39aSDag-Erling Smørgrav 8737b5038d7SDag-Erling Smørgrav return result; 8747b5038d7SDag-Erling Smørgrav } 8757b5038d7SDag-Erling Smørgrav 8767b5038d7SDag-Erling Smørgrav ldns_status 8777b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone, 8787b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 8797b5038d7SDag-Erling Smørgrav uint8_t algorithm, 8807b5038d7SDag-Erling Smørgrav uint8_t flags, 8817b5038d7SDag-Erling Smørgrav uint16_t iterations, 8827b5038d7SDag-Erling Smørgrav uint8_t salt_length, 8837b5038d7SDag-Erling Smørgrav uint8_t *salt) 8847b5038d7SDag-Erling Smørgrav { 8857b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm, 8867b5038d7SDag-Erling Smørgrav flags, iterations, salt_length, salt, NULL); 8877b5038d7SDag-Erling Smørgrav 8887b5038d7SDag-Erling Smørgrav } 8897b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8907b5038d7SDag-Erling Smørgrav 8917b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs * 8927b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures 8937b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(ldns_key_list *key_list) 8947b5038d7SDag-Erling Smørgrav , int (*func)(ldns_rr *, void *) 8957b5038d7SDag-Erling Smørgrav , void *arg 8967b5038d7SDag-Erling Smørgrav ) 8977b5038d7SDag-Erling Smørgrav { 8987b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *base_rrs = signatures; 8997b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rr = base_rrs; 9007b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *prev_rr = NULL; 9017b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *next_rr; 9027b5038d7SDag-Erling Smørgrav 9037b5038d7SDag-Erling Smørgrav uint16_t keytag; 9047b5038d7SDag-Erling Smørgrav size_t i; 9057b5038d7SDag-Erling Smørgrav 9067b5038d7SDag-Erling Smørgrav if (!cur_rr) { 9077b5038d7SDag-Erling Smørgrav switch(func(NULL, arg)) { 9087b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_ADD_NEW: 9097b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_ADD_NEW: 9107b5038d7SDag-Erling Smørgrav break; 9117b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_NO_ADD: 9127b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_NO_ADD: 9137b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, false); 9147b5038d7SDag-Erling Smørgrav break; 9157b5038d7SDag-Erling Smørgrav default: 9167b5038d7SDag-Erling Smørgrav fprintf(stderr, "[XX] unknown return value from callback\n"); 9177b5038d7SDag-Erling Smørgrav break; 9187b5038d7SDag-Erling Smørgrav } 9197b5038d7SDag-Erling Smørgrav return NULL; 9207b5038d7SDag-Erling Smørgrav } 9217b5038d7SDag-Erling Smørgrav (void)func(cur_rr->rr, arg); 9227b5038d7SDag-Erling Smørgrav 9237b5038d7SDag-Erling Smørgrav while (cur_rr) { 9247b5038d7SDag-Erling Smørgrav next_rr = cur_rr->next; 9257b5038d7SDag-Erling Smørgrav 9267b5038d7SDag-Erling Smørgrav switch (func(cur_rr->rr, arg)) { 9277b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_ADD_NEW: 9287b5038d7SDag-Erling Smørgrav prev_rr = cur_rr; 9297b5038d7SDag-Erling Smørgrav break; 9307b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_NO_ADD: 9317b5038d7SDag-Erling Smørgrav keytag = ldns_rdf2native_int16( 9327b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_rr->rr)); 9337b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 9347b5038d7SDag-Erling Smørgrav if (ldns_key_keytag(ldns_key_list_key(key_list, i)) == 9357b5038d7SDag-Erling Smørgrav keytag) { 9367b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i), 9377b5038d7SDag-Erling Smørgrav false); 9387b5038d7SDag-Erling Smørgrav } 9397b5038d7SDag-Erling Smørgrav } 9407b5038d7SDag-Erling Smørgrav prev_rr = cur_rr; 9417b5038d7SDag-Erling Smørgrav break; 9427b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_NO_ADD: 9437b5038d7SDag-Erling Smørgrav keytag = ldns_rdf2native_int16( 9447b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_rr->rr)); 9457b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 9467b5038d7SDag-Erling Smørgrav if (ldns_key_keytag(ldns_key_list_key(key_list, i)) 9477b5038d7SDag-Erling Smørgrav == keytag) { 9487b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i), 9497b5038d7SDag-Erling Smørgrav false); 9507b5038d7SDag-Erling Smørgrav } 9517b5038d7SDag-Erling Smørgrav } 9527b5038d7SDag-Erling Smørgrav if (prev_rr) { 9537b5038d7SDag-Erling Smørgrav prev_rr->next = next_rr; 9547b5038d7SDag-Erling Smørgrav } else { 9557b5038d7SDag-Erling Smørgrav base_rrs = next_rr; 9567b5038d7SDag-Erling Smørgrav } 9577b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rr); 9587b5038d7SDag-Erling Smørgrav break; 9597b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_ADD_NEW: 9607b5038d7SDag-Erling Smørgrav if (prev_rr) { 9617b5038d7SDag-Erling Smørgrav prev_rr->next = next_rr; 9627b5038d7SDag-Erling Smørgrav } else { 9637b5038d7SDag-Erling Smørgrav base_rrs = next_rr; 9647b5038d7SDag-Erling Smørgrav } 9657b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rr); 9667b5038d7SDag-Erling Smørgrav break; 9677b5038d7SDag-Erling Smørgrav default: 9687b5038d7SDag-Erling Smørgrav fprintf(stderr, "[XX] unknown return value from callback\n"); 9697b5038d7SDag-Erling Smørgrav break; 9707b5038d7SDag-Erling Smørgrav } 9717b5038d7SDag-Erling Smørgrav cur_rr = next_rr; 9727b5038d7SDag-Erling Smørgrav } 9737b5038d7SDag-Erling Smørgrav 9747b5038d7SDag-Erling Smørgrav return base_rrs; 9757b5038d7SDag-Erling Smørgrav } 9767b5038d7SDag-Erling Smørgrav 9777b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 9787b5038d7SDag-Erling Smørgrav ldns_status 9797b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone, 9807b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 9817b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 9827b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void*), 9837b5038d7SDag-Erling Smørgrav void *arg) 9847b5038d7SDag-Erling Smørgrav { 9857b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list, 9867b5038d7SDag-Erling Smørgrav func, arg, 0); 9877b5038d7SDag-Erling Smørgrav } 9887b5038d7SDag-Erling Smørgrav 9897b5038d7SDag-Erling Smørgrav /** If there are KSKs use only them and mark ZSKs unused */ 9907b5038d7SDag-Erling Smørgrav static void 9917b5038d7SDag-Erling Smørgrav ldns_key_list_filter_for_dnskey(ldns_key_list *key_list) 9927b5038d7SDag-Erling Smørgrav { 9937b5038d7SDag-Erling Smørgrav int saw_ksk = 0; 9947b5038d7SDag-Erling Smørgrav size_t i; 9957b5038d7SDag-Erling Smørgrav for(i=0; i<ldns_key_list_key_count(key_list); i++) 9967b5038d7SDag-Erling Smørgrav if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) { 9977b5038d7SDag-Erling Smørgrav saw_ksk = 1; 9987b5038d7SDag-Erling Smørgrav break; 9997b5038d7SDag-Erling Smørgrav } 10007b5038d7SDag-Erling Smørgrav if(!saw_ksk) 10017b5038d7SDag-Erling Smørgrav return; 10027b5038d7SDag-Erling Smørgrav for(i=0; i<ldns_key_list_key_count(key_list); i++) 10037b5038d7SDag-Erling Smørgrav if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) 10047b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i), 0); 10057b5038d7SDag-Erling Smørgrav } 10067b5038d7SDag-Erling Smørgrav 10077b5038d7SDag-Erling Smørgrav /** If there are no ZSKs use KSK as ZSK */ 10087b5038d7SDag-Erling Smørgrav static void 10097b5038d7SDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list) 10107b5038d7SDag-Erling Smørgrav { 10117b5038d7SDag-Erling Smørgrav int saw_zsk = 0; 10127b5038d7SDag-Erling Smørgrav size_t i; 10137b5038d7SDag-Erling Smørgrav for(i=0; i<ldns_key_list_key_count(key_list); i++) 10147b5038d7SDag-Erling Smørgrav if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) { 10157b5038d7SDag-Erling Smørgrav saw_zsk = 1; 10167b5038d7SDag-Erling Smørgrav break; 10177b5038d7SDag-Erling Smørgrav } 10187b5038d7SDag-Erling Smørgrav if(!saw_zsk) 10197b5038d7SDag-Erling Smørgrav return; 10207b5038d7SDag-Erling Smørgrav /* else filter all KSKs */ 10217b5038d7SDag-Erling Smørgrav for(i=0; i<ldns_key_list_key_count(key_list); i++) 10227b5038d7SDag-Erling Smørgrav if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) 10237b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i), 0); 10247b5038d7SDag-Erling Smørgrav } 10257b5038d7SDag-Erling Smørgrav 10267b5038d7SDag-Erling Smørgrav ldns_status 1027*2787e39aSDag-Erling Smørgrav ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone 1028*2787e39aSDag-Erling Smørgrav , ldns_rr_list *new_rrs 1029*2787e39aSDag-Erling Smørgrav , ldns_key_list *key_list 10307b5038d7SDag-Erling Smørgrav , int (*func)(ldns_rr *, void*) 10317b5038d7SDag-Erling Smørgrav , void *arg 10327b5038d7SDag-Erling Smørgrav , int flags 10337b5038d7SDag-Erling Smørgrav ) 10347b5038d7SDag-Erling Smørgrav { 10357b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 10367b5038d7SDag-Erling Smørgrav 10377b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node; 10387b5038d7SDag-Erling Smørgrav ldns_rr_list *rr_list; 10397b5038d7SDag-Erling Smørgrav 10407b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name; 10417b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrset; 10427b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rr; 10437b5038d7SDag-Erling Smørgrav 10447b5038d7SDag-Erling Smørgrav ldns_rr_list *siglist; 10457b5038d7SDag-Erling Smørgrav 10467b5038d7SDag-Erling Smørgrav size_t i; 10477b5038d7SDag-Erling Smørgrav 10487b5038d7SDag-Erling Smørgrav int on_delegation_point = 0; /* handle partially occluded names */ 10497b5038d7SDag-Erling Smørgrav 10507b5038d7SDag-Erling Smørgrav ldns_rr_list *pubkey_list = ldns_rr_list_new(); 10517b5038d7SDag-Erling Smørgrav for (i = 0; i<ldns_key_list_key_count(key_list); i++) { 10527b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr( pubkey_list 10537b5038d7SDag-Erling Smørgrav , ldns_key2rr(ldns_key_list_key( 10547b5038d7SDag-Erling Smørgrav key_list, i)) 10557b5038d7SDag-Erling Smørgrav ); 10567b5038d7SDag-Erling Smørgrav } 10577b5038d7SDag-Erling Smørgrav /* TODO: callback to see is list should be signed */ 10587b5038d7SDag-Erling Smørgrav /* TODO: remove 'old' signatures from signature list */ 10597b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_first(zone->names); 10607b5038d7SDag-Erling Smørgrav while (cur_node != LDNS_RBTREE_NULL) { 10617b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *) cur_node->data; 10627b5038d7SDag-Erling Smørgrav 10637b5038d7SDag-Erling Smørgrav if (!cur_name->is_glue) { 10647b5038d7SDag-Erling Smørgrav on_delegation_point = ldns_dnssec_rrsets_contains_type( 10657b5038d7SDag-Erling Smørgrav cur_name->rrsets, LDNS_RR_TYPE_NS) 10667b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type( 10677b5038d7SDag-Erling Smørgrav cur_name->rrsets, LDNS_RR_TYPE_SOA); 10687b5038d7SDag-Erling Smørgrav cur_rrset = cur_name->rrsets; 10697b5038d7SDag-Erling Smørgrav while (cur_rrset) { 10707b5038d7SDag-Erling Smørgrav /* reset keys to use */ 10717b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, true); 10727b5038d7SDag-Erling Smørgrav 10737b5038d7SDag-Erling Smørgrav /* walk through old sigs, remove the old, 10747b5038d7SDag-Erling Smørgrav and mark which keys (not) to use) */ 10757b5038d7SDag-Erling Smørgrav cur_rrset->signatures = 10767b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures(cur_rrset->signatures, 10777b5038d7SDag-Erling Smørgrav key_list, 10787b5038d7SDag-Erling Smørgrav func, 10797b5038d7SDag-Erling Smørgrav arg); 10807b5038d7SDag-Erling Smørgrav if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) && 10817b5038d7SDag-Erling Smørgrav cur_rrset->type == LDNS_RR_TYPE_DNSKEY) 10827b5038d7SDag-Erling Smørgrav ldns_key_list_filter_for_dnskey(key_list); 10837b5038d7SDag-Erling Smørgrav 10847b5038d7SDag-Erling Smørgrav if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY) 10857b5038d7SDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(key_list); 10867b5038d7SDag-Erling Smørgrav 10877b5038d7SDag-Erling Smørgrav /* TODO: just set count to zero? */ 10887b5038d7SDag-Erling Smørgrav rr_list = ldns_rr_list_new(); 10897b5038d7SDag-Erling Smørgrav 10907b5038d7SDag-Erling Smørgrav cur_rr = cur_rrset->rrs; 10917b5038d7SDag-Erling Smørgrav while (cur_rr) { 10927b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(rr_list, cur_rr->rr); 10937b5038d7SDag-Erling Smørgrav cur_rr = cur_rr->next; 10947b5038d7SDag-Erling Smørgrav } 10957b5038d7SDag-Erling Smørgrav 10967b5038d7SDag-Erling Smørgrav /* only sign non-delegation RRsets */ 10977b5038d7SDag-Erling Smørgrav /* (glue should have been marked earlier, 10987b5038d7SDag-Erling Smørgrav * except on the delegation points itself) */ 10997b5038d7SDag-Erling Smørgrav if (!on_delegation_point || 11007b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list) 11017b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_DS || 11027b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list) 11037b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC || 11047b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list) 11057b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3) { 11067b5038d7SDag-Erling Smørgrav siglist = ldns_sign_public(rr_list, key_list); 11077b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) { 11087b5038d7SDag-Erling Smørgrav if (cur_rrset->signatures) { 11097b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures, 11107b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, 11117b5038d7SDag-Erling Smørgrav i)); 11127b5038d7SDag-Erling Smørgrav } else { 11137b5038d7SDag-Erling Smørgrav cur_rrset->signatures = ldns_dnssec_rrs_new(); 11147b5038d7SDag-Erling Smørgrav cur_rrset->signatures->rr = 11157b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i); 1116*2787e39aSDag-Erling Smørgrav } 1117*2787e39aSDag-Erling Smørgrav if (new_rrs) { 11187b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, 11197b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, 11207b5038d7SDag-Erling Smørgrav i)); 11217b5038d7SDag-Erling Smørgrav } 11227b5038d7SDag-Erling Smørgrav } 11237b5038d7SDag-Erling Smørgrav ldns_rr_list_free(siglist); 11247b5038d7SDag-Erling Smørgrav } 11257b5038d7SDag-Erling Smørgrav 11267b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rr_list); 11277b5038d7SDag-Erling Smørgrav 11287b5038d7SDag-Erling Smørgrav cur_rrset = cur_rrset->next; 11297b5038d7SDag-Erling Smørgrav } 11307b5038d7SDag-Erling Smørgrav 11317b5038d7SDag-Erling Smørgrav /* sign the nsec */ 11327b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, true); 11337b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures = 11347b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures(cur_name->nsec_signatures, 11357b5038d7SDag-Erling Smørgrav key_list, 11367b5038d7SDag-Erling Smørgrav func, 11377b5038d7SDag-Erling Smørgrav arg); 11387b5038d7SDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(key_list); 11397b5038d7SDag-Erling Smørgrav 11407b5038d7SDag-Erling Smørgrav rr_list = ldns_rr_list_new(); 11417b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(rr_list, cur_name->nsec); 11427b5038d7SDag-Erling Smørgrav siglist = ldns_sign_public(rr_list, key_list); 11437b5038d7SDag-Erling Smørgrav 11447b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) { 11457b5038d7SDag-Erling Smørgrav if (cur_name->nsec_signatures) { 11467b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures, 11477b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i)); 11487b5038d7SDag-Erling Smørgrav } else { 11497b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures = ldns_dnssec_rrs_new(); 11507b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures->rr = 11517b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i); 1152*2787e39aSDag-Erling Smørgrav } 1153*2787e39aSDag-Erling Smørgrav if (new_rrs) { 11547b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, 11557b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i)); 11567b5038d7SDag-Erling Smørgrav } 11577b5038d7SDag-Erling Smørgrav } 11587b5038d7SDag-Erling Smørgrav 11597b5038d7SDag-Erling Smørgrav ldns_rr_list_free(siglist); 11607b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rr_list); 11617b5038d7SDag-Erling Smørgrav } 11627b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_next(cur_node); 11637b5038d7SDag-Erling Smørgrav } 11647b5038d7SDag-Erling Smørgrav 11657b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(pubkey_list); 11667b5038d7SDag-Erling Smørgrav return result; 11677b5038d7SDag-Erling Smørgrav } 11687b5038d7SDag-Erling Smørgrav 11697b5038d7SDag-Erling Smørgrav ldns_status 11707b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign(ldns_dnssec_zone *zone, 11717b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 11727b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 11737b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *), 11747b5038d7SDag-Erling Smørgrav void *arg) 11757b5038d7SDag-Erling Smørgrav { 11767b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0); 11777b5038d7SDag-Erling Smørgrav } 11787b5038d7SDag-Erling Smørgrav 11797b5038d7SDag-Erling Smørgrav ldns_status 11807b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, 11817b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 11827b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 11837b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *), 11847b5038d7SDag-Erling Smørgrav void *arg, 11857b5038d7SDag-Erling Smørgrav int flags) 11867b5038d7SDag-Erling Smørgrav { 11877b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 11887b5038d7SDag-Erling Smørgrav 11897b5038d7SDag-Erling Smørgrav if (!zone || !new_rrs || !key_list) { 11907b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 11917b5038d7SDag-Erling Smørgrav } 11927b5038d7SDag-Erling Smørgrav 11937b5038d7SDag-Erling Smørgrav /* zone is already sorted */ 11947b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_mark_glue(zone); 11957b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 11967b5038d7SDag-Erling Smørgrav return result; 11977b5038d7SDag-Erling Smørgrav } 11987b5038d7SDag-Erling Smørgrav 11997b5038d7SDag-Erling Smørgrav /* check whether we need to add nsecs */ 12007b5038d7SDag-Erling Smørgrav if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) { 12017b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_nsecs(zone, new_rrs); 12027b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 12037b5038d7SDag-Erling Smørgrav return result; 12047b5038d7SDag-Erling Smørgrav } 12057b5038d7SDag-Erling Smørgrav } 12067b5038d7SDag-Erling Smørgrav 12077b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_rrsigs_flg(zone, 12087b5038d7SDag-Erling Smørgrav new_rrs, 12097b5038d7SDag-Erling Smørgrav key_list, 12107b5038d7SDag-Erling Smørgrav func, 12117b5038d7SDag-Erling Smørgrav arg, 12127b5038d7SDag-Erling Smørgrav flags); 12137b5038d7SDag-Erling Smørgrav 12147b5038d7SDag-Erling Smørgrav return result; 12157b5038d7SDag-Erling Smørgrav } 12167b5038d7SDag-Erling Smørgrav 12177b5038d7SDag-Erling Smørgrav ldns_status 12187b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone, 12197b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 12207b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 12217b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *), 12227b5038d7SDag-Erling Smørgrav void *arg, 12237b5038d7SDag-Erling Smørgrav uint8_t algorithm, 12247b5038d7SDag-Erling Smørgrav uint8_t flags, 12257b5038d7SDag-Erling Smørgrav uint16_t iterations, 12267b5038d7SDag-Erling Smørgrav uint8_t salt_length, 12277b5038d7SDag-Erling Smørgrav uint8_t *salt) 12287b5038d7SDag-Erling Smørgrav { 12297b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list, 12307b5038d7SDag-Erling Smørgrav func, arg, algorithm, flags, iterations, salt_length, salt, 0, 12317b5038d7SDag-Erling Smørgrav NULL); 12327b5038d7SDag-Erling Smørgrav } 12337b5038d7SDag-Erling Smørgrav 12347b5038d7SDag-Erling Smørgrav ldns_status 12357b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, 12367b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 12377b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 12387b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *), 12397b5038d7SDag-Erling Smørgrav void *arg, 12407b5038d7SDag-Erling Smørgrav uint8_t algorithm, 12417b5038d7SDag-Erling Smørgrav uint8_t flags, 12427b5038d7SDag-Erling Smørgrav uint16_t iterations, 12437b5038d7SDag-Erling Smørgrav uint8_t salt_length, 12447b5038d7SDag-Erling Smørgrav uint8_t *salt, 12457b5038d7SDag-Erling Smørgrav int signflags, 12467b5038d7SDag-Erling Smørgrav ldns_rbtree_t **map) 12477b5038d7SDag-Erling Smørgrav { 12487b5038d7SDag-Erling Smørgrav ldns_rr *nsec3, *nsec3param; 12497b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK; 12507b5038d7SDag-Erling Smørgrav 12517b5038d7SDag-Erling Smørgrav /* zone is already sorted */ 12527b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_mark_glue(zone); 12537b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 12547b5038d7SDag-Erling Smørgrav return result; 12557b5038d7SDag-Erling Smørgrav } 12567b5038d7SDag-Erling Smørgrav 12577b5038d7SDag-Erling Smørgrav /* TODO if there are already nsec3s presents and their 12587b5038d7SDag-Erling Smørgrav * parameters are the same as these, we don't have to recreate 12597b5038d7SDag-Erling Smørgrav */ 12607b5038d7SDag-Erling Smørgrav if (zone->names) { 12617b5038d7SDag-Erling Smørgrav /* add empty nonterminals */ 12627b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_add_empty_nonterminals(zone); 12637b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 12647b5038d7SDag-Erling Smørgrav return result; 12657b5038d7SDag-Erling Smørgrav } 12667b5038d7SDag-Erling Smørgrav 12677b5038d7SDag-Erling Smørgrav nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec; 12687b5038d7SDag-Erling Smørgrav if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) { 12697b5038d7SDag-Erling Smørgrav /* no need to recreate */ 12707b5038d7SDag-Erling Smørgrav } else { 12717b5038d7SDag-Erling Smørgrav if (!ldns_dnssec_zone_find_rrset(zone, 12727b5038d7SDag-Erling Smørgrav zone->soa->name, 12737b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3PARAM)) { 12747b5038d7SDag-Erling Smørgrav /* create and add the nsec3param rr */ 12757b5038d7SDag-Erling Smørgrav nsec3param = 12767b5038d7SDag-Erling Smørgrav ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM); 12777b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec3param, 12787b5038d7SDag-Erling Smørgrav ldns_rdf_clone(zone->soa->name)); 12797b5038d7SDag-Erling Smørgrav ldns_nsec3_add_param_rdfs(nsec3param, 12807b5038d7SDag-Erling Smørgrav algorithm, 12817b5038d7SDag-Erling Smørgrav flags, 12827b5038d7SDag-Erling Smørgrav iterations, 12837b5038d7SDag-Erling Smørgrav salt_length, 12847b5038d7SDag-Erling Smørgrav salt); 12857b5038d7SDag-Erling Smørgrav /* always set bit 7 of the flags to zero, according to 12867b5038d7SDag-Erling Smørgrav * rfc5155 section 11. The bits are counted from right to left, 12877b5038d7SDag-Erling Smørgrav * so bit 7 in rfc5155 is bit 0 in ldns */ 12887b5038d7SDag-Erling Smørgrav ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0); 12897b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_add_rr(zone, nsec3param); 12907b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 12917b5038d7SDag-Erling Smørgrav return result; 12927b5038d7SDag-Erling Smørgrav } 12937b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec3param); 12947b5038d7SDag-Erling Smørgrav } 12957b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_nsec3s_mkmap(zone, 12967b5038d7SDag-Erling Smørgrav new_rrs, 12977b5038d7SDag-Erling Smørgrav algorithm, 12987b5038d7SDag-Erling Smørgrav flags, 12997b5038d7SDag-Erling Smørgrav iterations, 13007b5038d7SDag-Erling Smørgrav salt_length, 13017b5038d7SDag-Erling Smørgrav salt, 13027b5038d7SDag-Erling Smørgrav map); 13037b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) { 13047b5038d7SDag-Erling Smørgrav return result; 13057b5038d7SDag-Erling Smørgrav } 13067b5038d7SDag-Erling Smørgrav } 13077b5038d7SDag-Erling Smørgrav 13087b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_rrsigs_flg(zone, 13097b5038d7SDag-Erling Smørgrav new_rrs, 13107b5038d7SDag-Erling Smørgrav key_list, 13117b5038d7SDag-Erling Smørgrav func, 13127b5038d7SDag-Erling Smørgrav arg, 13137b5038d7SDag-Erling Smørgrav signflags); 13147b5038d7SDag-Erling Smørgrav } 13157b5038d7SDag-Erling Smørgrav 13167b5038d7SDag-Erling Smørgrav return result; 13177b5038d7SDag-Erling Smørgrav } 13187b5038d7SDag-Erling Smørgrav 13197b5038d7SDag-Erling Smørgrav ldns_status 13207b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone, 13217b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs, 13227b5038d7SDag-Erling Smørgrav ldns_key_list *key_list, 13237b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *), 13247b5038d7SDag-Erling Smørgrav void *arg, 13257b5038d7SDag-Erling Smørgrav uint8_t algorithm, 13267b5038d7SDag-Erling Smørgrav uint8_t flags, 13277b5038d7SDag-Erling Smørgrav uint16_t iterations, 13287b5038d7SDag-Erling Smørgrav uint8_t salt_length, 13297b5038d7SDag-Erling Smørgrav uint8_t *salt, 13307b5038d7SDag-Erling Smørgrav int signflags) 13317b5038d7SDag-Erling Smørgrav { 13327b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list, 13337b5038d7SDag-Erling Smørgrav func, arg, algorithm, flags, iterations, salt_length, salt, 13347b5038d7SDag-Erling Smørgrav signflags, NULL); 13357b5038d7SDag-Erling Smørgrav } 13367b5038d7SDag-Erling Smørgrav 13377b5038d7SDag-Erling Smørgrav ldns_zone * 13387b5038d7SDag-Erling Smørgrav ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list) 13397b5038d7SDag-Erling Smørgrav { 13407b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *dnssec_zone; 13417b5038d7SDag-Erling Smørgrav ldns_zone *signed_zone; 13427b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs; 13437b5038d7SDag-Erling Smørgrav size_t i; 13447b5038d7SDag-Erling Smørgrav 13457b5038d7SDag-Erling Smørgrav signed_zone = ldns_zone_new(); 13467b5038d7SDag-Erling Smørgrav dnssec_zone = ldns_dnssec_zone_new(); 13477b5038d7SDag-Erling Smørgrav 13487b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone)); 13497b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone))); 13507b5038d7SDag-Erling Smørgrav 13517b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 13527b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, 13537b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(ldns_zone_rrs(zone), 13547b5038d7SDag-Erling Smørgrav i)); 13557b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(signed_zone, 13567b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone), 13577b5038d7SDag-Erling Smørgrav i))); 13587b5038d7SDag-Erling Smørgrav } 13597b5038d7SDag-Erling Smørgrav 13607b5038d7SDag-Erling Smørgrav new_rrs = ldns_rr_list_new(); 13617b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_sign(dnssec_zone, 13627b5038d7SDag-Erling Smørgrav new_rrs, 13637b5038d7SDag-Erling Smørgrav key_list, 13647b5038d7SDag-Erling Smørgrav ldns_dnssec_default_replace_signatures, 13657b5038d7SDag-Erling Smørgrav NULL); 13667b5038d7SDag-Erling Smørgrav 13677b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) { 13687b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone), 13697b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(new_rrs, i))); 13707b5038d7SDag-Erling Smørgrav } 13717b5038d7SDag-Erling Smørgrav 13727b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_rrs); 13737b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(dnssec_zone); 13747b5038d7SDag-Erling Smørgrav 13757b5038d7SDag-Erling Smørgrav return signed_zone; 13767b5038d7SDag-Erling Smørgrav } 13777b5038d7SDag-Erling Smørgrav 13787b5038d7SDag-Erling Smørgrav ldns_zone * 13797b5038d7SDag-Erling Smørgrav ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt) 13807b5038d7SDag-Erling Smørgrav { 13817b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *dnssec_zone; 13827b5038d7SDag-Erling Smørgrav ldns_zone *signed_zone; 13837b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs; 13847b5038d7SDag-Erling Smørgrav size_t i; 13857b5038d7SDag-Erling Smørgrav 13867b5038d7SDag-Erling Smørgrav signed_zone = ldns_zone_new(); 13877b5038d7SDag-Erling Smørgrav dnssec_zone = ldns_dnssec_zone_new(); 13887b5038d7SDag-Erling Smørgrav 13897b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone)); 13907b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone))); 13917b5038d7SDag-Erling Smørgrav 13927b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 13937b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, 13947b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(ldns_zone_rrs(zone), 13957b5038d7SDag-Erling Smørgrav i)); 13967b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(signed_zone, 13977b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone), 13987b5038d7SDag-Erling Smørgrav i))); 13997b5038d7SDag-Erling Smørgrav } 14007b5038d7SDag-Erling Smørgrav 14017b5038d7SDag-Erling Smørgrav new_rrs = ldns_rr_list_new(); 14027b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone, 14037b5038d7SDag-Erling Smørgrav new_rrs, 14047b5038d7SDag-Erling Smørgrav key_list, 14057b5038d7SDag-Erling Smørgrav ldns_dnssec_default_replace_signatures, 14067b5038d7SDag-Erling Smørgrav NULL, 14077b5038d7SDag-Erling Smørgrav algorithm, 14087b5038d7SDag-Erling Smørgrav flags, 14097b5038d7SDag-Erling Smørgrav iterations, 14107b5038d7SDag-Erling Smørgrav salt_length, 14117b5038d7SDag-Erling Smørgrav salt); 14127b5038d7SDag-Erling Smørgrav 14137b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) { 14147b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone), 14157b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(new_rrs, i))); 14167b5038d7SDag-Erling Smørgrav } 14177b5038d7SDag-Erling Smørgrav 14187b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_rrs); 14197b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(dnssec_zone); 14207b5038d7SDag-Erling Smørgrav 14217b5038d7SDag-Erling Smørgrav return signed_zone; 14227b5038d7SDag-Erling Smørgrav } 14237b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 14247b5038d7SDag-Erling Smørgrav 14257b5038d7SDag-Erling Smørgrav 1426