mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
sigcrypt keyset processing
git-svn-id: file:///svn/unbound/trunk@501 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
bdb519c5c1
commit
8f58908f45
4 changed files with 214 additions and 8 deletions
|
|
@ -1,6 +1,8 @@
|
|||
8 August 2007: Wouter
|
||||
- ldns _raw routines created (in ldns trunk).
|
||||
- sigcrypt DS digest routines
|
||||
- val_utils uses sigcrypt to perform signature cryptography.
|
||||
- sigcrypt keyset processing
|
||||
|
||||
7 August 2007: Wouter
|
||||
- security status type.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,60 @@
|
|||
#error "Need SSL library to do digital signature cryptography"
|
||||
#endif
|
||||
|
||||
/** return number of rrs in an rrset */
|
||||
static size_t
|
||||
rrset_get_count(struct ub_packed_rrset_key* rrset)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->entry.data;
|
||||
if(!d) return 0;
|
||||
return d->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get RR signature count
|
||||
*/
|
||||
static size_t
|
||||
rrset_get_sigcount(struct ub_packed_rrset_key* k)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||
return d->rrsig_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get signature keytag value
|
||||
* @param k: rrset (with signatures)
|
||||
* @param sig_idx: signature index.
|
||||
* @return keytag or 0 if malformed rrsig.
|
||||
*/
|
||||
static uint16_t
|
||||
rrset_get_sig_keytag(struct ub_packed_rrset_key* k, size_t sig_idx)
|
||||
{
|
||||
uint16_t t;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||
log_assert(sig_idx < d->rrsig_count);
|
||||
if(d->rr_len[d->count + sig_idx] < 2+18)
|
||||
return 0;
|
||||
memmove(&t, d->rr_data[d->count + sig_idx]+2+16, 2);
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get signature signing algorithm value
|
||||
* @param k: rrset (with signatures)
|
||||
* @param sig_idx: signature index.
|
||||
* @return algo or 0 if malformed rrsig.
|
||||
*/
|
||||
static int
|
||||
rrset_get_sig_algo(struct ub_packed_rrset_key* k, size_t sig_idx)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
|
||||
log_assert(sig_idx < d->rrsig_count);
|
||||
if(d->rr_len[d->count + sig_idx] < 2+3)
|
||||
return 0;
|
||||
return (int)d->rr_data[d->count + sig_idx][2+2];
|
||||
}
|
||||
|
||||
/** get rdata pointer and size */
|
||||
static void
|
||||
rrset_get_rdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** rdata,
|
||||
|
|
@ -286,3 +340,97 @@ int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
dnskey_idx));
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
num = rrset_get_sigcount(rrset);
|
||||
if(num == 0) {
|
||||
verbose(VERB_ALGO, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskeyset_verify_rrset_sig(env, ve, rrset, dnskey, i);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
num = rrset_get_sigcount(rrset);
|
||||
if(num == 0) {
|
||||
verbose(VERB_ALGO, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskey_verify_rrset_sig(env, ve, rrset, dnskey,
|
||||
dnskey_idx, i);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t sig_idx)
|
||||
{
|
||||
/* find matching keys and check them */
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
uint16_t tag = rrset_get_sig_keytag(rrset, sig_idx);
|
||||
int algo = rrset_get_sig_algo(rrset, sig_idx);
|
||||
size_t i, num = rrset_get_count(dnskey);
|
||||
size_t numchecked = 0;
|
||||
|
||||
for(i=0; i<num; i++) {
|
||||
/* see if key matches keytag and algo */
|
||||
if(algo != dnskey_get_algo(dnskey, i) ||
|
||||
tag != dnskey_calc_keytag(dnskey, i))
|
||||
continue;
|
||||
|
||||
numchecked ++;
|
||||
/* see if key verifies */
|
||||
sec = dnskey_verify_rrset_sig(env, ve, rrset, dnskey,
|
||||
i, sig_idx);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
verbose(VERB_ALGO, "could not find appropriate key");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
dnskey_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx)
|
||||
{
|
||||
/* verify as many fields in rrsig as possible */
|
||||
/* verify key dname == sig signer name */
|
||||
/* verify covered type */
|
||||
/* verify keytag and sig algo (possibly again) */
|
||||
/* verify labels is in a valid range */
|
||||
/* original ttl, always ok */
|
||||
/* verify inception, expiration dates */
|
||||
|
||||
/* create rrset canonical format in buffer, ready for signature */
|
||||
|
||||
/* verify */
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
struct val_env;
|
||||
struct module_env;
|
||||
struct ub_packed_rrset_key;
|
||||
enum sec_status;
|
||||
|
||||
/**
|
||||
* Check if dnskey matches a DS digest
|
||||
|
|
@ -121,12 +122,61 @@ int ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx);
|
|||
*/
|
||||
int dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx);
|
||||
|
||||
/** verify rrset against dnskey rrset. */
|
||||
/**
|
||||
* Verify rrset against dnskey rrset.
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset to try.
|
||||
* @return SECURE if one key in the set verifies one rrsig.
|
||||
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
|
||||
* and BOGUS on verification failures (no keys match any signatures).
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey);
|
||||
|
||||
/** verify rrset against one specific dnskey (from rrset) */
|
||||
/**
|
||||
* verify rrset against one specific dnskey (from rrset)
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset.
|
||||
* @param dnskey_idx: which key from the rrset to try.
|
||||
* @return secure if *this* key signs any of the signatures on rrset.
|
||||
* unchecked on error or and bogus on bad signature.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t dnskey_idx);
|
||||
|
||||
/** verify rrset, with dnskey rrset, for a specific rrsig in rrset */
|
||||
/**
|
||||
* verify rrset, with dnskey rrset, for a specific rrsig in rrset
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset to try.
|
||||
* @param sig_idx: which signature to try to validate.
|
||||
* @return secure if any key signs *this* signature. bogus if no key signs it,
|
||||
* or unchecked on error.
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx);
|
||||
|
||||
/** verify rrset, with specific dnskey(from set), for a specific rrsig */
|
||||
/**
|
||||
* verify rrset, with specific dnskey(from set), for a specific rrsig
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset.
|
||||
* @param dnskey_idx: which key from the rrset to try.
|
||||
* @param sig_idx: which signature to try to validate.
|
||||
* @return secure if this key signs this signature. unchecked on error or
|
||||
* bogus if it did not validate.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset_sig(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, size_t sig_idx);
|
||||
|
||||
#endif /* VALIDATOR_VAL_SIGCRYPT_H */
|
||||
|
|
|
|||
|
|
@ -199,8 +199,15 @@ enum sec_status
|
|||
val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys)
|
||||
{
|
||||
enum sec_status sec;
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, keys);
|
||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||
|
||||
return sec_status_bogus;
|
||||
/* TODO: update rrset security status */
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
/** verify that a DS RR hashes to a key and that key signs the set */
|
||||
|
|
@ -230,9 +237,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
|||
|
||||
/* Otherwise, we have a match! Make sure that the DNSKEY
|
||||
* verifies *with this key* */
|
||||
/*
|
||||
sec = verify_rrset_key(env, ve, dnskey_rrset, dnskey_rrset, i);
|
||||
*/
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
dnskey_rrset, i);
|
||||
if(sec == sec_status_secure) {
|
||||
return sec;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue