[Opendnssec-commits] [keihatsu.kirei.se/svn/dnssec] r5300 - in branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src: . enforcer keystate

Yuri Schaeffer yuri at keihatsu.kirei.se
Thu Jul 7 18:12:07 CEST 2011


Author: yuri
Date: 2011-07-07 18:12:06 +0200 (Thu, 07 Jul 2011)
New Revision: 5300

Modified:
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/Makefile.am
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcer.cpp
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerdata.h
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.cpp
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.h
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate.proto
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate_list_task.cpp
   branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/update_keyzones_task.cpp
Log:
rewrite largely completed. 
added several RRSIG DNSKEY functions
removed initial NULL key



Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/Makefile.am
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/Makefile.am	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/Makefile.am	2011-07-07 16:12:06 UTC (rev 5300)
@@ -117,5 +117,5 @@
 ods_enforcer_LDADD=		$(LIBHSM)
 ods_enforcer_LDADD+=		@LDNS_LIBS@ @XML2_LIBS@
 
-%.pb.cc %.pb.h:  %.proto
+%.pb.cc %.pb.h: %.proto
 	$(PROTOC) $(AM_CPPFLAGS) --cpp_out=`dirname $@` -I=`dirname $@` `dirname $@`/`basename $@ .pb.cc`.proto

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcer.cpp
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcer.cpp	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcer.cpp	2011-07-07 16:12:06 UTC (rev 5300)
@@ -15,792 +15,427 @@
 }
 
 using namespace std;
+using ::ods::kasp::Policy;
 
 static const char *module_str = "enforcer";
 
-/* Link these to keystate to prevent later ambiguities.
- * Alias rather than use directly, we don't want to be too dependent
- * on spelling. */
-#define HID ods::keystate::hidden
-#define RUM ods::keystate::rumoured
-#define COM ods::keystate::committed
-#define OMN ods::keystate::omnipresent
-#define UNR ods::keystate::unretentive
-#define PCM ods::keystate::postcommitted
-#define REV ods::keystate::revoked
+/* be careful changing this, might mess up database*/
+enum STATE {HID, RUM, OMN, UNR, NOCARE}; 
+static const char* STATENAMES[] = {"HID", "RUM", "OMN", "UNR"};
+enum RECORD {REC_MIN, DS = REC_MIN, DK, RD, RS, REC_MAX};
+/* trick to loop over our enum */
+RECORD& operator++(RECORD& r){return r = (r >= REC_MAX)?REC_MAX:RECORD(r+1);}
+static const char* RECORDAMES[] = {"DS", "DNSKEY", "RRSIG DNSKEY", "RRSIG"};
+/* \careful */
 
+
 /* When no key available wait this many seconds before asking again. */
 #define NOKEY_TIMEOUT 60
+/* TODO: Temporary placeholder, must figure this out from policy. */
+#define ALLOW_UNSIGNED false
 
 /**
  * Stores smallest of two times in *min.
  * Avoiding negative values, which mean no update necessary
+ * Any other time in the past: ASAP.
  * */
