/build/ldns-00A0O8/ldns-1.8.4/dnssec_sign.c
Go to the documentation of this file.
#include <ldns/config.h>
#include <ldns/ldns.h>
#include <ldns/dnssec.h>
#include <ldns/dnssec_sign.h>
#include <strings.h>
#include <time.h>
#ifdef HAVE_SSL
/* this entire file is rather useless when you don't have
* crypto...
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#ifdef USE_DSA
#include <openssl/dsa.h>
#endif
#endif /* HAVE_SSL */
#define LDNS_SIGN_WITH_ZONEMD ( LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384 \
| LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512 )
ldns_rr *
ldns_create_empty_rrsig(const ldns_rr_list *rrset,
const ldns_key *current_key)
{
uint32_t orig_ttl;
ldns_rr_class orig_class;
time_t now;
ldns_rr *current_sig;
uint8_t label_count;
ldns_rdf *signame;
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_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,
ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
orig_ttl));
/* the signers name */
signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
ldns_dname2canonical(signame);
(void)ldns_rr_rrsig_set_signame(
current_sig,
signame);
/* 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,
label_count));
/* inception, expiration */
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));
}
(void)ldns_rr_rrsig_set_keytag(
current_sig,
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_key_algorithm(current_key)));
(void)ldns_rr_rrsig_set_typecovered(
current_sig,
ldns_native2rdf_int16(
LDNS_RDF_TYPE_TYPE,
ldns_rr_get_type(ldns_rr_list_rr(rrset,
0))));
return current_sig;
}
#ifdef HAVE_SSL
ldns_rdf *
ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
{
ldns_rdf *b64rdf = NULL;
switch(ldns_key_algorithm(current_key)) {
#ifdef USE_DSA
case LDNS_SIGN_DSA:
case LDNS_SIGN_DSA_NSEC3:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
# ifdef HAVE_EVP_DSS1
EVP_dss1()
# else
EVP_sha1()
# endif
);
break;
#endif /* USE_DSA */
case LDNS_SIGN_RSASHA1:
case LDNS_SIGN_RSASHA1_NSEC3:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
EVP_sha1());
break;
#ifdef USE_SHA2
case LDNS_SIGN_RSASHA256:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
EVP_sha256());
break;
case LDNS_SIGN_RSASHA512:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
EVP_sha512());
break;
#endif /* USE_SHA2 */
#ifdef USE_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
#ifdef USE_ED25519
case LDNS_SIGN_ED25519:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
NULL);
break;
#endif
#ifdef USE_ED448
case LDNS_SIGN_ED448:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
NULL);
break;
#endif
case LDNS_SIGN_RSAMD5:
b64rdf = ldns_sign_public_evp(
sign_buf,
ldns_key_evp_key(current_key),
EVP_md5());
break;
default:
/* do _you_ know this alg? */
printf("unknown algorithm, ");
printf("is the one used available on this system?\n");
break;
}
return b64rdf;
}
ldns_rr_list *
ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
{
ldns_rr_list *signatures;
ldns_rr_list *rrset_clone;
ldns_rr *current_sig;
ldns_rdf *b64rdf;
ldns_key *current_key;
size_t key_count;
uint16_t i;
ldns_buffer *sign_buf;
ldns_rdf *new_owner;
if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
return NULL;
}
new_owner = NULL;
/* prepare a signature and add all the know data
* prepare the rrset. Sign this together. */
rrset_clone = ldns_rr_list_clone(rrset);
if (!rrset_clone) {
return NULL;
}
/* make it canonical */
for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
}
/* sort */
ldns_rr_list_sort(rrset_clone);
signatures = ldns_rr_list_new();
for (key_count = 0;
key_count < ldns_key_list_key_count(keys);
key_count++) {
if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
continue;
}
sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
if (!sign_buf) {
ldns_rr_list_free(rrset_clone);
ldns_rr_list_free(signatures);
ldns_rdf_free(new_owner);
return NULL;
}
b64rdf = NULL;
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) {
current_sig = ldns_create_empty_rrsig(rrset_clone,
current_key);
/* 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);
/* ERROR */
ldns_rr_list_deep_free(rrset_clone);
ldns_rr_free(current_sig);
ldns_rr_list_deep_free(signatures);
return NULL;
}
/* add the rrset in sign_buf */
if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
!= LDNS_STATUS_OK) {
ldns_buffer_free(sign_buf);
ldns_rr_list_deep_free(rrset_clone);
ldns_rr_free(current_sig);
ldns_rr_list_deep_free(signatures);
return NULL;
}
b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
if (!b64rdf) {
/* signing went wrong */
ldns_rr_list_deep_free(rrset_clone);
ldns_rr_free(current_sig);
ldns_rr_list_deep_free(signatures);
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);
return signatures;
}
ldns_rdf *
ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
{
#ifdef USE_DSA
unsigned char md[EVP_MAX_MD_SIZE];
unsigned char *sha1_hash;
ldns_rdf *sigdata_rdf;
ldns_buffer *b64sig;
DSA_SIG *sig;
const BIGNUM *R, *S;
uint8_t *data;
size_t pad;
b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
if (!b64sig) {
return NULL;
}
sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign), md);
if (!sha1_hash) {
ldns_buffer_free(b64sig);
return NULL;
}
sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
if(!sig) {
ldns_buffer_free(b64sig);
return NULL;
}
data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
if(!data) {
ldns_buffer_free(b64sig);
DSA_SIG_free(sig);
return NULL;
}
data[0] = 1;
# ifdef HAVE_DSA_SIG_GET0
DSA_SIG_get0(sig, &R, &S);
# else
R = sig->r;
S = sig->s;
# endif
pad = 20 - (size_t) BN_num_bytes(R);
if (pad > 0) {
memset(data + 1, 0, pad);
}
BN_bn2bin(R, (unsigned char *) (data + 1) + pad);
pad = 20 - (size_t) BN_num_bytes(S);
if (pad > 0) {
memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
}
BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
1 + 2 * SHA_DIGEST_LENGTH,
data);
ldns_buffer_free(b64sig);
LDNS_FREE(data);
DSA_SIG_free(sig);
return sigdata_rdf;
#else
(void)to_sign; (void)key;
return NULL;
#endif
}
#ifdef USE_ECDSA
#ifndef S_SPLINT_S
static int
ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
{
EC_KEY* ec;
const EC_GROUP* g;
#ifdef HAVE_EVP_PKEY_GET_BASE_ID
if(EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC)
return 0;
#elif defined(HAVE_EVP_PKEY_BASE_ID)
if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
return 0;
#else
if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
return 0;
#endif
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_X9_62_prime256v1) {
EC_KEY_free(ec);
return 32; /* 256/8 */
}
if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
EC_KEY_free(ec);
return 48; /* 384/8 */
}
/* downref the eckey, the original is still inside the pkey */
EC_KEY_free(ec);
return 0;
}
#endif /* splint */
#endif /* USE_ECDSA */
ldns_rdf *
ldns_sign_public_evp(ldns_buffer *to_sign,
EVP_PKEY *key,
const EVP_MD *digest_type)
{
unsigned int siglen;
ldns_rdf *sigdata_rdf = NULL;
ldns_buffer *b64sig;
EVP_MD_CTX *ctx;
const EVP_MD *md_type;
int r;
siglen = 0;
b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
if (!b64sig) {
return NULL;
}
/* initializes a signing context */
md_type = digest_type;
#ifdef USE_ED25519
if(EVP_PKEY_id(key) == NID_ED25519) {
/* digest must be NULL for ED25519 sign and verify */
md_type = NULL;
} else
#endif
#ifdef USE_ED448
if(EVP_PKEY_id(key) == NID_ED448) {
md_type = NULL;
} else
#endif
if(!md_type) {
/* unknown message digest */
ldns_buffer_free(b64sig);
return NULL;
}
#ifdef HAVE_EVP_MD_CTX_NEW
ctx = EVP_MD_CTX_new();
#else
ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
if(ctx) EVP_MD_CTX_init(ctx);
#endif
if(!ctx) {
ldns_buffer_free(b64sig);
return NULL;
}
#if defined(USE_ED25519) || defined(USE_ED448)
if(md_type == NULL) {
/* for these methods we must use the one-shot DigestSign */
r = EVP_DigestSignInit(ctx, NULL, md_type, NULL, key);
if(r == 1) {
size_t siglen_sizet = ldns_buffer_capacity(b64sig);
r = EVP_DigestSign(ctx,
(unsigned char*)ldns_buffer_begin(b64sig),
&siglen_sizet,
(unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign));
siglen = (unsigned int)siglen_sizet;
}
} else {
#else
r = 0;
if(md_type != NULL) {
#endif
r = EVP_SignInit(ctx, md_type);
if(r == 1) {
r = EVP_SignUpdate(ctx, (unsigned char*)
ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign));
}
if(r == 1) {
r = EVP_SignFinal(ctx, (unsigned char*)
ldns_buffer_begin(b64sig), &siglen, key);
}
}
if(r != 1) {
ldns_buffer_free(b64sig);
EVP_MD_CTX_destroy(ctx);
return NULL;
}
/* OpenSSL output is different, convert it */
r = 0;
#ifdef USE_DSA
#ifndef S_SPLINT_S
/* unfortunately, OpenSSL output is different from DNS DSA format */
# ifdef HAVE_EVP_PKEY_GET_BASE_ID
if (EVP_PKEY_get_base_id(key) == EVP_PKEY_DSA) {
# elif defined(HAVE_EVP_PKEY_BASE_ID)
if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) {
# else
if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
# endif
r = 1;
sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
}
#endif
#endif
#if defined(USE_ECDSA)
if(
# ifdef HAVE_EVP_PKEY_GET_BASE_ID
EVP_PKEY_get_base_id(key)
# elif defined(HAVE_EVP_PKEY_BASE_ID)
EVP_PKEY_base_id(key)
# else
EVP_PKEY_type(key->type)
# endif
== EVP_PKEY_EC) {
# ifdef USE_ECDSA
if(ldns_pkey_is_ecdsa(key)) {
r = 1;
sigdata_rdf = ldns_convert_ecdsa_rrsig_asn1len2rdf(
b64sig, (long)siglen, ldns_pkey_is_ecdsa(key));
}
# endif /* USE_ECDSA */
}
#endif /* PKEY_EC */
if(r == 0) {
/* ok output for other types is the same */
sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
ldns_buffer_begin(b64sig));
}
ldns_buffer_free(b64sig);
EVP_MD_CTX_destroy(ctx);
return sigdata_rdf;
}
ldns_rdf *
ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
{
unsigned char md[EVP_MAX_MD_SIZE];
unsigned char *sha1_hash;
unsigned int siglen;
ldns_rdf *sigdata_rdf;
ldns_buffer *b64sig;
int result;
siglen = 0;
b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
if (!b64sig) {
return NULL;
}
sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign), md);
if (!sha1_hash) {
ldns_buffer_free(b64sig);
return NULL;
}
result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
(unsigned char*)ldns_buffer_begin(b64sig),
&siglen, key);
if (result != 1) {
ldns_buffer_free(b64sig);
return NULL;
}
sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
ldns_buffer_begin(b64sig));
ldns_buffer_free(b64sig); /* can't free this buffer ?? */
return sigdata_rdf;
}
ldns_rdf *
ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
{
unsigned char md[EVP_MAX_MD_SIZE];
unsigned char *md5_hash;
unsigned int siglen;
ldns_rdf *sigdata_rdf;
ldns_buffer *b64sig;
b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
if (!b64sig) {
return NULL;
}
md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign), md);
if (!md5_hash) {
ldns_buffer_free(b64sig);
return NULL;
}
RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
(unsigned char*)ldns_buffer_begin(b64sig),
&siglen, key);
sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
ldns_buffer_begin(b64sig));
ldns_buffer_free(b64sig);
return sigdata_rdf;
}
#endif /* HAVE_SSL */
static ldns_status
ldns_dnssec_addresses_on_glue_list(
ldns_dnssec_rrsets *cur_rrset,
ldns_rr_list *glue_list)
{
ldns_dnssec_rrs *cur_rrs;
while (cur_rrset) {
if (cur_rrset->type == LDNS_RR_TYPE_A
|| cur_rrset->type == LDNS_RR_TYPE_AAAA) {
for (cur_rrs = cur_rrset->rrs;
cur_rrs;
cur_rrs = cur_rrs->next) {
if (cur_rrs->rr) {
if (!ldns_rr_list_push_rr(glue_list,
cur_rrs->rr)) {
return LDNS_STATUS_MEM_ERR;
/* ldns_rr_list_push_rr()
* returns false when unable
* to increase the capacity
* of the ldns_rr_list
*/
}
}
}
}
cur_rrset = cur_rrset->next;
}
return LDNS_STATUS_OK;
}
ldns_status
ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
ldns_rr_list *glue_list)
{
ldns_rbnode_t *node;
ldns_dnssec_name *name;
ldns_rdf *owner;
ldns_rdf *cut = NULL; /* keeps track of zone cuts */
/* When the cut is caused by a delegation, below_delegation will be 1.
* When caused by a DNAME, below_delegation will be 0.
*/
int below_delegation = -1; /* init suppresses compiler warning */
ldns_status s;
if (!zone || !zone->names) {
return LDNS_STATUS_NULL;
}
for (node = ldns_rbtree_first(zone->names);
node != LDNS_RBTREE_NULL;
node = ldns_rbtree_next(node)) {
name = (ldns_dnssec_name *) node->data;
owner = ldns_dnssec_name_name(name);
if (cut) {
/* The previous node was a zone cut, or a subdomain
* below a zone cut. Is this node (still) a subdomain
* below the cut? Then the name is occluded. Unless
* the name contains a SOA, after which we are
* authoritative again.
*
* FIXME! If there are labels in between the SOA and
* the cut, going from the authoritative space (below
* the SOA) up into occluded space again, will not be
* detected with the construct below!
*/
if (ldns_dname_is_subdomain(owner, cut) &&
!ldns_dnssec_rrsets_contains_type(
name->rrsets, LDNS_RR_TYPE_SOA)) {
if (below_delegation && glue_list) {
s = ldns_dnssec_addresses_on_glue_list(
name->rrsets, glue_list);
if (s != LDNS_STATUS_OK) {
return s;
}
}
name->is_glue = true; /* Mark occluded name! */
continue;
} else {
cut = NULL;
}
}
/* The node is not below a zone cut. Is it a zone cut itself?
* Everything below a SOA is authoritative of course; Except
* when the name also contains a DNAME :).
*/
if (ldns_dnssec_rrsets_contains_type(
name->rrsets, LDNS_RR_TYPE_NS)
&& !ldns_dnssec_rrsets_contains_type(
name->rrsets, LDNS_RR_TYPE_SOA)) {
cut = owner;
below_delegation = 1;
if (glue_list) { /* record glue on the zone cut */
s = ldns_dnssec_addresses_on_glue_list(
name->rrsets, glue_list);
if (s != LDNS_STATUS_OK) {
return s;
}
}
} else if (ldns_dnssec_rrsets_contains_type(
name->rrsets, LDNS_RR_TYPE_DNAME)) {
cut = owner;
below_delegation = 0;
}
}
return LDNS_STATUS_OK;
}
ldns_status
ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
{
return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
}
ldns_rbnode_t *
ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
{
ldns_rbnode_t *next_node = NULL;
ldns_dnssec_name *next_name = NULL;
bool done = false;
if (node == LDNS_RBTREE_NULL) {
return NULL;
}
next_node = node;
while (!done) {
if (next_node == LDNS_RBTREE_NULL) {
return NULL;
} else {
next_name = (ldns_dnssec_name *)next_node->data;
if (!next_name->is_glue) {
done = true;
} else {
next_node = ldns_rbtree_next(next_node);
}
}
}
return next_node;
}
ldns_status
ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs)
{
ldns_rbnode_t *first_node, *cur_node, *next_node;
ldns_dnssec_name *cur_name, *next_name;
ldns_rr *nsec_rr;
uint32_t nsec_ttl;
ldns_dnssec_rrsets *soa;
/* The TTL value for any NSEC RR SHOULD be the same TTL value as the
* lesser of the MINIMUM field of the SOA record and the TTL of the SOA
* itself. This matches the definition of the TTL for negative
* responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
* 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
*/
if (soa && soa->rrs && soa->rrs->rr) {
ldns_rr *soa_rr = soa->rrs->rr;
ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
nsec_ttl = min_rdf == NULL
|| ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
} else {
nsec_ttl = LDNS_DEFAULT_TTL;
}
first_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_first(zone->names));
cur_node = first_node;
if (cur_node) {
next_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_next(cur_node));
} else {
next_node = NULL;
}
while (cur_node && next_node) {
cur_name = (ldns_dnssec_name *)cur_node->data;
next_name = (ldns_dnssec_name *)next_node->data;
nsec_rr = ldns_dnssec_create_nsec(cur_name,
next_name,
LDNS_RR_TYPE_NSEC);
ldns_rr_set_ttl(nsec_rr, nsec_ttl);
if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
ldns_rr_free(nsec_rr);
return LDNS_STATUS_ERR;
}
ldns_rr_list_push_rr(new_rrs, nsec_rr);
cur_node = next_node;
if (cur_node) {
next_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_next(cur_node));
}
}
if (cur_node && !next_node) {
cur_name = (ldns_dnssec_name *)cur_node->data;
next_name = (ldns_dnssec_name *)first_node->data;
nsec_rr = ldns_dnssec_create_nsec(cur_name,
next_name,
LDNS_RR_TYPE_NSEC);
ldns_rr_set_ttl(nsec_rr, nsec_ttl);
if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
ldns_rr_free(nsec_rr);
return LDNS_STATUS_ERR;
}
ldns_rr_list_push_rr(new_rrs, nsec_rr);
} else {
printf("error\n");
}
return LDNS_STATUS_OK;
}
#ifdef HAVE_SSL
static void
ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
(void) arg;
LDNS_FREE(node);
}
static ldns_status
ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
ldns_rbtree_t **map)
{
ldns_rbnode_t *first_name_node;
ldns_rbnode_t *current_name_node;
ldns_dnssec_name *current_name;
ldns_status result = LDNS_STATUS_OK;
ldns_rr *nsec_rr;
ldns_rr_list *nsec3_list;
uint32_t nsec_ttl;
ldns_dnssec_rrsets *soa;
ldns_rbnode_t *hashmap_node;
if (!zone || !new_rrs || !zone->names) {
return LDNS_STATUS_ERR;
}
/* The TTL value for any NSEC RR SHOULD be the same TTL value as the
* lesser of the MINIMUM field of the SOA record and the TTL of the SOA
* itself. This matches the definition of the TTL for negative
* responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
* 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
*/
if (soa && soa->rrs && soa->rrs->rr) {
ldns_rr *soa_rr = soa->rrs->rr;
ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
nsec_ttl = min_rdf == NULL
|| ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
} else {
nsec_ttl = LDNS_DEFAULT_TTL;
}
if (ldns_rdf_size(zone->soa->name) > 222) {
return LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW;
}
if (zone->hashed_names) {
ldns_traverse_postorder(zone->hashed_names,
ldns_hashed_names_node_free, NULL);
LDNS_FREE(zone->hashed_names);
}
zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
if (zone->hashed_names && map) {
*map = zone->hashed_names;
}
first_name_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_first(zone->names));
current_name_node = first_name_node;
while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
result == LDNS_STATUS_OK) {
current_name = (ldns_dnssec_name *) current_name_node->data;
nsec_rr = ldns_dnssec_create_nsec3(current_name,
NULL,
zone->soa->name,
algorithm,
flags,
iterations,
salt_length,
salt);
/* by default, our nsec based generator adds rrsigs
* remove the bitmap for empty nonterminals */
if (!current_name->rrsets) {
ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
}
ldns_rr_set_ttl(nsec_rr, nsec_ttl);
result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
ldns_rr_list_push_rr(new_rrs, nsec_rr);
if (ldns_rr_owner(nsec_rr)) {
hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
if (hashmap_node == NULL) {
return LDNS_STATUS_MEM_ERR;
}
current_name->hashed_name =
ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
if (current_name->hashed_name == NULL) {
LDNS_FREE(hashmap_node);
return LDNS_STATUS_MEM_ERR;
}
hashmap_node->key = current_name->hashed_name;
hashmap_node->data = current_name;
if (! ldns_rbtree_insert(zone->hashed_names
, hashmap_node)) {
LDNS_FREE(hashmap_node);
}
}
current_name_node = ldns_dnssec_name_node_next_nonglue(
ldns_rbtree_next(current_name_node));
}
if (result != LDNS_STATUS_OK) {
return result;
}
/* Make sorted list of nsec3s (via zone->hashed_names)
*/
nsec3_list = ldns_rr_list_new();
if (nsec3_list == NULL) {
return LDNS_STATUS_MEM_ERR;
}
for ( hashmap_node = ldns_rbtree_first(zone->hashed_names)
; hashmap_node != LDNS_RBTREE_NULL
; hashmap_node = ldns_rbtree_next(hashmap_node)
) {
nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
if (nsec_rr) {
ldns_rr_list_push_rr(nsec3_list, nsec_rr);
}
}
result = ldns_dnssec_chain_nsec3_list(nsec3_list);
ldns_rr_list_free(nsec3_list);
return result;
}
ldns_status
ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt)
{
return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
flags, iterations, salt_length, salt, NULL);
}
#endif /* HAVE_SSL */
ldns_dnssec_rrs *
ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
, ATTR_UNUSED(ldns_key_list *key_list)
, int (*func)(ldns_rr *, void *)
, void *arg
)
{
ldns_dnssec_rrs *base_rrs = signatures;
ldns_dnssec_rrs *cur_rr = base_rrs;
ldns_dnssec_rrs *prev_rr = NULL;
ldns_dnssec_rrs *next_rr;
uint16_t keytag;
size_t i;
if (!cur_rr) {
switch(func(NULL, arg)) {
case LDNS_SIGNATURE_LEAVE_ADD_NEW:
case LDNS_SIGNATURE_REMOVE_ADD_NEW:
break;
case LDNS_SIGNATURE_LEAVE_NO_ADD:
case LDNS_SIGNATURE_REMOVE_NO_ADD:
ldns_key_list_set_use(key_list, false);
break;
default:
#ifdef STDERR_MSGS
fprintf(stderr, "[XX] unknown return value from callback\n");
#endif
break;
}
return NULL;
}
(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;
break;
case LDNS_SIGNATURE_LEAVE_NO_ADD:
keytag = ldns_rdf2native_int16(
ldns_rr_rrsig_keytag(cur_rr->rr));
for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
keytag) {
ldns_key_set_use(ldns_key_list_key(key_list, i),
false);
}
}
prev_rr = cur_rr;
break;
case LDNS_SIGNATURE_REMOVE_NO_ADD:
keytag = ldns_rdf2native_int16(
ldns_rr_rrsig_keytag(cur_rr->rr));
for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
if (ldns_key_keytag(ldns_key_list_key(key_list, i))
== keytag) {
ldns_key_set_use(ldns_key_list_key(key_list, i),
false);
}
}
if (prev_rr) {
prev_rr->next = next_rr;
} else {
base_rrs = next_rr;
}
LDNS_FREE(cur_rr);
break;
case LDNS_SIGNATURE_REMOVE_ADD_NEW:
if (prev_rr) {
prev_rr->next = next_rr;
} else {
base_rrs = next_rr;
}
LDNS_FREE(cur_rr);
break;
default:
#ifdef STDERR_MSGS
fprintf(stderr, "[XX] unknown return value from callback\n");
#endif
break;
}
cur_rr = next_rr;
}
return base_rrs;
}
#ifdef HAVE_SSL
ldns_status
ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void*),
void *arg)
{
return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
func, arg, 0);
}
static void
ldns_key_list_filter_for_dnskey(ldns_key_list *key_list, int flags)
{
bool algos[256]
#ifndef S_SPLINT_S
= { false }
#endif
;
ldns_signing_algorithm saw_ksk = 0;
ldns_key *key;
size_t i;
if (!ldns_key_list_key_count(key_list))
return;
/* Mark all KSKs */
for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
key = ldns_key_list_key(key_list, i);
if ((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
if (!saw_ksk)
saw_ksk = ldns_key_algorithm(key);
algos[ldns_key_algorithm(key)] = true;
}
}
if (!saw_ksk)
return; /* No KSKs means sign using all ZSKs */
/* Deselect the ZSKs so they do not sign DNSKEY RRs.
* Except with the LDNS_SIGN_WITH_ALL_ALGORITHMS flag, then use it,
* but only if it has an algorithm for which there is no KSK
*/
for (i =0; i < ldns_key_list_key_count(key_list); i++) {
key = ldns_key_list_key(key_list, i);
if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
/* We have a ZSK.
* Still use it if it has a unique algorithm though!
*/
if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
!algos[ldns_key_algorithm(key)])
algos[ldns_key_algorithm(key)] = true;
else
ldns_key_set_use(key, 0);
}
}
}
static void
ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list, int flags)
{
bool algos[256]
#ifndef S_SPLINT_S
= { false }
#endif
;
ldns_signing_algorithm saw_zsk = 0;
ldns_key *key;
size_t i;
if (!ldns_key_list_key_count(key_list))
return;
/* Mark all ZSKs */
for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
key = ldns_key_list_key(key_list, i);
if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
if (!saw_zsk)
saw_zsk = ldns_key_algorithm(key);
algos[ldns_key_algorithm(key)] = true;
}
}
if (!saw_zsk)
return; /* No ZSKs means sign using all KSKs */
/* Deselect the KSKs so they do not sign non DNSKEY RRs.
* Except with the LDNS_SIGN_WITH_ALL_ALGORITHMS flag, then use it,
* but only if it has an algorithm for which there is no ZSK
*/
for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
key = ldns_key_list_key(key_list, i);
if((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
/* We have a KSK.
* Still use it if it has a unique algorithm though!
*/
if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
!algos[ldns_key_algorithm(key)])
algos[ldns_key_algorithm(key)] = true;
else
ldns_key_set_use(key, 0);
}
}
}
ldns_status
ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
, ldns_rr_list *new_rrs
, ldns_key_list *key_list
, int (*func)(ldns_rr *, void*)
, void *arg
, int flags
)
{
ldns_status result = LDNS_STATUS_OK;
ldns_rbnode_t *cur_node;
ldns_rr_list *rr_list;
ldns_dnssec_name *cur_name;
ldns_dnssec_rrsets *cur_rrset;
ldns_dnssec_rrs *cur_rr;
ldns_rr_list *siglist;
size_t i;
int on_delegation_point = 0; /* handle partially occluded names */
ldns_rr_list *pubkey_list = ldns_rr_list_new();
for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
ldns_rr_list_push_rr( pubkey_list
, ldns_key2rr(ldns_key_list_key(
key_list, i))
);
}
/* TODO: callback to see is list should be signed */
/* TODO: remove 'old' signatures from signature list */
cur_node = ldns_rbtree_first(zone->names);
while (cur_node != LDNS_RBTREE_NULL) {
cur_name = (ldns_dnssec_name *) cur_node->data;
if (!cur_name->is_glue) {
on_delegation_point = ldns_dnssec_rrsets_contains_type(
cur_name->rrsets, LDNS_RR_TYPE_NS)
&& !ldns_dnssec_rrsets_contains_type(
cur_name->rrsets, LDNS_RR_TYPE_SOA);
cur_rrset = cur_name->rrsets;
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 =
ldns_dnssec_remove_signatures(cur_rrset->signatures,
key_list,
func,
arg);
if(cur_rrset->type == LDNS_RR_TYPE_DNSKEY ||
cur_rrset->type == LDNS_RR_TYPE_CDNSKEY ||
cur_rrset->type == LDNS_RR_TYPE_CDS) {
if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK)) {
ldns_key_list_filter_for_dnskey(key_list, flags);
}
} else {
ldns_key_list_filter_for_non_dnskey(key_list, flags);
}
/* 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,
* except on the delegation points itself) */
if (!on_delegation_point ||
ldns_rr_list_type(rr_list)
== LDNS_RR_TYPE_DS ||
ldns_rr_list_type(rr_list)
== LDNS_RR_TYPE_NSEC ||
ldns_rr_list_type(rr_list)
== LDNS_RR_TYPE_NSEC3) {
siglist = ldns_sign_public(rr_list, key_list);
for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
if (cur_rrset->signatures) {
result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
ldns_rr_list_rr(siglist,
i));
} else {
cur_rrset->signatures = ldns_dnssec_rrs_new();
cur_rrset->signatures->rr =
ldns_rr_list_rr(siglist, i);
}
if (new_rrs) {
ldns_rr_list_push_rr(new_rrs,
ldns_rr_list_rr(siglist,
i));
}
}
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, flags);
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) {
result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
ldns_rr_list_rr(siglist, i));
} else {
cur_name->nsec_signatures = ldns_dnssec_rrs_new();
cur_name->nsec_signatures->rr =
ldns_rr_list_rr(siglist, i);
}
if (new_rrs) {
ldns_rr_list_push_rr(new_rrs,
ldns_rr_list_rr(siglist, i));
}
}
ldns_rr_list_free(siglist);
ldns_rr_list_free(rr_list);
}
cur_node = ldns_rbtree_next(cur_node);
}
ldns_rr_list_deep_free(pubkey_list);
return result;
}
ldns_status
ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg)
{
return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
}
ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs, ldns_key_list *key_list, int flags);
ldns_status
ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
int flags)
{
ldns_status result = LDNS_STATUS_OK;
ldns_dnssec_rrsets zonemd_rrset;
bool zonemd_added = false;
if (!zone || !new_rrs || !key_list) {
return LDNS_STATUS_ERR;
}
if (flags & LDNS_SIGN_WITH_ZONEMD) {
ldns_dnssec_rrsets **rrsets_ref = &zone->soa->rrsets;
while (*rrsets_ref
&& (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
rrsets_ref = &(*rrsets_ref)->next;
if (!*rrsets_ref
|| (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
zonemd_rrset.rrs = NULL;
zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
zonemd_rrset.signatures = NULL;
zonemd_rrset.next = *rrsets_ref;
*rrsets_ref = &zonemd_rrset;
zonemd_added = true;
}
}
/* zone is already sorted */
result = ldns_dnssec_zone_mark_glue(zone);
if (result != LDNS_STATUS_OK) {
return result;
}
/* check whether we need to add nsecs */
if ((flags & LDNS_SIGN_NO_KEYS_NO_NSECS)
&& ldns_key_list_key_count(key_list) < 1)
; /* pass */
else if (zone->names
&& !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
if (result != LDNS_STATUS_OK) {
return result;
}
}
result = ldns_dnssec_zone_create_rrsigs_flg(zone,
new_rrs,
key_list,
func,
arg,
flags);
if (zonemd_added) {
ldns_dnssec_rrsets **rrsets_ref
= &zone->soa->rrsets;
while (*rrsets_ref
&& (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
rrsets_ref = &(*rrsets_ref)->next;
*rrsets_ref = zonemd_rrset.next;
}
return flags & LDNS_SIGN_WITH_ZONEMD
? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, flags)
: result;
}
ldns_status
ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt)
{
return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
func, arg, algorithm, flags, iterations, salt_length, salt, 0,
NULL);
}
ldns_status
ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
int signflags,
ldns_rbtree_t **map)
{
ldns_rr *nsec3, *nsec3param;
ldns_status result = LDNS_STATUS_OK;
bool zonemd_added = false;
ldns_dnssec_rrsets zonemd_rrset;
/* zone is already sorted */
result = ldns_dnssec_zone_mark_glue(zone);
if (result != LDNS_STATUS_OK) {
return result;
}
/* TODO if there are already nsec3s presents and their
* parameters are the same as these, we don't have to recreate
*/
if (zone->names) {
/* add empty nonterminals */
result = ldns_dnssec_zone_add_empty_nonterminals(zone);
if (result != LDNS_STATUS_OK) {
return result;
}
nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
/* check whether we need to add nsecs */
if ((signflags & LDNS_SIGN_NO_KEYS_NO_NSECS)
&& ldns_key_list_key_count(key_list) < 1)
; /* pass */
else if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
/* no need to recreate */
} else {
if (!ldns_dnssec_zone_find_rrset(zone,
zone->soa->name,
LDNS_RR_TYPE_NSEC3PARAM)) {
/* create and add the nsec3param rr */
nsec3param =
ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
ldns_rr_set_owner(nsec3param,
ldns_rdf_clone(zone->soa->name));
ldns_nsec3_add_param_rdfs(nsec3param,
algorithm,
flags,
iterations,
salt_length,
salt);
/* always set bit 7 of the flags to zero, according to
* rfc5155 section 11. The bits are counted from right to left,
* so bit 7 in rfc5155 is bit 0 in ldns */
ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
result = ldns_dnssec_zone_add_rr(zone, nsec3param);
if (result != LDNS_STATUS_OK) {
return result;
}
ldns_rr_list_push_rr(new_rrs, nsec3param);
}
if (signflags & LDNS_SIGN_WITH_ZONEMD) {
ldns_dnssec_rrsets **rrsets_ref
= &zone->soa->rrsets;
while (*rrsets_ref
&& (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
rrsets_ref = &(*rrsets_ref)->next;
if (!*rrsets_ref
|| (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
zonemd_rrset.rrs = NULL;
zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
zonemd_rrset.signatures = NULL;
zonemd_rrset.next = *rrsets_ref;
*rrsets_ref = &zonemd_rrset;
zonemd_added = true;
}
}
result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
new_rrs,
algorithm,
flags,
iterations,
salt_length,
salt,
map);
if (zonemd_added) {
ldns_dnssec_rrsets **rrsets_ref
= &zone->soa->rrsets;
while (*rrsets_ref
&& (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
rrsets_ref = &(*rrsets_ref)->next;
*rrsets_ref = zonemd_rrset.next;
}
if (result != LDNS_STATUS_OK) {
return result;
}
}
result = ldns_dnssec_zone_create_rrsigs_flg(zone,
new_rrs,
key_list,
func,
arg,
signflags);
}
if (result || !zone->names)
return result;
return signflags & LDNS_SIGN_WITH_ZONEMD
? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, signflags)
: result;
}
ldns_status
ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
int signflags)
{
return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
func, arg, algorithm, flags, iterations, salt_length, salt,
signflags, NULL);
}
ldns_zone *
ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
{
ldns_dnssec_zone *dnssec_zone;
ldns_zone *signed_zone;
ldns_rr_list *new_rrs;
size_t i;
signed_zone = ldns_zone_new();
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_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_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
i)));
}
new_rrs = ldns_rr_list_new();
(void) ldns_dnssec_zone_sign(dnssec_zone,
new_rrs,
key_list,
ldns_dnssec_default_replace_signatures,
NULL);
for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
}
ldns_rr_list_deep_free(new_rrs);
ldns_dnssec_zone_free(dnssec_zone);
return signed_zone;
}
ldns_zone *
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)
{
ldns_dnssec_zone *dnssec_zone;
ldns_zone *signed_zone;
ldns_rr_list *new_rrs;
size_t i;
signed_zone = ldns_zone_new();
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_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_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
i)));
}
new_rrs = ldns_rr_list_new();
(void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
new_rrs,
key_list,
ldns_dnssec_default_replace_signatures,
NULL,
algorithm,
flags,
iterations,
salt_length,
salt);
for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
}
ldns_rr_list_deep_free(new_rrs);
ldns_dnssec_zone_free(dnssec_zone);
return signed_zone;
}
#endif /* HAVE_SSL */
ldns_buffer_free
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition buffer.c:137
ldns_buffer
struct ldns_struct_buffer ldns_buffer
Definition buffer.h:72
ldns_buffer_new
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
Definition buffer.c:16
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition common.h:72
config.h
HAVE_EVP_PKEY_GET_BASE_ID
#define HAVE_EVP_PKEY_GET_BASE_ID
Definition config.h:132
HAVE_EVP_PKEY_BASE_ID
#define HAVE_EVP_PKEY_BASE_ID
Definition config.h:129
ldns_dname_compare_v
int ldns_dname_compare_v(const void *a, const void *b)
Given in dnssec_zone.c, also used in dnssec_sign.c:w.
Definition dnssec_zone.c:906
ldns_dname_is_wildcard
int ldns_dname_is_wildcard(const ldns_rdf *dname)
Check if dname is a wildcard, starts with *.
Definition dname.c:456
ldns_dname_is_subdomain
signed char ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
test whether the name sub falls under parent (i.e.
Definition dname.c:296
ldns_dname2canonical
void ldns_dname2canonical(const ldns_rdf *rdf)
Put a dname into canonical fmt - ie.
Definition dname.c:280
ldns_dname_label
ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME try and retrieve a specific label.
Definition dname.c:560
ldns_dname_label_count
uint8_t ldns_dname_label_count(const ldns_rdf *r)
count the number of labels inside a LDNS_RDF_DNAME type rdf.
Definition dname.c:214
ldns_dnssec_create_nsec3
ldns_rr * ldns_dnssec_create_nsec3(const ldns_dnssec_name *from, const ldns_dnssec_name *to, const ldns_rdf *zone_name, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, const uint8_t *salt)
Creates NSEC3.
Definition dnssec.c:869
LDNS_DEFAULT_EXP_TIME
#define LDNS_DEFAULT_EXP_TIME
Definition dnssec.h:44
ldns_nsec3_add_param_rdfs
void ldns_nsec3_add_param_rdfs(ldns_rr *rr, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, const uint8_t *salt)
Sets all the NSEC3 options.
Definition dnssec.c:1107
LDNS_SIGNATURE_LEAVE_ADD_NEW
#define LDNS_SIGNATURE_LEAVE_ADD_NEW
return values for the old-signature callback
Definition dnssec.h:47
LDNS_SIGNATURE_REMOVE_NO_ADD
#define LDNS_SIGNATURE_REMOVE_NO_ADD
Definition dnssec.h:50
ldns_dnssec_default_replace_signatures
int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n)
Default callback function to always leave present signatures, and add new ones.
ldns_dnssec_chain_nsec3_list
ldns_status ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs)
chains nsec3 list
Definition dnssec.c:1634
LDNS_SIGNATURE_REMOVE_ADD_NEW
#define LDNS_SIGNATURE_REMOVE_ADD_NEW
Definition dnssec.h:49
ldns_convert_ecdsa_rrsig_asn1len2rdf
ldns_rdf * ldns_convert_ecdsa_rrsig_asn1len2rdf(const ldns_buffer *sig, const long sig_len, int num_bytes)
Converts the ECDSA signature from ASN1 representation (as used by OpenSSL) to raw signature data as u...
Definition dnssec.c:1871
ldns_dnssec_create_nsec
ldns_rr * ldns_dnssec_create_nsec(const ldns_dnssec_name *from, const ldns_dnssec_name *to, ldns_rr_type nsec_type)
Creates NSEC.
Definition dnssec.c:815
ldns_dnssec_rrsets_contains_type
int ldns_dnssec_rrsets_contains_type(const ldns_dnssec_rrsets *rrsets, ldns_rr_type type)
returns whether a rrset of the given type is found in the rrsets.
Definition dnssec.c:801
LDNS_SIGNATURE_LEAVE_NO_ADD
#define LDNS_SIGNATURE_LEAVE_NO_ADD
Definition dnssec.h:48
ldns_convert_dsa_rrsig_asn12rdf
ldns_rdf * ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
Converts the DSA signature from ASN1 representation (RFC2459, as used by OpenSSL) to raw signature da...
Definition dnssec.c:1746
ldns_sign_public_evp
ldns_rdf * ldns_sign_public_evp(ldns_buffer *to_sign, EVP_PKEY *key, const EVP_MD *digest_type)
Sign data with EVP (general method for different algorithms).
Definition dnssec_sign.c:444
ldns_dnssec_remove_signatures
ldns_dnssec_rrs * ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures, ldns_key_list *key_list __attribute__((unused)), int(*func)(ldns_rr *, void *), void *arg)
Definition dnssec_sign.c:1022
ldns_sign_public
ldns_rr_list * ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
use this function to sign with a public/private key alg return the created signatures
Definition dnssec_sign.c:227
LDNS_SIGN_WITH_ZONEMD
#define LDNS_SIGN_WITH_ZONEMD
Definition dnssec_sign.c:27
ldns_zone_sign
ldns_zone * ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
Signs the zone, and returns a newly allocated signed zone.
Definition dnssec_sign.c:1604
ldns_zone_sign_nsec3
ldns_zone * 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)
Signs the zone with NSEC3, and returns a newly allocated signed zone.
Definition dnssec_sign.c:1645
ldns_dnssec_zone_mark_glue
ldns_status ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
Marks the names in the zone that are occluded.
Definition dnssec_sign.c:754
ldns_dnssec_zone_mark_and_get_glue
ldns_status ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, ldns_rr_list *glue_list)
Marks the names in the zone that are occluded.
Definition dnssec_sign.c:675
ldns_create_empty_rrsig
ldns_rr * ldns_create_empty_rrsig(const ldns_rr_list *rrset, const ldns_key *current_key)
Create an empty RRSIG RR (i.e.
Definition dnssec_sign.c:31
ldns_dnssec_zone_create_nsec3s
ldns_status ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
Adds NSEC3 records to the zone.
Definition dnssec_sign.c:1007
ldns_dnssec_zone_sign
ldns_status ldns_dnssec_zone_sign(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg)
signs the given zone with the given keys
Definition dnssec_sign.c:1364
dnssec_zone_equip_zonemd
ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int flags)
Definition dnssec_zone.c:1917
ldns_dnssec_zone_sign_nsec3_flg
ldns_status ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, int signflags)
signs the given zone with the given new zone, with NSEC3
Definition dnssec_sign.c:1586
ldns_sign_public_rsasha1
ldns_rdf * ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
Sign a buffer with the RSA key (hash with SHA1).
Definition dnssec_sign.c:573
ldns_dnssec_zone_create_rrsigs
ldns_status ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg)
Adds signatures to the zone.
Definition dnssec_sign.c:1113
ldns_sign_public_rsamd5
ldns_rdf * ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
Sign a buffer with the RSA key (hash with MD5).
Definition dnssec_sign.c:610
ldns_dnssec_zone_sign_nsec3_flg_mkmap
ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, int signflags, ldns_rbtree_t **map)
signs the given zone with the given new zone, with NSEC3
Definition dnssec_sign.c:1463
ldns_dnssec_name_node_next_nonglue
ldns_rbnode_t * ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
Finds the first dnssec_name node in the rbtree that is not occluded.
Definition dnssec_sign.c:760
ldns_dnssec_zone_sign_flg
ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, int flags)
signs the given zone with the given keys
Definition dnssec_sign.c:1376
ldns_sign_public_dsa
ldns_rdf * ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
Sign a buffer with the DSA key (hash with SHA1).
Definition dnssec_sign.c:332
ldns_sign_public_buffer
ldns_rdf * ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
Sign the buffer which contains the wiredata of an rrset, and the corresponding empty rrsig rr with th...
Definition dnssec_sign.c:128
ldns_dnssec_zone_create_nsecs
ldns_status ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs)
Adds NSEC records to the given dnssec_zone.
Definition dnssec_sign.c:786
ldns_dnssec_zone_sign_nsec3
ldns_status ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
signs the given zone with the given new zone, with NSEC3
Definition dnssec_sign.c:1446
ldns_dnssec_zone_create_rrsigs_flg
ldns_status ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, int flags)
Adds signatures to the zone.
Definition dnssec_sign.c:1218
LDNS_SIGN_DNSKEY_WITH_ZSK
#define LDNS_SIGN_DNSKEY_WITH_ZSK
dnssec_verify
Definition dnssec_sign.h:15
LDNS_SIGN_WITH_ALL_ALGORITHMS
#define LDNS_SIGN_WITH_ALL_ALGORITHMS
Definition dnssec_sign.h:16
LDNS_SIGN_NO_KEYS_NO_NSECS
#define LDNS_SIGN_NO_KEYS_NO_NSECS
Definition dnssec_sign.h:17
ldns_dnssec_zone_new
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition dnssec_zone.c:570
ldns_dnssec_name_name
ldns_rdf * ldns_dnssec_name_name(const ldns_dnssec_name *name)
Returns the domain name of the given dnssec_name structure.
Definition dnssec_zone.c:395
ldns_dnssec_rrs_new
ldns_dnssec_rrs * ldns_dnssec_rrs_new(void)
Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs.
Definition dnssec_zone.c:10
ldns_dnssec_rrs_add_rr
ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
Adds an RR to the list of RRs.
Definition dnssec_zone.c:47
ldns_dnssec_zone_find_rrset
ldns_dnssec_rrsets * ldns_dnssec_zone_find_rrset(const ldns_dnssec_zone *zone, const ldns_rdf *dname, ldns_rr_type type)
Find the RRset with the given name and type in the zone.
Definition dnssec_zone.c:509
ldns_dnssec_rrs
struct ldns_struct_dnssec_rrs ldns_dnssec_rrs
Singly linked list of rrs.
Definition dnssec_zone.h:21
ldns_dnssec_name
struct ldns_struct_dnssec_name ldns_dnssec_name
Structure containing all resource records for a domain name Including the derived NSEC3,...
Definition dnssec_zone.h:44
ldns_dnssec_rrsets
struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets
Singly linked list of RRsets.
Definition dnssec_zone.h:31
ldns_dnssec_name_find_rrset
ldns_dnssec_rrsets * ldns_dnssec_name_find_rrset(const ldns_dnssec_name *name, ldns_rr_type type)
Find the RRset with the given type in within this name structure.
Definition dnssec_zone.c:493
ldns_dnssec_name_add_rr
ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name, ldns_rr *rr)
Inserts the given rr at the right place in the current dnssec_name No checking is done whether the na...
Definition dnssec_zone.c:449
ldns_dnssec_zone_add_rr
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
Definition dnssec_zone.c:1002
ldns_dnssec_zone_add_empty_nonterminals
ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
Adds explicit dnssec_name structures for the empty nonterminals in this zone.
Definition dnssec_zone.c:1254
ldns_dnssec_zone_free
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition dnssec_zone.c:865
ldns_dnssec_zone
struct ldns_struct_dnssec_zone ldns_dnssec_zone
Definition dnssec_zone.h:104
LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW
@ LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW
Definition error.h:131
LDNS_STATUS_NULL
@ LDNS_STATUS_NULL
Definition error.h:51
LDNS_STATUS_ERR
@ LDNS_STATUS_ERR
Definition error.h:37
LDNS_STATUS_MEM_ERR
@ LDNS_STATUS_MEM_ERR
Definition error.h:34
LDNS_STATUS_OK
@ LDNS_STATUS_OK
Definition error.h:26
ldns_status
enum ldns_enum_status ldns_status
Definition error.h:148
ldns_rrsig2buffer_wire
ldns_status ldns_rrsig2buffer_wire(ldns_buffer *output, const ldns_rr *sigrr)
Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata This is needed in DNSSEC verification.
Definition host2wire.c:294
ldns_rr_list2buffer_wire
ldns_status ldns_rr_list2buffer_wire(ldns_buffer *output, const ldns_rr_list *rrlist)
Copies the rr_list data to the buffer in wire format.
Definition host2wire.c:156
ldns_key_expiration
uint32_t ldns_key_expiration(const ldns_key *k)
return the key's expiration date
Definition keys.c:1565
ldns_key_list_set_use
void ldns_key_list_set_use(ldns_key_list *keys, signed char v)
Set the 'use' flag for all keys in the list.
Definition keys.c:1584
ldns_key_set_use
void ldns_key_set_use(ldns_key *k, signed char v)
set the use flag
Definition keys.c:1469
LDNS_KEY_SEP_KEY
#define LDNS_KEY_SEP_KEY
Definition keys.h:38
ldns_key_evp_key
EVP_PKEY * ldns_key_evp_key(const ldns_key *k)
returns the (openssl) EVP struct contained in the key
Definition keys.c:1488
ldns_signing_algorithm
enum ldns_enum_signing_algorithm ldns_signing_algorithm
Definition keys.h:110
ldns_key
struct ldns_struct_key ldns_key
Definition keys.h:167
ldns_key_list_key
ldns_key * ldns_key_list_key(const ldns_key_list *key, size_t nr)
returns a pointer to the key in the list at the given position
Definition keys.c:1453
ldns_key_keytag
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
Definition keys.c:1571
ldns_key_algorithm
ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k)
return the signing alg of the key
Definition keys.c:1463
ldns_key_list
struct ldns_struct_key_list ldns_key_list
Definition keys.h:177
ldns_key2rr
ldns_rr * ldns_key2rr(const ldns_key *k)
converts a ldns_key to a public key rr If the key data exists at an external point,...
Definition keys.c:1803
LDNS_SIGN_RSASHA1
@ LDNS_SIGN_RSASHA1
Definition keys.h:84
LDNS_SIGN_ECDSAP256SHA256
@ LDNS_SIGN_ECDSAP256SHA256
Definition keys.h:95
LDNS_SIGN_DSA_NSEC3
@ LDNS_SIGN_DSA_NSEC3
Definition keys.h:92
LDNS_SIGN_ECC_GOST
@ LDNS_SIGN_ECC_GOST
Definition keys.h:94
LDNS_SIGN_ED448
@ LDNS_SIGN_ED448
Definition keys.h:101
LDNS_SIGN_ED25519
@ LDNS_SIGN_ED25519
Definition keys.h:98
LDNS_SIGN_RSASHA1_NSEC3
@ LDNS_SIGN_RSASHA1_NSEC3
Definition keys.h:88
LDNS_SIGN_ECDSAP384SHA384
@ LDNS_SIGN_ECDSAP384SHA384
Definition keys.h:96
LDNS_SIGN_RSAMD5
@ LDNS_SIGN_RSAMD5
Definition keys.h:83
LDNS_SIGN_RSASHA512
@ LDNS_SIGN_RSASHA512
Definition keys.h:90
LDNS_SIGN_DSA
@ LDNS_SIGN_DSA
Definition keys.h:86
LDNS_SIGN_RSASHA256
@ LDNS_SIGN_RSASHA256
Definition keys.h:89
ldns_key_inception
uint32_t ldns_key_inception(const ldns_key *k)
return the key's inception date
Definition keys.c:1559
ldns_key_pubkey_owner
ldns_rdf * ldns_key_pubkey_owner(const ldns_key *k)
return the public key's owner
Definition keys.c:1577
ldns_key_use
signed char ldns_key_use(const ldns_key *k)
return the use flag
Definition keys.c:1477
ldns_key_flags
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
Definition keys.c:1553
LDNS_KEY_ZONE_KEY
#define LDNS_KEY_ZONE_KEY
Definition keys.h:37
ldns_key_list_key_count
size_t ldns_key_list_key_count(const ldns_key_list *key_list)
returns the number of keys in the key list
Definition keys.c:1447
LDNS_DEFAULT_TTL
#define LDNS_DEFAULT_TTL
Definition ldns.h:136
LDNS_MAX_PACKETLEN
#define LDNS_MAX_PACKETLEN
Definition packet.h:24
ldns_traverse_postorder
void ldns_traverse_postorder(ldns_rbtree_t *tree, void(*func)(ldns_rbnode_t *, void *), void *arg)
Call function for all elements in the redblack tree, such that leaf elements are called before parent...
Definition rbtree.c:666
ldns_rbtree_first
ldns_rbnode_t * ldns_rbtree_first(const ldns_rbtree_t *rbtree)
Returns first (smallest) node in the tree.
Definition rbtree.c:548
ldns_rbtree_next
ldns_rbnode_t * ldns_rbtree_next(ldns_rbnode_t *rbtree)
Returns next larger node in the tree.
Definition rbtree.c:574
ldns_rbtree_insert
ldns_rbnode_t * ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
Insert data into the tree.
Definition rbtree.c:242
LDNS_RBTREE_NULL
#define LDNS_RBTREE_NULL
The nullpointer, points to empty node.
Definition rbtree.h:76
ldns_rbtree_create
ldns_rbtree_t * ldns_rbtree_create(int(*cmpf)(const void *, const void *))
Create new tree (malloced) with given key compare function.
Definition rbtree.c:80
ldns_rdf_data
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition rdata.c:38
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition rdata.c:222
ldns_rdf_new_frm_data
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
Definition rdata.c:193
ldns_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition rdata.c:230
ldns_rdf2native_int32
uint32_t ldns_rdf2native_int32(const ldns_rdf *rd)
returns the native uint32_t representation from the rdf.
Definition rdata.c:98
ldns_rdf2native_int16
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition rdata.c:84
ldns_native2rdf_int16
ldns_rdf * ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
returns the rdf containing the native uint16_t representation.
Definition rdata.c:132
ldns_native2rdf_int8
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
Definition rdata.c:126
LDNS_RDF_TYPE_INT32
@ LDNS_RDF_TYPE_INT32
32 bits
Definition rdata.h:56
LDNS_RDF_TYPE_B64
@ LDNS_RDF_TYPE_B64
b64 string
Definition rdata.h:68
LDNS_RDF_TYPE_TIME
@ LDNS_RDF_TYPE_TIME
time (32 bits)
Definition rdata.h:84
LDNS_RDF_TYPE_INT8
@ LDNS_RDF_TYPE_INT8
8 bits
Definition rdata.h:52
LDNS_RDF_TYPE_INT16
@ LDNS_RDF_TYPE_INT16
16 bits
Definition rdata.h:54
LDNS_RDF_TYPE_ALG
@ LDNS_RDF_TYPE_ALG
a key algorithm
Definition rdata.h:80
LDNS_RDF_TYPE_TYPE
@ LDNS_RDF_TYPE_TYPE
a RR type
Definition rdata.h:74
ldns_native2rdf_int32
ldns_rdf * ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
returns an rdf that contains the given int32 value.
Definition rdata.c:147
ldns_rdf_size
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition rdata.c:24
ldns_rdf
struct ldns_struct_rdf ldns_rdf
Definition rdata.h:205
ldns_rdf_free
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
Definition rdata.c:241
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition rr.c:1015
ldns_rr_ttl
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition rr.c:935
ldns_rr_pop_rdf
ldns_rdf * ldns_rr_pop_rdf(ldns_rr *rr)
removes a rd_field member, it will be popped from the last position.
Definition rr.c:884
ldns_rr_list_deep_free
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition rr.c:1024
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition rr.c:81
ldns_rr_set_owner
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition rr.c:808
ldns_rr
struct ldns_struct_rr ldns_rr
Definition rr.h:337
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition rr.c:1004
ldns_rr_list_type
ldns_rr_type ldns_rr_list_type(const ldns_rr_list *rr_list)
Returns the type of the first element of the RR If there are no elements present, 0 is returned.
Definition rr.c:2779
ldns_rr_list_sort
void ldns_rr_list_sort(ldns_rr_list *unsorted)
sorts an rr_list (canonical wire format).
Definition rr.c:1520
ldns_rr_new_frm_type
ldns_rr * ldns_rr_new_frm_type(ldns_rr_type t)
creates a new rr structure, based on the given type.
Definition rr.c:48
LDNS_RR_TYPE_RRSIG
@ LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition rr.h:170
LDNS_RR_TYPE_A
@ LDNS_RR_TYPE_A
a host address
Definition rr.h:80
LDNS_RR_TYPE_ZONEMD
@ LDNS_RR_TYPE_ZONEMD
Definition rr.h:194
LDNS_RR_TYPE_DNSKEY
@ LDNS_RR_TYPE_DNSKEY
Definition rr.h:172
LDNS_RR_TYPE_SOA
@ LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition rr.h:90
LDNS_RR_TYPE_NSEC
@ LDNS_RR_TYPE_NSEC
Definition rr.h:171
LDNS_RR_TYPE_DNAME
@ LDNS_RR_TYPE_DNAME
RFC2672.
Definition rr.h:156
LDNS_RR_TYPE_DS
@ LDNS_RR_TYPE_DS
RFC4034, RFC3658.
Definition rr.h:164
LDNS_RR_TYPE_NSEC3PARAM
@ LDNS_RR_TYPE_NSEC3PARAM
Definition rr.h:177
LDNS_RR_TYPE_NSEC3
@ LDNS_RR_TYPE_NSEC3
Definition rr.h:176
LDNS_RR_TYPE_CDNSKEY
@ LDNS_RR_TYPE_CDNSKEY
Definition rr.h:191
LDNS_RR_TYPE_AAAA
@ LDNS_RR_TYPE_AAAA
ipv6 address
Definition rr.h:134
LDNS_RR_TYPE_NS
@ LDNS_RR_TYPE_NS
an authoritative name server
Definition rr.h:82
LDNS_RR_TYPE_CDS
@ LDNS_RR_TYPE_CDS
Definition rr.h:190
ldns_rr_list_push_rr
signed char ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition rr.c:1136
ldns_rr2canonical
void ldns_rr2canonical(ldns_rr *rr)
converts each dname in a rr to its canonical form.
Definition rr.c:1785
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition rr.c:913
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition rr.c:961
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition rr.c:947
ldns_rr_set_ttl
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition rr.c:820
ldns_rr_clone
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition rr.c:1404
ldns_rr_get_class
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr)
returns the class of the rr.
Definition rr.c:953
ldns_rr_list
struct ldns_struct_rr_list ldns_rr_list
Definition rr.h:351
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition rr.h:61
ldns_rr_list_rr
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition rr.c:994
ldns_rr_set_class
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
Definition rr.c:838
ldns_rr_list_clone
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition rr.c:1435
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition rr.c:923
ldns_rr_rrsig_set_expiration
bool ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f)
sets the expiration date of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:165
ldns_rr_rrsig_set_keytag
bool ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f)
sets the keytag of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:189
ldns_rr_rrsig_set_algorithm
bool ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f)
sets the algorithm of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:129
ldns_rr_rrsig_set_typecovered
bool ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f)
sets the typecovered of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:117
ldns_rr_rrsig_set_labels
bool ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f)
sets the number of labels of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:141
ldns_rr_rrsig_set_inception
bool ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f)
sets the inception date of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:177
ldns_rr_rrsig_set_signame
bool ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f)
sets the signers name of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:201
ldns_rr_rrsig_keytag
ldns_rdf * ldns_rr_rrsig_keytag(const ldns_rr *r)
returns the keytag of a LDNS_RR_TYPE_RRSIG RR
Definition rr_functions.c:183
ldns_rr_rrsig_set_sig
bool ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f)
sets the signature data of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:213
ldns_rr_rrsig_set_origttl
bool ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f)
sets the original TTL of a LDNS_RR_TYPE_RRSIG rr
Definition rr_functions.c:153
R
#define R(b, x)
Definition sha2.c:191
ldns_rbnode_t
The rbnode_t struct definition.
Definition rbtree.h:60
ldns_rbnode_t::data
const void * data
pointer to data
Definition rbtree.h:70
ldns_rbnode_t::key
const void * key
pointer to sorting key
Definition rbtree.h:68
ldns_rbtree_t
definition for tree struct
Definition rbtree.h:83
ldns_rbtree_t::root
ldns_rbnode_t * root
The root of the red-black tree.
Definition rbtree.h:85
ldns_struct_dnssec_name::nsec_signatures
ldns_dnssec_rrs * nsec_signatures
signatures for the NSEC record
Definition dnssec_zone.h:71
ldns_struct_dnssec_name::nsec
ldns_rr * nsec
NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3).
Definition dnssec_zone.h:67
ldns_struct_dnssec_name::hashed_name
ldns_rdf * hashed_name
pointer to store the hashed name (only used when in an NSEC3 zone
Definition dnssec_zone.h:85
ldns_struct_dnssec_name::rrsets
ldns_dnssec_rrsets * rrsets
The rrsets for this name.
Definition dnssec_zone.h:63
ldns_struct_dnssec_name::is_glue
signed char is_glue
Unlike what the name is_glue suggests, this field is set to true by ldns_dnssec_zone_mark_glue() or l...
Definition dnssec_zone.h:81
ldns_struct_dnssec_name::name
ldns_rdf * name
pointer to a dname containing the name.
Definition dnssec_zone.h:51
ldns_struct_dnssec_rrs::rr
ldns_rr * rr
Definition dnssec_zone.h:24
ldns_struct_dnssec_rrs::next
ldns_dnssec_rrs * next
Definition dnssec_zone.h:25
ldns_struct_dnssec_rrsets::rrs
ldns_dnssec_rrs * rrs
Definition dnssec_zone.h:34
ldns_struct_dnssec_rrsets::type
ldns_rr_type type
Definition dnssec_zone.h:35
ldns_struct_dnssec_rrsets::signatures
ldns_dnssec_rrs * signatures
Definition dnssec_zone.h:36
ldns_struct_dnssec_rrsets::next
ldns_dnssec_rrsets * next
Definition dnssec_zone.h:37
ldns_struct_dnssec_zone::hashed_names
ldns_rbtree_t * hashed_names
tree of ldns_dnssec_names by nsec3 hashes (when applicable)
Definition dnssec_zone.h:97
ldns_struct_dnssec_zone::names
ldns_rbtree_t * names
tree of ldns_dnssec_names
Definition dnssec_zone.h:95
ldns_struct_dnssec_zone::soa
ldns_dnssec_name * soa
points to the name containing the SOA RR
Definition dnssec_zone.h:93
LDNS_FREE
#define LDNS_FREE(ptr)
Definition util.h:60
LDNS_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition util.h:49
ldns_set_bit
void ldns_set_bit(uint8_t *byte, int bit_nr, signed char value)
sets the specified bit in the specified byte to 1 if value is true, 0 if false The bits are counted f...
Definition util.c:72
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition util.h:51
ldns_zone_set_soa
void ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa)
Set the zone's soa record.
Definition zone.c:29
ldns_zone_soa
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition zone.c:17
ldns_zone_push_rr
signed char ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
push an single rr to a zone structure.
Definition zone.c:53
ldns_zone_rrs
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition zone.c:35
ldns_zone_new
ldns_zone * ldns_zone_new(void)
create a new ldns_zone structure
Definition zone.c:165
ldns_zone
struct ldns_struct_zone ldns_zone
Definition zone.h:50