17b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
27b5038d7SDag-Erling Smørgrav
37b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
4*5afab0e5SDag-Erling Smørgrav #include <ldns/internal.h>
57b5038d7SDag-Erling Smørgrav
67b5038d7SDag-Erling Smørgrav #include <ldns/dnssec.h>
77b5038d7SDag-Erling Smørgrav #include <ldns/dnssec_sign.h>
87b5038d7SDag-Erling Smørgrav
97b5038d7SDag-Erling Smørgrav #include <strings.h>
107b5038d7SDag-Erling Smørgrav #include <time.h>
117b5038d7SDag-Erling Smørgrav
127b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
137b5038d7SDag-Erling Smørgrav /* this entire file is rather useless when you don't have
147b5038d7SDag-Erling Smørgrav * crypto...
157b5038d7SDag-Erling Smørgrav */
167b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h>
177b5038d7SDag-Erling Smørgrav #include <openssl/evp.h>
187b5038d7SDag-Erling Smørgrav #include <openssl/rand.h>
197b5038d7SDag-Erling Smørgrav #include <openssl/err.h>
207b5038d7SDag-Erling Smørgrav #include <openssl/md5.h>
21*5afab0e5SDag-Erling Smørgrav #include <openssl/bn.h>
22*5afab0e5SDag-Erling Smørgrav #include <openssl/rsa.h>
23*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
24*5afab0e5SDag-Erling Smørgrav #include <openssl/dsa.h>
25*5afab0e5SDag-Erling Smørgrav #endif
267b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
277b5038d7SDag-Erling Smørgrav
28*5afab0e5SDag-Erling Smørgrav #define LDNS_SIGN_WITH_ZONEMD ( LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384 \
29*5afab0e5SDag-Erling Smørgrav | LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512 )
30*5afab0e5SDag-Erling Smørgrav
317b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_create_empty_rrsig(const ldns_rr_list * rrset,const ldns_key * current_key)32986ba33cSDag-Erling Smørgrav ldns_create_empty_rrsig(const ldns_rr_list *rrset,
33986ba33cSDag-Erling Smørgrav const ldns_key *current_key)
347b5038d7SDag-Erling Smørgrav {
357b5038d7SDag-Erling Smørgrav uint32_t orig_ttl;
367b5038d7SDag-Erling Smørgrav ldns_rr_class orig_class;
377b5038d7SDag-Erling Smørgrav time_t now;
387b5038d7SDag-Erling Smørgrav ldns_rr *current_sig;
397b5038d7SDag-Erling Smørgrav uint8_t label_count;
407b5038d7SDag-Erling Smørgrav ldns_rdf *signame;
417b5038d7SDag-Erling Smørgrav
427b5038d7SDag-Erling Smørgrav label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
437b5038d7SDag-Erling Smørgrav 0)));
447b5038d7SDag-Erling Smørgrav /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
457b5038d7SDag-Erling Smørgrav if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
467b5038d7SDag-Erling Smørgrav label_count --;
477b5038d7SDag-Erling Smørgrav
487b5038d7SDag-Erling Smørgrav current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
497b5038d7SDag-Erling Smørgrav
507b5038d7SDag-Erling Smørgrav /* set the type on the new signature */
517b5038d7SDag-Erling Smørgrav orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
527b5038d7SDag-Erling Smørgrav orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
537b5038d7SDag-Erling Smørgrav
547b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(current_sig, orig_ttl);
557b5038d7SDag-Erling Smørgrav ldns_rr_set_class(current_sig, orig_class);
567b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(current_sig,
577b5038d7SDag-Erling Smørgrav ldns_rdf_clone(
587b5038d7SDag-Erling Smørgrav ldns_rr_owner(
597b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrset,
607b5038d7SDag-Erling Smørgrav 0))));
617b5038d7SDag-Erling Smørgrav
627b5038d7SDag-Erling Smørgrav /* fill in what we know of the signature */
637b5038d7SDag-Erling Smørgrav
647b5038d7SDag-Erling Smørgrav /* set the orig_ttl */
657b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_origttl(
667b5038d7SDag-Erling Smørgrav current_sig,
677b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
687b5038d7SDag-Erling Smørgrav orig_ttl));
697b5038d7SDag-Erling Smørgrav /* the signers name */
707b5038d7SDag-Erling Smørgrav signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
717b5038d7SDag-Erling Smørgrav ldns_dname2canonical(signame);
727b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_signame(
737b5038d7SDag-Erling Smørgrav current_sig,
747b5038d7SDag-Erling Smørgrav signame);
757b5038d7SDag-Erling Smørgrav /* label count - get it from the first rr in the rr_list */
767b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_labels(
777b5038d7SDag-Erling Smørgrav current_sig,
787b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
797b5038d7SDag-Erling Smørgrav label_count));
807b5038d7SDag-Erling Smørgrav /* inception, expiration */
817b5038d7SDag-Erling Smørgrav now = time(NULL);
827b5038d7SDag-Erling Smørgrav if (ldns_key_inception(current_key) != 0) {
837b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_inception(
847b5038d7SDag-Erling Smørgrav current_sig,
857b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(
867b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME,
877b5038d7SDag-Erling Smørgrav ldns_key_inception(current_key)));
887b5038d7SDag-Erling Smørgrav } else {
897b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_inception(
907b5038d7SDag-Erling Smørgrav current_sig,
917b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
927b5038d7SDag-Erling Smørgrav }
937b5038d7SDag-Erling Smørgrav if (ldns_key_expiration(current_key) != 0) {
947b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_expiration(
957b5038d7SDag-Erling Smørgrav current_sig,
967b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(
977b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME,
987b5038d7SDag-Erling Smørgrav ldns_key_expiration(current_key)));
997b5038d7SDag-Erling Smørgrav } else {
1007b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_expiration(
1017b5038d7SDag-Erling Smørgrav current_sig,
1027b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(
1037b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TIME,
1047b5038d7SDag-Erling Smørgrav now + LDNS_DEFAULT_EXP_TIME));
1057b5038d7SDag-Erling Smørgrav }
1067b5038d7SDag-Erling Smørgrav
1077b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_keytag(
1087b5038d7SDag-Erling Smørgrav current_sig,
1097b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
1107b5038d7SDag-Erling Smørgrav ldns_key_keytag(current_key)));
1117b5038d7SDag-Erling Smørgrav
1127b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_algorithm(
1137b5038d7SDag-Erling Smørgrav current_sig,
1147b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(
1157b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG,
1167b5038d7SDag-Erling Smørgrav ldns_key_algorithm(current_key)));
1177b5038d7SDag-Erling Smørgrav
1187b5038d7SDag-Erling Smørgrav (void)ldns_rr_rrsig_set_typecovered(
1197b5038d7SDag-Erling Smørgrav current_sig,
1207b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(
1217b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_TYPE,
1227b5038d7SDag-Erling Smørgrav ldns_rr_get_type(ldns_rr_list_rr(rrset,
1237b5038d7SDag-Erling Smørgrav 0))));
1247b5038d7SDag-Erling Smørgrav return current_sig;
1257b5038d7SDag-Erling Smørgrav }
1267b5038d7SDag-Erling Smørgrav
1277b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1287b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_sign_public_buffer(ldns_buffer * sign_buf,ldns_key * current_key)1297b5038d7SDag-Erling Smørgrav ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
1307b5038d7SDag-Erling Smørgrav {
1317b5038d7SDag-Erling Smørgrav ldns_rdf *b64rdf = NULL;
1327b5038d7SDag-Erling Smørgrav
1337b5038d7SDag-Erling Smørgrav switch(ldns_key_algorithm(current_key)) {
134986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
1357b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA:
1367b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3:
1377b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1387b5038d7SDag-Erling Smørgrav sign_buf,
1397b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
140986ba33cSDag-Erling Smørgrav # ifdef HAVE_EVP_DSS1
141986ba33cSDag-Erling Smørgrav EVP_dss1()
142986ba33cSDag-Erling Smørgrav # else
143986ba33cSDag-Erling Smørgrav EVP_sha1()
144986ba33cSDag-Erling Smørgrav # endif
145986ba33cSDag-Erling Smørgrav );
1467b5038d7SDag-Erling Smørgrav break;
147986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
1487b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1:
1497b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3:
1507b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1517b5038d7SDag-Erling Smørgrav sign_buf,
1527b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
1537b5038d7SDag-Erling Smørgrav EVP_sha1());
1547b5038d7SDag-Erling Smørgrav break;
1557b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
1567b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256:
1577b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1587b5038d7SDag-Erling Smørgrav sign_buf,
1597b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
1607b5038d7SDag-Erling Smørgrav EVP_sha256());
1617b5038d7SDag-Erling Smørgrav break;
1627b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512:
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_sha512());
1677b5038d7SDag-Erling Smørgrav break;
1687b5038d7SDag-Erling Smørgrav #endif /* USE_SHA2 */
1697b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
1707b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST:
1717b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1727b5038d7SDag-Erling Smørgrav sign_buf,
1737b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
1747b5038d7SDag-Erling Smørgrav EVP_get_digestbyname("md_gost94"));
1757b5038d7SDag-Erling Smørgrav break;
1767b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */
1777b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
1787b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256:
1797b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1807b5038d7SDag-Erling Smørgrav sign_buf,
1817b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
1827b5038d7SDag-Erling Smørgrav EVP_sha256());
1837b5038d7SDag-Erling Smørgrav break;
1847b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384:
1857b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
1867b5038d7SDag-Erling Smørgrav sign_buf,
1877b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
1887b5038d7SDag-Erling Smørgrav EVP_sha384());
1897b5038d7SDag-Erling Smørgrav break;
1907b5038d7SDag-Erling Smørgrav #endif
191986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
192986ba33cSDag-Erling Smørgrav case LDNS_SIGN_ED25519:
193986ba33cSDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
194986ba33cSDag-Erling Smørgrav sign_buf,
195986ba33cSDag-Erling Smørgrav ldns_key_evp_key(current_key),
196*5afab0e5SDag-Erling Smørgrav NULL);
197986ba33cSDag-Erling Smørgrav break;
198986ba33cSDag-Erling Smørgrav #endif
199986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
200986ba33cSDag-Erling Smørgrav case LDNS_SIGN_ED448:
201986ba33cSDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
202986ba33cSDag-Erling Smørgrav sign_buf,
203986ba33cSDag-Erling Smørgrav ldns_key_evp_key(current_key),
204*5afab0e5SDag-Erling Smørgrav NULL);
205986ba33cSDag-Erling Smørgrav break;
206986ba33cSDag-Erling Smørgrav #endif
2077b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5:
2087b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_evp(
2097b5038d7SDag-Erling Smørgrav sign_buf,
2107b5038d7SDag-Erling Smørgrav ldns_key_evp_key(current_key),
2117b5038d7SDag-Erling Smørgrav EVP_md5());
2127b5038d7SDag-Erling Smørgrav break;
2137b5038d7SDag-Erling Smørgrav default:
2147b5038d7SDag-Erling Smørgrav /* do _you_ know this alg? */
2157b5038d7SDag-Erling Smørgrav printf("unknown algorithm, ");
2167b5038d7SDag-Erling Smørgrav printf("is the one used available on this system?\n");
2177b5038d7SDag-Erling Smørgrav break;
2187b5038d7SDag-Erling Smørgrav }
2197b5038d7SDag-Erling Smørgrav
2207b5038d7SDag-Erling Smørgrav return b64rdf;
2217b5038d7SDag-Erling Smørgrav }
2227b5038d7SDag-Erling Smørgrav
2237b5038d7SDag-Erling Smørgrav /**
2247b5038d7SDag-Erling Smørgrav * use this function to sign with a public/private key alg
2257b5038d7SDag-Erling Smørgrav * return the created signatures
2267b5038d7SDag-Erling Smørgrav */
2277b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_sign_public(ldns_rr_list * rrset,ldns_key_list * keys)2287b5038d7SDag-Erling Smørgrav ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
2297b5038d7SDag-Erling Smørgrav {
2307b5038d7SDag-Erling Smørgrav ldns_rr_list *signatures;
2317b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_clone;
2327b5038d7SDag-Erling Smørgrav ldns_rr *current_sig;
2337b5038d7SDag-Erling Smørgrav ldns_rdf *b64rdf;
2347b5038d7SDag-Erling Smørgrav ldns_key *current_key;
2357b5038d7SDag-Erling Smørgrav size_t key_count;
2367b5038d7SDag-Erling Smørgrav uint16_t i;
2377b5038d7SDag-Erling Smørgrav ldns_buffer *sign_buf;
2387b5038d7SDag-Erling Smørgrav ldns_rdf *new_owner;
2397b5038d7SDag-Erling Smørgrav
2407b5038d7SDag-Erling Smørgrav if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
2417b5038d7SDag-Erling Smørgrav return NULL;
2427b5038d7SDag-Erling Smørgrav }
2437b5038d7SDag-Erling Smørgrav
2447b5038d7SDag-Erling Smørgrav new_owner = NULL;
2457b5038d7SDag-Erling Smørgrav
2467b5038d7SDag-Erling Smørgrav /* prepare a signature and add all the know data
2477b5038d7SDag-Erling Smørgrav * prepare the rrset. Sign this together. */
2487b5038d7SDag-Erling Smørgrav rrset_clone = ldns_rr_list_clone(rrset);
2497b5038d7SDag-Erling Smørgrav if (!rrset_clone) {
2507b5038d7SDag-Erling Smørgrav return NULL;
2517b5038d7SDag-Erling Smørgrav }
2527b5038d7SDag-Erling Smørgrav
2537b5038d7SDag-Erling Smørgrav /* make it canonical */
2547b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
2557b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
2567b5038d7SDag-Erling Smørgrav ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
2577b5038d7SDag-Erling Smørgrav ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
2587b5038d7SDag-Erling Smørgrav }
2597b5038d7SDag-Erling Smørgrav /* sort */
2607b5038d7SDag-Erling Smørgrav ldns_rr_list_sort(rrset_clone);
2617b5038d7SDag-Erling Smørgrav
262*5afab0e5SDag-Erling Smørgrav signatures = ldns_rr_list_new();
263*5afab0e5SDag-Erling Smørgrav
2647b5038d7SDag-Erling Smørgrav for (key_count = 0;
2657b5038d7SDag-Erling Smørgrav key_count < ldns_key_list_key_count(keys);
2667b5038d7SDag-Erling Smørgrav key_count++) {
2677b5038d7SDag-Erling Smørgrav if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
2687b5038d7SDag-Erling Smørgrav continue;
2697b5038d7SDag-Erling Smørgrav }
2707b5038d7SDag-Erling Smørgrav sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2717b5038d7SDag-Erling Smørgrav if (!sign_buf) {
2727b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rrset_clone);
2737b5038d7SDag-Erling Smørgrav ldns_rr_list_free(signatures);
2747b5038d7SDag-Erling Smørgrav ldns_rdf_free(new_owner);
2757b5038d7SDag-Erling Smørgrav return NULL;
2767b5038d7SDag-Erling Smørgrav }
2777b5038d7SDag-Erling Smørgrav b64rdf = NULL;
2787b5038d7SDag-Erling Smørgrav
2797b5038d7SDag-Erling Smørgrav current_key = ldns_key_list_key(keys, key_count);
2807b5038d7SDag-Erling Smørgrav /* sign all RRs with keys that have ZSKbit, !SEPbit.
2817b5038d7SDag-Erling Smørgrav sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
2827b5038d7SDag-Erling Smørgrav if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
2837b5038d7SDag-Erling Smørgrav current_sig = ldns_create_empty_rrsig(rrset_clone,
2847b5038d7SDag-Erling Smørgrav current_key);
2857b5038d7SDag-Erling Smørgrav
2867b5038d7SDag-Erling Smørgrav /* right now, we have: a key, a semi-sig and an rrset. For
2877b5038d7SDag-Erling Smørgrav * which we can create the sig and base64 encode that and
2887b5038d7SDag-Erling Smørgrav * add that to the signature */
2897b5038d7SDag-Erling Smørgrav
2907b5038d7SDag-Erling Smørgrav if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
2917b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
2927b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf);
2937b5038d7SDag-Erling Smørgrav /* ERROR */
2947b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
2952787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig);
2962787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures);
2977b5038d7SDag-Erling Smørgrav return NULL;
2987b5038d7SDag-Erling Smørgrav }
2997b5038d7SDag-Erling Smørgrav
3007b5038d7SDag-Erling Smørgrav /* add the rrset in sign_buf */
3017b5038d7SDag-Erling Smørgrav if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
3027b5038d7SDag-Erling Smørgrav != LDNS_STATUS_OK) {
3037b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf);
3047b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
3052787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig);
3062787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures);
3077b5038d7SDag-Erling Smørgrav return NULL;
3087b5038d7SDag-Erling Smørgrav }
3097b5038d7SDag-Erling Smørgrav
3107b5038d7SDag-Erling Smørgrav b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
3117b5038d7SDag-Erling Smørgrav
3127b5038d7SDag-Erling Smørgrav if (!b64rdf) {
3137b5038d7SDag-Erling Smørgrav /* signing went wrong */
3147b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
3152787e39aSDag-Erling Smørgrav ldns_rr_free(current_sig);
3162787e39aSDag-Erling Smørgrav ldns_rr_list_deep_free(signatures);
3177b5038d7SDag-Erling Smørgrav return NULL;
3187b5038d7SDag-Erling Smørgrav }
3197b5038d7SDag-Erling Smørgrav
3207b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_set_sig(current_sig, b64rdf);
3217b5038d7SDag-Erling Smørgrav
3227b5038d7SDag-Erling Smørgrav /* push the signature to the signatures list */
3237b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(signatures, current_sig);
3247b5038d7SDag-Erling Smørgrav }
3257b5038d7SDag-Erling Smørgrav ldns_buffer_free(sign_buf); /* restart for the next key */
3267b5038d7SDag-Erling Smørgrav }
3277b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrset_clone);
3287b5038d7SDag-Erling Smørgrav
3297b5038d7SDag-Erling Smørgrav return signatures;
3307b5038d7SDag-Erling Smørgrav }
3317b5038d7SDag-Erling Smørgrav
3327b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_sign_public_dsa(ldns_buffer * to_sign,DSA * key)3337b5038d7SDag-Erling Smørgrav ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
3347b5038d7SDag-Erling Smørgrav {
335986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
3367b5038d7SDag-Erling Smørgrav unsigned char *sha1_hash;
3377b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf;
3387b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig;
3397b5038d7SDag-Erling Smørgrav
3407b5038d7SDag-Erling Smørgrav DSA_SIG *sig;
341986ba33cSDag-Erling Smørgrav const BIGNUM *R, *S;
3427b5038d7SDag-Erling Smørgrav uint8_t *data;
3437b5038d7SDag-Erling Smørgrav size_t pad;
3447b5038d7SDag-Erling Smørgrav
3457b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3467b5038d7SDag-Erling Smørgrav if (!b64sig) {
3477b5038d7SDag-Erling Smørgrav return NULL;
3487b5038d7SDag-Erling Smørgrav }
3497b5038d7SDag-Erling Smørgrav
3507b5038d7SDag-Erling Smørgrav sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
3517b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL);
3527b5038d7SDag-Erling Smørgrav if (!sha1_hash) {
3537b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
3547b5038d7SDag-Erling Smørgrav return NULL;
3557b5038d7SDag-Erling Smørgrav }
3567b5038d7SDag-Erling Smørgrav
3577b5038d7SDag-Erling Smørgrav sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
3587b5038d7SDag-Erling Smørgrav if(!sig) {
3597b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
3607b5038d7SDag-Erling Smørgrav return NULL;
3617b5038d7SDag-Erling Smørgrav }
3627b5038d7SDag-Erling Smørgrav
3637b5038d7SDag-Erling Smørgrav data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
3647b5038d7SDag-Erling Smørgrav if(!data) {
3657b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
3667b5038d7SDag-Erling Smørgrav DSA_SIG_free(sig);
3677b5038d7SDag-Erling Smørgrav return NULL;
3687b5038d7SDag-Erling Smørgrav }
3697b5038d7SDag-Erling Smørgrav
3707b5038d7SDag-Erling Smørgrav data[0] = 1;
371986ba33cSDag-Erling Smørgrav # ifdef HAVE_DSA_SIG_GET0
372986ba33cSDag-Erling Smørgrav DSA_SIG_get0(sig, &R, &S);
373986ba33cSDag-Erling Smørgrav # else
374986ba33cSDag-Erling Smørgrav R = sig->r;
375986ba33cSDag-Erling Smørgrav S = sig->s;
376986ba33cSDag-Erling Smørgrav # endif
377986ba33cSDag-Erling Smørgrav pad = 20 - (size_t) BN_num_bytes(R);
3787b5038d7SDag-Erling Smørgrav if (pad > 0) {
3797b5038d7SDag-Erling Smørgrav memset(data + 1, 0, pad);
3807b5038d7SDag-Erling Smørgrav }
381986ba33cSDag-Erling Smørgrav BN_bn2bin(R, (unsigned char *) (data + 1) + pad);
3827b5038d7SDag-Erling Smørgrav
383986ba33cSDag-Erling Smørgrav pad = 20 - (size_t) BN_num_bytes(S);
3847b5038d7SDag-Erling Smørgrav if (pad > 0) {
3857b5038d7SDag-Erling Smørgrav memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
3867b5038d7SDag-Erling Smørgrav }
387986ba33cSDag-Erling Smørgrav BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
3887b5038d7SDag-Erling Smørgrav
3897b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
3907b5038d7SDag-Erling Smørgrav 1 + 2 * SHA_DIGEST_LENGTH,
3917b5038d7SDag-Erling Smørgrav data);
3927b5038d7SDag-Erling Smørgrav
3937b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
3947b5038d7SDag-Erling Smørgrav LDNS_FREE(data);
3957b5038d7SDag-Erling Smørgrav DSA_SIG_free(sig);
3967b5038d7SDag-Erling Smørgrav
3977b5038d7SDag-Erling Smørgrav return sigdata_rdf;
398986ba33cSDag-Erling Smørgrav #else
399986ba33cSDag-Erling Smørgrav (void)to_sign; (void)key;
400986ba33cSDag-Erling Smørgrav return NULL;
401986ba33cSDag-Erling Smørgrav #endif
4027b5038d7SDag-Erling Smørgrav }
4037b5038d7SDag-Erling Smørgrav
4047b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
4057b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
406986ba33cSDag-Erling Smørgrav /** returns the number of bytes per signature-component (i.e. bits/8), or 0. */
4077b5038d7SDag-Erling Smørgrav static int
ldns_pkey_is_ecdsa(EVP_PKEY * pkey)4087b5038d7SDag-Erling Smørgrav ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
4097b5038d7SDag-Erling Smørgrav {
4107b5038d7SDag-Erling Smørgrav EC_KEY* ec;
4117b5038d7SDag-Erling Smørgrav const EC_GROUP* g;
412*5afab0e5SDag-Erling Smørgrav #ifdef HAVE_EVP_PKEY_GET_BASE_ID
413*5afab0e5SDag-Erling Smørgrav if(EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC)
414*5afab0e5SDag-Erling Smørgrav return 0;
415*5afab0e5SDag-Erling Smørgrav #elif defined(HAVE_EVP_PKEY_BASE_ID)
416986ba33cSDag-Erling Smørgrav if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
4177b5038d7SDag-Erling Smørgrav return 0;
418986ba33cSDag-Erling Smørgrav #else
419*5afab0e5SDag-Erling Smørgrav if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
420986ba33cSDag-Erling Smørgrav return 0;
421986ba33cSDag-Erling Smørgrav #endif
4227b5038d7SDag-Erling Smørgrav ec = EVP_PKEY_get1_EC_KEY(pkey);
4237b5038d7SDag-Erling Smørgrav g = EC_KEY_get0_group(ec);
4247b5038d7SDag-Erling Smørgrav if(!g) {
4257b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
4267b5038d7SDag-Erling Smørgrav return 0;
4277b5038d7SDag-Erling Smørgrav }
428986ba33cSDag-Erling Smørgrav if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) {
4297b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
430986ba33cSDag-Erling Smørgrav return 32; /* 256/8 */
431986ba33cSDag-Erling Smørgrav }
432986ba33cSDag-Erling Smørgrav if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
433986ba33cSDag-Erling Smørgrav EC_KEY_free(ec);
434986ba33cSDag-Erling Smørgrav return 48; /* 384/8 */
4357b5038d7SDag-Erling Smørgrav }
4367b5038d7SDag-Erling Smørgrav /* downref the eckey, the original is still inside the pkey */
4377b5038d7SDag-Erling Smørgrav EC_KEY_free(ec);
4387b5038d7SDag-Erling Smørgrav return 0;
4397b5038d7SDag-Erling Smørgrav }
4407b5038d7SDag-Erling Smørgrav #endif /* splint */
4417b5038d7SDag-Erling Smørgrav #endif /* USE_ECDSA */
4427b5038d7SDag-Erling Smørgrav
4437b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_sign_public_evp(ldns_buffer * to_sign,EVP_PKEY * key,const EVP_MD * digest_type)4447b5038d7SDag-Erling Smørgrav ldns_sign_public_evp(ldns_buffer *to_sign,
4457b5038d7SDag-Erling Smørgrav EVP_PKEY *key,
4467b5038d7SDag-Erling Smørgrav const EVP_MD *digest_type)
4477b5038d7SDag-Erling Smørgrav {
4487b5038d7SDag-Erling Smørgrav unsigned int siglen;
449986ba33cSDag-Erling Smørgrav ldns_rdf *sigdata_rdf = NULL;
4507b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig;
451986ba33cSDag-Erling Smørgrav EVP_MD_CTX *ctx;
4527b5038d7SDag-Erling Smørgrav const EVP_MD *md_type;
4537b5038d7SDag-Erling Smørgrav int r;
4547b5038d7SDag-Erling Smørgrav
4557b5038d7SDag-Erling Smørgrav siglen = 0;
4567b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
4577b5038d7SDag-Erling Smørgrav if (!b64sig) {
4587b5038d7SDag-Erling Smørgrav return NULL;
4597b5038d7SDag-Erling Smørgrav }
4607b5038d7SDag-Erling Smørgrav
4617b5038d7SDag-Erling Smørgrav /* initializes a signing context */
4627b5038d7SDag-Erling Smørgrav md_type = digest_type;
463*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED25519
464*5afab0e5SDag-Erling Smørgrav if(EVP_PKEY_id(key) == NID_ED25519) {
465*5afab0e5SDag-Erling Smørgrav /* digest must be NULL for ED25519 sign and verify */
466*5afab0e5SDag-Erling Smørgrav md_type = NULL;
467*5afab0e5SDag-Erling Smørgrav } else
468*5afab0e5SDag-Erling Smørgrav #endif
469*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED448
470*5afab0e5SDag-Erling Smørgrav if(EVP_PKEY_id(key) == NID_ED448) {
471*5afab0e5SDag-Erling Smørgrav md_type = NULL;
472*5afab0e5SDag-Erling Smørgrav } else
473*5afab0e5SDag-Erling Smørgrav #endif
4747b5038d7SDag-Erling Smørgrav if(!md_type) {
475*5afab0e5SDag-Erling Smørgrav /* unknown message digest */
4767b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
4777b5038d7SDag-Erling Smørgrav return NULL;
4787b5038d7SDag-Erling Smørgrav }
4797b5038d7SDag-Erling Smørgrav
480986ba33cSDag-Erling Smørgrav #ifdef HAVE_EVP_MD_CTX_NEW
481986ba33cSDag-Erling Smørgrav ctx = EVP_MD_CTX_new();
482986ba33cSDag-Erling Smørgrav #else
483986ba33cSDag-Erling Smørgrav ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
484986ba33cSDag-Erling Smørgrav if(ctx) EVP_MD_CTX_init(ctx);
485986ba33cSDag-Erling Smørgrav #endif
486986ba33cSDag-Erling Smørgrav if(!ctx) {
4877b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
4887b5038d7SDag-Erling Smørgrav return NULL;
4897b5038d7SDag-Erling Smørgrav }
4907b5038d7SDag-Erling Smørgrav
491*5afab0e5SDag-Erling Smørgrav #if defined(USE_ED25519) || defined(USE_ED448)
492*5afab0e5SDag-Erling Smørgrav if(md_type == NULL) {
493*5afab0e5SDag-Erling Smørgrav /* for these methods we must use the one-shot DigestSign */
494*5afab0e5SDag-Erling Smørgrav r = EVP_DigestSignInit(ctx, NULL, md_type, NULL, key);
495*5afab0e5SDag-Erling Smørgrav if(r == 1) {
496*5afab0e5SDag-Erling Smørgrav size_t siglen_sizet = ldns_buffer_capacity(b64sig);
497*5afab0e5SDag-Erling Smørgrav r = EVP_DigestSign(ctx,
498*5afab0e5SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(b64sig),
499*5afab0e5SDag-Erling Smørgrav &siglen_sizet,
500*5afab0e5SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(to_sign),
501*5afab0e5SDag-Erling Smørgrav ldns_buffer_position(to_sign));
502*5afab0e5SDag-Erling Smørgrav siglen = (unsigned int)siglen_sizet;
503*5afab0e5SDag-Erling Smørgrav }
504*5afab0e5SDag-Erling Smørgrav } else {
505*5afab0e5SDag-Erling Smørgrav #else
506*5afab0e5SDag-Erling Smørgrav r = 0;
507*5afab0e5SDag-Erling Smørgrav if(md_type != NULL) {
508*5afab0e5SDag-Erling Smørgrav #endif
509986ba33cSDag-Erling Smørgrav r = EVP_SignInit(ctx, md_type);
510986ba33cSDag-Erling Smørgrav if(r == 1) {
511986ba33cSDag-Erling Smørgrav r = EVP_SignUpdate(ctx, (unsigned char*)
512986ba33cSDag-Erling Smørgrav ldns_buffer_begin(to_sign),
513986ba33cSDag-Erling Smørgrav ldns_buffer_position(to_sign));
514986ba33cSDag-Erling Smørgrav }
515986ba33cSDag-Erling Smørgrav if(r == 1) {
516986ba33cSDag-Erling Smørgrav r = EVP_SignFinal(ctx, (unsigned char*)
517986ba33cSDag-Erling Smørgrav ldns_buffer_begin(b64sig), &siglen, key);
518*5afab0e5SDag-Erling Smørgrav }
519986ba33cSDag-Erling Smørgrav }
520986ba33cSDag-Erling Smørgrav if(r != 1) {
521986ba33cSDag-Erling Smørgrav ldns_buffer_free(b64sig);
522986ba33cSDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx);
523986ba33cSDag-Erling Smørgrav return NULL;
524986ba33cSDag-Erling Smørgrav }
525986ba33cSDag-Erling Smørgrav
526986ba33cSDag-Erling Smørgrav /* OpenSSL output is different, convert it */
527986ba33cSDag-Erling Smørgrav r = 0;
528986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
529986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
530986ba33cSDag-Erling Smørgrav /* unfortunately, OpenSSL output is different from DNS DSA format */
531*5afab0e5SDag-Erling Smørgrav # ifdef HAVE_EVP_PKEY_GET_BASE_ID
532*5afab0e5SDag-Erling Smørgrav if (EVP_PKEY_get_base_id(key) == EVP_PKEY_DSA) {
533*5afab0e5SDag-Erling Smørgrav # elif defined(HAVE_EVP_PKEY_BASE_ID)
534986ba33cSDag-Erling Smørgrav if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) {
535986ba33cSDag-Erling Smørgrav # else
536986ba33cSDag-Erling Smørgrav if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
537986ba33cSDag-Erling Smørgrav # endif
538986ba33cSDag-Erling Smørgrav r = 1;
539986ba33cSDag-Erling Smørgrav sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
540986ba33cSDag-Erling Smørgrav }
541986ba33cSDag-Erling Smørgrav #endif
542986ba33cSDag-Erling Smørgrav #endif
543*5afab0e5SDag-Erling Smørgrav #if defined(USE_ECDSA)
544986ba33cSDag-Erling Smørgrav if(
545*5afab0e5SDag-Erling Smørgrav # ifdef HAVE_EVP_PKEY_GET_BASE_ID
546*5afab0e5SDag-Erling Smørgrav EVP_PKEY_get_base_id(key)
547*5afab0e5SDag-Erling Smørgrav # elif defined(HAVE_EVP_PKEY_BASE_ID)
548986ba33cSDag-Erling Smørgrav EVP_PKEY_base_id(key)
549986ba33cSDag-Erling Smørgrav # else
550986ba33cSDag-Erling Smørgrav EVP_PKEY_type(key->type)
551986ba33cSDag-Erling Smørgrav # endif
552986ba33cSDag-Erling Smørgrav == EVP_PKEY_EC) {
553986ba33cSDag-Erling Smørgrav # ifdef USE_ECDSA
554986ba33cSDag-Erling Smørgrav if(ldns_pkey_is_ecdsa(key)) {
555986ba33cSDag-Erling Smørgrav r = 1;
556986ba33cSDag-Erling Smørgrav sigdata_rdf = ldns_convert_ecdsa_rrsig_asn1len2rdf(
557986ba33cSDag-Erling Smørgrav b64sig, (long)siglen, ldns_pkey_is_ecdsa(key));
558986ba33cSDag-Erling Smørgrav }
559986ba33cSDag-Erling Smørgrav # endif /* USE_ECDSA */
560986ba33cSDag-Erling Smørgrav }
561986ba33cSDag-Erling Smørgrav #endif /* PKEY_EC */
562986ba33cSDag-Erling Smørgrav if(r == 0) {
5637b5038d7SDag-Erling Smørgrav /* ok output for other types is the same */
5647b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
5657b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig));
5667b5038d7SDag-Erling Smørgrav }
5677b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
568986ba33cSDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx);
5697b5038d7SDag-Erling Smørgrav return sigdata_rdf;
5707b5038d7SDag-Erling Smørgrav }
5717b5038d7SDag-Erling Smørgrav
5727b5038d7SDag-Erling Smørgrav ldns_rdf *
5737b5038d7SDag-Erling Smørgrav ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
5747b5038d7SDag-Erling Smørgrav {
5757b5038d7SDag-Erling Smørgrav unsigned char *sha1_hash;
5767b5038d7SDag-Erling Smørgrav unsigned int siglen;
5777b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf;
5787b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig;
5797b5038d7SDag-Erling Smørgrav int result;
5807b5038d7SDag-Erling Smørgrav
5817b5038d7SDag-Erling Smørgrav siglen = 0;
5827b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
5837b5038d7SDag-Erling Smørgrav if (!b64sig) {
5847b5038d7SDag-Erling Smørgrav return NULL;
5857b5038d7SDag-Erling Smørgrav }
5867b5038d7SDag-Erling Smørgrav
5877b5038d7SDag-Erling Smørgrav sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
5887b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL);
5897b5038d7SDag-Erling Smørgrav if (!sha1_hash) {
5907b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
5917b5038d7SDag-Erling Smørgrav return NULL;
5927b5038d7SDag-Erling Smørgrav }
5937b5038d7SDag-Erling Smørgrav
5947b5038d7SDag-Erling Smørgrav result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
5957b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(b64sig),
5967b5038d7SDag-Erling Smørgrav &siglen, key);
5977b5038d7SDag-Erling Smørgrav if (result != 1) {
5982787e39aSDag-Erling Smørgrav ldns_buffer_free(b64sig);
5997b5038d7SDag-Erling Smørgrav return NULL;
6007b5038d7SDag-Erling Smørgrav }
6017b5038d7SDag-Erling Smørgrav
6027b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
6037b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig));
6047b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig); /* can't free this buffer ?? */
6057b5038d7SDag-Erling Smørgrav return sigdata_rdf;
6067b5038d7SDag-Erling Smørgrav }
6077b5038d7SDag-Erling Smørgrav
6087b5038d7SDag-Erling Smørgrav ldns_rdf *
6097b5038d7SDag-Erling Smørgrav ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
6107b5038d7SDag-Erling Smørgrav {
6117b5038d7SDag-Erling Smørgrav unsigned char *md5_hash;
6127b5038d7SDag-Erling Smørgrav unsigned int siglen;
6137b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf;
6147b5038d7SDag-Erling Smørgrav ldns_buffer *b64sig;
6157b5038d7SDag-Erling Smørgrav
6167b5038d7SDag-Erling Smørgrav b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
6177b5038d7SDag-Erling Smørgrav if (!b64sig) {
6187b5038d7SDag-Erling Smørgrav return NULL;
6197b5038d7SDag-Erling Smørgrav }
6207b5038d7SDag-Erling Smørgrav
6217b5038d7SDag-Erling Smørgrav md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
6227b5038d7SDag-Erling Smørgrav ldns_buffer_position(to_sign), NULL);
6237b5038d7SDag-Erling Smørgrav if (!md5_hash) {
6247b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
6257b5038d7SDag-Erling Smørgrav return NULL;
6267b5038d7SDag-Erling Smørgrav }
6277b5038d7SDag-Erling Smørgrav
6287b5038d7SDag-Erling Smørgrav RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
6297b5038d7SDag-Erling Smørgrav (unsigned char*)ldns_buffer_begin(b64sig),
6307b5038d7SDag-Erling Smørgrav &siglen, key);
6317b5038d7SDag-Erling Smørgrav
6327b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
6337b5038d7SDag-Erling Smørgrav ldns_buffer_begin(b64sig));
6347b5038d7SDag-Erling Smørgrav ldns_buffer_free(b64sig);
6357b5038d7SDag-Erling Smørgrav return sigdata_rdf;
6367b5038d7SDag-Erling Smørgrav }
6377b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6387b5038d7SDag-Erling Smørgrav
6397b5038d7SDag-Erling Smørgrav /**
6407b5038d7SDag-Erling Smørgrav * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
6417b5038d7SDag-Erling Smørgrav */
6427b5038d7SDag-Erling Smørgrav static ldns_status
6437b5038d7SDag-Erling Smørgrav ldns_dnssec_addresses_on_glue_list(
6447b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrset,
6457b5038d7SDag-Erling Smørgrav ldns_rr_list *glue_list)
6467b5038d7SDag-Erling Smørgrav {
6477b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rrs;
6487b5038d7SDag-Erling Smørgrav while (cur_rrset) {
6497b5038d7SDag-Erling Smørgrav if (cur_rrset->type == LDNS_RR_TYPE_A
6507b5038d7SDag-Erling Smørgrav || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
6517b5038d7SDag-Erling Smørgrav for (cur_rrs = cur_rrset->rrs;
6527b5038d7SDag-Erling Smørgrav cur_rrs;
6537b5038d7SDag-Erling Smørgrav cur_rrs = cur_rrs->next) {
6547b5038d7SDag-Erling Smørgrav if (cur_rrs->rr) {
6557b5038d7SDag-Erling Smørgrav if (!ldns_rr_list_push_rr(glue_list,
6567b5038d7SDag-Erling Smørgrav cur_rrs->rr)) {
6577b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
6587b5038d7SDag-Erling Smørgrav /* ldns_rr_list_push_rr()
6597b5038d7SDag-Erling Smørgrav * returns false when unable
6607b5038d7SDag-Erling Smørgrav * to increase the capacity
661*5afab0e5SDag-Erling Smørgrav * of the ldns_rr_list
6627b5038d7SDag-Erling Smørgrav */
6637b5038d7SDag-Erling Smørgrav }
6647b5038d7SDag-Erling Smørgrav }
6657b5038d7SDag-Erling Smørgrav }
6667b5038d7SDag-Erling Smørgrav }
6677b5038d7SDag-Erling Smørgrav cur_rrset = cur_rrset->next;
6687b5038d7SDag-Erling Smørgrav }
6697b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
6707b5038d7SDag-Erling Smørgrav }
6717b5038d7SDag-Erling Smørgrav
6727b5038d7SDag-Erling Smørgrav ldns_status
6737b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
6747b5038d7SDag-Erling Smørgrav ldns_rr_list *glue_list)
6757b5038d7SDag-Erling Smørgrav {
6767b5038d7SDag-Erling Smørgrav ldns_rbnode_t *node;
6777b5038d7SDag-Erling Smørgrav ldns_dnssec_name *name;
6787b5038d7SDag-Erling Smørgrav ldns_rdf *owner;
6797b5038d7SDag-Erling Smørgrav ldns_rdf *cut = NULL; /* keeps track of zone cuts */
6807b5038d7SDag-Erling Smørgrav /* When the cut is caused by a delegation, below_delegation will be 1.
6817b5038d7SDag-Erling Smørgrav * When caused by a DNAME, below_delegation will be 0.
6827b5038d7SDag-Erling Smørgrav */
683*5afab0e5SDag-Erling Smørgrav int below_delegation = -1; /* init suppresses compiler warning */
6847b5038d7SDag-Erling Smørgrav ldns_status s;
6857b5038d7SDag-Erling Smørgrav
6867b5038d7SDag-Erling Smørgrav if (!zone || !zone->names) {
6877b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL;
6887b5038d7SDag-Erling Smørgrav }
6897b5038d7SDag-Erling Smørgrav for (node = ldns_rbtree_first(zone->names);
6907b5038d7SDag-Erling Smørgrav node != LDNS_RBTREE_NULL;
6917b5038d7SDag-Erling Smørgrav node = ldns_rbtree_next(node)) {
6927b5038d7SDag-Erling Smørgrav name = (ldns_dnssec_name *) node->data;
6937b5038d7SDag-Erling Smørgrav owner = ldns_dnssec_name_name(name);
6947b5038d7SDag-Erling Smørgrav
6957b5038d7SDag-Erling Smørgrav if (cut) {
6967b5038d7SDag-Erling Smørgrav /* The previous node was a zone cut, or a subdomain
6977b5038d7SDag-Erling Smørgrav * below a zone cut. Is this node (still) a subdomain
6987b5038d7SDag-Erling Smørgrav * below the cut? Then the name is occluded. Unless
6997b5038d7SDag-Erling Smørgrav * the name contains a SOA, after which we are
7007b5038d7SDag-Erling Smørgrav * authoritative again.
7017b5038d7SDag-Erling Smørgrav *
7027b5038d7SDag-Erling Smørgrav * FIXME! If there are labels in between the SOA and
7037b5038d7SDag-Erling Smørgrav * the cut, going from the authoritative space (below
7047b5038d7SDag-Erling Smørgrav * the SOA) up into occluded space again, will not be
705*5afab0e5SDag-Erling Smørgrav * detected with the construct below!
7067b5038d7SDag-Erling Smørgrav */
7077b5038d7SDag-Erling Smørgrav if (ldns_dname_is_subdomain(owner, cut) &&
7087b5038d7SDag-Erling Smørgrav !ldns_dnssec_rrsets_contains_type(
7097b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_SOA)) {
7107b5038d7SDag-Erling Smørgrav
7117b5038d7SDag-Erling Smørgrav if (below_delegation && glue_list) {
7127b5038d7SDag-Erling Smørgrav s = ldns_dnssec_addresses_on_glue_list(
7137b5038d7SDag-Erling Smørgrav name->rrsets, glue_list);
7147b5038d7SDag-Erling Smørgrav if (s != LDNS_STATUS_OK) {
7157b5038d7SDag-Erling Smørgrav return s;
7167b5038d7SDag-Erling Smørgrav }
7177b5038d7SDag-Erling Smørgrav }
7187b5038d7SDag-Erling Smørgrav name->is_glue = true; /* Mark occluded name! */
7197b5038d7SDag-Erling Smørgrav continue;
7207b5038d7SDag-Erling Smørgrav } else {
7217b5038d7SDag-Erling Smørgrav cut = NULL;
7227b5038d7SDag-Erling Smørgrav }
7237b5038d7SDag-Erling Smørgrav }
7247b5038d7SDag-Erling Smørgrav
7257b5038d7SDag-Erling Smørgrav /* The node is not below a zone cut. Is it a zone cut itself?
7267b5038d7SDag-Erling Smørgrav * Everything below a SOA is authoritative of course; Except
7277b5038d7SDag-Erling Smørgrav * when the name also contains a DNAME :).
7287b5038d7SDag-Erling Smørgrav */
7297b5038d7SDag-Erling Smørgrav if (ldns_dnssec_rrsets_contains_type(
7307b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_NS)
7317b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type(
7327b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_SOA)) {
7337b5038d7SDag-Erling Smørgrav cut = owner;
7347b5038d7SDag-Erling Smørgrav below_delegation = 1;
7357b5038d7SDag-Erling Smørgrav if (glue_list) { /* record glue on the zone cut */
7367b5038d7SDag-Erling Smørgrav s = ldns_dnssec_addresses_on_glue_list(
7377b5038d7SDag-Erling Smørgrav name->rrsets, glue_list);
7387b5038d7SDag-Erling Smørgrav if (s != LDNS_STATUS_OK) {
7397b5038d7SDag-Erling Smørgrav return s;
7407b5038d7SDag-Erling Smørgrav }
7417b5038d7SDag-Erling Smørgrav }
7427b5038d7SDag-Erling Smørgrav } else if (ldns_dnssec_rrsets_contains_type(
7437b5038d7SDag-Erling Smørgrav name->rrsets, LDNS_RR_TYPE_DNAME)) {
7447b5038d7SDag-Erling Smørgrav cut = owner;
7457b5038d7SDag-Erling Smørgrav below_delegation = 0;
7467b5038d7SDag-Erling Smørgrav }
7477b5038d7SDag-Erling Smørgrav }
7487b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
7497b5038d7SDag-Erling Smørgrav }
7507b5038d7SDag-Erling Smørgrav
7517b5038d7SDag-Erling Smørgrav ldns_status
7527b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
7537b5038d7SDag-Erling Smørgrav {
7547b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
7557b5038d7SDag-Erling Smørgrav }
7567b5038d7SDag-Erling Smørgrav
7577b5038d7SDag-Erling Smørgrav ldns_rbnode_t *
7587b5038d7SDag-Erling Smørgrav ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
7597b5038d7SDag-Erling Smørgrav {
7607b5038d7SDag-Erling Smørgrav ldns_rbnode_t *next_node = NULL;
7617b5038d7SDag-Erling Smørgrav ldns_dnssec_name *next_name = NULL;
7627b5038d7SDag-Erling Smørgrav bool done = false;
7637b5038d7SDag-Erling Smørgrav
7647b5038d7SDag-Erling Smørgrav if (node == LDNS_RBTREE_NULL) {
7657b5038d7SDag-Erling Smørgrav return NULL;
7667b5038d7SDag-Erling Smørgrav }
7677b5038d7SDag-Erling Smørgrav next_node = node;
7687b5038d7SDag-Erling Smørgrav while (!done) {
7697b5038d7SDag-Erling Smørgrav if (next_node == LDNS_RBTREE_NULL) {
7707b5038d7SDag-Erling Smørgrav return NULL;
7717b5038d7SDag-Erling Smørgrav } else {
7727b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)next_node->data;
7737b5038d7SDag-Erling Smørgrav if (!next_name->is_glue) {
7747b5038d7SDag-Erling Smørgrav done = true;
7757b5038d7SDag-Erling Smørgrav } else {
7767b5038d7SDag-Erling Smørgrav next_node = ldns_rbtree_next(next_node);
7777b5038d7SDag-Erling Smørgrav }
7787b5038d7SDag-Erling Smørgrav }
7797b5038d7SDag-Erling Smørgrav }
7807b5038d7SDag-Erling Smørgrav return next_node;
7817b5038d7SDag-Erling Smørgrav }
7827b5038d7SDag-Erling Smørgrav
7837b5038d7SDag-Erling Smørgrav ldns_status
7847b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
7857b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs)
7867b5038d7SDag-Erling Smørgrav {
7877b5038d7SDag-Erling Smørgrav
7887b5038d7SDag-Erling Smørgrav ldns_rbnode_t *first_node, *cur_node, *next_node;
7897b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name, *next_name;
7907b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr;
7917b5038d7SDag-Erling Smørgrav uint32_t nsec_ttl;
7927b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *soa;
7937b5038d7SDag-Erling Smørgrav
794*5afab0e5SDag-Erling Smørgrav /* The TTL value for any NSEC RR SHOULD be the same TTL value as the
795*5afab0e5SDag-Erling Smørgrav * lesser of the MINIMUM field of the SOA record and the TTL of the SOA
796*5afab0e5SDag-Erling Smørgrav * itself. This matches the definition of the TTL for negative
797*5afab0e5SDag-Erling Smørgrav * responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
798*5afab0e5SDag-Erling Smørgrav * RFC4035 Section 2.3)
7997b5038d7SDag-Erling Smørgrav */
8007b5038d7SDag-Erling Smørgrav soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
8017b5038d7SDag-Erling Smørgrav
8027b5038d7SDag-Erling Smørgrav /* did the caller actually set it? if not,
8037b5038d7SDag-Erling Smørgrav * fall back to default ttl
8047b5038d7SDag-Erling Smørgrav */
805*5afab0e5SDag-Erling Smørgrav if (soa && soa->rrs && soa->rrs->rr) {
806*5afab0e5SDag-Erling Smørgrav ldns_rr *soa_rr = soa->rrs->rr;
807*5afab0e5SDag-Erling Smørgrav ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
808*5afab0e5SDag-Erling Smørgrav
809*5afab0e5SDag-Erling Smørgrav nsec_ttl = min_rdf == NULL
810*5afab0e5SDag-Erling Smørgrav || ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
811*5afab0e5SDag-Erling Smørgrav ? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
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 first_node = ldns_dnssec_name_node_next_nonglue(
8177b5038d7SDag-Erling Smørgrav ldns_rbtree_first(zone->names));
8187b5038d7SDag-Erling Smørgrav cur_node = first_node;
8197b5038d7SDag-Erling Smørgrav if (cur_node) {
8207b5038d7SDag-Erling Smørgrav next_node = ldns_dnssec_name_node_next_nonglue(
8217b5038d7SDag-Erling Smørgrav ldns_rbtree_next(cur_node));
8227b5038d7SDag-Erling Smørgrav } else {
8237b5038d7SDag-Erling Smørgrav next_node = NULL;
8247b5038d7SDag-Erling Smørgrav }
8257b5038d7SDag-Erling Smørgrav
8267b5038d7SDag-Erling Smørgrav while (cur_node && next_node) {
8277b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *)cur_node->data;
8287b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)next_node->data;
8297b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec(cur_name,
8307b5038d7SDag-Erling Smørgrav next_name,
8317b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC);
8327b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl);
8337b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
8347b5038d7SDag-Erling Smørgrav ldns_rr_free(nsec_rr);
8357b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
8367b5038d7SDag-Erling Smørgrav }
8377b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr);
8387b5038d7SDag-Erling Smørgrav cur_node = next_node;
8397b5038d7SDag-Erling Smørgrav if (cur_node) {
8407b5038d7SDag-Erling Smørgrav next_node = ldns_dnssec_name_node_next_nonglue(
8417b5038d7SDag-Erling Smørgrav ldns_rbtree_next(cur_node));
8427b5038d7SDag-Erling Smørgrav }
8437b5038d7SDag-Erling Smørgrav }
8447b5038d7SDag-Erling Smørgrav
8457b5038d7SDag-Erling Smørgrav if (cur_node && !next_node) {
8467b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *)cur_node->data;
8477b5038d7SDag-Erling Smørgrav next_name = (ldns_dnssec_name *)first_node->data;
8487b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec(cur_name,
8497b5038d7SDag-Erling Smørgrav next_name,
8507b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC);
8517b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl);
8527b5038d7SDag-Erling Smørgrav if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
8537b5038d7SDag-Erling Smørgrav ldns_rr_free(nsec_rr);
8547b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
8557b5038d7SDag-Erling Smørgrav }
8567b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr);
8577b5038d7SDag-Erling Smørgrav } else {
8587b5038d7SDag-Erling Smørgrav printf("error\n");
8597b5038d7SDag-Erling Smørgrav }
8607b5038d7SDag-Erling Smørgrav
8617b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
8627b5038d7SDag-Erling Smørgrav }
8637b5038d7SDag-Erling Smørgrav
8647b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
86517d15b25SDag-Erling Smørgrav static void
86617d15b25SDag-Erling Smørgrav ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
86717d15b25SDag-Erling Smørgrav (void) arg;
86817d15b25SDag-Erling Smørgrav LDNS_FREE(node);
86917d15b25SDag-Erling Smørgrav }
87017d15b25SDag-Erling Smørgrav
8717b5038d7SDag-Erling Smørgrav static ldns_status
8727b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
8737b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
8747b5038d7SDag-Erling Smørgrav uint8_t algorithm,
8757b5038d7SDag-Erling Smørgrav uint8_t flags,
8767b5038d7SDag-Erling Smørgrav uint16_t iterations,
8777b5038d7SDag-Erling Smørgrav uint8_t salt_length,
8787b5038d7SDag-Erling Smørgrav uint8_t *salt,
8797b5038d7SDag-Erling Smørgrav ldns_rbtree_t **map)
8807b5038d7SDag-Erling Smørgrav {
8817b5038d7SDag-Erling Smørgrav ldns_rbnode_t *first_name_node;
8827b5038d7SDag-Erling Smørgrav ldns_rbnode_t *current_name_node;
8837b5038d7SDag-Erling Smørgrav ldns_dnssec_name *current_name;
8847b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK;
8857b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr;
8867b5038d7SDag-Erling Smørgrav ldns_rr_list *nsec3_list;
8877b5038d7SDag-Erling Smørgrav uint32_t nsec_ttl;
8887b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *soa;
8897b5038d7SDag-Erling Smørgrav ldns_rbnode_t *hashmap_node;
8907b5038d7SDag-Erling Smørgrav
8917b5038d7SDag-Erling Smørgrav if (!zone || !new_rrs || !zone->names) {
8927b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
8937b5038d7SDag-Erling Smørgrav }
8947b5038d7SDag-Erling Smørgrav
895*5afab0e5SDag-Erling Smørgrav /* The TTL value for any NSEC RR SHOULD be the same TTL value as the
896*5afab0e5SDag-Erling Smørgrav * lesser of the MINIMUM field of the SOA record and the TTL of the SOA
897*5afab0e5SDag-Erling Smørgrav * itself. This matches the definition of the TTL for negative
898*5afab0e5SDag-Erling Smørgrav * responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
899*5afab0e5SDag-Erling Smørgrav * RFC4035 Section 2.3)
9007b5038d7SDag-Erling Smørgrav */
9017b5038d7SDag-Erling Smørgrav soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
9027b5038d7SDag-Erling Smørgrav
9037b5038d7SDag-Erling Smørgrav /* did the caller actually set it? if not,
9047b5038d7SDag-Erling Smørgrav * fall back to default ttl
9057b5038d7SDag-Erling Smørgrav */
906*5afab0e5SDag-Erling Smørgrav if (soa && soa->rrs && soa->rrs->rr) {
907*5afab0e5SDag-Erling Smørgrav ldns_rr *soa_rr = soa->rrs->rr;
908*5afab0e5SDag-Erling Smørgrav ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
909*5afab0e5SDag-Erling Smørgrav
910*5afab0e5SDag-Erling Smørgrav nsec_ttl = min_rdf == NULL
911*5afab0e5SDag-Erling Smørgrav || ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
912*5afab0e5SDag-Erling Smørgrav ? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
9137b5038d7SDag-Erling Smørgrav } else {
9147b5038d7SDag-Erling Smørgrav nsec_ttl = LDNS_DEFAULT_TTL;
9157b5038d7SDag-Erling Smørgrav }
9167b5038d7SDag-Erling Smørgrav
917986ba33cSDag-Erling Smørgrav if (ldns_rdf_size(zone->soa->name) > 222) {
918986ba33cSDag-Erling Smørgrav return LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW;
919986ba33cSDag-Erling Smørgrav }
920986ba33cSDag-Erling Smørgrav
92117d15b25SDag-Erling Smørgrav if (zone->hashed_names) {
92217d15b25SDag-Erling Smørgrav ldns_traverse_postorder(zone->hashed_names,
92317d15b25SDag-Erling Smørgrav ldns_hashed_names_node_free, NULL);
92417d15b25SDag-Erling Smørgrav LDNS_FREE(zone->hashed_names);
9257b5038d7SDag-Erling Smørgrav }
92617d15b25SDag-Erling Smørgrav zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
92717d15b25SDag-Erling Smørgrav if (zone->hashed_names && map) {
92817d15b25SDag-Erling Smørgrav *map = zone->hashed_names;
92917d15b25SDag-Erling Smørgrav }
9307b5038d7SDag-Erling Smørgrav
9317b5038d7SDag-Erling Smørgrav first_name_node = ldns_dnssec_name_node_next_nonglue(
9327b5038d7SDag-Erling Smørgrav ldns_rbtree_first(zone->names));
9337b5038d7SDag-Erling Smørgrav
9347b5038d7SDag-Erling Smørgrav current_name_node = first_name_node;
9357b5038d7SDag-Erling Smørgrav
93617d15b25SDag-Erling Smørgrav while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
93717d15b25SDag-Erling Smørgrav result == LDNS_STATUS_OK) {
93817d15b25SDag-Erling Smørgrav
9397b5038d7SDag-Erling Smørgrav current_name = (ldns_dnssec_name *) current_name_node->data;
9407b5038d7SDag-Erling Smørgrav nsec_rr = ldns_dnssec_create_nsec3(current_name,
9417b5038d7SDag-Erling Smørgrav NULL,
9427b5038d7SDag-Erling Smørgrav zone->soa->name,
9437b5038d7SDag-Erling Smørgrav algorithm,
9447b5038d7SDag-Erling Smørgrav flags,
9457b5038d7SDag-Erling Smørgrav iterations,
9467b5038d7SDag-Erling Smørgrav salt_length,
9477b5038d7SDag-Erling Smørgrav salt);
9487b5038d7SDag-Erling Smørgrav /* by default, our nsec based generator adds rrsigs
9497b5038d7SDag-Erling Smørgrav * remove the bitmap for empty nonterminals */
9507b5038d7SDag-Erling Smørgrav if (!current_name->rrsets) {
9517b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
9527b5038d7SDag-Erling Smørgrav }
9537b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(nsec_rr, nsec_ttl);
9547b5038d7SDag-Erling Smørgrav result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
9557b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec_rr);
95617d15b25SDag-Erling Smørgrav if (ldns_rr_owner(nsec_rr)) {
9577b5038d7SDag-Erling Smørgrav hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
95817d15b25SDag-Erling Smørgrav if (hashmap_node == NULL) {
95917d15b25SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
9607b5038d7SDag-Erling Smørgrav }
96117d15b25SDag-Erling Smørgrav current_name->hashed_name =
96217d15b25SDag-Erling Smørgrav ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
96317d15b25SDag-Erling Smørgrav
96417d15b25SDag-Erling Smørgrav if (current_name->hashed_name == NULL) {
96517d15b25SDag-Erling Smørgrav LDNS_FREE(hashmap_node);
96617d15b25SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
96717d15b25SDag-Erling Smørgrav }
96817d15b25SDag-Erling Smørgrav hashmap_node->key = current_name->hashed_name;
96917d15b25SDag-Erling Smørgrav hashmap_node->data = current_name;
97017d15b25SDag-Erling Smørgrav
97117d15b25SDag-Erling Smørgrav if (! ldns_rbtree_insert(zone->hashed_names
97217d15b25SDag-Erling Smørgrav , hashmap_node)) {
97317d15b25SDag-Erling Smørgrav LDNS_FREE(hashmap_node);
9747b5038d7SDag-Erling Smørgrav }
9757b5038d7SDag-Erling Smørgrav }
9767b5038d7SDag-Erling Smørgrav current_name_node = ldns_dnssec_name_node_next_nonglue(
9777b5038d7SDag-Erling Smørgrav ldns_rbtree_next(current_name_node));
9787b5038d7SDag-Erling Smørgrav }
9797b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
9807b5038d7SDag-Erling Smørgrav return result;
9817b5038d7SDag-Erling Smørgrav }
9827b5038d7SDag-Erling Smørgrav
98317d15b25SDag-Erling Smørgrav /* Make sorted list of nsec3s (via zone->hashed_names)
98417d15b25SDag-Erling Smørgrav */
98517d15b25SDag-Erling Smørgrav nsec3_list = ldns_rr_list_new();
98617d15b25SDag-Erling Smørgrav if (nsec3_list == NULL) {
98717d15b25SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
98817d15b25SDag-Erling Smørgrav }
98917d15b25SDag-Erling Smørgrav for ( hashmap_node = ldns_rbtree_first(zone->hashed_names)
99017d15b25SDag-Erling Smørgrav ; hashmap_node != LDNS_RBTREE_NULL
99117d15b25SDag-Erling Smørgrav ; hashmap_node = ldns_rbtree_next(hashmap_node)
99217d15b25SDag-Erling Smørgrav ) {
99317d15b25SDag-Erling Smørgrav nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
99417d15b25SDag-Erling Smørgrav if (nsec_rr) {
99517d15b25SDag-Erling Smørgrav ldns_rr_list_push_rr(nsec3_list, nsec_rr);
99617d15b25SDag-Erling Smørgrav }
99717d15b25SDag-Erling Smørgrav }
9987b5038d7SDag-Erling Smørgrav result = ldns_dnssec_chain_nsec3_list(nsec3_list);
9997b5038d7SDag-Erling Smørgrav ldns_rr_list_free(nsec3_list);
10002787e39aSDag-Erling Smørgrav
10017b5038d7SDag-Erling Smørgrav return result;
10027b5038d7SDag-Erling Smørgrav }
10037b5038d7SDag-Erling Smørgrav
10047b5038d7SDag-Erling Smørgrav ldns_status
10057b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
10067b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
10077b5038d7SDag-Erling Smørgrav uint8_t algorithm,
10087b5038d7SDag-Erling Smørgrav uint8_t flags,
10097b5038d7SDag-Erling Smørgrav uint16_t iterations,
10107b5038d7SDag-Erling Smørgrav uint8_t salt_length,
10117b5038d7SDag-Erling Smørgrav uint8_t *salt)
10127b5038d7SDag-Erling Smørgrav {
10137b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
10147b5038d7SDag-Erling Smørgrav flags, iterations, salt_length, salt, NULL);
10157b5038d7SDag-Erling Smørgrav
10167b5038d7SDag-Erling Smørgrav }
10177b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
10187b5038d7SDag-Erling Smørgrav
10197b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *
10207b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
10217b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(ldns_key_list *key_list)
10227b5038d7SDag-Erling Smørgrav , int (*func)(ldns_rr *, void *)
10237b5038d7SDag-Erling Smørgrav , void *arg
10247b5038d7SDag-Erling Smørgrav )
10257b5038d7SDag-Erling Smørgrav {
10267b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *base_rrs = signatures;
10277b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rr = base_rrs;
10287b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *prev_rr = NULL;
10297b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *next_rr;
10307b5038d7SDag-Erling Smørgrav
10317b5038d7SDag-Erling Smørgrav uint16_t keytag;
10327b5038d7SDag-Erling Smørgrav size_t i;
10337b5038d7SDag-Erling Smørgrav
10347b5038d7SDag-Erling Smørgrav if (!cur_rr) {
10357b5038d7SDag-Erling Smørgrav switch(func(NULL, arg)) {
10367b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_ADD_NEW:
10377b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_ADD_NEW:
10387b5038d7SDag-Erling Smørgrav break;
10397b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_NO_ADD:
10407b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_NO_ADD:
10417b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, false);
10427b5038d7SDag-Erling Smørgrav break;
10437b5038d7SDag-Erling Smørgrav default:
104417d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
10457b5038d7SDag-Erling Smørgrav fprintf(stderr, "[XX] unknown return value from callback\n");
104617d15b25SDag-Erling Smørgrav #endif
10477b5038d7SDag-Erling Smørgrav break;
10487b5038d7SDag-Erling Smørgrav }
10497b5038d7SDag-Erling Smørgrav return NULL;
10507b5038d7SDag-Erling Smørgrav }
10517b5038d7SDag-Erling Smørgrav (void)func(cur_rr->rr, arg);
10527b5038d7SDag-Erling Smørgrav
10537b5038d7SDag-Erling Smørgrav while (cur_rr) {
10547b5038d7SDag-Erling Smørgrav next_rr = cur_rr->next;
10557b5038d7SDag-Erling Smørgrav
10567b5038d7SDag-Erling Smørgrav switch (func(cur_rr->rr, arg)) {
10577b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_ADD_NEW:
10587b5038d7SDag-Erling Smørgrav prev_rr = cur_rr;
10597b5038d7SDag-Erling Smørgrav break;
10607b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_LEAVE_NO_ADD:
10617b5038d7SDag-Erling Smørgrav keytag = ldns_rdf2native_int16(
10627b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_rr->rr));
10637b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
10647b5038d7SDag-Erling Smørgrav if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
10657b5038d7SDag-Erling Smørgrav keytag) {
10667b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i),
10677b5038d7SDag-Erling Smørgrav false);
10687b5038d7SDag-Erling Smørgrav }
10697b5038d7SDag-Erling Smørgrav }
10707b5038d7SDag-Erling Smørgrav prev_rr = cur_rr;
10717b5038d7SDag-Erling Smørgrav break;
10727b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_NO_ADD:
10737b5038d7SDag-Erling Smørgrav keytag = ldns_rdf2native_int16(
10747b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_keytag(cur_rr->rr));
10757b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
10767b5038d7SDag-Erling Smørgrav if (ldns_key_keytag(ldns_key_list_key(key_list, i))
10777b5038d7SDag-Erling Smørgrav == keytag) {
10787b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(key_list, i),
10797b5038d7SDag-Erling Smørgrav false);
10807b5038d7SDag-Erling Smørgrav }
10817b5038d7SDag-Erling Smørgrav }
10827b5038d7SDag-Erling Smørgrav if (prev_rr) {
10837b5038d7SDag-Erling Smørgrav prev_rr->next = next_rr;
10847b5038d7SDag-Erling Smørgrav } else {
10857b5038d7SDag-Erling Smørgrav base_rrs = next_rr;
10867b5038d7SDag-Erling Smørgrav }
10877b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rr);
10887b5038d7SDag-Erling Smørgrav break;
10897b5038d7SDag-Erling Smørgrav case LDNS_SIGNATURE_REMOVE_ADD_NEW:
10907b5038d7SDag-Erling Smørgrav if (prev_rr) {
10917b5038d7SDag-Erling Smørgrav prev_rr->next = next_rr;
10927b5038d7SDag-Erling Smørgrav } else {
10937b5038d7SDag-Erling Smørgrav base_rrs = next_rr;
10947b5038d7SDag-Erling Smørgrav }
10957b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rr);
10967b5038d7SDag-Erling Smørgrav break;
10977b5038d7SDag-Erling Smørgrav default:
109817d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
10997b5038d7SDag-Erling Smørgrav fprintf(stderr, "[XX] unknown return value from callback\n");
110017d15b25SDag-Erling Smørgrav #endif
11017b5038d7SDag-Erling Smørgrav break;
11027b5038d7SDag-Erling Smørgrav }
11037b5038d7SDag-Erling Smørgrav cur_rr = next_rr;
11047b5038d7SDag-Erling Smørgrav }
11057b5038d7SDag-Erling Smørgrav
11067b5038d7SDag-Erling Smørgrav return base_rrs;
11077b5038d7SDag-Erling Smørgrav }
11087b5038d7SDag-Erling Smørgrav
11097b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
11107b5038d7SDag-Erling Smørgrav ldns_status
11117b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
11127b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
11137b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
11147b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void*),
11157b5038d7SDag-Erling Smørgrav void *arg)
11167b5038d7SDag-Erling Smørgrav {
11177b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
11187b5038d7SDag-Erling Smørgrav func, arg, 0);
11197b5038d7SDag-Erling Smørgrav }
11207b5038d7SDag-Erling Smørgrav
11217b5038d7SDag-Erling Smørgrav /** If there are KSKs use only them and mark ZSKs unused */
11227b5038d7SDag-Erling Smørgrav static void
1123986ba33cSDag-Erling Smørgrav ldns_key_list_filter_for_dnskey(ldns_key_list *key_list, int flags)
11247b5038d7SDag-Erling Smørgrav {
1125986ba33cSDag-Erling Smørgrav bool algos[256]
1126986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
1127986ba33cSDag-Erling Smørgrav = { false }
1128986ba33cSDag-Erling Smørgrav #endif
1129986ba33cSDag-Erling Smørgrav ;
1130986ba33cSDag-Erling Smørgrav ldns_signing_algorithm saw_ksk = 0;
1131986ba33cSDag-Erling Smørgrav ldns_key *key;
11327b5038d7SDag-Erling Smørgrav size_t i;
1133986ba33cSDag-Erling Smørgrav
1134986ba33cSDag-Erling Smørgrav if (!ldns_key_list_key_count(key_list))
1135986ba33cSDag-Erling Smørgrav return;
1136986ba33cSDag-Erling Smørgrav
1137*5afab0e5SDag-Erling Smørgrav /* Mark all KSKs */
1138986ba33cSDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1139986ba33cSDag-Erling Smørgrav key = ldns_key_list_key(key_list, i);
1140*5afab0e5SDag-Erling Smørgrav if ((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1141*5afab0e5SDag-Erling Smørgrav if (!saw_ksk)
1142986ba33cSDag-Erling Smørgrav saw_ksk = ldns_key_algorithm(key);
1143986ba33cSDag-Erling Smørgrav algos[ldns_key_algorithm(key)] = true;
11447b5038d7SDag-Erling Smørgrav }
1145*5afab0e5SDag-Erling Smørgrav }
11467b5038d7SDag-Erling Smørgrav if (!saw_ksk)
1147*5afab0e5SDag-Erling Smørgrav return; /* No KSKs means sign using all ZSKs */
1148986ba33cSDag-Erling Smørgrav
1149*5afab0e5SDag-Erling Smørgrav /* Deselect the ZSKs so they do not sign DNSKEY RRs.
1150*5afab0e5SDag-Erling Smørgrav * Except with the LDNS_SIGN_WITH_ALL_ALGORITHMS flag, then use it,
1151*5afab0e5SDag-Erling Smørgrav * but only if it has an algorithm for which there is no KSK
1152*5afab0e5SDag-Erling Smørgrav */
1153986ba33cSDag-Erling Smørgrav for (i =0; i < ldns_key_list_key_count(key_list); i++) {
1154986ba33cSDag-Erling Smørgrav key = ldns_key_list_key(key_list, i);
1155986ba33cSDag-Erling Smørgrav if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1156986ba33cSDag-Erling Smørgrav /* We have a ZSK.
1157986ba33cSDag-Erling Smørgrav * Still use it if it has a unique algorithm though!
1158986ba33cSDag-Erling Smørgrav */
1159986ba33cSDag-Erling Smørgrav if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
1160*5afab0e5SDag-Erling Smørgrav !algos[ldns_key_algorithm(key)])
1161*5afab0e5SDag-Erling Smørgrav algos[ldns_key_algorithm(key)] = true;
1162986ba33cSDag-Erling Smørgrav else
1163986ba33cSDag-Erling Smørgrav ldns_key_set_use(key, 0);
1164986ba33cSDag-Erling Smørgrav }
1165986ba33cSDag-Erling Smørgrav }
11667b5038d7SDag-Erling Smørgrav }
11677b5038d7SDag-Erling Smørgrav
1168*5afab0e5SDag-Erling Smørgrav /** If there are no ZSKs use KSKs as ZSK too */
11697b5038d7SDag-Erling Smørgrav static void
1170986ba33cSDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list, int flags)
11717b5038d7SDag-Erling Smørgrav {
1172986ba33cSDag-Erling Smørgrav bool algos[256]
1173986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
1174986ba33cSDag-Erling Smørgrav = { false }
1175986ba33cSDag-Erling Smørgrav #endif
1176986ba33cSDag-Erling Smørgrav ;
1177986ba33cSDag-Erling Smørgrav ldns_signing_algorithm saw_zsk = 0;
1178986ba33cSDag-Erling Smørgrav ldns_key *key;
11797b5038d7SDag-Erling Smørgrav size_t i;
1180986ba33cSDag-Erling Smørgrav
1181986ba33cSDag-Erling Smørgrav if (!ldns_key_list_key_count(key_list))
1182986ba33cSDag-Erling Smørgrav return;
1183986ba33cSDag-Erling Smørgrav
1184*5afab0e5SDag-Erling Smørgrav /* Mark all ZSKs */
1185986ba33cSDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1186986ba33cSDag-Erling Smørgrav key = ldns_key_list_key(key_list, i);
1187*5afab0e5SDag-Erling Smørgrav if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1188*5afab0e5SDag-Erling Smørgrav if (!saw_zsk)
1189986ba33cSDag-Erling Smørgrav saw_zsk = ldns_key_algorithm(key);
1190986ba33cSDag-Erling Smørgrav algos[ldns_key_algorithm(key)] = true;
11917b5038d7SDag-Erling Smørgrav }
1192*5afab0e5SDag-Erling Smørgrav }
11937b5038d7SDag-Erling Smørgrav if (!saw_zsk)
1194*5afab0e5SDag-Erling Smørgrav return; /* No ZSKs means sign using all KSKs */
1195986ba33cSDag-Erling Smørgrav
1196*5afab0e5SDag-Erling Smørgrav /* Deselect the KSKs so they do not sign non DNSKEY RRs.
1197*5afab0e5SDag-Erling Smørgrav * Except with the LDNS_SIGN_WITH_ALL_ALGORITHMS flag, then use it,
1198*5afab0e5SDag-Erling Smørgrav * but only if it has an algorithm for which there is no ZSK
1199*5afab0e5SDag-Erling Smørgrav */
1200986ba33cSDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1201986ba33cSDag-Erling Smørgrav key = ldns_key_list_key(key_list, i);
1202986ba33cSDag-Erling Smørgrav if((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1203986ba33cSDag-Erling Smørgrav /* We have a KSK.
1204986ba33cSDag-Erling Smørgrav * Still use it if it has a unique algorithm though!
1205986ba33cSDag-Erling Smørgrav */
1206986ba33cSDag-Erling Smørgrav if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
1207*5afab0e5SDag-Erling Smørgrav !algos[ldns_key_algorithm(key)])
1208*5afab0e5SDag-Erling Smørgrav algos[ldns_key_algorithm(key)] = true;
1209986ba33cSDag-Erling Smørgrav else
1210986ba33cSDag-Erling Smørgrav ldns_key_set_use(key, 0);
1211986ba33cSDag-Erling Smørgrav }
1212986ba33cSDag-Erling Smørgrav }
12137b5038d7SDag-Erling Smørgrav }
12147b5038d7SDag-Erling Smørgrav
12157b5038d7SDag-Erling Smørgrav ldns_status
12162787e39aSDag-Erling Smørgrav ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
12172787e39aSDag-Erling Smørgrav , ldns_rr_list *new_rrs
12182787e39aSDag-Erling Smørgrav , ldns_key_list *key_list
12197b5038d7SDag-Erling Smørgrav , int (*func)(ldns_rr *, void*)
12207b5038d7SDag-Erling Smørgrav , void *arg
12217b5038d7SDag-Erling Smørgrav , int flags
12227b5038d7SDag-Erling Smørgrav )
12237b5038d7SDag-Erling Smørgrav {
12247b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK;
12257b5038d7SDag-Erling Smørgrav
12267b5038d7SDag-Erling Smørgrav ldns_rbnode_t *cur_node;
12277b5038d7SDag-Erling Smørgrav ldns_rr_list *rr_list;
12287b5038d7SDag-Erling Smørgrav
12297b5038d7SDag-Erling Smørgrav ldns_dnssec_name *cur_name;
12307b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrset;
12317b5038d7SDag-Erling Smørgrav ldns_dnssec_rrs *cur_rr;
12327b5038d7SDag-Erling Smørgrav
12337b5038d7SDag-Erling Smørgrav ldns_rr_list *siglist;
12347b5038d7SDag-Erling Smørgrav
12357b5038d7SDag-Erling Smørgrav size_t i;
12367b5038d7SDag-Erling Smørgrav
12377b5038d7SDag-Erling Smørgrav int on_delegation_point = 0; /* handle partially occluded names */
12387b5038d7SDag-Erling Smørgrav
12397b5038d7SDag-Erling Smørgrav ldns_rr_list *pubkey_list = ldns_rr_list_new();
12407b5038d7SDag-Erling Smørgrav for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
12417b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr( pubkey_list
12427b5038d7SDag-Erling Smørgrav , ldns_key2rr(ldns_key_list_key(
12437b5038d7SDag-Erling Smørgrav key_list, i))
12447b5038d7SDag-Erling Smørgrav );
12457b5038d7SDag-Erling Smørgrav }
12467b5038d7SDag-Erling Smørgrav /* TODO: callback to see is list should be signed */
12477b5038d7SDag-Erling Smørgrav /* TODO: remove 'old' signatures from signature list */
12487b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_first(zone->names);
12497b5038d7SDag-Erling Smørgrav while (cur_node != LDNS_RBTREE_NULL) {
12507b5038d7SDag-Erling Smørgrav cur_name = (ldns_dnssec_name *) cur_node->data;
12517b5038d7SDag-Erling Smørgrav
12527b5038d7SDag-Erling Smørgrav if (!cur_name->is_glue) {
12537b5038d7SDag-Erling Smørgrav on_delegation_point = ldns_dnssec_rrsets_contains_type(
12547b5038d7SDag-Erling Smørgrav cur_name->rrsets, LDNS_RR_TYPE_NS)
12557b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type(
12567b5038d7SDag-Erling Smørgrav cur_name->rrsets, LDNS_RR_TYPE_SOA);
12577b5038d7SDag-Erling Smørgrav cur_rrset = cur_name->rrsets;
12587b5038d7SDag-Erling Smørgrav while (cur_rrset) {
12597b5038d7SDag-Erling Smørgrav /* reset keys to use */
12607b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, true);
12617b5038d7SDag-Erling Smørgrav
12627b5038d7SDag-Erling Smørgrav /* walk through old sigs, remove the old,
12637b5038d7SDag-Erling Smørgrav and mark which keys (not) to use) */
12647b5038d7SDag-Erling Smørgrav cur_rrset->signatures =
12657b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures(cur_rrset->signatures,
12667b5038d7SDag-Erling Smørgrav key_list,
12677b5038d7SDag-Erling Smørgrav func,
12687b5038d7SDag-Erling Smørgrav arg);
1269*5afab0e5SDag-Erling Smørgrav if(cur_rrset->type == LDNS_RR_TYPE_DNSKEY ||
1270*5afab0e5SDag-Erling Smørgrav cur_rrset->type == LDNS_RR_TYPE_CDNSKEY ||
1271*5afab0e5SDag-Erling Smørgrav cur_rrset->type == LDNS_RR_TYPE_CDS) {
1272*5afab0e5SDag-Erling Smørgrav if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK)) {
1273986ba33cSDag-Erling Smørgrav ldns_key_list_filter_for_dnskey(key_list, flags);
1274*5afab0e5SDag-Erling Smørgrav }
1275*5afab0e5SDag-Erling Smørgrav } else {
1276986ba33cSDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(key_list, flags);
1277*5afab0e5SDag-Erling Smørgrav }
12787b5038d7SDag-Erling Smørgrav
12797b5038d7SDag-Erling Smørgrav /* TODO: just set count to zero? */
12807b5038d7SDag-Erling Smørgrav rr_list = ldns_rr_list_new();
12817b5038d7SDag-Erling Smørgrav
12827b5038d7SDag-Erling Smørgrav cur_rr = cur_rrset->rrs;
12837b5038d7SDag-Erling Smørgrav while (cur_rr) {
12847b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(rr_list, cur_rr->rr);
12857b5038d7SDag-Erling Smørgrav cur_rr = cur_rr->next;
12867b5038d7SDag-Erling Smørgrav }
12877b5038d7SDag-Erling Smørgrav
12887b5038d7SDag-Erling Smørgrav /* only sign non-delegation RRsets */
12897b5038d7SDag-Erling Smørgrav /* (glue should have been marked earlier,
12907b5038d7SDag-Erling Smørgrav * except on the delegation points itself) */
12917b5038d7SDag-Erling Smørgrav if (!on_delegation_point ||
12927b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list)
12937b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_DS ||
12947b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list)
12957b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC ||
12967b5038d7SDag-Erling Smørgrav ldns_rr_list_type(rr_list)
12977b5038d7SDag-Erling Smørgrav == LDNS_RR_TYPE_NSEC3) {
12987b5038d7SDag-Erling Smørgrav siglist = ldns_sign_public(rr_list, key_list);
12997b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
13007b5038d7SDag-Erling Smørgrav if (cur_rrset->signatures) {
13017b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
13027b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist,
13037b5038d7SDag-Erling Smørgrav i));
13047b5038d7SDag-Erling Smørgrav } else {
13057b5038d7SDag-Erling Smørgrav cur_rrset->signatures = ldns_dnssec_rrs_new();
13067b5038d7SDag-Erling Smørgrav cur_rrset->signatures->rr =
13077b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i);
13082787e39aSDag-Erling Smørgrav }
13092787e39aSDag-Erling Smørgrav if (new_rrs) {
13107b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs,
13117b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist,
13127b5038d7SDag-Erling Smørgrav i));
13137b5038d7SDag-Erling Smørgrav }
13147b5038d7SDag-Erling Smørgrav }
13157b5038d7SDag-Erling Smørgrav ldns_rr_list_free(siglist);
13167b5038d7SDag-Erling Smørgrav }
13177b5038d7SDag-Erling Smørgrav
13187b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rr_list);
13197b5038d7SDag-Erling Smørgrav
13207b5038d7SDag-Erling Smørgrav cur_rrset = cur_rrset->next;
13217b5038d7SDag-Erling Smørgrav }
13227b5038d7SDag-Erling Smørgrav
13237b5038d7SDag-Erling Smørgrav /* sign the nsec */
13247b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(key_list, true);
13257b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures =
13267b5038d7SDag-Erling Smørgrav ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
13277b5038d7SDag-Erling Smørgrav key_list,
13287b5038d7SDag-Erling Smørgrav func,
13297b5038d7SDag-Erling Smørgrav arg);
1330986ba33cSDag-Erling Smørgrav ldns_key_list_filter_for_non_dnskey(key_list, flags);
13317b5038d7SDag-Erling Smørgrav
13327b5038d7SDag-Erling Smørgrav rr_list = ldns_rr_list_new();
13337b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(rr_list, cur_name->nsec);
13347b5038d7SDag-Erling Smørgrav siglist = ldns_sign_public(rr_list, key_list);
13357b5038d7SDag-Erling Smørgrav
13367b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
13377b5038d7SDag-Erling Smørgrav if (cur_name->nsec_signatures) {
13387b5038d7SDag-Erling Smørgrav result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
13397b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i));
13407b5038d7SDag-Erling Smørgrav } else {
13417b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures = ldns_dnssec_rrs_new();
13427b5038d7SDag-Erling Smørgrav cur_name->nsec_signatures->rr =
13437b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i);
13442787e39aSDag-Erling Smørgrav }
13452787e39aSDag-Erling Smørgrav if (new_rrs) {
13467b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs,
13477b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(siglist, i));
13487b5038d7SDag-Erling Smørgrav }
13497b5038d7SDag-Erling Smørgrav }
13507b5038d7SDag-Erling Smørgrav
13517b5038d7SDag-Erling Smørgrav ldns_rr_list_free(siglist);
13527b5038d7SDag-Erling Smørgrav ldns_rr_list_free(rr_list);
13537b5038d7SDag-Erling Smørgrav }
13547b5038d7SDag-Erling Smørgrav cur_node = ldns_rbtree_next(cur_node);
13557b5038d7SDag-Erling Smørgrav }
13567b5038d7SDag-Erling Smørgrav
13577b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(pubkey_list);
13587b5038d7SDag-Erling Smørgrav return result;
13597b5038d7SDag-Erling Smørgrav }
13607b5038d7SDag-Erling Smørgrav
13617b5038d7SDag-Erling Smørgrav ldns_status
13627b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
13637b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
13647b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
13657b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *),
13667b5038d7SDag-Erling Smørgrav void *arg)
13677b5038d7SDag-Erling Smørgrav {
13687b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
13697b5038d7SDag-Erling Smørgrav }
13707b5038d7SDag-Erling Smørgrav
13717b5038d7SDag-Erling Smørgrav ldns_status
13727b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
13737b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
13747b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
13757b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *),
13767b5038d7SDag-Erling Smørgrav void *arg,
13777b5038d7SDag-Erling Smørgrav int flags)
13787b5038d7SDag-Erling Smørgrav {
13797b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK;
1380*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets zonemd_rrset;
1381*5afab0e5SDag-Erling Smørgrav bool zonemd_added = false;
13827b5038d7SDag-Erling Smørgrav
13837b5038d7SDag-Erling Smørgrav if (!zone || !new_rrs || !key_list) {
13847b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
13857b5038d7SDag-Erling Smørgrav }
1386*5afab0e5SDag-Erling Smørgrav if (flags & LDNS_SIGN_WITH_ZONEMD) {
1387*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets **rrsets_ref = &zone->soa->rrsets;
13887b5038d7SDag-Erling Smørgrav
1389*5afab0e5SDag-Erling Smørgrav while (*rrsets_ref
1390*5afab0e5SDag-Erling Smørgrav && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
1391*5afab0e5SDag-Erling Smørgrav rrsets_ref = &(*rrsets_ref)->next;
1392*5afab0e5SDag-Erling Smørgrav if (!*rrsets_ref
1393*5afab0e5SDag-Erling Smørgrav || (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
1394*5afab0e5SDag-Erling Smørgrav zonemd_rrset.rrs = NULL;
1395*5afab0e5SDag-Erling Smørgrav zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
1396*5afab0e5SDag-Erling Smørgrav zonemd_rrset.signatures = NULL;
1397*5afab0e5SDag-Erling Smørgrav zonemd_rrset.next = *rrsets_ref;
1398*5afab0e5SDag-Erling Smørgrav *rrsets_ref = &zonemd_rrset;
1399*5afab0e5SDag-Erling Smørgrav zonemd_added = true;
1400*5afab0e5SDag-Erling Smørgrav }
1401*5afab0e5SDag-Erling Smørgrav }
14027b5038d7SDag-Erling Smørgrav /* zone is already sorted */
14037b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_mark_glue(zone);
14047b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
14057b5038d7SDag-Erling Smørgrav return result;
14067b5038d7SDag-Erling Smørgrav }
14077b5038d7SDag-Erling Smørgrav /* check whether we need to add nsecs */
1408*5afab0e5SDag-Erling Smørgrav if ((flags & LDNS_SIGN_NO_KEYS_NO_NSECS)
1409*5afab0e5SDag-Erling Smørgrav && ldns_key_list_key_count(key_list) < 1)
1410*5afab0e5SDag-Erling Smørgrav ; /* pass */
1411*5afab0e5SDag-Erling Smørgrav
1412*5afab0e5SDag-Erling Smørgrav else if (zone->names
1413*5afab0e5SDag-Erling Smørgrav && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
1414*5afab0e5SDag-Erling Smørgrav
14157b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
14167b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
14177b5038d7SDag-Erling Smørgrav return result;
14187b5038d7SDag-Erling Smørgrav }
14197b5038d7SDag-Erling Smørgrav }
14207b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_rrsigs_flg(zone,
14217b5038d7SDag-Erling Smørgrav new_rrs,
14227b5038d7SDag-Erling Smørgrav key_list,
14237b5038d7SDag-Erling Smørgrav func,
14247b5038d7SDag-Erling Smørgrav arg,
14257b5038d7SDag-Erling Smørgrav flags);
14267b5038d7SDag-Erling Smørgrav
1427*5afab0e5SDag-Erling Smørgrav if (zonemd_added) {
1428*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets **rrsets_ref
1429*5afab0e5SDag-Erling Smørgrav = &zone->soa->rrsets;
1430*5afab0e5SDag-Erling Smørgrav
1431*5afab0e5SDag-Erling Smørgrav while (*rrsets_ref
1432*5afab0e5SDag-Erling Smørgrav && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
1433*5afab0e5SDag-Erling Smørgrav rrsets_ref = &(*rrsets_ref)->next;
1434*5afab0e5SDag-Erling Smørgrav *rrsets_ref = zonemd_rrset.next;
1435*5afab0e5SDag-Erling Smørgrav }
1436*5afab0e5SDag-Erling Smørgrav return flags & LDNS_SIGN_WITH_ZONEMD
1437*5afab0e5SDag-Erling Smørgrav ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, flags)
1438*5afab0e5SDag-Erling Smørgrav : result;
14397b5038d7SDag-Erling Smørgrav }
14407b5038d7SDag-Erling Smørgrav
14417b5038d7SDag-Erling Smørgrav ldns_status
14427b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
14437b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
14447b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
14457b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *),
14467b5038d7SDag-Erling Smørgrav void *arg,
14477b5038d7SDag-Erling Smørgrav uint8_t algorithm,
14487b5038d7SDag-Erling Smørgrav uint8_t flags,
14497b5038d7SDag-Erling Smørgrav uint16_t iterations,
14507b5038d7SDag-Erling Smørgrav uint8_t salt_length,
14517b5038d7SDag-Erling Smørgrav uint8_t *salt)
14527b5038d7SDag-Erling Smørgrav {
14537b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
14547b5038d7SDag-Erling Smørgrav func, arg, algorithm, flags, iterations, salt_length, salt, 0,
14557b5038d7SDag-Erling Smørgrav NULL);
14567b5038d7SDag-Erling Smørgrav }
14577b5038d7SDag-Erling Smørgrav
14587b5038d7SDag-Erling Smørgrav ldns_status
14597b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
14607b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
14617b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
14627b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *),
14637b5038d7SDag-Erling Smørgrav void *arg,
14647b5038d7SDag-Erling Smørgrav uint8_t algorithm,
14657b5038d7SDag-Erling Smørgrav uint8_t flags,
14667b5038d7SDag-Erling Smørgrav uint16_t iterations,
14677b5038d7SDag-Erling Smørgrav uint8_t salt_length,
14687b5038d7SDag-Erling Smørgrav uint8_t *salt,
14697b5038d7SDag-Erling Smørgrav int signflags,
14707b5038d7SDag-Erling Smørgrav ldns_rbtree_t **map)
14717b5038d7SDag-Erling Smørgrav {
14727b5038d7SDag-Erling Smørgrav ldns_rr *nsec3, *nsec3param;
14737b5038d7SDag-Erling Smørgrav ldns_status result = LDNS_STATUS_OK;
1474*5afab0e5SDag-Erling Smørgrav bool zonemd_added = false;
1475*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets zonemd_rrset;
14767b5038d7SDag-Erling Smørgrav
14777b5038d7SDag-Erling Smørgrav /* zone is already sorted */
14787b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_mark_glue(zone);
14797b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
14807b5038d7SDag-Erling Smørgrav return result;
14817b5038d7SDag-Erling Smørgrav }
14827b5038d7SDag-Erling Smørgrav
14837b5038d7SDag-Erling Smørgrav /* TODO if there are already nsec3s presents and their
14847b5038d7SDag-Erling Smørgrav * parameters are the same as these, we don't have to recreate
14857b5038d7SDag-Erling Smørgrav */
14867b5038d7SDag-Erling Smørgrav if (zone->names) {
14877b5038d7SDag-Erling Smørgrav /* add empty nonterminals */
14887b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_add_empty_nonterminals(zone);
14897b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
14907b5038d7SDag-Erling Smørgrav return result;
14917b5038d7SDag-Erling Smørgrav }
14927b5038d7SDag-Erling Smørgrav
14937b5038d7SDag-Erling Smørgrav nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1494*5afab0e5SDag-Erling Smørgrav
1495*5afab0e5SDag-Erling Smørgrav /* check whether we need to add nsecs */
1496*5afab0e5SDag-Erling Smørgrav if ((signflags & LDNS_SIGN_NO_KEYS_NO_NSECS)
1497*5afab0e5SDag-Erling Smørgrav && ldns_key_list_key_count(key_list) < 1)
1498*5afab0e5SDag-Erling Smørgrav ; /* pass */
1499*5afab0e5SDag-Erling Smørgrav
1500*5afab0e5SDag-Erling Smørgrav else if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
15017b5038d7SDag-Erling Smørgrav /* no need to recreate */
15027b5038d7SDag-Erling Smørgrav } else {
15037b5038d7SDag-Erling Smørgrav if (!ldns_dnssec_zone_find_rrset(zone,
15047b5038d7SDag-Erling Smørgrav zone->soa->name,
15057b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3PARAM)) {
15067b5038d7SDag-Erling Smørgrav /* create and add the nsec3param rr */
15077b5038d7SDag-Erling Smørgrav nsec3param =
15087b5038d7SDag-Erling Smørgrav ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
15097b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec3param,
15107b5038d7SDag-Erling Smørgrav ldns_rdf_clone(zone->soa->name));
15117b5038d7SDag-Erling Smørgrav ldns_nsec3_add_param_rdfs(nsec3param,
15127b5038d7SDag-Erling Smørgrav algorithm,
15137b5038d7SDag-Erling Smørgrav flags,
15147b5038d7SDag-Erling Smørgrav iterations,
15157b5038d7SDag-Erling Smørgrav salt_length,
15167b5038d7SDag-Erling Smørgrav salt);
15177b5038d7SDag-Erling Smørgrav /* always set bit 7 of the flags to zero, according to
15187b5038d7SDag-Erling Smørgrav * rfc5155 section 11. The bits are counted from right to left,
15197b5038d7SDag-Erling Smørgrav * so bit 7 in rfc5155 is bit 0 in ldns */
15207b5038d7SDag-Erling Smørgrav ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
15217b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_add_rr(zone, nsec3param);
15227b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
15237b5038d7SDag-Erling Smørgrav return result;
15247b5038d7SDag-Erling Smørgrav }
15257b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new_rrs, nsec3param);
15267b5038d7SDag-Erling Smørgrav }
1527*5afab0e5SDag-Erling Smørgrav if (signflags & LDNS_SIGN_WITH_ZONEMD) {
1528*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets **rrsets_ref
1529*5afab0e5SDag-Erling Smørgrav = &zone->soa->rrsets;
1530*5afab0e5SDag-Erling Smørgrav
1531*5afab0e5SDag-Erling Smørgrav while (*rrsets_ref
1532*5afab0e5SDag-Erling Smørgrav && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
1533*5afab0e5SDag-Erling Smørgrav rrsets_ref = &(*rrsets_ref)->next;
1534*5afab0e5SDag-Erling Smørgrav if (!*rrsets_ref
1535*5afab0e5SDag-Erling Smørgrav || (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
1536*5afab0e5SDag-Erling Smørgrav zonemd_rrset.rrs = NULL;
1537*5afab0e5SDag-Erling Smørgrav zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
1538*5afab0e5SDag-Erling Smørgrav zonemd_rrset.signatures = NULL;
1539*5afab0e5SDag-Erling Smørgrav zonemd_rrset.next = *rrsets_ref;
1540*5afab0e5SDag-Erling Smørgrav *rrsets_ref = &zonemd_rrset;
1541*5afab0e5SDag-Erling Smørgrav zonemd_added = true;
1542*5afab0e5SDag-Erling Smørgrav }
1543*5afab0e5SDag-Erling Smørgrav }
15447b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
15457b5038d7SDag-Erling Smørgrav new_rrs,
15467b5038d7SDag-Erling Smørgrav algorithm,
15477b5038d7SDag-Erling Smørgrav flags,
15487b5038d7SDag-Erling Smørgrav iterations,
15497b5038d7SDag-Erling Smørgrav salt_length,
15507b5038d7SDag-Erling Smørgrav salt,
15517b5038d7SDag-Erling Smørgrav map);
1552*5afab0e5SDag-Erling Smørgrav if (zonemd_added) {
1553*5afab0e5SDag-Erling Smørgrav ldns_dnssec_rrsets **rrsets_ref
1554*5afab0e5SDag-Erling Smørgrav = &zone->soa->rrsets;
1555*5afab0e5SDag-Erling Smørgrav
1556*5afab0e5SDag-Erling Smørgrav while (*rrsets_ref
1557*5afab0e5SDag-Erling Smørgrav && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
1558*5afab0e5SDag-Erling Smørgrav rrsets_ref = &(*rrsets_ref)->next;
1559*5afab0e5SDag-Erling Smørgrav *rrsets_ref = zonemd_rrset.next;
1560*5afab0e5SDag-Erling Smørgrav }
15617b5038d7SDag-Erling Smørgrav if (result != LDNS_STATUS_OK) {
15627b5038d7SDag-Erling Smørgrav return result;
15637b5038d7SDag-Erling Smørgrav }
15647b5038d7SDag-Erling Smørgrav }
15657b5038d7SDag-Erling Smørgrav
15667b5038d7SDag-Erling Smørgrav result = ldns_dnssec_zone_create_rrsigs_flg(zone,
15677b5038d7SDag-Erling Smørgrav new_rrs,
15687b5038d7SDag-Erling Smørgrav key_list,
15697b5038d7SDag-Erling Smørgrav func,
15707b5038d7SDag-Erling Smørgrav arg,
15717b5038d7SDag-Erling Smørgrav signflags);
15727b5038d7SDag-Erling Smørgrav }
1573*5afab0e5SDag-Erling Smørgrav if (result || !zone->names)
15747b5038d7SDag-Erling Smørgrav return result;
1575*5afab0e5SDag-Erling Smørgrav
1576*5afab0e5SDag-Erling Smørgrav return signflags & LDNS_SIGN_WITH_ZONEMD
1577*5afab0e5SDag-Erling Smørgrav ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, signflags)
1578*5afab0e5SDag-Erling Smørgrav : result;
15797b5038d7SDag-Erling Smørgrav }
15807b5038d7SDag-Erling Smørgrav
15817b5038d7SDag-Erling Smørgrav ldns_status
15827b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
15837b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs,
15847b5038d7SDag-Erling Smørgrav ldns_key_list *key_list,
15857b5038d7SDag-Erling Smørgrav int (*func)(ldns_rr *, void *),
15867b5038d7SDag-Erling Smørgrav void *arg,
15877b5038d7SDag-Erling Smørgrav uint8_t algorithm,
15887b5038d7SDag-Erling Smørgrav uint8_t flags,
15897b5038d7SDag-Erling Smørgrav uint16_t iterations,
15907b5038d7SDag-Erling Smørgrav uint8_t salt_length,
15917b5038d7SDag-Erling Smørgrav uint8_t *salt,
15927b5038d7SDag-Erling Smørgrav int signflags)
15937b5038d7SDag-Erling Smørgrav {
15947b5038d7SDag-Erling Smørgrav return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
15957b5038d7SDag-Erling Smørgrav func, arg, algorithm, flags, iterations, salt_length, salt,
15967b5038d7SDag-Erling Smørgrav signflags, NULL);
15977b5038d7SDag-Erling Smørgrav }
15987b5038d7SDag-Erling Smørgrav
15997b5038d7SDag-Erling Smørgrav ldns_zone *
16007b5038d7SDag-Erling Smørgrav ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
16017b5038d7SDag-Erling Smørgrav {
16027b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *dnssec_zone;
16037b5038d7SDag-Erling Smørgrav ldns_zone *signed_zone;
16047b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs;
16057b5038d7SDag-Erling Smørgrav size_t i;
16067b5038d7SDag-Erling Smørgrav
16077b5038d7SDag-Erling Smørgrav signed_zone = ldns_zone_new();
16087b5038d7SDag-Erling Smørgrav dnssec_zone = ldns_dnssec_zone_new();
16097b5038d7SDag-Erling Smørgrav
16107b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
16117b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
16127b5038d7SDag-Erling Smørgrav
16137b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
16147b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone,
16157b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(ldns_zone_rrs(zone),
16167b5038d7SDag-Erling Smørgrav i));
16177b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(signed_zone,
16187b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
16197b5038d7SDag-Erling Smørgrav i)));
16207b5038d7SDag-Erling Smørgrav }
16217b5038d7SDag-Erling Smørgrav
16227b5038d7SDag-Erling Smørgrav new_rrs = ldns_rr_list_new();
16237b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_sign(dnssec_zone,
16247b5038d7SDag-Erling Smørgrav new_rrs,
16257b5038d7SDag-Erling Smørgrav key_list,
16267b5038d7SDag-Erling Smørgrav ldns_dnssec_default_replace_signatures,
16277b5038d7SDag-Erling Smørgrav NULL);
16287b5038d7SDag-Erling Smørgrav
16297b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
16307b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
16317b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
16327b5038d7SDag-Erling Smørgrav }
16337b5038d7SDag-Erling Smørgrav
16347b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_rrs);
16357b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(dnssec_zone);
16367b5038d7SDag-Erling Smørgrav
16377b5038d7SDag-Erling Smørgrav return signed_zone;
16387b5038d7SDag-Erling Smørgrav }
16397b5038d7SDag-Erling Smørgrav
16407b5038d7SDag-Erling Smørgrav ldns_zone *
16417b5038d7SDag-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)
16427b5038d7SDag-Erling Smørgrav {
16437b5038d7SDag-Erling Smørgrav ldns_dnssec_zone *dnssec_zone;
16447b5038d7SDag-Erling Smørgrav ldns_zone *signed_zone;
16457b5038d7SDag-Erling Smørgrav ldns_rr_list *new_rrs;
16467b5038d7SDag-Erling Smørgrav size_t i;
16477b5038d7SDag-Erling Smørgrav
16487b5038d7SDag-Erling Smørgrav signed_zone = ldns_zone_new();
16497b5038d7SDag-Erling Smørgrav dnssec_zone = ldns_dnssec_zone_new();
16507b5038d7SDag-Erling Smørgrav
16517b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
16527b5038d7SDag-Erling Smørgrav ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
16537b5038d7SDag-Erling Smørgrav
16547b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
16557b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_add_rr(dnssec_zone,
16567b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(ldns_zone_rrs(zone),
16577b5038d7SDag-Erling Smørgrav i));
16587b5038d7SDag-Erling Smørgrav ldns_zone_push_rr(signed_zone,
16597b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
16607b5038d7SDag-Erling Smørgrav i)));
16617b5038d7SDag-Erling Smørgrav }
16627b5038d7SDag-Erling Smørgrav
16637b5038d7SDag-Erling Smørgrav new_rrs = ldns_rr_list_new();
16647b5038d7SDag-Erling Smørgrav (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
16657b5038d7SDag-Erling Smørgrav new_rrs,
16667b5038d7SDag-Erling Smørgrav key_list,
16677b5038d7SDag-Erling Smørgrav ldns_dnssec_default_replace_signatures,
16687b5038d7SDag-Erling Smørgrav NULL,
16697b5038d7SDag-Erling Smørgrav algorithm,
16707b5038d7SDag-Erling Smørgrav flags,
16717b5038d7SDag-Erling Smørgrav iterations,
16727b5038d7SDag-Erling Smørgrav salt_length,
16737b5038d7SDag-Erling Smørgrav salt);
16747b5038d7SDag-Erling Smørgrav
16757b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
16767b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
16777b5038d7SDag-Erling Smørgrav ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
16787b5038d7SDag-Erling Smørgrav }
16797b5038d7SDag-Erling Smørgrav
16807b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_rrs);
16817b5038d7SDag-Erling Smørgrav ldns_dnssec_zone_free(dnssec_zone);
16827b5038d7SDag-Erling Smørgrav
16837b5038d7SDag-Erling Smørgrav return signed_zone;
16847b5038d7SDag-Erling Smørgrav }
16857b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
16867b5038d7SDag-Erling Smørgrav
16877b5038d7SDag-Erling Smørgrav
1688