xref: /dflybsd-src/contrib/ldns/dnssec_sign.c (revision d1b2b5caec9ab35b37f82c6e75b7f14f9c9103b2)
1825eb42bSJan Lentfer #include <ldns/config.h>
2825eb42bSJan Lentfer 
3825eb42bSJan Lentfer #include <ldns/ldns.h>
4825eb42bSJan Lentfer 
5825eb42bSJan Lentfer #include <ldns/dnssec.h>
6825eb42bSJan Lentfer #include <ldns/dnssec_sign.h>
7825eb42bSJan Lentfer 
8825eb42bSJan Lentfer #include <strings.h>
9825eb42bSJan Lentfer #include <time.h>
10825eb42bSJan Lentfer 
11825eb42bSJan Lentfer #ifdef HAVE_SSL
12825eb42bSJan Lentfer /* this entire file is rather useless when you don't have
13825eb42bSJan Lentfer  * crypto...
14825eb42bSJan Lentfer  */
15825eb42bSJan Lentfer #include <openssl/ssl.h>
16825eb42bSJan Lentfer #include <openssl/evp.h>
17825eb42bSJan Lentfer #include <openssl/rand.h>
18825eb42bSJan Lentfer #include <openssl/err.h>
19825eb42bSJan Lentfer #include <openssl/md5.h>
20825eb42bSJan Lentfer #endif /* HAVE_SSL */
21825eb42bSJan Lentfer 
22825eb42bSJan Lentfer ldns_rr *
23825eb42bSJan Lentfer ldns_create_empty_rrsig(ldns_rr_list *rrset,
24825eb42bSJan Lentfer                         ldns_key *current_key)
25825eb42bSJan Lentfer {
26825eb42bSJan Lentfer 	uint32_t orig_ttl;
27825eb42bSJan Lentfer 	ldns_rr_class orig_class;
28825eb42bSJan Lentfer 	time_t now;
29825eb42bSJan Lentfer 	ldns_rr *current_sig;
30825eb42bSJan Lentfer 	uint8_t label_count;
31*d1b2b5caSJohn Marino 	ldns_rdf *signame;
32825eb42bSJan Lentfer 
33825eb42bSJan Lentfer 	label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
34825eb42bSJan Lentfer 	                                                   0)));
35ac996e71SJan Lentfer         /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
36ac996e71SJan Lentfer         if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
37ac996e71SJan Lentfer                 label_count --;
38825eb42bSJan Lentfer 
39825eb42bSJan Lentfer 	current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
40825eb42bSJan Lentfer 
41825eb42bSJan Lentfer 	/* set the type on the new signature */
42825eb42bSJan Lentfer 	orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
43825eb42bSJan Lentfer 	orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
44825eb42bSJan Lentfer 
45825eb42bSJan Lentfer 	ldns_rr_set_ttl(current_sig, orig_ttl);
46825eb42bSJan Lentfer 	ldns_rr_set_class(current_sig, orig_class);
47825eb42bSJan Lentfer 	ldns_rr_set_owner(current_sig,
48825eb42bSJan Lentfer 			  ldns_rdf_clone(
49825eb42bSJan Lentfer 			       ldns_rr_owner(
50825eb42bSJan Lentfer 				    ldns_rr_list_rr(rrset,
51825eb42bSJan Lentfer 						    0))));
52825eb42bSJan Lentfer 
53825eb42bSJan Lentfer 	/* fill in what we know of the signature */
54825eb42bSJan Lentfer 
55825eb42bSJan Lentfer 	/* set the orig_ttl */
56825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_origttl(
57825eb42bSJan Lentfer 		   current_sig,
58825eb42bSJan Lentfer 		   ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
59825eb42bSJan Lentfer 					 orig_ttl));
60825eb42bSJan Lentfer 	/* the signers name */
61*d1b2b5caSJohn Marino 	signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
62*d1b2b5caSJohn Marino 	ldns_dname2canonical(signame);
63825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_signame(
64825eb42bSJan Lentfer 			current_sig,
65*d1b2b5caSJohn Marino 			signame);
66825eb42bSJan Lentfer 	/* label count - get it from the first rr in the rr_list */
67825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_labels(
68825eb42bSJan Lentfer 			current_sig,
69825eb42bSJan Lentfer 			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
70825eb42bSJan Lentfer 			                     label_count));
71825eb42bSJan Lentfer 	/* inception, expiration */
72825eb42bSJan Lentfer 	now = time(NULL);
73825eb42bSJan Lentfer 	if (ldns_key_inception(current_key) != 0) {
74825eb42bSJan Lentfer 		(void)ldns_rr_rrsig_set_inception(
75825eb42bSJan Lentfer 				current_sig,
76825eb42bSJan Lentfer 				ldns_native2rdf_int32(
77825eb42bSJan Lentfer 				    LDNS_RDF_TYPE_TIME,
78825eb42bSJan Lentfer 				    ldns_key_inception(current_key)));
79825eb42bSJan Lentfer 	} else {
80825eb42bSJan Lentfer 		(void)ldns_rr_rrsig_set_inception(
81825eb42bSJan Lentfer 				current_sig,
82825eb42bSJan Lentfer 				ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
83825eb42bSJan Lentfer 	}
84825eb42bSJan Lentfer 	if (ldns_key_expiration(current_key) != 0) {
85825eb42bSJan Lentfer 		(void)ldns_rr_rrsig_set_expiration(
86825eb42bSJan Lentfer 				current_sig,
87825eb42bSJan Lentfer 				ldns_native2rdf_int32(
88825eb42bSJan Lentfer 				    LDNS_RDF_TYPE_TIME,
89825eb42bSJan Lentfer 				    ldns_key_expiration(current_key)));
90825eb42bSJan Lentfer 	} else {
91825eb42bSJan Lentfer 		(void)ldns_rr_rrsig_set_expiration(
92825eb42bSJan Lentfer 			     current_sig,
93825eb42bSJan Lentfer 				ldns_native2rdf_int32(
94825eb42bSJan Lentfer 				    LDNS_RDF_TYPE_TIME,
95825eb42bSJan Lentfer 				    now + LDNS_DEFAULT_EXP_TIME));
96825eb42bSJan Lentfer 	}
97825eb42bSJan Lentfer 
98825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_keytag(
99825eb42bSJan Lentfer 		   current_sig,
100825eb42bSJan Lentfer 		   ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
101825eb42bSJan Lentfer 		                         ldns_key_keytag(current_key)));
102825eb42bSJan Lentfer 
103825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_algorithm(
104825eb42bSJan Lentfer 			current_sig,
105825eb42bSJan Lentfer 			ldns_native2rdf_int8(
106825eb42bSJan Lentfer 			    LDNS_RDF_TYPE_ALG,
107825eb42bSJan Lentfer 			    ldns_key_algorithm(current_key)));
108825eb42bSJan Lentfer 
109825eb42bSJan Lentfer 	(void)ldns_rr_rrsig_set_typecovered(
110825eb42bSJan Lentfer 			current_sig,
111825eb42bSJan Lentfer 			ldns_native2rdf_int16(
112825eb42bSJan Lentfer 			    LDNS_RDF_TYPE_TYPE,
113825eb42bSJan Lentfer 			    ldns_rr_get_type(ldns_rr_list_rr(rrset,
114825eb42bSJan Lentfer 			                                     0))));
115825eb42bSJan Lentfer 	return current_sig;
116825eb42bSJan Lentfer }
117825eb42bSJan Lentfer 
118825eb42bSJan Lentfer #ifdef HAVE_SSL
119825eb42bSJan Lentfer ldns_rdf *
120825eb42bSJan Lentfer ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
121825eb42bSJan Lentfer {
122825eb42bSJan Lentfer 	ldns_rdf *b64rdf = NULL;
123825eb42bSJan Lentfer 
124825eb42bSJan Lentfer 	switch(ldns_key_algorithm(current_key)) {
125825eb42bSJan Lentfer 	case LDNS_SIGN_DSA:
126fd185f4dSJan Lentfer 	case LDNS_SIGN_DSA_NSEC3:
127825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
128825eb42bSJan Lentfer 				   sign_buf,
129825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
130825eb42bSJan Lentfer 				   EVP_dss1());
131825eb42bSJan Lentfer 		break;
132825eb42bSJan Lentfer 	case LDNS_SIGN_RSASHA1:
133825eb42bSJan Lentfer 	case LDNS_SIGN_RSASHA1_NSEC3:
134825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
135825eb42bSJan Lentfer 				   sign_buf,
136825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
137825eb42bSJan Lentfer 				   EVP_sha1());
138825eb42bSJan Lentfer 		break;
139825eb42bSJan Lentfer #ifdef USE_SHA2
140825eb42bSJan Lentfer 	case LDNS_SIGN_RSASHA256:
141825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
142825eb42bSJan Lentfer 				   sign_buf,
143825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
144825eb42bSJan Lentfer 				   EVP_sha256());
145825eb42bSJan Lentfer 		break;
146825eb42bSJan Lentfer 	case LDNS_SIGN_RSASHA512:
147825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
148825eb42bSJan Lentfer 				   sign_buf,
149825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
150825eb42bSJan Lentfer 				   EVP_sha512());
151825eb42bSJan Lentfer 		break;
152825eb42bSJan Lentfer #endif /* USE_SHA2 */
153825eb42bSJan Lentfer #ifdef USE_GOST
154ac996e71SJan Lentfer 	case LDNS_SIGN_ECC_GOST:
155825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
156825eb42bSJan Lentfer 				   sign_buf,
157825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
158825eb42bSJan Lentfer 				   EVP_get_digestbyname("md_gost94"));
159825eb42bSJan Lentfer 		break;
160825eb42bSJan Lentfer #endif /* USE_GOST */
161ac996e71SJan Lentfer #ifdef USE_ECDSA
162ac996e71SJan Lentfer         case LDNS_SIGN_ECDSAP256SHA256:
163ac996e71SJan Lentfer        		b64rdf = ldns_sign_public_evp(
164ac996e71SJan Lentfer 				   sign_buf,
165ac996e71SJan Lentfer 				   ldns_key_evp_key(current_key),
166ac996e71SJan Lentfer 				   EVP_sha256());
167ac996e71SJan Lentfer                 break;
168ac996e71SJan Lentfer         case LDNS_SIGN_ECDSAP384SHA384:
169ac996e71SJan Lentfer        		b64rdf = ldns_sign_public_evp(
170ac996e71SJan Lentfer 				   sign_buf,
171ac996e71SJan Lentfer 				   ldns_key_evp_key(current_key),
172ac996e71SJan Lentfer 				   EVP_sha384());
173ac996e71SJan Lentfer                 break;
174ac996e71SJan Lentfer #endif
175825eb42bSJan Lentfer 	case LDNS_SIGN_RSAMD5:
176825eb42bSJan Lentfer 		b64rdf = ldns_sign_public_evp(
177825eb42bSJan Lentfer 				   sign_buf,
178825eb42bSJan Lentfer 				   ldns_key_evp_key(current_key),
179825eb42bSJan Lentfer 				   EVP_md5());
180825eb42bSJan Lentfer 		break;
181825eb42bSJan Lentfer 	default:
182825eb42bSJan Lentfer 		/* do _you_ know this alg? */
183825eb42bSJan Lentfer 		printf("unknown algorithm, ");
184825eb42bSJan Lentfer 		printf("is the one used available on this system?\n");
185825eb42bSJan Lentfer 		break;
186825eb42bSJan Lentfer 	}
187825eb42bSJan Lentfer 
188825eb42bSJan Lentfer 	return b64rdf;
189825eb42bSJan Lentfer }
190825eb42bSJan Lentfer 
191825eb42bSJan Lentfer /**
192825eb42bSJan Lentfer  * use this function to sign with a public/private key alg
193825eb42bSJan Lentfer  * return the created signatures
194825eb42bSJan Lentfer  */
195825eb42bSJan Lentfer ldns_rr_list *
196825eb42bSJan Lentfer ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
197825eb42bSJan Lentfer {
198825eb42bSJan Lentfer 	ldns_rr_list *signatures;
199825eb42bSJan Lentfer 	ldns_rr_list *rrset_clone;
200825eb42bSJan Lentfer 	ldns_rr *current_sig;
201825eb42bSJan Lentfer 	ldns_rdf *b64rdf;
202825eb42bSJan Lentfer 	ldns_key *current_key;
203825eb42bSJan Lentfer 	size_t key_count;
204825eb42bSJan Lentfer 	uint16_t i;
205825eb42bSJan Lentfer 	ldns_buffer *sign_buf;
206825eb42bSJan Lentfer 	ldns_rdf *new_owner;
207825eb42bSJan Lentfer 
208825eb42bSJan Lentfer 	if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
209825eb42bSJan Lentfer 		return NULL;
210825eb42bSJan Lentfer 	}
211825eb42bSJan Lentfer 
212825eb42bSJan Lentfer 	new_owner = NULL;
213825eb42bSJan Lentfer 
214825eb42bSJan Lentfer 	signatures = ldns_rr_list_new();
215825eb42bSJan Lentfer 
216825eb42bSJan Lentfer 	/* prepare a signature and add all the know data
217825eb42bSJan Lentfer 	 * prepare the rrset. Sign this together.  */
218825eb42bSJan Lentfer 	rrset_clone = ldns_rr_list_clone(rrset);
219825eb42bSJan Lentfer 	if (!rrset_clone) {
220825eb42bSJan Lentfer 		return NULL;
221825eb42bSJan Lentfer 	}
222825eb42bSJan Lentfer 
223825eb42bSJan Lentfer 	/* make it canonical */
224825eb42bSJan Lentfer 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
225825eb42bSJan Lentfer 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
226825eb42bSJan Lentfer 			ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
227825eb42bSJan Lentfer 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
228825eb42bSJan Lentfer 	}
229825eb42bSJan Lentfer 	/* sort */
230825eb42bSJan Lentfer 	ldns_rr_list_sort(rrset_clone);
231825eb42bSJan Lentfer 
232825eb42bSJan Lentfer 	for (key_count = 0;
233825eb42bSJan Lentfer 		key_count < ldns_key_list_key_count(keys);
234825eb42bSJan Lentfer 		key_count++) {
235825eb42bSJan Lentfer 		if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
236825eb42bSJan Lentfer 			continue;
237825eb42bSJan Lentfer 		}
238825eb42bSJan Lentfer 		sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
239825eb42bSJan Lentfer 		if (!sign_buf) {
240825eb42bSJan Lentfer 			ldns_rr_list_free(rrset_clone);
241825eb42bSJan Lentfer 			ldns_rr_list_free(signatures);
242825eb42bSJan Lentfer 			ldns_rdf_free(new_owner);
243825eb42bSJan Lentfer 			return NULL;
244825eb42bSJan Lentfer 		}
245825eb42bSJan Lentfer 		b64rdf = NULL;
246825eb42bSJan Lentfer 
247825eb42bSJan Lentfer 		current_key = ldns_key_list_key(keys, key_count);
248825eb42bSJan Lentfer 		/* sign all RRs with keys that have ZSKbit, !SEPbit.
249825eb42bSJan Lentfer 		   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
250ac996e71SJan Lentfer 		if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
251825eb42bSJan Lentfer 			current_sig = ldns_create_empty_rrsig(rrset_clone,
252825eb42bSJan Lentfer 			                                      current_key);
253825eb42bSJan Lentfer 
254825eb42bSJan Lentfer 			/* right now, we have: a key, a semi-sig and an rrset. For
255825eb42bSJan Lentfer 			 * which we can create the sig and base64 encode that and
256825eb42bSJan Lentfer 			 * add that to the signature */
257825eb42bSJan Lentfer 
258825eb42bSJan Lentfer 			if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
259825eb42bSJan Lentfer 			    != LDNS_STATUS_OK) {
260825eb42bSJan Lentfer 				ldns_buffer_free(sign_buf);
261825eb42bSJan Lentfer 				/* ERROR */
262825eb42bSJan Lentfer 				ldns_rr_list_deep_free(rrset_clone);
263*d1b2b5caSJohn Marino 				ldns_rr_free(current_sig);
264*d1b2b5caSJohn Marino 				ldns_rr_list_deep_free(signatures);
265825eb42bSJan Lentfer 				return NULL;
266825eb42bSJan Lentfer 			}
267825eb42bSJan Lentfer 
268825eb42bSJan Lentfer 			/* add the rrset in sign_buf */
269825eb42bSJan Lentfer 			if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
270825eb42bSJan Lentfer 			    != LDNS_STATUS_OK) {
271825eb42bSJan Lentfer 				ldns_buffer_free(sign_buf);
272825eb42bSJan Lentfer 				ldns_rr_list_deep_free(rrset_clone);
273*d1b2b5caSJohn Marino 				ldns_rr_free(current_sig);
274*d1b2b5caSJohn Marino 				ldns_rr_list_deep_free(signatures);
275825eb42bSJan Lentfer 				return NULL;
276825eb42bSJan Lentfer 			}
277825eb42bSJan Lentfer 
278825eb42bSJan Lentfer 			b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
279825eb42bSJan Lentfer 
280825eb42bSJan Lentfer 			if (!b64rdf) {
281825eb42bSJan Lentfer 				/* signing went wrong */
282825eb42bSJan Lentfer 				ldns_rr_list_deep_free(rrset_clone);
283*d1b2b5caSJohn Marino 				ldns_rr_free(current_sig);
284*d1b2b5caSJohn Marino 				ldns_rr_list_deep_free(signatures);
285825eb42bSJan Lentfer 				return NULL;
286825eb42bSJan Lentfer 			}
287825eb42bSJan Lentfer 
288825eb42bSJan Lentfer 			ldns_rr_rrsig_set_sig(current_sig, b64rdf);
289825eb42bSJan Lentfer 
290825eb42bSJan Lentfer 			/* push the signature to the signatures list */
291825eb42bSJan Lentfer 			ldns_rr_list_push_rr(signatures, current_sig);
292825eb42bSJan Lentfer 		}
293825eb42bSJan Lentfer 		ldns_buffer_free(sign_buf); /* restart for the next key */
294825eb42bSJan Lentfer 	}
295825eb42bSJan Lentfer 	ldns_rr_list_deep_free(rrset_clone);
296825eb42bSJan Lentfer 
297825eb42bSJan Lentfer 	return signatures;
298825eb42bSJan Lentfer }
299825eb42bSJan Lentfer 
300825eb42bSJan Lentfer /**
301825eb42bSJan Lentfer  * Sign data with DSA
302825eb42bSJan Lentfer  *
303825eb42bSJan Lentfer  * \param[in] to_sign The ldns_buffer containing raw data that is
304825eb42bSJan Lentfer  *                    to be signed
305825eb42bSJan Lentfer  * \param[in] key The DSA key structure to sign with
306825eb42bSJan Lentfer  * \return ldns_rdf for the RRSIG ldns_rr
307825eb42bSJan Lentfer  */
308825eb42bSJan Lentfer ldns_rdf *
309825eb42bSJan Lentfer ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
310825eb42bSJan Lentfer {
311825eb42bSJan Lentfer 	unsigned char *sha1_hash;
312825eb42bSJan Lentfer 	ldns_rdf *sigdata_rdf;
313825eb42bSJan Lentfer 	ldns_buffer *b64sig;
314825eb42bSJan Lentfer 
315825eb42bSJan Lentfer 	DSA_SIG *sig;
316825eb42bSJan Lentfer 	uint8_t *data;
317825eb42bSJan Lentfer 	size_t pad;
318825eb42bSJan Lentfer 
319825eb42bSJan Lentfer 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
320825eb42bSJan Lentfer 	if (!b64sig) {
321825eb42bSJan Lentfer 		return NULL;
322825eb42bSJan Lentfer 	}
323825eb42bSJan Lentfer 
324825eb42bSJan Lentfer 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
325825eb42bSJan Lentfer 				  ldns_buffer_position(to_sign), NULL);
326825eb42bSJan Lentfer 	if (!sha1_hash) {
327825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
328825eb42bSJan Lentfer 		return NULL;
329825eb42bSJan Lentfer 	}
330825eb42bSJan Lentfer 
331825eb42bSJan Lentfer 	sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
332fd185f4dSJan Lentfer         if(!sig) {
333fd185f4dSJan Lentfer 		ldns_buffer_free(b64sig);
334fd185f4dSJan Lentfer 		return NULL;
335fd185f4dSJan Lentfer         }
336825eb42bSJan Lentfer 
337825eb42bSJan Lentfer 	data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
338fd185f4dSJan Lentfer         if(!data) {
339fd185f4dSJan Lentfer 		ldns_buffer_free(b64sig);
340fd185f4dSJan Lentfer                 DSA_SIG_free(sig);
341fd185f4dSJan Lentfer 		return NULL;
342fd185f4dSJan Lentfer         }
343825eb42bSJan Lentfer 
344825eb42bSJan Lentfer 	data[0] = 1;
345825eb42bSJan Lentfer 	pad = 20 - (size_t) BN_num_bytes(sig->r);
346825eb42bSJan Lentfer 	if (pad > 0) {
347825eb42bSJan Lentfer 		memset(data + 1, 0, pad);
348825eb42bSJan Lentfer 	}
349825eb42bSJan Lentfer 	BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
350825eb42bSJan Lentfer 
351825eb42bSJan Lentfer 	pad = 20 - (size_t) BN_num_bytes(sig->s);
352825eb42bSJan Lentfer 	if (pad > 0) {
353825eb42bSJan Lentfer 		memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
354825eb42bSJan Lentfer 	}
355825eb42bSJan Lentfer 	BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
356825eb42bSJan Lentfer 
357825eb42bSJan Lentfer 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
358825eb42bSJan Lentfer 								 1 + 2 * SHA_DIGEST_LENGTH,
359825eb42bSJan Lentfer 								 data);
360825eb42bSJan Lentfer 
361825eb42bSJan Lentfer 	ldns_buffer_free(b64sig);
362825eb42bSJan Lentfer 	LDNS_FREE(data);
363fd185f4dSJan Lentfer         DSA_SIG_free(sig);
364825eb42bSJan Lentfer 
365825eb42bSJan Lentfer 	return sigdata_rdf;
366825eb42bSJan Lentfer }
367825eb42bSJan Lentfer 
368ac996e71SJan Lentfer #ifdef USE_ECDSA
369fd185f4dSJan Lentfer #ifndef S_SPLINT_S
370ac996e71SJan Lentfer static int
371ac996e71SJan Lentfer ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
372ac996e71SJan Lentfer {
373ac996e71SJan Lentfer         EC_KEY* ec;
374ac996e71SJan Lentfer         const EC_GROUP* g;
375ac996e71SJan Lentfer         if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
376ac996e71SJan Lentfer                 return 0;
377ac996e71SJan Lentfer         ec = EVP_PKEY_get1_EC_KEY(pkey);
378ac996e71SJan Lentfer         g = EC_KEY_get0_group(ec);
379ac996e71SJan Lentfer         if(!g) {
380ac996e71SJan Lentfer                 EC_KEY_free(ec);
381ac996e71SJan Lentfer                 return 0;
382ac996e71SJan Lentfer         }
383ac996e71SJan Lentfer         if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
384ac996e71SJan Lentfer                 EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
385ac996e71SJan Lentfer                 EC_GROUP_get_curve_name(g) == NID_secp384r1) {
386ac996e71SJan Lentfer                 EC_KEY_free(ec);
387ac996e71SJan Lentfer                 return 1;
388ac996e71SJan Lentfer         }
389ac996e71SJan Lentfer         /* downref the eckey, the original is still inside the pkey */
390ac996e71SJan Lentfer         EC_KEY_free(ec);
391ac996e71SJan Lentfer         return 0;
392ac996e71SJan Lentfer }
393fd185f4dSJan Lentfer #endif /* splint */
394ac996e71SJan Lentfer #endif /* USE_ECDSA */
395ac996e71SJan Lentfer 
396825eb42bSJan Lentfer ldns_rdf *
397825eb42bSJan Lentfer ldns_sign_public_evp(ldns_buffer *to_sign,
398825eb42bSJan Lentfer 				 EVP_PKEY *key,
399825eb42bSJan Lentfer 				 const EVP_MD *digest_type)
400825eb42bSJan Lentfer {
401825eb42bSJan Lentfer 	unsigned int siglen;
402825eb42bSJan Lentfer 	ldns_rdf *sigdata_rdf;
403825eb42bSJan Lentfer 	ldns_buffer *b64sig;
404825eb42bSJan Lentfer 	EVP_MD_CTX ctx;
405825eb42bSJan Lentfer 	const EVP_MD *md_type;
406825eb42bSJan Lentfer 	int r;
407825eb42bSJan Lentfer 
408825eb42bSJan Lentfer 	siglen = 0;
409825eb42bSJan Lentfer 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
410825eb42bSJan Lentfer 	if (!b64sig) {
411825eb42bSJan Lentfer 		return NULL;
412825eb42bSJan Lentfer 	}
413825eb42bSJan Lentfer 
414825eb42bSJan Lentfer 	/* initializes a signing context */
415825eb42bSJan Lentfer 	md_type = digest_type;
416825eb42bSJan Lentfer 	if(!md_type) {
417825eb42bSJan Lentfer 		/* unknown message difest */
418825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
419825eb42bSJan Lentfer 		return NULL;
420825eb42bSJan Lentfer 	}
421825eb42bSJan Lentfer 
422825eb42bSJan Lentfer 	EVP_MD_CTX_init(&ctx);
423825eb42bSJan Lentfer 	r = EVP_SignInit(&ctx, md_type);
424825eb42bSJan Lentfer 	if(r == 1) {
425825eb42bSJan Lentfer 		r = EVP_SignUpdate(&ctx, (unsigned char*)
426825eb42bSJan Lentfer 					    ldns_buffer_begin(to_sign),
427825eb42bSJan Lentfer 					    ldns_buffer_position(to_sign));
428825eb42bSJan Lentfer 	} else {
429825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
430825eb42bSJan Lentfer 		return NULL;
431825eb42bSJan Lentfer 	}
432825eb42bSJan Lentfer 	if(r == 1) {
433825eb42bSJan Lentfer 		r = EVP_SignFinal(&ctx, (unsigned char*)
434825eb42bSJan Lentfer 					   ldns_buffer_begin(b64sig), &siglen, key);
435825eb42bSJan Lentfer 	} else {
436825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
437825eb42bSJan Lentfer 		return NULL;
438825eb42bSJan Lentfer 	}
439825eb42bSJan Lentfer 	if(r != 1) {
440825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
441825eb42bSJan Lentfer 		return NULL;
442825eb42bSJan Lentfer 	}
443825eb42bSJan Lentfer 
444825eb42bSJan Lentfer 	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
445fd185f4dSJan Lentfer #ifndef S_SPLINT_S
446825eb42bSJan Lentfer 	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
447825eb42bSJan Lentfer 		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
448ac996e71SJan Lentfer #ifdef USE_ECDSA
449ac996e71SJan Lentfer         } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
450ac996e71SJan Lentfer                 ldns_pkey_is_ecdsa(key)) {
451ac996e71SJan Lentfer                 sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
452ac996e71SJan Lentfer #endif
453825eb42bSJan Lentfer 	} else {
454825eb42bSJan Lentfer 		/* ok output for other types is the same */
455825eb42bSJan Lentfer 		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
456825eb42bSJan Lentfer 									 ldns_buffer_begin(b64sig));
457825eb42bSJan Lentfer 	}
458fd185f4dSJan Lentfer #endif /* splint */
459825eb42bSJan Lentfer 	ldns_buffer_free(b64sig);
460825eb42bSJan Lentfer 	EVP_MD_CTX_cleanup(&ctx);
461825eb42bSJan Lentfer 	return sigdata_rdf;
462825eb42bSJan Lentfer }
463825eb42bSJan Lentfer 
464825eb42bSJan Lentfer ldns_rdf *
465825eb42bSJan Lentfer ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
466825eb42bSJan Lentfer {
467825eb42bSJan Lentfer 	unsigned char *sha1_hash;
468825eb42bSJan Lentfer 	unsigned int siglen;
469825eb42bSJan Lentfer 	ldns_rdf *sigdata_rdf;
470825eb42bSJan Lentfer 	ldns_buffer *b64sig;
471825eb42bSJan Lentfer 	int result;
472825eb42bSJan Lentfer 
473825eb42bSJan Lentfer 	siglen = 0;
474825eb42bSJan Lentfer 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
475825eb42bSJan Lentfer 	if (!b64sig) {
476825eb42bSJan Lentfer 		return NULL;
477825eb42bSJan Lentfer 	}
478825eb42bSJan Lentfer 
479825eb42bSJan Lentfer 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
480825eb42bSJan Lentfer 				  ldns_buffer_position(to_sign), NULL);
481825eb42bSJan Lentfer 	if (!sha1_hash) {
482825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
483825eb42bSJan Lentfer 		return NULL;
484825eb42bSJan Lentfer 	}
485825eb42bSJan Lentfer 
486825eb42bSJan Lentfer 	result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
487825eb42bSJan Lentfer 				   (unsigned char*)ldns_buffer_begin(b64sig),
488825eb42bSJan Lentfer 				   &siglen, key);
489825eb42bSJan Lentfer 	if (result != 1) {
490*d1b2b5caSJohn Marino 		ldns_buffer_free(b64sig);
491825eb42bSJan Lentfer 		return NULL;
492825eb42bSJan Lentfer 	}
493825eb42bSJan Lentfer 
494825eb42bSJan Lentfer 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
495825eb42bSJan Lentfer 								 ldns_buffer_begin(b64sig));
496825eb42bSJan Lentfer 	ldns_buffer_free(b64sig); /* can't free this buffer ?? */
497825eb42bSJan Lentfer 	return sigdata_rdf;
498825eb42bSJan Lentfer }
499825eb42bSJan Lentfer 
500825eb42bSJan Lentfer ldns_rdf *
501825eb42bSJan Lentfer ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
502825eb42bSJan Lentfer {
503825eb42bSJan Lentfer 	unsigned char *md5_hash;
504825eb42bSJan Lentfer 	unsigned int siglen;
505825eb42bSJan Lentfer 	ldns_rdf *sigdata_rdf;
506825eb42bSJan Lentfer 	ldns_buffer *b64sig;
507825eb42bSJan Lentfer 
508825eb42bSJan Lentfer 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
509825eb42bSJan Lentfer 	if (!b64sig) {
510825eb42bSJan Lentfer 		return NULL;
511825eb42bSJan Lentfer 	}
512825eb42bSJan Lentfer 
513825eb42bSJan Lentfer 	md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
514825eb42bSJan Lentfer 				ldns_buffer_position(to_sign), NULL);
515825eb42bSJan Lentfer 	if (!md5_hash) {
516825eb42bSJan Lentfer 		ldns_buffer_free(b64sig);
517825eb42bSJan Lentfer 		return NULL;
518825eb42bSJan Lentfer 	}
519825eb42bSJan Lentfer 
520825eb42bSJan Lentfer 	RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
521825eb42bSJan Lentfer 		    (unsigned char*)ldns_buffer_begin(b64sig),
522825eb42bSJan Lentfer 		    &siglen, key);
523825eb42bSJan Lentfer 
524825eb42bSJan Lentfer 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
525825eb42bSJan Lentfer 								 ldns_buffer_begin(b64sig));
526825eb42bSJan Lentfer 	ldns_buffer_free(b64sig);
527825eb42bSJan Lentfer 	return sigdata_rdf;
528825eb42bSJan Lentfer }
529825eb42bSJan Lentfer #endif /* HAVE_SSL */
530825eb42bSJan Lentfer 
531b5dedccaSJan Lentfer /**
532b5dedccaSJan Lentfer  * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
533b5dedccaSJan Lentfer  */
534b5dedccaSJan Lentfer static ldns_status
535b5dedccaSJan Lentfer ldns_dnssec_addresses_on_glue_list(
536b5dedccaSJan Lentfer 		ldns_dnssec_rrsets *cur_rrset,
537b5dedccaSJan Lentfer 		ldns_rr_list *glue_list)
538825eb42bSJan Lentfer {
539b5dedccaSJan Lentfer 	ldns_dnssec_rrs *cur_rrs;
540825eb42bSJan Lentfer 	while (cur_rrset) {
541b5dedccaSJan Lentfer 		if (cur_rrset->type == LDNS_RR_TYPE_A
542b5dedccaSJan Lentfer 				|| cur_rrset->type == LDNS_RR_TYPE_AAAA) {
543b5dedccaSJan Lentfer 			for (cur_rrs = cur_rrset->rrs;
544b5dedccaSJan Lentfer 					cur_rrs;
545b5dedccaSJan Lentfer 					cur_rrs = cur_rrs->next) {
546b5dedccaSJan Lentfer 				if (cur_rrs->rr) {
547b5dedccaSJan Lentfer 					if (!ldns_rr_list_push_rr(glue_list,
548b5dedccaSJan Lentfer 							cur_rrs->rr)) {
549b5dedccaSJan Lentfer 						return LDNS_STATUS_MEM_ERR;
550b5dedccaSJan Lentfer 						/* ldns_rr_list_push_rr()
551b5dedccaSJan Lentfer 						 * returns false when unable
552b5dedccaSJan Lentfer 						 * to increase the capacity
553b5dedccaSJan Lentfer 						 * of the ldsn_rr_list
554b5dedccaSJan Lentfer 						 */
555b5dedccaSJan Lentfer 					}
556b5dedccaSJan Lentfer 				}
557b5dedccaSJan Lentfer 			}
558b5dedccaSJan Lentfer 		}
559825eb42bSJan Lentfer 		cur_rrset = cur_rrset->next;
560825eb42bSJan Lentfer 	}
561b5dedccaSJan Lentfer 	return LDNS_STATUS_OK;
562825eb42bSJan Lentfer }
563825eb42bSJan Lentfer 
564b5dedccaSJan Lentfer /**
565b5dedccaSJan Lentfer  * Marks the names in the zone that are occluded. Those names will be skipped
566b5dedccaSJan Lentfer  * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
567b5dedccaSJan Lentfer  * function. But watch out! Names that are partially occluded (like glue with
568b5dedccaSJan Lentfer  * the same name as the delegation) will not be marked and should specifically
569b5dedccaSJan Lentfer  * be taken into account seperately.
570b5dedccaSJan Lentfer  *
571b5dedccaSJan Lentfer  * When glue_list is given (not NULL), in the process of marking the names, all
572b5dedccaSJan Lentfer  * glue resource records will be pushed to that list, even glue at delegation names.
573b5dedccaSJan Lentfer  *
574b5dedccaSJan Lentfer  * \param[in] zone the zone in which to mark the names
575b5dedccaSJan Lentfer  * \param[in] glue_list the list to which to push the glue rrs
576b5dedccaSJan Lentfer  * \return LDNS_STATUS_OK on success, an error code otherwise
577825eb42bSJan Lentfer  */
578b5dedccaSJan Lentfer ldns_status
579b5dedccaSJan Lentfer ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
580b5dedccaSJan Lentfer 	ldns_rr_list *glue_list)
581b5dedccaSJan Lentfer {
582b5dedccaSJan Lentfer 	ldns_rbnode_t    *node;
583b5dedccaSJan Lentfer 	ldns_dnssec_name *name;
584b5dedccaSJan Lentfer 	ldns_rdf         *owner;
585b5dedccaSJan Lentfer 	ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
586b5dedccaSJan Lentfer 	/* When the cut is caused by a delegation, below_delegation will be 1.
587b5dedccaSJan Lentfer 	 * When caused by a DNAME, below_delegation will be 0.
588b5dedccaSJan Lentfer 	 */
589b5dedccaSJan Lentfer 	int below_delegation = -1; /* init suppresses comiler warning */
590b5dedccaSJan Lentfer 	ldns_status s;
591b5dedccaSJan Lentfer 
592b5dedccaSJan Lentfer 	if (!zone || !zone->names) {
593b5dedccaSJan Lentfer 		return LDNS_STATUS_NULL;
594825eb42bSJan Lentfer 	}
595b5dedccaSJan Lentfer 	for (node = ldns_rbtree_first(zone->names);
596b5dedccaSJan Lentfer 			node != LDNS_RBTREE_NULL;
597b5dedccaSJan Lentfer 			node = ldns_rbtree_next(node)) {
598b5dedccaSJan Lentfer 		name = (ldns_dnssec_name *) node->data;
599b5dedccaSJan Lentfer 		owner = ldns_dnssec_name_name(name);
600b5dedccaSJan Lentfer 
601b5dedccaSJan Lentfer 		if (cut) {
602b5dedccaSJan Lentfer 			/* The previous node was a zone cut, or a subdomain
603b5dedccaSJan Lentfer 			 * below a zone cut. Is this node (still) a subdomain
604b5dedccaSJan Lentfer 			 * below the cut? Then the name is occluded. Unless
605b5dedccaSJan Lentfer 			 * the name contains a SOA, after which we are
606b5dedccaSJan Lentfer 			 * authoritative again.
607b5dedccaSJan Lentfer 			 *
608b5dedccaSJan Lentfer 			 * FIXME! If there are labels in between the SOA and
609b5dedccaSJan Lentfer 			 * the cut, going from the authoritative space (below
610b5dedccaSJan Lentfer 			 * the SOA) up into occluded space again, will not be
611b5dedccaSJan Lentfer 			 * detected with the contruct below!
612b5dedccaSJan Lentfer 			 */
613b5dedccaSJan Lentfer 			if (ldns_dname_is_subdomain(owner, cut) &&
614b5dedccaSJan Lentfer 					!ldns_dnssec_rrsets_contains_type(
615b5dedccaSJan Lentfer 					name->rrsets, LDNS_RR_TYPE_SOA)) {
616b5dedccaSJan Lentfer 
617b5dedccaSJan Lentfer 				if (below_delegation && glue_list) {
618b5dedccaSJan Lentfer 					s = ldns_dnssec_addresses_on_glue_list(
619b5dedccaSJan Lentfer 						name->rrsets, glue_list);
620b5dedccaSJan Lentfer 					if (s != LDNS_STATUS_OK) {
621b5dedccaSJan Lentfer 						return s;
622825eb42bSJan Lentfer 					}
623b5dedccaSJan Lentfer 				}
624b5dedccaSJan Lentfer 				name->is_glue = true; /* Mark occluded name! */
625b5dedccaSJan Lentfer 				continue;
626b5dedccaSJan Lentfer 			} else {
627b5dedccaSJan Lentfer 				cut = NULL;
628b5dedccaSJan Lentfer 			}
629b5dedccaSJan Lentfer 		}
630b5dedccaSJan Lentfer 
631b5dedccaSJan Lentfer 		/* The node is not below a zone cut. Is it a zone cut itself?
632b5dedccaSJan Lentfer 		 * Everything below a SOA is authoritative of course; Except
633b5dedccaSJan Lentfer 		 * when the name also contains a DNAME :).
634b5dedccaSJan Lentfer 		 */
635b5dedccaSJan Lentfer 		if (ldns_dnssec_rrsets_contains_type(
636b5dedccaSJan Lentfer 				name->rrsets, LDNS_RR_TYPE_NS)
637b5dedccaSJan Lentfer 			    && !ldns_dnssec_rrsets_contains_type(
638b5dedccaSJan Lentfer 				name->rrsets, LDNS_RR_TYPE_SOA)) {
639b5dedccaSJan Lentfer 			cut = owner;
640b5dedccaSJan Lentfer 			below_delegation = 1;
641b5dedccaSJan Lentfer 			if (glue_list) { /* record glue on the zone cut */
642b5dedccaSJan Lentfer 				s = ldns_dnssec_addresses_on_glue_list(
643b5dedccaSJan Lentfer 					name->rrsets, glue_list);
644b5dedccaSJan Lentfer 				if (s != LDNS_STATUS_OK) {
645b5dedccaSJan Lentfer 					return s;
646b5dedccaSJan Lentfer 				}
647b5dedccaSJan Lentfer 			}
648b5dedccaSJan Lentfer 		} else if (ldns_dnssec_rrsets_contains_type(
649b5dedccaSJan Lentfer 				name->rrsets, LDNS_RR_TYPE_DNAME)) {
650b5dedccaSJan Lentfer 			cut = owner;
651b5dedccaSJan Lentfer 			below_delegation = 0;
652825eb42bSJan Lentfer 		}
653825eb42bSJan Lentfer 	}
654825eb42bSJan Lentfer 	return LDNS_STATUS_OK;
655825eb42bSJan Lentfer }
656825eb42bSJan Lentfer 
657b5dedccaSJan Lentfer /**
658b5dedccaSJan Lentfer  * Marks the names in the zone that are occluded. Those names will be skipped
659b5dedccaSJan Lentfer  * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
660b5dedccaSJan Lentfer  * function. But watch out! Names that are partially occluded (like glue with
661b5dedccaSJan Lentfer  * the same name as the delegation) will not be marked and should specifically
662b5dedccaSJan Lentfer  * be taken into account seperately.
663b5dedccaSJan Lentfer  *
664b5dedccaSJan Lentfer  * \param[in] zone the zone in which to mark the names
665b5dedccaSJan Lentfer  * \return LDNS_STATUS_OK on success, an error code otherwise
666b5dedccaSJan Lentfer  */
667b5dedccaSJan Lentfer ldns_status
668b5dedccaSJan Lentfer ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
669b5dedccaSJan Lentfer {
670b5dedccaSJan Lentfer 	return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
671b5dedccaSJan Lentfer }
672b5dedccaSJan Lentfer 
673825eb42bSJan Lentfer ldns_rbnode_t *
674825eb42bSJan Lentfer ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
675825eb42bSJan Lentfer {
676825eb42bSJan Lentfer 	ldns_rbnode_t *next_node = NULL;
677825eb42bSJan Lentfer 	ldns_dnssec_name *next_name = NULL;
678825eb42bSJan Lentfer 	bool done = false;
679825eb42bSJan Lentfer 
680825eb42bSJan Lentfer 	if (node == LDNS_RBTREE_NULL) {
681825eb42bSJan Lentfer 		return NULL;
682825eb42bSJan Lentfer 	}
683825eb42bSJan Lentfer 	next_node = node;
684825eb42bSJan Lentfer 	while (!done) {
685825eb42bSJan Lentfer 		if (next_node == LDNS_RBTREE_NULL) {
686825eb42bSJan Lentfer 			return NULL;
687825eb42bSJan Lentfer 		} else {
688825eb42bSJan Lentfer 			next_name = (ldns_dnssec_name *)next_node->data;
689825eb42bSJan Lentfer 			if (!next_name->is_glue) {
690825eb42bSJan Lentfer 				done = true;
691825eb42bSJan Lentfer 			} else {
692825eb42bSJan Lentfer 				next_node = ldns_rbtree_next(next_node);
693825eb42bSJan Lentfer 			}
694825eb42bSJan Lentfer 		}
695825eb42bSJan Lentfer 	}
696825eb42bSJan Lentfer 	return next_node;
697825eb42bSJan Lentfer }
698825eb42bSJan Lentfer 
699825eb42bSJan Lentfer ldns_status
700825eb42bSJan Lentfer ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
701825eb42bSJan Lentfer                               ldns_rr_list *new_rrs)
702825eb42bSJan Lentfer {
703825eb42bSJan Lentfer 
704825eb42bSJan Lentfer 	ldns_rbnode_t *first_node, *cur_node, *next_node;
705825eb42bSJan Lentfer 	ldns_dnssec_name *cur_name, *next_name;
706825eb42bSJan Lentfer 	ldns_rr *nsec_rr;
707825eb42bSJan Lentfer 	uint32_t nsec_ttl;
708825eb42bSJan Lentfer 	ldns_dnssec_rrsets *soa;
709825eb42bSJan Lentfer 
710825eb42bSJan Lentfer 	/* the TTL of NSEC rrs should be set to the minimum TTL of
711825eb42bSJan Lentfer 	 * the zone SOA (RFC4035 Section 2.3)
712825eb42bSJan Lentfer 	 */
713825eb42bSJan Lentfer 	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
714825eb42bSJan Lentfer 
715825eb42bSJan Lentfer 	/* did the caller actually set it? if not,
716825eb42bSJan Lentfer 	 * fall back to default ttl
717825eb42bSJan Lentfer 	 */
718b5dedccaSJan Lentfer 	if (soa && soa->rrs && soa->rrs->rr
719b5dedccaSJan Lentfer 			&& (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
720b5dedccaSJan Lentfer 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
721825eb42bSJan Lentfer 	} else {
722825eb42bSJan Lentfer 		nsec_ttl = LDNS_DEFAULT_TTL;
723825eb42bSJan Lentfer 	}
724825eb42bSJan Lentfer 
725825eb42bSJan Lentfer 	first_node = ldns_dnssec_name_node_next_nonglue(
726825eb42bSJan Lentfer 			       ldns_rbtree_first(zone->names));
727825eb42bSJan Lentfer 	cur_node = first_node;
728825eb42bSJan Lentfer 	if (cur_node) {
729825eb42bSJan Lentfer 		next_node = ldns_dnssec_name_node_next_nonglue(
730825eb42bSJan Lentfer 			           ldns_rbtree_next(cur_node));
731825eb42bSJan Lentfer 	} else {
732825eb42bSJan Lentfer 		next_node = NULL;
733825eb42bSJan Lentfer 	}
734825eb42bSJan Lentfer 
735825eb42bSJan Lentfer 	while (cur_node && next_node) {
736825eb42bSJan Lentfer 		cur_name = (ldns_dnssec_name *)cur_node->data;
737825eb42bSJan Lentfer 		next_name = (ldns_dnssec_name *)next_node->data;
738825eb42bSJan Lentfer 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
739825eb42bSJan Lentfer 		                                  next_name,
740825eb42bSJan Lentfer 		                                  LDNS_RR_TYPE_NSEC);
741825eb42bSJan Lentfer 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
742fd185f4dSJan Lentfer 		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
743fd185f4dSJan Lentfer 			ldns_rr_free(nsec_rr);
744fd185f4dSJan Lentfer 			return LDNS_STATUS_ERR;
745fd185f4dSJan Lentfer 		}
746825eb42bSJan Lentfer 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
747825eb42bSJan Lentfer 		cur_node = next_node;
748825eb42bSJan Lentfer 		if (cur_node) {
749825eb42bSJan Lentfer 			next_node = ldns_dnssec_name_node_next_nonglue(
750825eb42bSJan Lentfer                                ldns_rbtree_next(cur_node));
751825eb42bSJan Lentfer 		}
752825eb42bSJan Lentfer 	}
753825eb42bSJan Lentfer 
754825eb42bSJan Lentfer 	if (cur_node && !next_node) {
755825eb42bSJan Lentfer 		cur_name = (ldns_dnssec_name *)cur_node->data;
756825eb42bSJan Lentfer 		next_name = (ldns_dnssec_name *)first_node->data;
757825eb42bSJan Lentfer 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
758825eb42bSJan Lentfer 		                                  next_name,
759825eb42bSJan Lentfer 		                                  LDNS_RR_TYPE_NSEC);
760825eb42bSJan Lentfer 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
761fd185f4dSJan Lentfer 		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
762fd185f4dSJan Lentfer 			ldns_rr_free(nsec_rr);
763fd185f4dSJan Lentfer 			return LDNS_STATUS_ERR;
764fd185f4dSJan Lentfer 		}
765825eb42bSJan Lentfer 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
766825eb42bSJan Lentfer 	} else {
767825eb42bSJan Lentfer 		printf("error\n");
768825eb42bSJan Lentfer 	}
769825eb42bSJan Lentfer 
770825eb42bSJan Lentfer 	return LDNS_STATUS_OK;
771825eb42bSJan Lentfer }
772825eb42bSJan Lentfer 
773825eb42bSJan Lentfer #ifdef HAVE_SSL
774b5dedccaSJan Lentfer /* in dnssec_zone.c */
775b5dedccaSJan Lentfer extern int ldns_dname_compare_v(const void *a, const void *b);
776b5dedccaSJan Lentfer 
777825eb42bSJan Lentfer ldns_status
778b5dedccaSJan Lentfer ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
779825eb42bSJan Lentfer 		ldns_rr_list *new_rrs,
780825eb42bSJan Lentfer 		uint8_t algorithm,
781825eb42bSJan Lentfer 		uint8_t flags,
782825eb42bSJan Lentfer 		uint16_t iterations,
783825eb42bSJan Lentfer 		uint8_t salt_length,
784b5dedccaSJan Lentfer 		uint8_t *salt,
785b5dedccaSJan Lentfer 		ldns_rbtree_t **map)
786825eb42bSJan Lentfer {
787825eb42bSJan Lentfer 	ldns_rbnode_t *first_name_node;
788825eb42bSJan Lentfer 	ldns_rbnode_t *current_name_node;
789825eb42bSJan Lentfer 	ldns_dnssec_name *current_name;
790825eb42bSJan Lentfer 	ldns_status result = LDNS_STATUS_OK;
791825eb42bSJan Lentfer 	ldns_rr *nsec_rr;
792825eb42bSJan Lentfer 	ldns_rr_list *nsec3_list;
793825eb42bSJan Lentfer 	uint32_t nsec_ttl;
794825eb42bSJan Lentfer 	ldns_dnssec_rrsets *soa;
795b5dedccaSJan Lentfer 	ldns_rbnode_t *hashmap_node;
796825eb42bSJan Lentfer 
797825eb42bSJan Lentfer 	if (!zone || !new_rrs || !zone->names) {
798825eb42bSJan Lentfer 		return LDNS_STATUS_ERR;
799825eb42bSJan Lentfer 	}
800825eb42bSJan Lentfer 
801825eb42bSJan Lentfer 	/* the TTL of NSEC rrs should be set to the minimum TTL of
802825eb42bSJan Lentfer 	 * the zone SOA (RFC4035 Section 2.3)
803825eb42bSJan Lentfer 	 */
804825eb42bSJan Lentfer 	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
805825eb42bSJan Lentfer 
806825eb42bSJan Lentfer 	/* did the caller actually set it? if not,
807825eb42bSJan Lentfer 	 * fall back to default ttl
808825eb42bSJan Lentfer 	 */
809b5dedccaSJan Lentfer 	if (soa && soa->rrs && soa->rrs->rr
810b5dedccaSJan Lentfer 			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
811b5dedccaSJan Lentfer 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
812825eb42bSJan Lentfer 	} else {
813825eb42bSJan Lentfer 		nsec_ttl = LDNS_DEFAULT_TTL;
814825eb42bSJan Lentfer 	}
815825eb42bSJan Lentfer 
816b5dedccaSJan Lentfer 	if (map) {
817b5dedccaSJan Lentfer 		if ((*map = ldns_rbtree_create(ldns_dname_compare_v))
818b5dedccaSJan Lentfer 				== NULL) {
819b5dedccaSJan Lentfer 			map = NULL;
820b5dedccaSJan Lentfer 		};
821b5dedccaSJan Lentfer 	}
822825eb42bSJan Lentfer 	nsec3_list = ldns_rr_list_new();
823825eb42bSJan Lentfer 
824825eb42bSJan Lentfer 	first_name_node = ldns_dnssec_name_node_next_nonglue(
825825eb42bSJan Lentfer 					  ldns_rbtree_first(zone->names));
826825eb42bSJan Lentfer 
827825eb42bSJan Lentfer 	current_name_node = first_name_node;
828825eb42bSJan Lentfer 
829825eb42bSJan Lentfer 	while (current_name_node &&
830825eb42bSJan Lentfer 	       current_name_node != LDNS_RBTREE_NULL) {
831825eb42bSJan Lentfer 		current_name = (ldns_dnssec_name *) current_name_node->data;
832825eb42bSJan Lentfer 		nsec_rr = ldns_dnssec_create_nsec3(current_name,
833825eb42bSJan Lentfer 		                                   NULL,
834825eb42bSJan Lentfer 		                                   zone->soa->name,
835825eb42bSJan Lentfer 		                                   algorithm,
836825eb42bSJan Lentfer 		                                   flags,
837825eb42bSJan Lentfer 		                                   iterations,
838825eb42bSJan Lentfer 		                                   salt_length,
839825eb42bSJan Lentfer 		                                   salt);
840825eb42bSJan Lentfer 		/* by default, our nsec based generator adds rrsigs
841825eb42bSJan Lentfer 		 * remove the bitmap for empty nonterminals */
842825eb42bSJan Lentfer 		if (!current_name->rrsets) {
843825eb42bSJan Lentfer 			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
844825eb42bSJan Lentfer 		}
845825eb42bSJan Lentfer 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
846fd185f4dSJan Lentfer 		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
847825eb42bSJan Lentfer 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
848825eb42bSJan Lentfer 		ldns_rr_list_push_rr(nsec3_list, nsec_rr);
849b5dedccaSJan Lentfer 		if (map) {
850b5dedccaSJan Lentfer 			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
851b5dedccaSJan Lentfer 			if (hashmap_node && ldns_rr_owner(nsec_rr)) {
852b5dedccaSJan Lentfer 				hashmap_node->key = ldns_dname_label(
853b5dedccaSJan Lentfer 					ldns_rr_owner(nsec_rr), 0);
854b5dedccaSJan Lentfer 				if (hashmap_node->key) {
855b5dedccaSJan Lentfer 					hashmap_node->data = current_name->name;
856b5dedccaSJan Lentfer 					(void) ldns_rbtree_insert(
857b5dedccaSJan Lentfer 							*map, hashmap_node);
858b5dedccaSJan Lentfer 				}
859b5dedccaSJan Lentfer 			}
860b5dedccaSJan Lentfer 		}
861825eb42bSJan Lentfer 		current_name_node = ldns_dnssec_name_node_next_nonglue(
862825eb42bSJan Lentfer 		                   ldns_rbtree_next(current_name_node));
863825eb42bSJan Lentfer 	}
864fd185f4dSJan Lentfer 	if (result != LDNS_STATUS_OK) {
865*d1b2b5caSJohn Marino 		ldns_rr_list_free(nsec3_list);
866fd185f4dSJan Lentfer 		return result;
867fd185f4dSJan Lentfer 	}
868825eb42bSJan Lentfer 
869825eb42bSJan Lentfer 	ldns_rr_list_sort_nsec3(nsec3_list);
870fd185f4dSJan Lentfer 	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
871825eb42bSJan Lentfer 	ldns_rr_list_free(nsec3_list);
872*d1b2b5caSJohn Marino 
873825eb42bSJan Lentfer 	return result;
874825eb42bSJan Lentfer }
875b5dedccaSJan Lentfer 
876b5dedccaSJan Lentfer ldns_status
877b5dedccaSJan Lentfer ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
878b5dedccaSJan Lentfer 		ldns_rr_list *new_rrs,
879b5dedccaSJan Lentfer 		uint8_t algorithm,
880b5dedccaSJan Lentfer 		uint8_t flags,
881b5dedccaSJan Lentfer 		uint16_t iterations,
882b5dedccaSJan Lentfer 		uint8_t salt_length,
883b5dedccaSJan Lentfer 		uint8_t *salt)
884b5dedccaSJan Lentfer {
885b5dedccaSJan Lentfer 	return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
886b5dedccaSJan Lentfer 		       	flags, iterations, salt_length, salt, NULL);
887b5dedccaSJan Lentfer 
888b5dedccaSJan Lentfer }
889825eb42bSJan Lentfer #endif /* HAVE_SSL */
890825eb42bSJan Lentfer 
891825eb42bSJan Lentfer ldns_dnssec_rrs *
892*d1b2b5caSJohn Marino ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
893*d1b2b5caSJohn Marino 			     , ATTR_UNUSED(ldns_key_list *key_list)
894*d1b2b5caSJohn Marino 			     , int (*func)(ldns_rr *, void *)
895*d1b2b5caSJohn Marino 			     , void *arg
896*d1b2b5caSJohn Marino 			     )
897825eb42bSJan Lentfer {
898825eb42bSJan Lentfer 	ldns_dnssec_rrs *base_rrs = signatures;
899825eb42bSJan Lentfer 	ldns_dnssec_rrs *cur_rr = base_rrs;
900825eb42bSJan Lentfer 	ldns_dnssec_rrs *prev_rr = NULL;
901825eb42bSJan Lentfer 	ldns_dnssec_rrs *next_rr;
902825eb42bSJan Lentfer 
903825eb42bSJan Lentfer 	uint16_t keytag;
904825eb42bSJan Lentfer 	size_t i;
905825eb42bSJan Lentfer 
906825eb42bSJan Lentfer 	if (!cur_rr) {
907825eb42bSJan Lentfer 		switch(func(NULL, arg)) {
908825eb42bSJan Lentfer 		case LDNS_SIGNATURE_LEAVE_ADD_NEW:
909825eb42bSJan Lentfer 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
910825eb42bSJan Lentfer 		break;
911825eb42bSJan Lentfer 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
912825eb42bSJan Lentfer 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
913825eb42bSJan Lentfer 		ldns_key_list_set_use(key_list, false);
914825eb42bSJan Lentfer 		break;
915825eb42bSJan Lentfer 		default:
916825eb42bSJan Lentfer 			fprintf(stderr, "[XX] unknown return value from callback\n");
917825eb42bSJan Lentfer 			break;
918825eb42bSJan Lentfer 		}
919825eb42bSJan Lentfer 		return NULL;
920825eb42bSJan Lentfer 	}
921ac996e71SJan Lentfer 	(void)func(cur_rr->rr, arg);
922825eb42bSJan Lentfer 
923825eb42bSJan Lentfer 	while (cur_rr) {
924825eb42bSJan Lentfer 		next_rr = cur_rr->next;
925825eb42bSJan Lentfer 
926825eb42bSJan Lentfer 		switch (func(cur_rr->rr, arg)) {
927825eb42bSJan Lentfer 		case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
928825eb42bSJan Lentfer 			prev_rr = cur_rr;
929825eb42bSJan Lentfer 			break;
930825eb42bSJan Lentfer 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
931825eb42bSJan Lentfer 			keytag = ldns_rdf2native_int16(
932825eb42bSJan Lentfer 					   ldns_rr_rrsig_keytag(cur_rr->rr));
933825eb42bSJan Lentfer 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
934825eb42bSJan Lentfer 				if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
935825eb42bSJan Lentfer 				    keytag) {
936825eb42bSJan Lentfer 					ldns_key_set_use(ldns_key_list_key(key_list, i),
937825eb42bSJan Lentfer 								  false);
938825eb42bSJan Lentfer 				}
939825eb42bSJan Lentfer 			}
940825eb42bSJan Lentfer 			prev_rr = cur_rr;
941825eb42bSJan Lentfer 			break;
942825eb42bSJan Lentfer 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
943825eb42bSJan Lentfer 			keytag = ldns_rdf2native_int16(
944825eb42bSJan Lentfer 					   ldns_rr_rrsig_keytag(cur_rr->rr));
945825eb42bSJan Lentfer 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
946825eb42bSJan Lentfer 				if (ldns_key_keytag(ldns_key_list_key(key_list, i))
947825eb42bSJan Lentfer 				    == keytag) {
948825eb42bSJan Lentfer 					ldns_key_set_use(ldns_key_list_key(key_list, i),
949825eb42bSJan Lentfer 								  false);
950825eb42bSJan Lentfer 				}
951825eb42bSJan Lentfer 			}
952825eb42bSJan Lentfer 			if (prev_rr) {
953825eb42bSJan Lentfer 				prev_rr->next = next_rr;
954825eb42bSJan Lentfer 			} else {
955825eb42bSJan Lentfer 				base_rrs = next_rr;
956825eb42bSJan Lentfer 			}
957825eb42bSJan Lentfer 			LDNS_FREE(cur_rr);
958825eb42bSJan Lentfer 			break;
959825eb42bSJan Lentfer 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
960825eb42bSJan Lentfer 			if (prev_rr) {
961825eb42bSJan Lentfer 				prev_rr->next = next_rr;
962825eb42bSJan Lentfer 			} else {
963825eb42bSJan Lentfer 				base_rrs = next_rr;
964825eb42bSJan Lentfer 			}
965825eb42bSJan Lentfer 			LDNS_FREE(cur_rr);
966825eb42bSJan Lentfer 			break;
967825eb42bSJan Lentfer 		default:
968825eb42bSJan Lentfer 			fprintf(stderr, "[XX] unknown return value from callback\n");
969825eb42bSJan Lentfer 			break;
970825eb42bSJan Lentfer 		}
971825eb42bSJan Lentfer 		cur_rr = next_rr;
972825eb42bSJan Lentfer 	}
973825eb42bSJan Lentfer 
974825eb42bSJan Lentfer 	return base_rrs;
975825eb42bSJan Lentfer }
976825eb42bSJan Lentfer 
977825eb42bSJan Lentfer #ifdef HAVE_SSL
978825eb42bSJan Lentfer ldns_status
979825eb42bSJan Lentfer ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
980825eb42bSJan Lentfer                                ldns_rr_list *new_rrs,
981825eb42bSJan Lentfer                                ldns_key_list *key_list,
982825eb42bSJan Lentfer                                int (*func)(ldns_rr *, void*),
983825eb42bSJan Lentfer                                void *arg)
984825eb42bSJan Lentfer {
985825eb42bSJan Lentfer 	return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
986825eb42bSJan Lentfer 		func, arg, 0);
987825eb42bSJan Lentfer }
988825eb42bSJan Lentfer 
989825eb42bSJan Lentfer /** If there are KSKs use only them and mark ZSKs unused */
990825eb42bSJan Lentfer static void
991825eb42bSJan Lentfer ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
992825eb42bSJan Lentfer {
993825eb42bSJan Lentfer 	int saw_ksk = 0;
994825eb42bSJan Lentfer 	size_t i;
995825eb42bSJan Lentfer 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
996825eb42bSJan Lentfer 		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
997825eb42bSJan Lentfer 			saw_ksk = 1;
998825eb42bSJan Lentfer 			break;
999825eb42bSJan Lentfer 		}
1000825eb42bSJan Lentfer 	if(!saw_ksk)
1001825eb42bSJan Lentfer 		return;
1002825eb42bSJan Lentfer 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1003825eb42bSJan Lentfer 		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1004825eb42bSJan Lentfer 			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
1005825eb42bSJan Lentfer }
1006825eb42bSJan Lentfer 
1007ac996e71SJan Lentfer /** If there are no ZSKs use KSK as ZSK */
1008ac996e71SJan Lentfer static void
1009ac996e71SJan Lentfer ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
1010ac996e71SJan Lentfer {
1011ac996e71SJan Lentfer 	int saw_zsk = 0;
1012ac996e71SJan Lentfer 	size_t i;
1013ac996e71SJan Lentfer 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1014ac996e71SJan Lentfer 		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
1015ac996e71SJan Lentfer 			saw_zsk = 1;
1016ac996e71SJan Lentfer 			break;
1017ac996e71SJan Lentfer 		}
1018ac996e71SJan Lentfer 	if(!saw_zsk)
1019ac996e71SJan Lentfer 		return;
1020ac996e71SJan Lentfer 	/* else filter all KSKs */
1021ac996e71SJan Lentfer 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1022ac996e71SJan Lentfer 		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1023ac996e71SJan Lentfer 			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
1024ac996e71SJan Lentfer }
1025ac996e71SJan Lentfer 
1026825eb42bSJan Lentfer ldns_status
1027*d1b2b5caSJohn Marino ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
1028*d1b2b5caSJohn Marino 				  , ldns_rr_list *new_rrs
1029*d1b2b5caSJohn Marino 				  , ldns_key_list *key_list
1030*d1b2b5caSJohn Marino 				  , int (*func)(ldns_rr *, void*)
1031*d1b2b5caSJohn Marino 				  , void *arg
1032*d1b2b5caSJohn Marino 				  , int flags
1033*d1b2b5caSJohn Marino 				  )
1034825eb42bSJan Lentfer {
1035825eb42bSJan Lentfer 	ldns_status result = LDNS_STATUS_OK;
1036825eb42bSJan Lentfer 
1037825eb42bSJan Lentfer 	ldns_rbnode_t *cur_node;
1038825eb42bSJan Lentfer 	ldns_rr_list *rr_list;
1039825eb42bSJan Lentfer 
1040825eb42bSJan Lentfer 	ldns_dnssec_name *cur_name;
1041825eb42bSJan Lentfer 	ldns_dnssec_rrsets *cur_rrset;
1042825eb42bSJan Lentfer 	ldns_dnssec_rrs *cur_rr;
1043825eb42bSJan Lentfer 
1044825eb42bSJan Lentfer 	ldns_rr_list *siglist;
1045825eb42bSJan Lentfer 
1046825eb42bSJan Lentfer 	size_t i;
1047825eb42bSJan Lentfer 
1048b5dedccaSJan Lentfer 	int on_delegation_point = 0; /* handle partially occluded names */
1049b5dedccaSJan Lentfer 
1050825eb42bSJan Lentfer 	ldns_rr_list *pubkey_list = ldns_rr_list_new();
1051825eb42bSJan Lentfer 	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
1052*d1b2b5caSJohn Marino 		ldns_rr_list_push_rr( pubkey_list
1053*d1b2b5caSJohn Marino 				    , ldns_key2rr(ldns_key_list_key(
1054*d1b2b5caSJohn Marino 							key_list, i))
1055*d1b2b5caSJohn Marino 				    );
1056825eb42bSJan Lentfer 	}
1057825eb42bSJan Lentfer 	/* TODO: callback to see is list should be signed */
1058825eb42bSJan Lentfer 	/* TODO: remove 'old' signatures from signature list */
1059825eb42bSJan Lentfer 	cur_node = ldns_rbtree_first(zone->names);
1060825eb42bSJan Lentfer 	while (cur_node != LDNS_RBTREE_NULL) {
1061825eb42bSJan Lentfer 		cur_name = (ldns_dnssec_name *) cur_node->data;
1062825eb42bSJan Lentfer 
1063825eb42bSJan Lentfer 		if (!cur_name->is_glue) {
1064b5dedccaSJan Lentfer 			on_delegation_point = ldns_dnssec_rrsets_contains_type(
1065b5dedccaSJan Lentfer 					cur_name->rrsets, LDNS_RR_TYPE_NS)
1066b5dedccaSJan Lentfer 				&& !ldns_dnssec_rrsets_contains_type(
1067b5dedccaSJan Lentfer 					cur_name->rrsets, LDNS_RR_TYPE_SOA);
1068825eb42bSJan Lentfer 			cur_rrset = cur_name->rrsets;
1069825eb42bSJan Lentfer 			while (cur_rrset) {
1070825eb42bSJan Lentfer 				/* reset keys to use */
1071825eb42bSJan Lentfer 				ldns_key_list_set_use(key_list, true);
1072825eb42bSJan Lentfer 
1073825eb42bSJan Lentfer 				/* walk through old sigs, remove the old,
1074825eb42bSJan Lentfer 				   and mark which keys (not) to use) */
1075825eb42bSJan Lentfer 				cur_rrset->signatures =
1076825eb42bSJan Lentfer 					ldns_dnssec_remove_signatures(cur_rrset->signatures,
1077825eb42bSJan Lentfer 											key_list,
1078825eb42bSJan Lentfer 											func,
1079825eb42bSJan Lentfer 											arg);
1080825eb42bSJan Lentfer 				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
1081825eb42bSJan Lentfer 					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
1082825eb42bSJan Lentfer 					ldns_key_list_filter_for_dnskey(key_list);
1083825eb42bSJan Lentfer 
1084ac996e71SJan Lentfer 				if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
1085ac996e71SJan Lentfer 					ldns_key_list_filter_for_non_dnskey(key_list);
1086ac996e71SJan Lentfer 
1087825eb42bSJan Lentfer 				/* TODO: just set count to zero? */
1088825eb42bSJan Lentfer 				rr_list = ldns_rr_list_new();
1089825eb42bSJan Lentfer 
1090825eb42bSJan Lentfer 				cur_rr = cur_rrset->rrs;
1091825eb42bSJan Lentfer 				while (cur_rr) {
1092825eb42bSJan Lentfer 					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
1093825eb42bSJan Lentfer 					cur_rr = cur_rr->next;
1094825eb42bSJan Lentfer 				}
1095825eb42bSJan Lentfer 
1096825eb42bSJan Lentfer 				/* only sign non-delegation RRsets */
1097b5dedccaSJan Lentfer 				/* (glue should have been marked earlier,
1098b5dedccaSJan Lentfer 				 *  except on the delegation points itself) */
1099b5dedccaSJan Lentfer 				if (!on_delegation_point ||
1100b5dedccaSJan Lentfer 						ldns_rr_list_type(rr_list)
1101b5dedccaSJan Lentfer 							== LDNS_RR_TYPE_DS ||
1102b5dedccaSJan Lentfer 						ldns_rr_list_type(rr_list)
1103b5dedccaSJan Lentfer 							== LDNS_RR_TYPE_NSEC ||
1104b5dedccaSJan Lentfer 						ldns_rr_list_type(rr_list)
1105b5dedccaSJan Lentfer 							== LDNS_RR_TYPE_NSEC3) {
1106825eb42bSJan Lentfer 					siglist = ldns_sign_public(rr_list, key_list);
1107825eb42bSJan Lentfer 					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1108825eb42bSJan Lentfer 						if (cur_rrset->signatures) {
1109fd185f4dSJan Lentfer 							result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
1110825eb42bSJan Lentfer 											   ldns_rr_list_rr(siglist,
1111825eb42bSJan Lentfer 														    i));
1112825eb42bSJan Lentfer 						} else {
1113825eb42bSJan Lentfer 							cur_rrset->signatures = ldns_dnssec_rrs_new();
1114825eb42bSJan Lentfer 							cur_rrset->signatures->rr =
1115825eb42bSJan Lentfer 								ldns_rr_list_rr(siglist, i);
1116*d1b2b5caSJohn Marino 						}
1117*d1b2b5caSJohn Marino 						if (new_rrs) {
1118825eb42bSJan Lentfer 							ldns_rr_list_push_rr(new_rrs,
1119825eb42bSJan Lentfer 												 ldns_rr_list_rr(siglist,
1120825eb42bSJan Lentfer 															  i));
1121825eb42bSJan Lentfer 						}
1122825eb42bSJan Lentfer 					}
1123825eb42bSJan Lentfer 					ldns_rr_list_free(siglist);
1124825eb42bSJan Lentfer 				}
1125825eb42bSJan Lentfer 
1126825eb42bSJan Lentfer 				ldns_rr_list_free(rr_list);
1127825eb42bSJan Lentfer 
1128825eb42bSJan Lentfer 				cur_rrset = cur_rrset->next;
1129825eb42bSJan Lentfer 			}
1130825eb42bSJan Lentfer 
1131825eb42bSJan Lentfer 			/* sign the nsec */
1132ac996e71SJan Lentfer 			ldns_key_list_set_use(key_list, true);
1133825eb42bSJan Lentfer 			cur_name->nsec_signatures =
1134825eb42bSJan Lentfer 				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
1135825eb42bSJan Lentfer 										key_list,
1136825eb42bSJan Lentfer 										func,
1137825eb42bSJan Lentfer 										arg);
1138ac996e71SJan Lentfer 			ldns_key_list_filter_for_non_dnskey(key_list);
1139825eb42bSJan Lentfer 
1140825eb42bSJan Lentfer 			rr_list = ldns_rr_list_new();
1141825eb42bSJan Lentfer 			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
1142825eb42bSJan Lentfer 			siglist = ldns_sign_public(rr_list, key_list);
1143825eb42bSJan Lentfer 
1144825eb42bSJan Lentfer 			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1145825eb42bSJan Lentfer 				if (cur_name->nsec_signatures) {
1146fd185f4dSJan Lentfer 					result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
1147825eb42bSJan Lentfer 									   ldns_rr_list_rr(siglist, i));
1148825eb42bSJan Lentfer 				} else {
1149825eb42bSJan Lentfer 					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
1150825eb42bSJan Lentfer 					cur_name->nsec_signatures->rr =
1151825eb42bSJan Lentfer 						ldns_rr_list_rr(siglist, i);
1152*d1b2b5caSJohn Marino 				}
1153*d1b2b5caSJohn Marino 				if (new_rrs) {
1154825eb42bSJan Lentfer 					ldns_rr_list_push_rr(new_rrs,
1155825eb42bSJan Lentfer 								 ldns_rr_list_rr(siglist, i));
1156825eb42bSJan Lentfer 				}
1157825eb42bSJan Lentfer 			}
1158825eb42bSJan Lentfer 
1159825eb42bSJan Lentfer 			ldns_rr_list_free(siglist);
1160825eb42bSJan Lentfer 			ldns_rr_list_free(rr_list);
1161825eb42bSJan Lentfer 		}
1162825eb42bSJan Lentfer 		cur_node = ldns_rbtree_next(cur_node);
1163825eb42bSJan Lentfer 	}
1164825eb42bSJan Lentfer 
1165825eb42bSJan Lentfer 	ldns_rr_list_deep_free(pubkey_list);
1166825eb42bSJan Lentfer 	return result;
1167825eb42bSJan Lentfer }
1168825eb42bSJan Lentfer 
1169825eb42bSJan Lentfer ldns_status
1170825eb42bSJan Lentfer ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
1171825eb42bSJan Lentfer 				  ldns_rr_list *new_rrs,
1172825eb42bSJan Lentfer 				  ldns_key_list *key_list,
1173825eb42bSJan Lentfer 				  int (*func)(ldns_rr *, void *),
1174825eb42bSJan Lentfer 				  void *arg)
1175825eb42bSJan Lentfer {
1176825eb42bSJan Lentfer 	return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
1177825eb42bSJan Lentfer }
1178825eb42bSJan Lentfer 
1179825eb42bSJan Lentfer ldns_status
1180825eb42bSJan Lentfer ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
1181825eb42bSJan Lentfer 				  ldns_rr_list *new_rrs,
1182825eb42bSJan Lentfer 				  ldns_key_list *key_list,
1183825eb42bSJan Lentfer 				  int (*func)(ldns_rr *, void *),
1184825eb42bSJan Lentfer 				  void *arg,
1185825eb42bSJan Lentfer 				  int flags)
1186825eb42bSJan Lentfer {
1187825eb42bSJan Lentfer 	ldns_status result = LDNS_STATUS_OK;
1188825eb42bSJan Lentfer 
1189825eb42bSJan Lentfer 	if (!zone || !new_rrs || !key_list) {
1190825eb42bSJan Lentfer 		return LDNS_STATUS_ERR;
1191825eb42bSJan Lentfer 	}
1192825eb42bSJan Lentfer 
1193825eb42bSJan Lentfer 	/* zone is already sorted */
1194fd185f4dSJan Lentfer 	result = ldns_dnssec_zone_mark_glue(zone);
1195fd185f4dSJan Lentfer 	if (result != LDNS_STATUS_OK) {
1196fd185f4dSJan Lentfer 		return result;
1197fd185f4dSJan Lentfer 	}
1198825eb42bSJan Lentfer 
1199825eb42bSJan Lentfer 	/* check whether we need to add nsecs */
1200825eb42bSJan Lentfer 	if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
1201825eb42bSJan Lentfer 		result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
1202825eb42bSJan Lentfer 		if (result != LDNS_STATUS_OK) {
1203825eb42bSJan Lentfer 			return result;
1204825eb42bSJan Lentfer 		}
1205825eb42bSJan Lentfer 	}
1206825eb42bSJan Lentfer 
1207825eb42bSJan Lentfer 	result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1208825eb42bSJan Lentfer 					new_rrs,
1209825eb42bSJan Lentfer 					key_list,
1210825eb42bSJan Lentfer 					func,
1211825eb42bSJan Lentfer 					arg,
1212825eb42bSJan Lentfer 					flags);
1213825eb42bSJan Lentfer 
1214825eb42bSJan Lentfer 	return result;
1215825eb42bSJan Lentfer }
1216825eb42bSJan Lentfer 
1217825eb42bSJan Lentfer ldns_status
1218825eb42bSJan Lentfer ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
1219825eb42bSJan Lentfer 					   ldns_rr_list *new_rrs,
1220825eb42bSJan Lentfer 					   ldns_key_list *key_list,
1221825eb42bSJan Lentfer 					   int (*func)(ldns_rr *, void *),
1222825eb42bSJan Lentfer 					   void *arg,
1223825eb42bSJan Lentfer 					   uint8_t algorithm,
1224825eb42bSJan Lentfer 					   uint8_t flags,
1225825eb42bSJan Lentfer 					   uint16_t iterations,
1226825eb42bSJan Lentfer 					   uint8_t salt_length,
1227825eb42bSJan Lentfer 					   uint8_t *salt)
1228825eb42bSJan Lentfer {
1229b5dedccaSJan Lentfer 	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1230b5dedccaSJan Lentfer 		func, arg, algorithm, flags, iterations, salt_length, salt, 0,
1231b5dedccaSJan Lentfer 	       	NULL);
1232825eb42bSJan Lentfer }
1233825eb42bSJan Lentfer 
1234825eb42bSJan Lentfer ldns_status
1235b5dedccaSJan Lentfer ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
1236825eb42bSJan Lentfer 		ldns_rr_list *new_rrs,
1237825eb42bSJan Lentfer 		ldns_key_list *key_list,
1238825eb42bSJan Lentfer 		int (*func)(ldns_rr *, void *),
1239825eb42bSJan Lentfer 		void *arg,
1240825eb42bSJan Lentfer 		uint8_t algorithm,
1241825eb42bSJan Lentfer 		uint8_t flags,
1242825eb42bSJan Lentfer 		uint16_t iterations,
1243825eb42bSJan Lentfer 		uint8_t salt_length,
1244825eb42bSJan Lentfer 		uint8_t *salt,
1245b5dedccaSJan Lentfer 		int signflags,
1246b5dedccaSJan Lentfer 		ldns_rbtree_t **map)
1247825eb42bSJan Lentfer {
1248b5dedccaSJan Lentfer 	ldns_rr *nsec3, *nsec3param;
1249825eb42bSJan Lentfer 	ldns_status result = LDNS_STATUS_OK;
1250825eb42bSJan Lentfer 
1251825eb42bSJan Lentfer 	/* zone is already sorted */
1252fd185f4dSJan Lentfer 	result = ldns_dnssec_zone_mark_glue(zone);
1253fd185f4dSJan Lentfer 	if (result != LDNS_STATUS_OK) {
1254fd185f4dSJan Lentfer 		return result;
1255fd185f4dSJan Lentfer 	}
1256825eb42bSJan Lentfer 
1257825eb42bSJan Lentfer 	/* TODO if there are already nsec3s presents and their
1258825eb42bSJan Lentfer 	 * parameters are the same as these, we don't have to recreate
1259825eb42bSJan Lentfer 	 */
1260825eb42bSJan Lentfer 	if (zone->names) {
1261825eb42bSJan Lentfer 		/* add empty nonterminals */
1262fd185f4dSJan Lentfer 		result = ldns_dnssec_zone_add_empty_nonterminals(zone);
1263fd185f4dSJan Lentfer 		if (result != LDNS_STATUS_OK) {
1264fd185f4dSJan Lentfer 			return result;
1265fd185f4dSJan Lentfer 		}
1266825eb42bSJan Lentfer 
1267825eb42bSJan Lentfer 		nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1268825eb42bSJan Lentfer 		if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
1269825eb42bSJan Lentfer 			/* no need to recreate */
1270825eb42bSJan Lentfer 		} else {
1271825eb42bSJan Lentfer 			if (!ldns_dnssec_zone_find_rrset(zone,
1272825eb42bSJan Lentfer 									   zone->soa->name,
1273b5dedccaSJan Lentfer 									   LDNS_RR_TYPE_NSEC3PARAM)) {
1274b5dedccaSJan Lentfer 				/* create and add the nsec3param rr */
1275b5dedccaSJan Lentfer 				nsec3param =
1276b5dedccaSJan Lentfer 					ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
1277b5dedccaSJan Lentfer 				ldns_rr_set_owner(nsec3param,
1278825eb42bSJan Lentfer 							   ldns_rdf_clone(zone->soa->name));
1279b5dedccaSJan Lentfer 				ldns_nsec3_add_param_rdfs(nsec3param,
1280825eb42bSJan Lentfer 									 algorithm,
1281825eb42bSJan Lentfer 									 flags,
1282825eb42bSJan Lentfer 									 iterations,
1283825eb42bSJan Lentfer 									 salt_length,
1284825eb42bSJan Lentfer 									 salt);
1285825eb42bSJan Lentfer 				/* always set bit 7 of the flags to zero, according to
1286*d1b2b5caSJohn Marino 				 * rfc5155 section 11. The bits are counted from right to left,
1287*d1b2b5caSJohn Marino 				 * so bit 7 in rfc5155 is bit 0 in ldns */
1288*d1b2b5caSJohn Marino 				ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
1289b5dedccaSJan Lentfer 				result = ldns_dnssec_zone_add_rr(zone, nsec3param);
1290fd185f4dSJan Lentfer 				if (result != LDNS_STATUS_OK) {
1291fd185f4dSJan Lentfer 					return result;
1292fd185f4dSJan Lentfer 				}
1293b5dedccaSJan Lentfer 				ldns_rr_list_push_rr(new_rrs, nsec3param);
1294825eb42bSJan Lentfer 			}
1295b5dedccaSJan Lentfer 			result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
1296825eb42bSJan Lentfer 											new_rrs,
1297825eb42bSJan Lentfer 											algorithm,
1298825eb42bSJan Lentfer 											flags,
1299825eb42bSJan Lentfer 											iterations,
1300825eb42bSJan Lentfer 											salt_length,
1301b5dedccaSJan Lentfer 											salt,
1302b5dedccaSJan Lentfer 											map);
1303825eb42bSJan Lentfer 			if (result != LDNS_STATUS_OK) {
1304825eb42bSJan Lentfer 				return result;
1305825eb42bSJan Lentfer 			}
1306825eb42bSJan Lentfer 		}
1307825eb42bSJan Lentfer 
1308825eb42bSJan Lentfer 		result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1309825eb42bSJan Lentfer 						new_rrs,
1310825eb42bSJan Lentfer 						key_list,
1311825eb42bSJan Lentfer 						func,
1312825eb42bSJan Lentfer 						arg,
1313825eb42bSJan Lentfer 						signflags);
1314825eb42bSJan Lentfer 	}
1315825eb42bSJan Lentfer 
1316825eb42bSJan Lentfer 	return result;
1317825eb42bSJan Lentfer }
1318825eb42bSJan Lentfer 
1319b5dedccaSJan Lentfer ldns_status
1320b5dedccaSJan Lentfer ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
1321b5dedccaSJan Lentfer 		ldns_rr_list *new_rrs,
1322b5dedccaSJan Lentfer 		ldns_key_list *key_list,
1323b5dedccaSJan Lentfer 		int (*func)(ldns_rr *, void *),
1324b5dedccaSJan Lentfer 		void *arg,
1325b5dedccaSJan Lentfer 		uint8_t algorithm,
1326b5dedccaSJan Lentfer 		uint8_t flags,
1327b5dedccaSJan Lentfer 		uint16_t iterations,
1328b5dedccaSJan Lentfer 		uint8_t salt_length,
1329b5dedccaSJan Lentfer 		uint8_t *salt,
1330b5dedccaSJan Lentfer 		int signflags)
1331b5dedccaSJan Lentfer {
1332b5dedccaSJan Lentfer 	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1333b5dedccaSJan Lentfer 		func, arg, algorithm, flags, iterations, salt_length, salt,
1334b5dedccaSJan Lentfer 		signflags, NULL);
1335b5dedccaSJan Lentfer }
1336825eb42bSJan Lentfer 
1337825eb42bSJan Lentfer ldns_zone *
1338825eb42bSJan Lentfer ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
1339825eb42bSJan Lentfer {
1340825eb42bSJan Lentfer 	ldns_dnssec_zone *dnssec_zone;
1341825eb42bSJan Lentfer 	ldns_zone *signed_zone;
1342825eb42bSJan Lentfer 	ldns_rr_list *new_rrs;
1343825eb42bSJan Lentfer 	size_t i;
1344825eb42bSJan Lentfer 
1345825eb42bSJan Lentfer 	signed_zone = ldns_zone_new();
1346825eb42bSJan Lentfer 	dnssec_zone = ldns_dnssec_zone_new();
1347825eb42bSJan Lentfer 
1348825eb42bSJan Lentfer 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1349ac996e71SJan Lentfer 	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1350825eb42bSJan Lentfer 
1351825eb42bSJan Lentfer 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1352825eb42bSJan Lentfer 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1353825eb42bSJan Lentfer 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1354825eb42bSJan Lentfer 											  i));
1355825eb42bSJan Lentfer 		ldns_zone_push_rr(signed_zone,
1356825eb42bSJan Lentfer 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1357825eb42bSJan Lentfer 											   i)));
1358825eb42bSJan Lentfer 	}
1359825eb42bSJan Lentfer 
1360825eb42bSJan Lentfer 	new_rrs = ldns_rr_list_new();
1361825eb42bSJan Lentfer 	(void) ldns_dnssec_zone_sign(dnssec_zone,
1362825eb42bSJan Lentfer 						    new_rrs,
1363825eb42bSJan Lentfer 						    key_list,
1364825eb42bSJan Lentfer 						    ldns_dnssec_default_replace_signatures,
1365825eb42bSJan Lentfer 						    NULL);
1366825eb42bSJan Lentfer 
1367825eb42bSJan Lentfer     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1368825eb42bSJan Lentfer 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1369825eb42bSJan Lentfer 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1370825eb42bSJan Lentfer 	}
1371825eb42bSJan Lentfer 
1372825eb42bSJan Lentfer 	ldns_rr_list_deep_free(new_rrs);
1373825eb42bSJan Lentfer 	ldns_dnssec_zone_free(dnssec_zone);
1374825eb42bSJan Lentfer 
1375825eb42bSJan Lentfer 	return signed_zone;
1376825eb42bSJan Lentfer }
1377825eb42bSJan Lentfer 
1378825eb42bSJan Lentfer ldns_zone *
1379825eb42bSJan Lentfer 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)
1380825eb42bSJan Lentfer {
1381825eb42bSJan Lentfer 	ldns_dnssec_zone *dnssec_zone;
1382825eb42bSJan Lentfer 	ldns_zone *signed_zone;
1383825eb42bSJan Lentfer 	ldns_rr_list *new_rrs;
1384825eb42bSJan Lentfer 	size_t i;
1385825eb42bSJan Lentfer 
1386825eb42bSJan Lentfer 	signed_zone = ldns_zone_new();
1387825eb42bSJan Lentfer 	dnssec_zone = ldns_dnssec_zone_new();
1388825eb42bSJan Lentfer 
1389825eb42bSJan Lentfer 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1390ac996e71SJan Lentfer 	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1391825eb42bSJan Lentfer 
1392825eb42bSJan Lentfer 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1393825eb42bSJan Lentfer 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1394825eb42bSJan Lentfer 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1395825eb42bSJan Lentfer 											  i));
1396825eb42bSJan Lentfer 		ldns_zone_push_rr(signed_zone,
1397825eb42bSJan Lentfer 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1398825eb42bSJan Lentfer 											   i)));
1399825eb42bSJan Lentfer 	}
1400825eb42bSJan Lentfer 
1401825eb42bSJan Lentfer 	new_rrs = ldns_rr_list_new();
1402825eb42bSJan Lentfer 	(void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
1403825eb42bSJan Lentfer 								new_rrs,
1404825eb42bSJan Lentfer 								key_list,
1405825eb42bSJan Lentfer 								ldns_dnssec_default_replace_signatures,
1406825eb42bSJan Lentfer 								NULL,
1407825eb42bSJan Lentfer 								algorithm,
1408825eb42bSJan Lentfer 								flags,
1409825eb42bSJan Lentfer 								iterations,
1410825eb42bSJan Lentfer 								salt_length,
1411825eb42bSJan Lentfer 								salt);
1412825eb42bSJan Lentfer 
1413825eb42bSJan Lentfer     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1414825eb42bSJan Lentfer 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1415825eb42bSJan Lentfer 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1416825eb42bSJan Lentfer 	}
1417825eb42bSJan Lentfer 
1418825eb42bSJan Lentfer 	ldns_rr_list_deep_free(new_rrs);
1419825eb42bSJan Lentfer 	ldns_dnssec_zone_free(dnssec_zone);
1420825eb42bSJan Lentfer 
1421825eb42bSJan Lentfer 	return signed_zone;
1422825eb42bSJan Lentfer }
1423825eb42bSJan Lentfer #endif /* HAVE_SSL */
1424825eb42bSJan Lentfer 
1425b5dedccaSJan Lentfer 
1426