-inline void minTime(const time_t t, time_t &min) {
-	if ( (t < min || min < 0) && t >= 0 )
-		min = t;
+inline void 
+minTime(const time_t t, time_t &min)
+{
+	if ( (t < min || min < 0) && t >= 0 ) min = t;
 }
 
-/**
- * Translate the record state to something human readable.
- **/
-const char* stateName(const int state) {
-	return ods::keystate::rrstate_Name((ods::keystate::rrstate)state).c_str();
+KeyState&
+getRecord(KeyData &key, const RECORD record)
+{
+	const char *scmd = "getRecord";
+	switch(record) {
+		case DS: return key.keyStateDS();
+		case DK: return key.keyStateDNSKEY();
+		case RD: return key.keyStateRRSIGDNSKEY();
+		case RS: return key.keyStateRRSIG();
+		default: 
+			ods_fatal_exit("[%s] %s Unknown record type (%d), "
+				"fault of programmer. Abort.", 
+				module_str, scmd, (int)record);
+	}
 }
 
-/**
- * Search for youngest key in use by any zone with this policy
- * with at least the roles requested. See if it isn't expired.
- * also, check if it isn't in zone already. Also length, algorithm
- * must match and it must be a first generation key.
- * */
-bool getLastReusableKey(EnforcerZone &zone,
-		const ::ods::kasp::Policy *policy, const KeyRole role,
-        int bits, const string &repository, int algorithm, const time_t now, HsmKey **ppKey,
-		HsmKeyFactory &keyfactory, int lifetime) {
-	if (!keyfactory.UseSharedKey(bits, repository, policy->name(), algorithm,
-									 role, zone.name(), ppKey))
-		return false;
-	assert(*ppKey != NULL); /* FindSharedKeys() promised us. */
-	/* Key must (still) be in use */
-	if (now < (*ppKey)->inception() + lifetime)
-		return true;
-	/* Was set by default, unset */
-	(*ppKey)->setUsedByZone(zone.name(), false);
-	return false;
+void
+setState(KeyData &key, const RECORD record, const STATE state, 
+	const time_t now)
+{
+	KeyState &ks = getRecord(key, record);
+	ks.setState(state);
+	ks.setLastChange(now);
+
 }
 
-/* Applies new state to record and keeps additional administration.
- * */
-void setState(KeyState &record_state, const int new_state,
-		const time_t now ) {
-	const char *scmd = "setState";
+STATE
+getState(KeyData &key, const RECORD record)
+{
+	return (STATE)getRecord(key, record).state();
+}
 
-	ods_log_verbose("[%s] %s to %s", module_str, scmd,
-			stateName(new_state));
-	record_state.setState(new_state);
-	record_state.setLastChange(now);
+/**
+ * Given goal and state, what will be the next state?
+ * */
+STATE
+getDesiredState(const bool introducing, const STATE state)
+{
+	const char *scmd = "getDesiredState";
+	if (state > NOCARE || state < HID) 
+		ods_fatal_exit("[%s] %s Key in unknown state (%d), "
+			"Corrupt database? Abort.",  module_str, scmd, (int)state);
+	const STATE jmp[2][5] = {{HID, UNR, UNR, HID, NOCARE}, {RUM, OMN, OMN, RUM, NOCARE}};
+	return jmp[introducing][(int)state];
 }
 
-/* A DS|DNSKEY|RRSIG RR is considered reliable (useable in a validation
- * chain) if it is known to all caches or it is being introduced and
- * another DS|DNSKEY|RRSIG is decommissioned at the same time.
+/**
+ * The policy approval function makes sure records are introduced in
+ * correct order.
  * */
-bool reliableDs(KeyDataList &key_list, KeyData &key) {
-	if (key.keyStateDS().state() == OMN) return true;
-	if (key.keyStateDS().state() != COM) return false;
-	int alg = key.algorithm();
-	for (int i = 0; i < key_list.numKeys(); i++) {
-		KeyData &k = key_list.key(i);
-		if  (k.keyStateDS().state() == PCM &&
-				k.algorithm() == alg)
-			return true;
+bool
+policy_approval(KeyData &key, const RECORD record, const STATE next_state)
+{
+	const char *scmd = "getDesiredState";
+	if (next_state != RUM) return true; /* already introducing */
+	switch(record) {
+		case DS:
+			return !key.keyStateDS().minimize() || 
+				getState(key, DK) == OMN;
+		case DK:
+			return !key.keyStateDNSKEY().minimize() || 
+				(getState(key, DS) == OMN && getState(key, RS) == OMN);
+		case RD:
+			return getState(key, DK) != HID;
+		case RS:
+			return !key.keyStateRRSIG().minimize() || 
+				getState(key, DK) == OMN;
+		default: 
+			ods_fatal_exit("[%s] %s Unknown record type (%d), "
+				"fault of programmer. Abort.",
+				module_str, scmd, (int)record);
 	}
-	return false;
 }
-bool reliableDnskey(KeyDataList &key_list, KeyData &key) {
-	if (key.keyStateDNSKEY().state() == OMN) return true;
-	if (key.keyStateDNSKEY().state() != COM) return false;
-	int alg = key.algorithm();
-	for (int i = 0; i < key_list.numKeys(); i++) {
-		KeyData &k = key_list.key(i);
-		if  (k.keyStateDNSKEY().state() == PCM &&
-				k.algorithm() == alg)
-			return true;
-	}
+
+bool
+exists(KeyDataList &key_list, KeyData &key, 
+	const RECORD record,const STATE next_state, 
+	const bool require_same_algorithm, const bool pretend_update, 
+	const STATE mask[4])
+{
+		for (int i = 0; i < key_list.numKeys(); i++) {
+			KeyData &k = key_list.key(i);
+			if (require_same_algorithm && k.algorithm() != key.algorithm())
+				continue;
+			bool sub_key = pretend_update && !key.locator().compare(k.locator());
+			//~ ods_log_verbose("[%s] %d %d %s %s", module_str, sub_key, pretend_update, key.locator().c_str(), k.locator().c_str());
+			bool match = true;
+			for (RECORD r = REC_MIN; r < REC_MAX; ++r) {
+				bool sub_rec = sub_key && record == r;
+				if (mask[r] == NOCARE) continue;
+				/* if key and record match and pretend_update
+				 * pretend the record has state next_state */
+				STATE state = sub_rec?next_state:getState(k, r);
+				if (mask[r] != state) {
+					match = false;
+					break;
+				}
+			}
+			if (match) return true;
+		}
 	return false;
 }
-bool reliableRrsig(KeyDataList &key_list, KeyData &key) {
-	if (key.keyStateRRSIG().state() == OMN) return true;
-	if (key.keyStateRRSIG().state() != COM) return false;
-	int alg = key.algorithm();
+
+bool
+unsigned_ok(KeyDataList &key_list, KeyData &key, const RECORD record, 
+	const STATE next_state, const bool pretend_update, 
+	const STATE mask[4], const RECORD mustHID)
+{
+	//check all keys
 	for (int i = 0; i < key_list.numKeys(); i++) {
 		KeyData &k = key_list.key(i);
-		if  (k.keyStateRRSIG().state() == PCM &&
-				k.algorithm() == alg)
-			return true;
+		if (k.algorithm() != key.algorithm()) continue;
+		STATE k_state[4];
+		for (RECORD r = REC_MIN; r < REC_MAX; ++r)
+			k_state[r] = (pretend_update && record==r && !key.locator().compare(k.locator()))?next_state:getState(k, r);
+		if (k_state[mustHID] == HID || k_state[mustHID] == NOCARE) continue;
+		STATE amask[4];
+		for (RECORD r = REC_MIN; r < REC_MAX; ++r)
+			amask[r] = (mustHID==r)?k_state[r]:mask[r];
+		if (!exists(key_list, key, record, next_state, true, pretend_update, amask))
+			return false; //we can't satisfy this condition
 	}
-	return false;
+	return true;
 }
 
-bool updateDs(EnforcerZone &zone, KeyDataList &key_list, KeyData &key,
-		const time_t now, time_t &next_update_for_record) {
-	bool record_changed = false;
-	int num_keys = key_list.numKeys();
-	const ::ods::kasp::Policy *policy = zone.policy();
-	KeyData *k;
-	time_t Tprop;
+bool
+rule1(KeyDataList &key_list, KeyData &key, const RECORD record, 
+	const STATE next_state, const bool pretend_update)
+{
+	const STATE mask1[] =  {RUM, NOCARE, NOCARE, NOCARE};
+	const STATE mask2[] =  {OMN, NOCARE, NOCARE, NOCARE};
+	return  exists(key_list, key, record, next_state, false, pretend_update, mask1) ||
+			exists(key_list, key, record, next_state, false, pretend_update, mask2);
+}
 
-	bool exists_ds_postcomitted;
-	bool forall;
-	bool ds_omni_or_com;
+bool
+rule2(KeyDataList &key_list, KeyData &key, const RECORD record, 
+	const STATE next_state, const bool pretend_update)
+{
+	const STATE mask1[] =  {RUM, OMN, OMN, NOCARE};
+	const STATE mask2[] =  {UNR, OMN, OMN, NOCARE};
+	const STATE mask3[] =  {OMN, OMN, OMN, NOCARE};
+	const STATE mask4[] =  {OMN, RUM, RUM, NOCARE};
+	const STATE mask5[] =  {OMN, OMN, RUM, NOCARE};
+	const STATE mask6[] =  {OMN, UNR, UNR, NOCARE};
+	const STATE mask7[] =  {OMN, UNR, OMN, NOCARE};
+	const STATE mask_unsg[] =  {HID, OMN, OMN, NOCARE};
 
-	const char *scmd = "updateDs";
+	//~ return
+	//~ unsigned_ok(key_list, key, record, next_state, pretend_update, mask_unsg, DS);
+	return
+	unsigned_ok(key_list, key, record, next_state, pretend_update, mask_unsg, DS) ||
+	
+	exists(key_list, key, record, next_state, true, pretend_update, mask1) &&
+	exists(key_list, key, record, next_state, true, pretend_update, mask2) ||
+	
+	exists(key_list, key, record, next_state, true, pretend_update, mask3) ||
+	
+	(exists(key_list, key, record, next_state, true, pretend_update, mask4) ||
+	 exists(key_list, key, record, next_state, true, pretend_update, mask5) )&&
+	(exists(key_list, key, record, next_state, true, pretend_update, mask6) ||
+	 exists(key_list, key, record, next_state, true, pretend_update, mask7) );
+}
 
-	KeyState &record_state = key.keyStateDS();
-	ods_log_verbose("[%s] %s state %s", module_str, scmd,
-			stateName(record_state.state()));
-	switch ( record_state.state() ) {
+bool
+rule3(KeyDataList &key_list, KeyData &key, const RECORD record, 
+	const STATE next_state, const bool pretend_update)
+{
+	const STATE mask_triv[] =  {NOCARE, OMN, NOCARE, OMN};
+	const STATE mask_keyi[] =  {NOCARE, RUM, NOCARE, OMN};
+	const STATE mask_keyo[] =  {NOCARE, UNR, NOCARE, OMN};
+	const STATE mask_sigi[] =  {NOCARE, OMN, NOCARE, RUM};
+	const STATE mask_sigo[] =  {NOCARE, OMN, NOCARE, UNR};
+	const STATE mask_unsg[] =  {NOCARE, HID, NOCARE, OMN};
 
-	case HID:
-	if (!key.introducing() || key.standby()) break;
-	if (!record_state.minimize()) {
-		int similar_ksks = 0;
-		if (key.keyStateDNSKEY().state() == OMN) {
-			setState(record_state, RUM, now);
-			record_changed = true;
-			/* The DS record must be submit to the parent */
-			key.setSubmitToParent(true);
-			key.setDSSeen(false);
-			/* The signer configuration does not change */
-			break;
-		}
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if (k->algorithm() == key.algorithm() &&
-					reliableDs(key_list, *k) &&
-					reliableDnskey(key_list, *k)) {
-				setState(record_state, RUM, now);
-				record_changed = true;
-				/* The DS record must be submit to the parent */
-				key.setSubmitToParent(true);
-				key.setDSSeen(false);
-				/* The signer configuration does not change */
-				break;
-			}
-		}
-	}
-	if (key.keyStateDNSKEY().state() == OMN) {
-		setState(record_state, COM, now);
-		record_changed = true;
-		/* The DS record must be submit to the parent */
-		key.setSubmitToParent(true);
-		key.setDSSeen(false);
-		/* The signer configuration does not change */
-	}
-	break;
-
-	case RUM:
-	if (!key.introducing()) {
-		setState(record_state, UNR, now);
-		record_changed = true;
-		/* The DS record withdrawal must be submit to the parent */
-		key.setSubmitToParent(true);
-		key.setDSSeen(false);
-		/* The signer configuration does not change */
-	} else if (key.isDSSeen()) {
-		Tprop = record_state.lastChange() + policy->parent().ttlds()
-				+ policy->parent().registrationdelay()
-				+ policy->parent().propagationdelay();
-		if (now >= Tprop) {
-			setState(record_state, OMN, now);
-			record_changed = true;
-			/* There is no next update scheduled for this record
-			 * since it is now omnipresent and introducing */
-		} else {
-			/* All requirements are met but not the propagation time
-			 * ask to come back at a later date. */
-			next_update_for_record = Tprop;
-		}
-	}
-	break;
-
-	case COM:
-	if (!key.isDSSeen()) break;
-	Tprop = record_state.lastChange() + policy->parent().ttlds()
-			+ policy->parent().registrationdelay()
-			+ policy->parent().propagationdelay();
-	if (now >= Tprop) {
-		setState(record_state, OMN, now);
-		record_changed = true;
-		/* There is no next update scheduled for this record
-		 * since it is now omnipresent and introducing */
-	} else {
-		/* All requirements are met but not the propagation time
-		 * ask to come back at a later date. */
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case OMN:
-	if (key.introducing()) break; /* already there */
-	if (key.keyStateDNSKEY().state() != OMN) {
-		bool exists_ds_comitted = false;
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if (k->keyStateDS().state() == COM) {
-				exists_ds_comitted = true;
-				break;
-			}
-		}
-		if (exists_ds_comitted) {
-			setState(record_state, PCM, now);
-			record_changed = true;
-			/* The DS record withdrawal must be submit to the parent */
-			key.setSubmitToParent(true);
-			key.setDSSeen(false);
-			/* The signer configuration does not change */
-			break; /* from switch */
-		}
-	}
-
-	if (key.keyStateDNSKEY().state() == PCM) break;
-
-	exists_ds_postcomitted = false;
-	for (int i = 0; i < num_keys; i++) {
-		k = &key_list.key(i);
-		if (k->keyStateDS().state() == PCM) {
-			exists_ds_postcomitted = true;
-			break;
-		}
-	}
-	forall = true;
-	ds_omni_or_com = false;
-	for (int i = 0; i < num_keys; i++) {
-		k = &key_list.key(i);
-		ds_omni_or_com |= k != &key && (k->keyStateDS().state() == OMN ||
-				(k->keyStateDS().state() == COM && exists_ds_postcomitted));
-		if (k->algorithm() != key.algorithm() ) continue;
-		if (k->keyStateDS().state() == HID) continue;
-		if (reliableDnskey(key_list, *k)) continue;
-
-		/* Leave innerloop as last check,
-		 * for performance. */
-		bool hasReplacement = false;
-		KeyData *l;
-		for (int j = 0; j < num_keys; j++) {
-			l = &key_list.key(j);
-			if (l->algorithm() == k->algorithm() && l != &key
-					&& reliableDs(key_list, *l) && reliableDnskey(key_list, *l)) {
-				hasReplacement = true;
-				break;
-			}
-		}
-		if (!hasReplacement) {
-			forall = false;
-			break;
-		}
-	}
-
-	if (ds_omni_or_com && forall) {
-		setState(record_state, UNR, now);
-		record_changed = true;
-		/* The DS record withdrawal must be submit to the parent */
-		key.setSubmitToParent(true);
-		key.setDSSeen(false);
-		/* The signer configuration does not change */
-	}
-	break;
-
-	case UNR:
-	/* We might *not* allow this, for simplicity */
-	if (key.introducing()) {
-		setState(record_state, RUM, now);
-		record_changed = true;
-		/* The DS record withdrawal must be submit to the parent */
-		key.setSubmitToParent(true);
-		key.setDSSeen(false);
-		/* The signer configuration does not change */
-		break;
-	}
-	Tprop = record_state.lastChange() + policy->parent().ttlds()
-			+ policy->parent().registrationdelay()
-			+ policy->parent().propagationdelay();
-	if (now >= Tprop) {
-		setState(record_state, HID, now);
-		record_changed = true;
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case PCM:
-	Tprop = record_state.lastChange() + policy->parent().ttlds()
-			+ policy->parent().registrationdelay()
-			+ policy->parent().propagationdelay();
-	if (now >= Tprop) {
-		setState(record_state, HID, now);
-		record_changed = true;
-		/* no need to notify signer. Nothing changes in
-		 * its perspective. */
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case REV:
-		/* NOT IMPL */
-	break;
-
-	default:
-		assert(0); /* Nonexistent state. */
-	}
-
-	return record_changed;
+	return
+	unsigned_ok(key_list, key, record, next_state, pretend_update, mask_unsg, DK) ||
+	
+	exists(key_list, key, record, next_state, true, pretend_update, mask_triv) ||
+	
+	exists(key_list, key, record, next_state, true, pretend_update, mask_keyi) &&
+	exists(key_list, key, record, next_state, true, pretend_update, mask_keyo) ||
+	
+	exists(key_list, key, record, next_state, true, pretend_update, mask_sigi) &&
+	exists(key_list, key, record, next_state, true, pretend_update, mask_sigo);
 }
 
-bool updateDnskey(EnforcerZone &zone, KeyDataList &key_list,
-		KeyData &key, const time_t now, time_t &next_update_for_record) {
-	bool record_changed = false;
-	bool signer_needs_update = false;
-	next_update_for_record = -1;
-	const ::ods::kasp::Policy *policy = zone.policy();
-	int num_keys = key_list.numKeys();
-	KeyData *k, *l;
-	time_t Tprop;
+bool
+dnssec_approval(KeyDataList &key_list, KeyData &key, const RECORD record, 
+	const STATE next_state)
+{
+	bool a = rule1(key_list, key, record, next_state, false);
+	bool b = rule2(key_list, key, record, next_state, false);
+	bool c = rule3(key_list, key, record, next_state, false);
+	bool d = rule1(key_list, key, record, next_state, true);
+	bool e = rule2(key_list, key, record, next_state, true);
+	bool f = rule3(key_list, key, record, next_state, true);
+	
+	ods_log_verbose("[%s] %d%d%d %d%d%d", module_str, a,b,c,d,e,f);
 
-	const char *scmd = "updateDnskey";
-
-	KeyState &record_state = key.keyStateDNSKEY();
-	ods_log_verbose("[%s] %s state %s", module_str, scmd,
-			stateName(record_state.state()));
-	switch ( record_state.state() ) {
-
-	case HID:
-	if (!key.introducing()) break;
-	if (record_state.minimize() && (key.keyStateDS().state() == OMN ||
-		!(key.role() & KSK)) &&
-		(key.keyStateRRSIG().state() == OMN ||
-		!(key.role() & ZSK)) ) {
-		setState(record_state, COM, now);
-		record_changed = true;
-		/* The DNSKEY now needs to be published. */
-		signer_needs_update = true;
-		break;
-	}
-	if (record_state.minimize() && !key.standby()) {
-		bool noneExist = true;
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if (!(key.algorithm() == k->algorithm() &&
-					reliableDnskey(key_list, *k) &&
-					key.role() & KSK)){
-				noneExist = false;
-				break;
-			}
-		}
-		if (!noneExist) break;
-	}
-	if (!reliableRrsig(key_list, key)) {
-		bool oneExist = false;
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if (key.algorithm() == k->algorithm() &&
-					reliableDnskey(key_list, *k) &&
-					reliableRrsig(key_list, *k)){
-				oneExist = true;
-				break;
-			}
-		}
-		if (!oneExist) break;
-	}
-	setState(record_state, RUM, now);
-	record_changed = true;
-	/* The DNSKEY now needs to be published. */
-	signer_needs_update = true;
-	break;
-
-	case RUM:
-	if (!key.introducing()) {
-		setState(record_state, UNR, now);
-		record_changed = true;
-		signer_needs_update = true;
-		break;
-	}
-	Tprop = record_state.lastChange() + policy->keys().ttl()
-			+ policy->keys().publishsafety()
-			+ policy->zone().propagationdelay();
-	if (now >= Tprop) {
-		setState(record_state, OMN, now);
-		record_changed = true;
-		break;
-	}
-	next_update_for_record = Tprop;
-	break;
-
-	case COM:
-	Tprop = record_state.lastChange() + policy->keys().ttl()
-			+ policy->keys().publishsafety()
-			+ policy->zone().propagationdelay();
-	if (now >= Tprop) {
-		setState(record_state, OMN, now);
-		record_changed = true;
-		break;
-	}
-	next_update_for_record = Tprop;
-	break;
-
-	case OMN:
-	if (key.introducing() || key.keyStateDS().state() == PCM ||
-		key.keyStateRRSIG().state() == PCM ) break;
-	if ( key.keyStateDS().state() == OMN &&
-		key.keyStateRRSIG().state() == OMN &&
-		!key.revoke()) {
-		bool hasReplacement = false;
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if ( k->keyStateDNSKEY().state() == COM &&
-					key.algorithm() == k->algorithm() &&
-					key.role() == k->role() ) {
-				hasReplacement = true;
-				break;
-			}
-		}
-		if ( hasReplacement ) {
-		/* withdraw stuff */
-		setState(record_state, PCM, now);
-		record_changed = true;
-		break;
-		}
-	}
-	if ( key.keyStateDS().state() != PCM &&
-			key.keyStateRRSIG().state() != PCM ) {
-		/* We must check if any other key depend on 'key'
-		 * if so, we can not take an action */
-		bool all = true;
-		/* forall */
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			bool ksk_ok, zsk_ok;
-			ksk_ok = !(k->role() & KSK) || k->keyStateDS().state() == HID ||
-				(k != &key && reliableDnskey(key_list, *k));
-			zsk_ok = k->keyStateDNSKEY().state() == HID ||
-				reliableRrsig(key_list, *k);
-			if (ksk_ok && zsk_ok) continue;
-			/* This key breaks the chain, see if there is a
-			 * candidate that fixes this. */
-			/* exists */
-			for ( int j = 0; j < num_keys; j++ ) {
-				l = &key_list.key(j);
-				if ( 	&key == l ||
-						k->algorithm() != l->algorithm() ||
-						!reliableDnskey( key_list, *l ) )
-					continue;
-				ksk_ok |= reliableDs( key_list, *l );
-				zsk_ok |= reliableRrsig( key_list, *l );
-				if (ksk_ok && zsk_ok) break; /* inner loop */
-			}
-			if ( !ksk_ok || !zsk_ok ) {
-				all = false;
-				break; /* outer loop */
-			}
-		}
-		if ( all ) {
-			setState(record_state, key.revoke() ? REV : UNR, now);
-			record_changed = true;
-			/* submit or revoke stuff */
-		}
-	}
-	break;
-
-	case REV:
-	Tprop = 0 /* TODO */;
-	if (now >= Tprop) {
-		setState(record_state, UNR, now);
-		record_changed = true;
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case UNR:
-	Tprop = record_state.lastChange() + policy->keys().ttl()
-			+ policy->keys().retiresafety()
-			+ policy->zone().propagationdelay();
-	if (key.introducing()) {
-		/* submit,
-		 * key->dnskey_state = Key::ST_UNRETENTIVE;
-		 * record_changed = true;
-		 * */
-	} else if (now >= Tprop) {
-		setState(record_state, HID, now);
-		record_changed = true;
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case PCM:
-	break;
-
-	}
-
-	if (signer_needs_update) zone.setSignerConfNeedsWriting(true);
-	return record_changed;
+	
+	return 
+		(!rule1(key_list, key, record, next_state, false) ||
+		  rule1(key_list, key, record, next_state, true ) ) &&
+		(!rule2(key_list, key, record, next_state, false) ||
+		  rule2(key_list, key, record, next_state, true ) ) &&
+		(!rule3(key_list, key, record, next_state, false) ||
+		  rule3(key_list, key, record, next_state, true ) );
 }
 
-bool updateRrsig(EnforcerZone &zone, KeyDataList &key_list, KeyData &key,
-		const time_t now, time_t &next_update_for_record) {
-	bool record_changed = false;
-	bool signer_needs_update = false;
-	next_update_for_record = -1;
-	const ::ods::kasp::Policy *policy = zone.policy();
-	int num_keys = key_list.numKeys();
-	KeyData *k;
-	time_t Tprop;
-	const char *scmd = "updateRrsig";
-
-	bool exists;
-	bool safeToWithdraw;
-
-	KeyState &record_state = key.keyStateRRSIG();
-	ods_log_verbose("[%s] %s state %s", module_str, scmd,
-			stateName(record_state.state()));
-	switch ( record_state.state() ) {
-
-	case HID:
-	if ( !key.introducing() || key.standby() ) {
-		ods_log_info("[%s] %s, not introducing or standby ", module_str, scmd);
-		break;
-	}
-	exists = false;
-	//~ if (!record_state.minimize()) {
-	if (false) { // DEBUG
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if ( key.algorithm() == k->algorithm() &&
-					reliableRrsig(key_list, *k) ) {
-				exists = true;
-				break;
-			}
-		}
-	}
-	//~ if ( !exists || !record_state.minimize() ) {
-	//~ if ( !exists && !record_state.minimize() ) {
-	if ( !exists || false ) { //DEBUG
-		/* There exists no other propagated ZSK, so no use for a
-		 * gradual rollover. */
-		ods_log_info("[%s] %s, not exists", module_str, scmd);
-		setState(record_state, RUM, now);
-		record_changed = true;
-		break;
-	}
-	//~ if ( record_state.minimize() &&
-	if ( true && //DEBUG
-			key.keyStateDNSKEY().state() == OMN) {
-		/* submit stuff */
-		ods_log_info("[%s] %s, minimize", module_str, scmd);
-		setState(record_state, COM, now);
-		record_changed = true;
-		break;
-	}
-	ods_log_info("[%s] %s, no match", module_str, scmd);
-	break;
-
-	case RUM:
-	//ods_log_info("[%s] %s, info sigttl %d", module_str, scmd, policy->signatures().ttl());
-	//ods_log_info("[%s] %s, info prpdly %d", module_str, scmd, policy->zone().propagationdelay());
-	Tprop = record_state.lastChange() + policy->signatures().ttl()
-			+ policy->zone().propagationdelay();
-	if ( !key.introducing() ) {
-		/* withdraw stuff */
-		setState(record_state, UNR, now);
-		record_changed = true;
-		break;
-	} else if ( now >= Tprop ) {
-		/* do stuff */
-		setState(record_state, OMN, now);
-		record_changed = true;
-		break;
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case COM:
-	Tprop = record_state.lastChange() + policy->signatures().ttl()
-			+ policy->zone().propagationdelay();
-	if ( now >= Tprop ) {
-		/* do stuff */
-		setState(record_state, OMN, now);
-		record_changed = true;
-		break;
-	}
-	break;
-
-	case OMN:
-	if ( key.introducing() ) break;
-	if ( key.keyStateDNSKEY().state() == OMN ) {
-		bool exist3 = false;
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if ( k->keyStateRRSIG().state() == COM &&
-					key.algorithm() == k->algorithm() ) {
-				exist3 = true;
-				break;
-			}
-		}
-		if ( exist3 ) {
-			setState(record_state, HID, now);
-			record_changed = true;
-			break;
-		}
-	}
-	if ( key.keyStateDNSKEY().state() == PCM ) break;
-
-	safeToWithdraw = ( key.keyStateDNSKEY().state() == HID );
-	if ( !safeToWithdraw ) {
-		for (int i = 0; i < num_keys; i++) {
-			k = &key_list.key(i);
-			if ( &key != k && key.algorithm() == k->algorithm() &&
-					reliableDnskey(key_list, *k) &&
-					reliableRrsig(key_list, *k)) {
-				safeToWithdraw = true;
-				break;
-			}
-		}
-	}
-	if ( safeToWithdraw ) {
-		/* submit stuff */
-		setState(record_state, UNR, now);
-		record_changed = true;
-		break;
-	}
-	break;
-
-	case REV:
-	break;
-
-	case UNR:
-	Tprop = record_state.lastChange() + policy->signatures().ttl()
-			+ policy->zone().propagationdelay();
-	if ( key.introducing()) {
-	    /* submit
-	     * state -> rumoured
-	     break;*/
-	} if ( now >= Tprop ) {
-		setState(record_state, HID, now);
-		record_changed = true;
-	    break;
-	} else {
-		next_update_for_record = Tprop;
-	}
-	break;
-
-	case PCM:
-	Tprop = record_state.lastChange() + policy->signatures().ttl()
-			+ policy->zone().propagationdelay();
-	if ( now >= Tprop ) {
-		setState(record_state, HID, now);
-		record_changed = true;
-	    break;
-	} else {
-		next_update_for_record = Tprop;
-	}
-
-	break;
-
-    }
-
-    if (signer_needs_update)
-		zone.setSignerConfNeedsWriting(true);
-    return record_changed;
+time_t
+addtime(const time_t &t, const int seconds)
+{
+	struct tm *tp = localtime(&t);
+	tp->tm_sec += seconds;
+	return mktime(tp);
 }
 
-/* updateKey
- * Updates all relevant (with respect to role) records of a key.
- *
- * @return: true on any changes within this key */
-bool updateKey(EnforcerZone &zone, KeyDataList &key_list, KeyData &key,
-		const time_t now, time_t &next_update_for_key) {
-	time_t next_update_for_record = -1;
-	next_update_for_key = -1;
-	bool key_changed = false;
-	const char *scmd = "updateKey";
+time_t
+min_transition_time(const Policy *policy, const RECORD record, const STATE state, 
+	const STATE next_state, const time_t lastchange)
+{
+	const char *scmd = "min_transition_time";
 
-	ods_log_info("[%s] %s %s", module_str, scmd, key.locator().c_str());
-
-	if (key.role() & KSK) { /* KSK and CSK */
-		key_changed |= updateDs(zone, key_list, key, now, next_update_for_record);
-		minTime(next_update_for_record, next_update_for_key);
+	/* if previous state was a certain state record may
+	 * transition directly. TODO improve comment */
+	if (next_state == RUM || next_state == UNR) return lastchange;
+	
+	//~ ods_log_verbose("[%s] %d %d %d %d %d %d %d %d %d %d", module_str, 
+	//~ policy->parent().ttlds(),
+	//~ policy->parent().registrationdelay(),
+	//~ policy->parent().propagationdelay(),
+	//~ policy->keys().ttl(),
+	//~ policy->zone().propagationdelay(),
+	//~ policy->keys().publishsafety(),
+	//~ policy->keys().retiresafety(),
+	//~ policy->signatures().ttl(),
+	//~ policy->zone().propagationdelay(),
+	//~ lastchange
+	//~ );
+	
+	switch(record) {
+		case DS:
+			return addtime(lastchange,
+				  policy->parent().ttlds()
+				+ policy->parent().registrationdelay()
+				+ policy->parent().propagationdelay());
+		/* TODO: 5011 will create special case here */
+		case DK: /* intentional fall-through */
+		case RD:
+			return addtime(lastchange,
+				  policy->keys().ttl()
+				+ policy->zone().propagationdelay()
+				+ (next_state == OMN)
+					? policy->keys().publishsafety()
+					: policy->keys().retiresafety());
+		case RS:
+			return addtime(lastchange,
+				  policy->signatures().ttl()
+				+ policy->zone().propagationdelay());
+		default: 
+			ods_fatal_exit("[%s] %s Unknown record type (%d), "
+				"fault of programmer. Abort.",
+				module_str, scmd, (int)record);
 	}
-
-	key_changed |= updateDnskey(zone, key_list, key, now, next_update_for_record);
-	minTime(next_update_for_record, next_update_for_key);
-
-	if (key.role() & ZSK) { /* ZSK and CSK */
-		key_changed |= updateRrsig(zone, key_list, key, now, next_update_for_record);
-		minTime(next_update_for_record, next_update_for_key);
-	}
-	return key_changed;
 }
 
 /**
  * Try to push each key for this zone to a next state. If one changes
  * visit the rest again. Loop stops when no changes can be made without
- * advance of time. Return time of first possible event. */
-time_t updateZone(EnforcerZone &zone, const time_t now) {
-	time_t return_at = -1;
-	time_t next_update_for_key;
+ * advance of time. Return time of first possible event. 
+ * */
+time_t
+updateZone(EnforcerZone &zone, const time_t now)
+{
+	time_t returntime_zone = -1;
+	time_t returntime_key;
+	bool change;
 	KeyDataList &key_list = zone.keyDataList();
+	const ::ods::kasp::Policy *policy = zone.policy();
 	const char *scmd = "updateZone";
-	int dbg_cnt = 0;
-
 	ods_log_verbose("[%s] %s", module_str, scmd);
 
 	/* Keep looping till there are no state changes.
 	 * Find the soonest update time */
-	bool a_key_changed = true;
-	while (a_key_changed) {
-		a_key_changed = false;
+	do {
+		change = false;
 		/* Loop over all keys */
 		for (int i = 0; i < key_list.numKeys(); i++) {
-			if (updateKey(zone, key_list, key_list.key(i), now, next_update_for_key)) {
-				a_key_changed = true;
-				dbg_cnt++;
+			KeyData &key = key_list.key(i);
+			ods_log_verbose("[%s] %s processing key %s", module_str, scmd, key.locator().c_str());
+			/* Loop over records */
+			for (RECORD record = REC_MIN; record < REC_MAX; ++record) {
+				STATE state = getState(key, record);
+				STATE next_state = getDesiredState(key.introducing(), state);
+				if (state == next_state) continue;
+				ods_log_verbose("[%s] %s May %s transition to %s?", module_str, scmd, RECORDAMES[(int)record], STATENAMES[(int)next_state]);
+				
+				if (!policy_approval(key, record, next_state)) continue;
+				ods_log_verbose("[%s] %s Policy says we can (1/3)", module_str, scmd);
+				
+				if (!dnssec_approval(key_list, key, record, next_state)) continue;
+				ods_log_verbose("[%s] %s DNSSEC says we can (2/3)", module_str, scmd);
+				/* do time stuff */
+				time_t returntime_key = min_transition_time(policy, record, 
+					state, next_state, getRecord(key, record).lastChange());
+				//~ ods_log_verbose("[%s] %s retkey %d", module_str, scmd, returntime_key);
+
+				if (returntime_key > now) {
+					minTime(returntime_key, returntime_zone);
+					continue;
+				}
+				ods_log_verbose("[%s] %s Timing says we can (3/3) now: %d key: %d", module_str, scmd, now, returntime_key);
+				setState(key, record, next_state, now); //now == next change?
+				change = true;
 			}
-			minTime(next_update_for_key, return_at);
 		}
-	}
-	ods_log_verbose("[%s] %s %d changes in keylist", module_str, scmd, dbg_cnt);
-	return return_at;
+	} while (change);
+	return returntime_zone;
 }
 
-/* Abstraction to generalize different kind of keys. */
-int numberOfKeys(const ::ods::kasp::Keys *policyKeys, const KeyRole role) {
-	const char *scmd = "numberOfKeys";
+/**
+ * Search for youngest key in use by any zone with this policy
+ * with at least the roles requested. See if it isn't expired.
+ * also, check if it isn't in zone already. Also length, algorithm
+ * must match and it must be a first generation key.
+ * */
+bool 
+getLastReusableKey(EnforcerZone &zone,
+	const Policy *policy, const KeyRole role,
+	int bits, const string &repository, int algorithm, 
+	const time_t now, HsmKey **ppKey,
+	HsmKeyFactory &keyfactory, int lifetime)
+{
+	if (!keyfactory.UseSharedKey(bits, repository, policy->name(), algorithm,
+									 role, zone.name(), ppKey))
+		return false;
+	assert(*ppKey != NULL); /* FindSharedKeys() promised us. */
+	/* Key must (still) be in use */
+	if (now < (*ppKey)->inception() + lifetime)
+		return true;
+	/* Was set by default, unset */
+	(*ppKey)->setUsedByZone(zone.name(), false);
+	return false;
+}
 
+/* Abstraction to generalize different kind of keys. 
+ * return number of keys _in_a_policy_ */
+int 
+numberOfKeys(const ::ods::kasp::Keys *policyKeys, const KeyRole role)
+{
+	const char *scmd = "numberOfKeys";
 	switch (role) {
-		case KSK:
-			return policyKeys->ksk_size();
-		case ZSK:
-			return policyKeys->zsk_size();
-		case CSK:
-			return policyKeys->csk_size();
+		case KSK: return policyKeys->ksk_size();
+		case ZSK: return policyKeys->zsk_size();
+		case CSK: return policyKeys->csk_size();
 		default:
 			ods_fatal_exit("[%s] %s Unknow Role: (%d)", 
 					module_str, scmd, role); /* report a bug! */
 	}
 }
 
-/* Abstraction to generalize different kind of keys. */
-void keyProperties(const ::ods::kasp::Keys *policyKeys, const KeyRole role,
+/* Abstraction to generalize different kind of keys. 
+ * Note: a better solution would be inheritance. */
+void 
+keyProperties(const ::ods::kasp::Keys *policyKeys, const KeyRole role,
 		const int index, int *bits, int *algorithm, int *lifetime,
-        string &repository) {
+        string &repository)
+{
 	const char *scmd = "keyProperties";
-
+	assert(index < numberOfKeys(policyKeys, role)); /* programming error */
+	
 	switch (role) {
 		case KSK:
-			assert(index < policyKeys->ksk_size());
 			*bits	   = policyKeys->ksk(index).bits();
 			*algorithm = policyKeys->ksk(index).algorithm();
 			*lifetime  = policyKeys->ksk(index).lifetime();
             repository.assign(policyKeys->ksk(index).repository());
-			return;
+			break;
 		case ZSK:
-			assert(index < policyKeys->zsk_size());
 			*bits	   = policyKeys->zsk(index).bits();
 			*algorithm = policyKeys->zsk(index).algorithm();
 			*lifetime  = policyKeys->zsk(index).lifetime();
             repository.assign(policyKeys->zsk(index).repository());
-			return;
+			break;
 		case CSK:
-			assert(index < policyKeys->csk_size());
 			*bits	   = policyKeys->csk(index).bits();
 			*algorithm = policyKeys->csk(index).algorithm();
 			*lifetime  = policyKeys->csk(index).lifetime();
             repository.assign(policyKeys->csk(index).repository());
-			return;
+			break;
 		default:
 			ods_fatal_exit("[%s] %s Unknow Role: (%d)",
 					module_str, scmd, role); /* report a bug! */
@@ -883,7 +518,7 @@
 			if ( !got_key ) {
 				/* The factory was not ready, return in 60s */
 				minTime( now + NOKEY_TIMEOUT, return_at);
-				ods_log_info("[%s] %s No keys available on hsm, retry in %d seconds", module_str, scmd, NOKEY_TIMEOUT);
+				ods_log_warning("[%s] %s No keys available on hsm, retry in %d seconds", module_str, scmd, NOKEY_TIMEOUT);
 				continue;
 			}
 
@@ -895,9 +530,14 @@
 			/* fill next_key */
 			new_key.setDSSeen( false );
 			new_key.setSubmitToParent( false );
-			new_key.keyStateDS().setState(HID);
+			new_key.keyStateDS().setState((role&KSK)?HID:NOCARE);
 			new_key.keyStateDNSKEY().setState(HID);
-			new_key.keyStateRRSIG().setState(HID);
+			new_key.keyStateRRSIGDNSKEY().setState((role&KSK)?HID:NOCARE);
+			new_key.keyStateRRSIG().setState((role&ZSK)?HID:NOCARE);
+			new_key.keyStateDS().setLastChange(now);
+			new_key.keyStateDNSKEY().setLastChange(now);
+			new_key.keyStateRRSIGDNSKEY().setLastChange(now);
+			new_key.keyStateRRSIG().setLastChange(now);
 			new_key.setIntroducing(true);
 
 			/* New key inserted, come back after its lifetime */
@@ -925,11 +565,13 @@
 
 	for (int i = key_list.numKeys()-1; i >= 0; i--) {
 		KeyData &key = key_list.key(i);
-		if (	key.keyStateDS().state() == HID &&
-				key.keyStateDNSKEY().state() == HID &&
-				key.keyStateRRSIG().state() == HID &&
+		/* TODO make loop for this */
+		if (	(getState(key, DS) == HID || getState(key, DS) == NOCARE) &&
+				(getState(key, DK) == HID || getState(key, DK) == NOCARE) &&
+				(getState(key, RD) == HID || getState(key, RD) == NOCARE) &&
+				(getState(key, RS) == HID || getState(key, RS) == NOCARE) &&
 				!key.introducing()) {
-			ods_log_verbose("[%s] %s delete key: %s", module_str, scmd, key.locator().c_str());
+			ods_log_info("[%s] %s delete key: %s", module_str, scmd, key.locator().c_str());
 			key_list.delKey(i);
 		}
 	}
@@ -941,9 +583,9 @@
 	KeyDataList &key_list = zone.keyDataList();
 	const char *scmd = "update";
 
-	ods_log_verbose("[%s] %s -----------------------", module_str, scmd, zone.name().c_str());
-	ods_log_info("[%s] %s zoneName: %s", module_str, scmd, zone.name().c_str());
-	ods_log_verbose("[%s] %s time: %d", module_str, scmd, now);
+	//~ ods_log_verbose("[%s] %s -----------------------", module_str, scmd, zone.name().c_str());
+	ods_log_info("[%s] %s Zone: %s", module_str, scmd, zone.name().c_str());
+	//~ ods_log_verbose("[%s] %s time: %d", module_str, scmd, now);
 
 	policy_return_time = updatePolicy(zone, now, keyfactory, key_list);
 	zone_return_time = updateZone(zone, now);
@@ -955,17 +597,10 @@
 	 * signerconf might not be available, we have no way of telling. :(
 	 * */
 	/* if (zone.signerConfNeedsWriting()) { ... }*/
-	KeyData *key;
 	for (int i = 0; i < key_list.numKeys(); i++) {
-		key = &key_list.key(i);
-		key->setPublish(
-			key->keyStateDNSKEY().state() == OMN ||
-			key->keyStateDNSKEY().state() == RUM ||
-			key->keyStateDNSKEY().state() == COM);
-		key->setActive(
-			key->keyStateRRSIG().state() == OMN ||
-			key->keyStateRRSIG().state() == RUM ||
-			key->keyStateRRSIG().state() == COM);
+		KeyData &key = key_list.key(i);
+		key.setPublish(getState(key, DK) == OMN || getState(key, DK) == RUM);
+		key.setActive(getState(key, RS) == OMN || getState(key, RS) == RUM);
 	}
 
 	minTime(policy_return_time, zone_return_time);

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerdata.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerdata.h	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerdata.h	2011-07-07 16:12:06 UTC (rev 5300)
@@ -153,6 +153,7 @@
     virtual KeyState &keyStateDS() = 0;
     virtual KeyState &keyStateRRSIG() = 0;
     virtual KeyState &keyStateDNSKEY() = 0;
+    virtual KeyState &keyStateRRSIGDNSKEY() = 0;
 
     virtual bool isDSSeen() = 0;
     virtual void setDSSeen(bool value) = 0;

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.cpp
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.cpp	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.cpp	2011-07-07 16:12:06 UTC (rev 5300)
@@ -59,7 +59,8 @@
 :   _keydata(keydata),
     _keyStateDS( _keydata->mutable_ds() ),
     _keyStateRRSIG( _keydata->mutable_rrsig() ),
-    _keyStateDNSKEY( _keydata->mutable_dnskey() )
+    _keyStateDNSKEY( _keydata->mutable_dnskey() ),
+    _keyStateRRSIGDNSKEY( _keydata->mutable_rrsigdnskey() )
 {
 }
 
@@ -113,6 +114,11 @@
     return _keyStateDNSKEY;
 }
 
+KeyState &KeyDataPB::keyStateRRSIGDNSKEY()
+{
+    return _keyStateRRSIGDNSKEY;
+}
+
 KeyRole KeyDataPB::role()
 {
     return (KeyRole)_keydata->role();

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.h	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/enforcer/enforcerzone.h	2011-07-07 16:12:06 UTC (rev 5300)
@@ -34,6 +34,7 @@
     KeyStatePB _keyStateDS;
     KeyStatePB _keyStateRRSIG;
     KeyStatePB _keyStateDNSKEY;
+    KeyStatePB _keyStateRRSIGDNSKEY;
 public:
     KeyDataPB( ::ods::keystate::KeyData *keydata );
     bool matches( const ::ods::keystate::KeyData *keydata );
@@ -50,6 +51,7 @@
     virtual KeyState &keyStateDS();
     virtual KeyState &keyStateRRSIG();
     virtual KeyState &keyStateDNSKEY();
+    virtual KeyState &keyStateRRSIGDNSKEY();
     
     virtual KeyRole role();
     void setRole(KeyRole value);

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate.proto
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate.proto	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate.proto	2011-07-07 16:12:06 UTC (rev 5300)
@@ -56,9 +56,7 @@
 enum rrstate {
     hidden = 0;
     rumoured = 1;
-    committed = 2;
-    omnipresent = 3;
-    unretentive = 4;
-    postcommitted = 5;
-    revoked = 6;
+    omnipresent = 2;
+    unretentive = 3;
+    NA = 4;
 }

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate_list_task.cpp
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate_list_task.cpp	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/keystate_list_task.cpp	2011-07-07 16:12:06 UTC (rev 5300)
@@ -46,6 +46,7 @@
                    "Key role:     "
                    "DS:          "
                    "DNSKEY:      "
+                   "RRSIGDNSKEY: "
                    "RRSIG:       "
                    "Pub: "
                    "Act: "
@@ -63,14 +64,16 @@
             const ::ods::keystate::KeyData &key = zone.keys(k);
             std::string keyrole = keyrole_Name(key.role());
             std::string ds_rrstate = rrstate_Name(key.ds().state());
+            std::string dnskey_rrstate = rrstate_Name(key.dnskey().state());
+            std::string rrsigdnskey_rrstate = rrstate_Name(key.rrsigdnskey().state());
             std::string rrsig_rrstate = rrstate_Name(key.rrsig().state());
-            std::string dnskey_rrstate = rrstate_Name(key.dnskey().state());
             (void)snprintf(buf, ODS_SE_MAXLINE,
-                       "%-31s %-13s %-12s %-12s %-12s %d %4d    %s\n",
+                       "%-31s %-13s %-12s %-12s %-12s %-12s %d %4d    %s\n",
                        zone.name().c_str(),
                        keyrole.c_str(),
                        ds_rrstate.c_str(),
                        dnskey_rrstate.c_str(),
+                       rrsigdnskey_rrstate.c_str(),
                        rrsig_rrstate.c_str(),
                        key.publish(),
                        key.active(),

Modified: branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/update_keyzones_task.cpp
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/update_keyzones_task.cpp	2011-07-07 11:09:10 UTC (rev 5299)
+++ branches/OpenDNSSEC-enforcer-ng/enforcer-ng/src/keystate/update_keyzones_task.cpp	2011-07-07 16:12:06 UTC (rev 5300)
@@ -107,22 +107,6 @@
                         
             // enforcer needs to trigger signer configuration writing.
             ks_zone->set_signconf_needs_writing( false );
-            
-            // Add NULL key state
-            ::ods::keystate::KeyData *ks_key = ks_zone->add_keys();
-            ks_key->set_locator( "" );
-            ks_key->set_algorithm( 0 );
-            ks_key->set_inception( 0 );
-            ks_key->mutable_ds()->set_minimize( false );
-            ks_key->mutable_ds()->set_state( ::ods::keystate::omnipresent );
-            ks_key->mutable_dnskey()->set_minimize( false );
-            ks_key->mutable_dnskey()->set_state( ::ods::keystate::omnipresent );
-            ks_key->mutable_rrsig()->set_minimize( false);
-            ks_key->mutable_rrsig()->set_state( ::ods::keystate::omnipresent );
-            ks_key->set_role( ::ods::keystate::CSK );
-            ks_key->set_introducing(false);
-            ks_key->set_revoke(false);
-            ks_key->set_standby( false );
         }
     }
     




More information about the Opendnssec-commits mailing list