From: Jelte Jansen Date: Fri, 12 Aug 2005 09:52:35 +0000 (+0000) Subject: made zone signing function, untested, but it seems to produce something :) X-Git-Tag: release-1.0.0~288 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=608438b087cccec8a55abe969c19bd23caaf783a;p=thirdparty%2Fldns.git made zone signing function, untested, but it seems to produce something :) (actual crypto signing functions are not completed yet) added ldns_rr_list_pop_rrset() that pops the first rrset from the list, which of course has to be sorted --- diff --git a/dnssec.c b/dnssec.c index 3f124e0d..0437c915 100644 --- a/dnssec.c +++ b/dnssec.c @@ -1056,6 +1056,7 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys) /* set the orig_ttl */ (void)ldns_rr_rrsig_set_origttl(current_sig, ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, orig_ttl)); /* the signers name */ + (void)ldns_rr_rrsig_set_signame(current_sig, ldns_key_pubkey_owner(current_key)); /* label count - get it from the first rr in the rr_list */ @@ -1297,3 +1298,67 @@ ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, #endif return ldns_verify(rrset, sigs, k); } + +ldns_zone * +ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list) +{ + /* + * Algorithm to be created: + * - sort the rrs (name/class/type?) + * - if sorted, every next rr is belongs either to the rrset + * you are working on, or the rrset is complete + * for each rrset, calculate rrsig and nsec + * put the rrset, rrsig and nsec in the new zone + * done! + * ow and don't sign old rrsigs etc. + */ + + ldns_zone *signed_zone; + ldns_rr_list *cur_rrset; + ldns_rr_list *cur_rrsigs; + ldns_rr_list *orig_zone_rrs; + + signed_zone = ldns_zone_new(); + + /* there should only be 1 SOA, so the soa record is 1 rrset */ + cur_rrset = ldns_rr_list_new(); + ldns_rr_list_push_rr(cur_rrset, ldns_zone_soa(zone)); + cur_rrsigs = ldns_sign_public(cur_rrset, key_list); + + + ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone))); + ldns_zone_push_rr_list(signed_zone, cur_rrsigs); + + orig_zone_rrs = ldns_rr_list_clone(ldns_zone_rrs(zone)); + + /* + printf("UNSORTED:\n"); + ldns_rr_list_print(stdout, orig_zone_rrs); + */ + ldns_rr_list_sort(orig_zone_rrs); + + /* + printf("SORTED:\n"); + ldns_rr_list_print(stdout, orig_zone_rrs); + */ + cur_rrset = ldns_rr_list_pop_rrset(orig_zone_rrs); + while (cur_rrset) { + /* + printf("NEXT RRSET:\n"); + ldns_rr_list_print(stdout, cur_rrset); + printf("\n"); + */ + cur_rrsigs = ldns_sign_public(cur_rrset, key_list); + ldns_zone_push_rr_list(signed_zone, cur_rrset); + ldns_zone_push_rr_list(signed_zone, cur_rrsigs); + + ldns_rr_list_free(cur_rrset); + ldns_rr_list_free(cur_rrsigs); + + cur_rrset = ldns_rr_list_pop_rrset(orig_zone_rrs); + } + + return signed_zone; + +} + diff --git a/keys.c b/keys.c index 4109dc17..9c4bed54 100644 --- a/keys.c +++ b/keys.c @@ -65,6 +65,7 @@ ldns_key_new_frm_fp(FILE *fp) ldns_signing_algorithm alg; k = ldns_key_new(); + d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); if (!k || !d) { return NULL; diff --git a/ldns/dnssec.h b/ldns/dnssec.h index 21c95eea..7464f51e 100644 --- a/ldns/dnssec.h +++ b/ldns/dnssec.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #define LDNS_MAX_KEYLEN 2048 @@ -165,5 +166,16 @@ ldns_rr * ldns_create_nsec(ldns_rr_list *before, ldns_rr_list *after); */ ldns_rr_list *ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s); +/** + * signs the given zone with the given new zone + * returns a newly allocated signed zone + * extra arguments will come later (expiration etc.) + * + * \param[in] zone the zone to sign + * \param[in] key_list the list of keys to sign the zone with + * \return the signed zone + */ +ldns_zone *ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list); + #endif /* _LDNS_DNSSEC_H_ */ diff --git a/ldns/rr.h b/ldns/rr.h index f2fe3f44..d7d83888 100644 --- a/ldns/rr.h +++ b/ldns/rr.h @@ -495,6 +495,13 @@ bool ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr); */ ldns_rr* ldns_rr_set_pop_rr(ldns_rr_list *rr_list); +/** + * pops the first rrset from the list, + * the list must be sorted, so that all rr's from each rrset + * are next to each other + */ +ldns_rr_list *ldns_rr_list_pop_rrset(ldns_rr_list *rr_list); + /** * retrieves a rrtype by looking up its name. diff --git a/net.c b/net.c index e2caa7f1..a73926d7 100644 --- a/net.c +++ b/net.c @@ -342,7 +342,7 @@ ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from, wire_size = recvfrom(sockfd, wire, LDNS_MAX_PACKETLEN, 0, (struct sockaddr*) from, fromlen); - printf("from len %d\n", *fromlen); + printf("from len %d\n", (int) *fromlen); if (wire_size == -1) { if (errno == EAGAIN) { @@ -355,7 +355,7 @@ ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from, *size = (size_t)wire_size; wire = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size); - printf("wire size %d\n", wire_size); + printf("wire size %d\n", (int) wire_size); return wire; } diff --git a/rr.c b/rr.c index d206739a..89bcd6c6 100644 --- a/rr.c +++ b/rr.c @@ -871,6 +871,58 @@ ldns_rr_set_pop_rr(ldns_rr_list *rr_list) return ldns_rr_list_pop_rr(rr_list); } +ldns_rr_list * +ldns_rr_list_pop_rrset(ldns_rr_list *rr_list) +{ + ldns_rr_list *rrset; + ldns_rr *last_rr = NULL; + ldns_rr *next_rr; + + if (!rr_list) { + return NULL; + } + + rrset = ldns_rr_list_new(); + if (!last_rr) { + last_rr = ldns_rr_list_pop_rr(rr_list); + if (!last_rr) { + ldns_rr_list_free(rrset); + return NULL; + } else { + ldns_rr_list_push_rr(rrset, last_rr); + } + } + + if (ldns_rr_list_rr_count(rr_list) > 0) { + next_rr = ldns_rr_list_rr(rr_list, 0); + } else { + next_rr = NULL; + } + + while (next_rr) { + if ( + ldns_rdf_compare(ldns_rr_owner(next_rr), + ldns_rr_owner(last_rr)) == 0 + && + ldns_rr_get_type(next_rr) == ldns_rr_get_type(last_rr) + && + ldns_rr_get_class(next_rr) == ldns_rr_get_class(last_rr) + ) { + ldns_rr_list_push_rr(rrset, ldns_rr_list_pop_rr(rr_list)); + if (ldns_rr_list_rr_count(rr_list) > 0) { + last_rr = next_rr; + next_rr = ldns_rr_list_rr(rr_list, 0); + } else { + next_rr = NULL; + } + } else { + next_rr = NULL; + } + } + + return rrset; +} + ldns_rr * ldns_rr_clone(const ldns_rr *rr) { diff --git a/signzone.c b/signzone.c index d5fef5c3..626a921f 100644 --- a/signzone.c +++ b/signzone.c @@ -40,7 +40,7 @@ main(int argc, char *argv[]) uint16_t ttl = 0; ldns_rr_class class = LDNS_RR_CLASS_IN; - ldns_rr_list *rrs; + ldns_zone *signed_zone = NULL; if (argc < 3) { usage(stdout, argv[0]); @@ -50,6 +50,12 @@ main(int argc, char *argv[]) zonefile_name = argv[2]; } + if (!origin) { + /* default to root origin */ + /*origin = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, ".");*/ + origin = ldns_dname_new_frm_str(zone_name); + } + keys = ldns_key_list_new(); argi = 3; @@ -60,6 +66,8 @@ main(int argc, char *argv[]) } else { key = ldns_key_new_frm_fp(keyfile); if (key) { + /* TODO: should this be in frm_fp? */ + ldns_key_set_pubkey_owner(key, ldns_rdf_clone(origin)); ldns_key_list_push_key(keys, key); } else { fprintf(stderr, "Error reading key from %s\n", argv[argi]); @@ -75,12 +83,6 @@ main(int argc, char *argv[]) return 1; } - if (!origin) { - /* default to root origin */ - /*origin = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, ".");*/ - origin = ldns_dname_new_frm_str(zone_name); - } - printf("Reading zonefile: %s\n", zonefile_name); zonefile = fopen(zonefile_name, "r"); @@ -100,11 +102,17 @@ main(int argc, char *argv[]) ldns_rr_print(stdout, orig_soa); printf("\n"); - rrs = ldns_rr_list_new(); - ldns_rr_list_push_rr(rrs, orig_soa); - ldns_rr_list_cat(rrs, orig_rrs); - - ldns_rr_list_free(rrs); + printf("Signing...\n"); + signed_zone = ldns_zone_sign(orig_zone, keys); + printf("done!\n\n"); + + if (signed_zone) { + printf("SIGNED ZONE:\n"); + ldns_zone_print(stdout, signed_zone); + ldns_zone_deep_free(signed_zone); + } else { + fprintf(stderr, "Error signing zone."); + } ldns_zone_deep_free(orig_zone); }