diff options
Diffstat (limited to 'validator/val_sigcrypt.c')
| -rw-r--r-- | validator/val_sigcrypt.c | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index de730f681893..b15fba3f499d 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -386,6 +386,49 @@ int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset, dnskey_idx)); } +int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset, + size_t dnskey_idx) +{ +#ifdef DEPRECATE_RSA_1024 + uint8_t* rdata; + size_t len; + int alg = dnskey_get_algo(dnskey_rrset, dnskey_idx); + size_t keysize; + + rrset_get_rdata(dnskey_rrset, dnskey_idx, &rdata, &len); + if(len < 2+4) + return 0; + keysize = sldns_rr_dnskey_key_size_raw(rdata+2+4, len-2-4, alg); + + switch((sldns_algorithm)alg) { + case LDNS_RSAMD5: + case LDNS_RSASHA1: + case LDNS_RSASHA1_NSEC3: + case LDNS_RSASHA256: + case LDNS_RSASHA512: + /* reject RSA keys of 1024 bits and shorter */ + if(keysize <= 1024) + return 0; + break; + default: + break; + } +#else + (void)dnskey_rrset; (void)dnskey_idx; +#endif /* DEPRECATE_RSA_1024 */ + return 1; +} + +int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset) +{ + size_t i, num = rrset_get_count(dnskey_rrset); + for(i=0; i<num; i++) { + if(!dnskey_size_is_supported(dnskey_rrset, i)) + return 0; + } + return 1; +} + void algo_needs_init_dnskey_add(struct algo_needs* n, struct ub_packed_rrset_key* dnskey, uint8_t* sigalg) { @@ -1187,7 +1230,7 @@ rrset_canonical(struct regional* region, sldns_buffer* buf, * section, to prevent that a wildcard synthesized NSEC can be used in * the non-existence proves. */ if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC && - section == LDNS_SECTION_AUTHORITY) { + section == LDNS_SECTION_AUTHORITY && qstate) { k->rk.dname = regional_alloc_init(qstate->region, can_owner, can_owner_len); if(!k->rk.dname) @@ -1199,6 +1242,59 @@ rrset_canonical(struct regional* region, sldns_buffer* buf, return 1; } +int +rrset_canonicalize_to_buffer(struct regional* region, sldns_buffer* buf, + struct ub_packed_rrset_key* k) +{ + struct rbtree_type* sortree = NULL; + struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; + uint8_t* can_owner = NULL; + size_t can_owner_len = 0; + struct canon_rr* walk; + struct canon_rr* rrs; + + sortree = (struct rbtree_type*)regional_alloc(region, + sizeof(rbtree_type)); + if(!sortree) + return 0; + if(d->count > RR_COUNT_MAX) + return 0; /* integer overflow protection */ + rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count); + if(!rrs) { + return 0; + } + rbtree_init(sortree, &canonical_tree_compare); + canonical_sort(k, d, sortree, rrs); + + sldns_buffer_clear(buf); + RBTREE_FOR(walk, struct canon_rr*, sortree) { + /* see if there is enough space left in the buffer */ + if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4 + + d->rr_len[walk->rr_idx]) { + log_err("verify: failed to canonicalize, " + "rrset too big"); + return 0; + } + /* determine canonical owner name */ + if(can_owner) + sldns_buffer_write(buf, can_owner, can_owner_len); + else { + can_owner = sldns_buffer_current(buf); + sldns_buffer_write(buf, k->rk.dname, k->rk.dname_len); + query_dname_tolower(can_owner); + can_owner_len = k->rk.dname_len; + } + sldns_buffer_write(buf, &k->rk.type, 2); + sldns_buffer_write(buf, &k->rk.rrset_class, 2); + sldns_buffer_write_u32(buf, d->rr_ttl[walk->rr_idx]); + sldns_buffer_write(buf, d->rr_data[walk->rr_idx], + d->rr_len[walk->rr_idx]); + canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]); + } + sldns_buffer_flip(buf); + return 1; +} + /** pretty print rrsig error with dates */ static void sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now) |
