ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, ldns_rr_list *keys, ldns_rr_list *good_keys)
{
uint16_t i;
- ldns_rr_list *result;
/* ldns_rr_list *keys_verified;*/
bool valid;
ldns_status verify_result = LDNS_STATUS_ERR;
valid = false;
- result = ldns_rr_list_new();
for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
verify_result = ldns_verify_rrsig_keylist(rrset,
ldns_buffer_free(verify_buf);
if (ldns_rr_list_rr_count(validkeys) == 0) {
/* no keys were added, return last error */
+ldns_rr_list_free(validkeys);
return result;
} else {
+ldns_rr_list_free(validkeys);
ldns_rr_list_cat(good_keys, validkeys);
return LDNS_STATUS_OK;
}
b64rdf = NULL;
current_key = ldns_key_list_key(keys, key_count);
- current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
-
- /* set the type on the new signature */
- /*orig_ttl = ldns_key_origttl(current_key);*/
- orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
-
- /* set the ttl from the priv key on the rrset */
- for (i = 0; i < ldns_rr_list_rr_count(rrset); i++) {
- ldns_rr_set_ttl(
- ldns_rr_list_rr(rrset_clone, i), orig_ttl);
- }
-
- ldns_rr_set_owner(current_sig,
- ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, 0))));
-
- /* fill in what we know of the signature */
-
- /* 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_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,
- ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, ldns_rr_label_count(
- ldns_rr_list_rr(rrset_clone, 0))));
- /* inception, expiration */
- /* TODO: is this a good place for default values? */
- now = time(NULL);
- if (ldns_key_inception(current_key) != 0) {
- (void)ldns_rr_rrsig_set_inception(current_sig,
- ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, ldns_key_inception(current_key)));
- } else {
- (void)ldns_rr_rrsig_set_inception(current_sig,
- ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
- }
- if (ldns_key_expiration(current_key) != 0) {
- (void)ldns_rr_rrsig_set_expiration(current_sig,
- ldns_native2rdf_int32(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, now + LDNS_DEFAULT_EXP_TIME));
- }
+ 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)
+ ) {
+ current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
+
+ /* set the type on the new signature */
+ /*orig_ttl = ldns_key_origttl(current_key);*/
+ orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
+
+ /* set the ttl from the priv key on the rrset */
+ for (i = 0; i < ldns_rr_list_rr_count(rrset); i++) {
+ ldns_rr_set_ttl(
+ ldns_rr_list_rr(rrset_clone, i), orig_ttl);
+ }
- /* key-tag */
- (void)ldns_rr_rrsig_set_keytag(current_sig,
- ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_key_keytag(current_key)));
-
- /* algorithm - check the key and substitute that */
- (void)ldns_rr_rrsig_set_algorithm(current_sig,
- ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(current_key)));
- /* type-covered */
- (void)ldns_rr_rrsig_set_typecovered(current_sig,
- ldns_native2rdf_int16(LDNS_RDF_TYPE_TYPE,
- ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0))));
- /* right now, we have: a key, a semi-sig and an rrset. For
- * which we can create the sig and base64 encode that and
- * add that to the signature */
-
- if (ldns_rrsig2buffer_wire(sign_buf, current_sig) != LDNS_STATUS_OK) {
- ldns_buffer_free(sign_buf);
- dprintf("%s\n", "couldn't convert to buffer 1");
- /* ERROR */
- return NULL;
- }
- /* add the rrset in sign_buf */
- if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone) != LDNS_STATUS_OK) {
- dprintf("%s\n", "couldn't convert to buffer 2");
- ldns_buffer_free(sign_buf);
- return NULL;
- }
-
- switch(ldns_key_algorithm(current_key)) {
- case LDNS_SIGN_DSA:
- b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
- break;
- case LDNS_SIGN_RSASHA1:
- b64rdf = ldns_sign_public_rsasha1(sign_buf, ldns_key_rsa_key(current_key));
- break;
- case LDNS_SIGN_RSAMD5:
- b64rdf = ldns_sign_public_rsamd5(sign_buf, ldns_key_rsa_key(current_key));
- break;
- default:
- /* do _you_ know this alg? */
- break;
- }
- if (!b64rdf) {
- /* signing went wrong */
- dprintf("%s", "couldn't sign!\n");
- return NULL;
- }
- ldns_rr_rrsig_set_sig(current_sig, b64rdf);
+ ldns_rr_set_owner(current_sig,
+ ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, 0))));
+
+ /* fill in what we know of the signature */
+
+ /* 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_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,
+ ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, ldns_rr_label_count(
+ ldns_rr_list_rr(rrset_clone, 0))));
+ /* inception, expiration */
+ /* TODO: is this a good place for default values? */
+ now = time(NULL);
+ if (ldns_key_inception(current_key) != 0) {
+ (void)ldns_rr_rrsig_set_inception(current_sig,
+ ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, ldns_key_inception(current_key)));
+ } else {
+ (void)ldns_rr_rrsig_set_inception(current_sig,
+ ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
+ }
+ if (ldns_key_expiration(current_key) != 0) {
+ (void)ldns_rr_rrsig_set_expiration(current_sig,
+ ldns_native2rdf_int32(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, now + LDNS_DEFAULT_EXP_TIME));
+ }
- /* push the signature to the signatures list */
- ldns_rr_list_push_rr(signatures, current_sig);
+ /* key-tag */
+ (void)ldns_rr_rrsig_set_keytag(current_sig,
+ ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_key_keytag(current_key)));
+
+ /* algorithm - check the key and substitute that */
+ (void)ldns_rr_rrsig_set_algorithm(current_sig,
+ ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(current_key)));
+ /* type-covered */
+ (void)ldns_rr_rrsig_set_typecovered(current_sig,
+ ldns_native2rdf_int16(LDNS_RDF_TYPE_TYPE,
+ ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0))));
+ /* right now, we have: a key, a semi-sig and an rrset. For
+ * which we can create the sig and base64 encode that and
+ * add that to the signature */
+
+ if (ldns_rrsig2buffer_wire(sign_buf, current_sig) != LDNS_STATUS_OK) {
+ ldns_buffer_free(sign_buf);
+ dprintf("%s\n", "couldn't convert to buffer 1");
+ /* ERROR */
+ return NULL;
+ }
+ /* add the rrset in sign_buf */
+ if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone) != LDNS_STATUS_OK) {
+ dprintf("%s\n", "couldn't convert to buffer 2");
+ ldns_buffer_free(sign_buf);
+ return NULL;
+ }
+
+ switch(ldns_key_algorithm(current_key)) {
+ case LDNS_SIGN_DSA:
+ b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
+ break;
+ case LDNS_SIGN_RSASHA1:
+ b64rdf = ldns_sign_public_rsasha1(sign_buf, ldns_key_rsa_key(current_key));
+ break;
+ case LDNS_SIGN_RSAMD5:
+ b64rdf = ldns_sign_public_rsamd5(sign_buf, ldns_key_rsa_key(current_key));
+ break;
+ default:
+ /* do _you_ know this alg? */
+ break;
+ }
+ if (!b64rdf) {
+ /* signing went wrong */
+ dprintf("%s", "couldn't sign!\n");
+ return NULL;
+ }
+ ldns_rr_rrsig_set_sig(current_sig, b64rdf);
+ /* push the signature to the signatures list */
+ ldns_rr_list_push_rr(signatures, current_sig);
+ }
ldns_buffer_free(sign_buf); /* restart for the next key */
}
ldns_rr_list_deep_free(rrset_clone);
}
ldns_zone *
-ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list, ldns_key_list *key_signing_key_list)
+ldns_zone_sign(ldns_zone *zone, ldns_key_list *key_list)
{
/*
* Algorithm to be created:
/* if we have KSKs, use them for DNSKEYS, otherwise
make them selfsigned (?) */
- if (cur_rrset_type == LDNS_RR_TYPE_DNSKEY) {
- if (key_signing_key_list) {
- cur_rrsigs = ldns_sign_public(cur_rrset, key_signing_key_list);
- } else {
- 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_rrsigs);
- } else if (cur_rrset_type != LDNS_RR_TYPE_RRSIG &&
+ if (cur_rrset_type != LDNS_RR_TYPE_RRSIG &&
(ldns_dname_is_subdomain(cur_dname, ldns_rr_owner(ldns_zone_soa(zone))) ||
ldns_rdf_compare(cur_dname, ldns_rr_owner(ldns_zone_soa(zone))) == 0
)
) {
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_rrsigs);
fprintf(fp, " -e <date>\t\texpiration date\n");
fprintf(fp, " -f <file>\t\toutput zone to file (default <name>.signed)\n");
fprintf(fp, " -i <date>\t\tinception date\n");
- fprintf(fp, " -k <keyfile>\t\tkey signing key\n");
fprintf(fp, "\t\t\tdates can be in YYYYMMDD[HHmmSS] format or timestamps\n");
fprintf(fp, " -o <domain>\t\torigin for the zone\n");
- fprintf(fp, "keys and keysigning keys (-k option) can be given multiple times\n");
+ fprintf(fp, "keys can be given multiple times\n");
+ fprintf(fp, "keys are specified by their base name, there should be a file\n");
+ fprintf(fp, "called <name>.key and <name>.private present. The .key should\n");
+ fprintf(fp, "contain the DNSKEY RR of the public key, and will be added to the zone\n");
}
int
ldns_rr_list *orig_rrs = NULL;
ldns_rr *orig_soa = NULL;
+ const char *keyfile_name_base;
+ char *keyfile_name;
FILE *keyfile = NULL;
ldns_key *key = NULL;
+ ldns_rr *pubkey = NULL;
ldns_key_list *keys;
+
char *outputfile_name = NULL;
FILE *outputfile;
/* we need to know the origin before reading ksk's,
* so keep an array of filenames until we know it
*/
+/*
int key_signing_key_nr = 0;
char **key_signing_key_filenames = NULL;
ldns_key_list *key_signing_keys;
-
+*/
struct tm tm;
uint32_t inception;
uint32_t expiration;
inception = 0;
expiration = 0;
- while ((c = getopt(argc, argv, "e:f:i:k:o:")) != -1) {
+ while ((c = getopt(argc, argv, "e:f:i:o:")) != -1) {
switch (c) {
case 'e':
/* try to parse YYYYMMDD first,
inception = atol(optarg);
}
break;
- case 'k':
- key_signing_key_filenames = LDNS_XREALLOC(key_signing_key_filenames, char *, key_signing_key_nr + 1);
- if (!key_signing_key_filenames) {
- fprintf(stderr, "Out of memory\n");
- }
- key_signing_key_filenames[key_signing_key_nr] = optarg;
- key_signing_key_nr++;
- break;
case 'o':
if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
fprintf(stderr, "Bad origin, not a correct domain name\n");
/* read the ZSKs */
argi = 1;
while (argi < argc) {
- keyfile = fopen(argv[argi], "r");
+ keyfile_name_base = argv[argi];
+ keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
+ sprintf(keyfile_name, "%s.private", keyfile_name_base);
+ keyfile = fopen(keyfile_name, "r");
+ line_nr = 0;
if (!keyfile) {
- fprintf(stderr, "Error: unable to read k%s (%s)\n", argv[argi], strerror(errno));
+ fprintf(stderr, "Error: unable to read %s: %s\n", keyfile_name, strerror(errno));
} else {
- key = ldns_key_new_frm_fp(keyfile);
+ key = ldns_key_new_frm_fp_l(keyfile, &line_nr);
+ fclose(keyfile);
if (key) {
- /* TODO: should this be in frm_fp? */
- ldns_key_set_pubkey_owner(key, ldns_rdf_clone(origin));
-
/* set times in key? they will end up
in the rrsigs
*/
ldns_key_set_inception(key, inception);
}
- ldns_key_set_flags(key, ldns_key_flags(key) | LDNS_KEY_ZONE_KEY_FLAG);
- ldns_key_list_push_key(keys, key);
+ LDNS_FREE(keyfile_name);
+ keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 5);
+ sprintf(keyfile_name, "%s.key", keyfile_name_base);
+ keyfile = fopen(keyfile_name, "r");
+ line_nr = 0;
+ if (!keyfile) {
+ fprintf(stderr, "Error: unable to read %s: %s\n", keyfile_name, strerror(errno));
+ } else {
+ pubkey = ldns_rr_new_frm_fp_l(keyfile, LDNS_DEFAULT_TTL, NULL, &line_nr);
+ if (pubkey) {
+ ldns_key_set_pubkey_owner(key, ldns_rdf_clone(ldns_rr_owner(pubkey)));
+ ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
+ }
+ /*ldns_key_set_flags(key, ldns_key_flags(key) | LDNS_KEY_ZONE_KEY);*/
+ ldns_key_list_push_key(keys, key);
+ /*
+ ldns_zone_push_rr(orig_zone, ldns_rr_clone(pubkey));
+ */ ldns_rr_free(pubkey);
+ }
+
} else {
- fprintf(stderr, "Error reading key from %s\n", argv[argi]);
+ fprintf(stderr, "Error reading key from %s at line %d\n", argv[argi], line_nr);
}
- fclose(keyfile);
}
+
argi++;
}
exit(EXIT_FAILURE);
}
- /* read the KSKs */
- key_signing_keys = ldns_key_list_new();
-
- for (argi = 0; argi < key_signing_key_nr; argi++) {
- keyfile = fopen(key_signing_key_filenames[argi], "r");
- if (!keyfile) {
- fprintf(stderr, "Error: unable to read KSK %s (%s)\n", argv[argi], strerror(errno));
- } 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));
-
- /* set times in key? they will end up
- in the rrsigs
- */
- if (expiration != 0) {
- ldns_key_set_expiration(key, expiration);
- }
- if (inception != 0) {
- ldns_key_set_inception(key, inception);
- }
-
- ldns_key_set_flags(key, ldns_key_flags(key) | LDNS_KEY_ZONE_KEY_FLAG | LDNS_KEY_SEP_KEY_FLAG);
- ldns_key_list_push_key(key_signing_keys, key);
- } else {
- fprintf(stderr, "Error reading KSK from %s\n", argv[argi]);
- }
- fclose(keyfile);
- }
- }
-
- signed_zone = ldns_zone_sign(orig_zone, keys, key_signing_keys);
-
+ signed_zone = ldns_zone_sign(orig_zone, keys);
if (!outputfile_name) {
outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
}
ldns_key_list_free(keys);
- ldns_key_list_free(key_signing_keys);
ldns_zone_deep_free(orig_zone);
LDNS_FREE(outputfile_name);
- LDNS_FREE(key_signing_key_filenames);
exit(EXIT_SUCCESS);
}