]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
sigcrypt keyset processing
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 8 Aug 2007 13:59:57 +0000 (13:59 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 8 Aug 2007 13:59:57 +0000 (13:59 +0000)
git-svn-id: file:///svn/unbound/trunk@501 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
validator/val_sigcrypt.c
validator/val_sigcrypt.h
validator/val_utils.c

index e85f072ade300458b25999519d440ea3218d018f..e843be86d1af9edf50ea2c31cbdb582a5fc666c4 100644 (file)
@@ -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.
index 3eb20ed5ae00bd5843907efddc381cf6a3a262f5..0808d1dd764a66a6c9bd7fafd22f5c16e17cf7c2 100644 (file)
 #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;
+}
index 219ec4b0931ae3653c94fcb60755b77c202ebe48..43a83e18d6aa769dafeb7fcbf02503d3213dfaa6 100644 (file)
@@ -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 */
index 50ab9e4c93dab82d368b33bced029151664b315e..d2f9052d8c13c5c2d48ddf6ab1ef48bb1573b4fb 100644 (file)
@@ -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;
                }