label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
0)));
-
+ /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
+ if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
+ label_count --;
+
current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
-
+
/* set the type on the new signature */
orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
ldns_rr_set_ttl(current_sig, orig_ttl);
ldns_rr_set_class(current_sig, orig_class);
- ldns_rr_set_owner(current_sig,
+ ldns_rr_set_owner(current_sig,
ldns_rdf_clone(
ldns_rr_owner(
ldns_rr_list_rr(rrset,
0))));
/* fill in what we know of the signature */
-
+
/* set the orig_ttl */
(void)ldns_rr_rrsig_set_origttl(
- current_sig,
+ current_sig,
ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
orig_ttl));
/* the signers name */
(void)ldns_rr_rrsig_set_signame(
- current_sig,
+ current_sig,
ldns_rdf_clone(ldns_key_pubkey_owner(current_key)));
/* label count - get it from the first rr in the rr_list */
(void)ldns_rr_rrsig_set_labels(
- current_sig,
+ current_sig,
ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
label_count));
/* inception, expiration */
(void)ldns_rr_rrsig_set_inception(
current_sig,
ldns_native2rdf_int32(
- LDNS_RDF_TYPE_TIME,
+ LDNS_RDF_TYPE_TIME,
ldns_key_inception(current_key)));
} else {
(void)ldns_rr_rrsig_set_inception(
(void)ldns_rr_rrsig_set_expiration(
current_sig,
ldns_native2rdf_int32(
- LDNS_RDF_TYPE_TIME,
+ LDNS_RDF_TYPE_TIME,
ldns_key_expiration(current_key)));
} else {
(void)ldns_rr_rrsig_set_expiration(
current_sig,
ldns_native2rdf_int32(
- LDNS_RDF_TYPE_TIME,
+ LDNS_RDF_TYPE_TIME,
now + LDNS_DEFAULT_EXP_TIME));
}
(void)ldns_rr_rrsig_set_keytag(
current_sig,
- ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
+ ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
ldns_key_keytag(current_key)));
(void)ldns_rr_rrsig_set_algorithm(
current_sig,
ldns_native2rdf_int8(
- LDNS_RDF_TYPE_ALG,
+ LDNS_RDF_TYPE_ALG,
ldns_key_algorithm(current_key)));
(void)ldns_rr_rrsig_set_typecovered(
break;
#endif /* USE_SHA2 */
#ifdef USE_GOST
- case LDNS_SIGN_GOST:
+ case LDNS_SIGN_ECC_GOST:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
EVP_get_digestbyname("md_gost94"));
break;
#endif /* USE_GOST */
+#ifdef USE_ECDSA
+ case LDNS_SIGN_ECDSAP256SHA256:
+ b64rdf = ldns_sign_public_evp(
+ sign_buf,
+ ldns_key_evp_key(current_key),
+ EVP_sha256());
+ break;
+ case LDNS_SIGN_ECDSAP384SHA384:
+ b64rdf = ldns_sign_public_evp(
+ sign_buf,
+ ldns_key_evp_key(current_key),
+ EVP_sha384());
+ break;
+#endif
case LDNS_SIGN_RSAMD5:
b64rdf = ldns_sign_public_evp(
sign_buf,
printf("is the one used available on this system?\n");
break;
}
-
+
return b64rdf;
}
if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
return NULL;
}
-
+
new_owner = NULL;
- key_count = 0;
signatures = ldns_rr_list_new();
/* prepare a signature and add all the know data
}
/* sort */
ldns_rr_list_sort(rrset_clone);
-
+
for (key_count = 0;
key_count < ldns_key_list_key_count(keys);
key_count++) {
current_key = ldns_key_list_key(keys, key_count);
/* sign all RRs with keys that have ZSKbit, !SEPbit.
sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
- if (
- ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
- (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY)
- || ldns_rr_get_type(ldns_rr_list_rr(rrset, 0))
- == LDNS_RR_TYPE_DNSKEY)
- ) {
+ if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
current_sig = ldns_create_empty_rrsig(rrset_clone,
current_key);
if (!b64sig) {
return NULL;
}
-
+
sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign), NULL);
if (!sha1_hash) {
return sigdata_rdf;
}
+#ifdef USE_ECDSA
+static int
+ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
+{
+ EC_KEY* ec;
+ const EC_GROUP* g;
+ if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
+ return 0;
+ ec = EVP_PKEY_get1_EC_KEY(pkey);
+ g = EC_KEY_get0_group(ec);
+ if(!g) {
+ EC_KEY_free(ec);
+ return 0;
+ }
+ if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
+ EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
+ EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+ EC_KEY_free(ec);
+ return 1;
+ }
+ /* downref the eckey, the original is still inside the pkey */
+ EC_KEY_free(ec);
+ return 0;
+}
+#endif /* USE_ECDSA */
+
ldns_rdf *
ldns_sign_public_evp(ldns_buffer *to_sign,
EVP_PKEY *key,
r = EVP_SignInit(&ctx, md_type);
if(r == 1) {
r = EVP_SignUpdate(&ctx, (unsigned char*)
- ldns_buffer_begin(to_sign),
+ ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign));
} else {
ldns_buffer_free(b64sig);
/* unfortunately, OpenSSL output is differenct from DNS DSA format */
if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
+#ifdef USE_ECDSA
+ } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
+ ldns_pkey_is_ecdsa(key)) {
+ sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
+#endif
} else {
/* ok output for other types is the same */
sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
if (!b64sig) {
return NULL;
}
-
+
md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign), NULL);
if (!md5_hash) {
(unsigned char*)ldns_buffer_begin(b64sig),
&siglen, key);
- sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
+ sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
ldns_buffer_begin(b64sig));
ldns_buffer_free(b64sig);
return sigdata_rdf;
ldns_rr *nsec_rr;
uint32_t nsec_ttl;
ldns_dnssec_rrsets *soa;
-
+
/* the TTL of NSEC rrs should be set to the minimum TTL of
* the zone SOA (RFC4035 Section 2.3)
*/
soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-
+
/* did the caller actually set it? if not,
* fall back to default ttl
*/
} else {
nsec_ttl = LDNS_DEFAULT_TTL;
}
-
+
first_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_first(zone->names));
cur_node = first_node;
ldns_rr_list *nsec3_list;
uint32_t nsec_ttl;
ldns_dnssec_rrsets *soa;
-
+
if (!zone || !new_rrs || !zone->names) {
return LDNS_STATUS_ERR;
}
-
+
/* the TTL of NSEC rrs should be set to the minimum TTL of
* the zone SOA (RFC4035 Section 2.3)
*/
soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-
+
/* did the caller actually set it? if not,
* fall back to default ttl
*/
first_name_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_first(zone->names));
-
+
current_name_node = first_name_node;
while (current_name_node &&
if (result != LDNS_STATUS_OK) {
return result;
}
-
+
ldns_rr_list_free(nsec3_list);
return result;
}
uint16_t keytag;
size_t i;
- int v;
key_list = key_list;
}
return NULL;
}
- v = func(cur_rr->rr, arg);
+ (void)func(cur_rr->rr, arg);
while (cur_rr) {
next_rr = cur_rr->next;
-
+
switch (func(cur_rr->rr, arg)) {
case LDNS_SIGNATURE_LEAVE_ADD_NEW:
prev_rr = cur_rr;
int (*func)(ldns_rr *, void*),
void *arg)
{
- return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
+ return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
func, arg, 0);
}
ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
}
+/** If there are no ZSKs use KSK as ZSK */
+static void
+ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
+{
+ int saw_zsk = 0;
+ size_t i;
+ for(i=0; i<ldns_key_list_key_count(key_list); i++)
+ if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
+ saw_zsk = 1;
+ break;
+ }
+ if(!saw_zsk)
+ return;
+ /* else filter all KSKs */
+ for(i=0; i<ldns_key_list_key_count(key_list); i++)
+ if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
+ ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
+}
+
ldns_status
ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_dnssec_rrs *cur_rr;
ldns_rr_list *siglist;
-
+
size_t i;
ldns_rr_list *pubkey_list = ldns_rr_list_new();
while (cur_rrset) {
/* reset keys to use */
ldns_key_list_set_use(key_list, true);
-
+
/* walk through old sigs, remove the old,
and mark which keys (not) to use) */
cur_rrset->signatures =
if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
ldns_key_list_filter_for_dnskey(key_list);
-
+
+ if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
+ ldns_key_list_filter_for_non_dnskey(key_list);
+
/* TODO: just set count to zero? */
rr_list = ldns_rr_list_new();
-
+
cur_rr = cur_rrset->rrs;
while (cur_rr) {
ldns_rr_list_push_rr(rr_list, cur_rr->rr);
cur_rr = cur_rr->next;
}
-
+
/* only sign non-delegation RRsets */
/* (glue should have been marked earlier) */
if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
}
ldns_rr_list_free(siglist);
}
-
+
ldns_rr_list_free(rr_list);
-
+
cur_rrset = cur_rrset->next;
}
-
+
/* sign the nsec */
+ ldns_key_list_set_use(key_list, true);
cur_name->nsec_signatures =
ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
key_list,
func,
arg);
-
+ ldns_key_list_filter_for_non_dnskey(key_list);
+
rr_list = ldns_rr_list_new();
ldns_rr_list_push_rr(rr_list, cur_name->nsec);
siglist = ldns_sign_public(rr_list, key_list);
-
+
for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
if (cur_name->nsec_signatures) {
ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
ldns_rr_list_rr(siglist, i));
}
}
-
+
ldns_rr_list_free(siglist);
ldns_rr_list_free(rr_list);
}
/* zone is already sorted */
ldns_dnssec_zone_mark_glue(zone);
-
+
/* check whether we need to add nsecs */
if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
arg,
signflags);
}
-
+
return result;
}
dnssec_zone = ldns_dnssec_zone_new();
(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
- ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
-
+ ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
(void) ldns_dnssec_zone_add_rr(dnssec_zone,
ldns_rr_list_rr(ldns_zone_rrs(zone),
i));
- ldns_zone_push_rr(signed_zone,
+ ldns_zone_push_rr(signed_zone,
ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
i)));
}
dnssec_zone = ldns_dnssec_zone_new();
(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
- ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
-
+ ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
(void) ldns_dnssec_zone_add_rr(dnssec_zone,
ldns_rr_list_rr(ldns_zone_rrs(zone),