key_purge.c
Go to the documentation of this file.
/*
* Copyright (c) 2017 NLNet Labs. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "key_purge.h"
#include "clientpipe.h"
#include "log.h"
#include "hsmkey/hsm_key_factory.h"
static void free_all(key_data_list_t *key_list, key_data_t** keylist,
key_dependency_list_t *deplist, key_dependency_t **deplist2,
zone_db_t *zone)
{
int i;
key_dependency_list_free(deplist);
deplist = NULL;
key_data_list_free(key_list);
key_list = NULL;
if (keylist) {
int keylist_size = key_data_list_size(key_list);
for (i = 0; i < keylist_size; i++) {
key_data_free(keylist[i]);
}
free(keylist);
keylist = NULL;
}
if (deplist2) {
int deplist2_size = key_dependency_list_size(deplist);
for (i = 0; i < deplist2_size; i++){
key_dependency_free(deplist2[i]);
}
free(deplist2);
deplist2 = NULL;
}
zone_db_free(zone);
}
int removeDeadKeysNow(int sockfd, db_connection_t *dbconn,
policy_t *policy, zone_db_t *rzone, int purge)
{
static const char *scmd = "removeDeadKeysNow";
size_t i, deplist2_size = 0;
int key_purgable, cmp;
int zone_key_purgable;
unsigned int j;
const key_state_t* state = NULL;
key_data_list_t *key_list = NULL;
key_data_t** keylist = NULL;
key_dependency_list_t *deplist = NULL;
key_dependency_t **deplist2 = NULL;
size_t keylist_size;
zone_list_db_t *zonelist = NULL;
zone_db_t *zone = NULL;
int listsize = 0;
if (!dbconn) {
ods_log_error("[%s] no dbconn", scmd);
client_printf_err(sockfd, "[%s] no dbconn", scmd);
return 1;
}
if (policy) {
if (policy_retrieve_zone_list(policy)) {
ods_log_error("[%s] Error fetching zones", scmd);
client_printf_err(sockfd, "[%s] Error fetching zones", scmd);
return 1;
}
zonelist = policy_zone_list(policy);
listsize = zone_list_db_size(zonelist);
if (listsize == 0) {
client_printf (sockfd, "No zones on policy %s\n", policy_name(policy));
client_printf (sockfd, "No keys to purge\n");
return 0;
}
zone = zone_list_db_get_next(zonelist);
} else if (rzone) {
listsize = 1;
zone = zone_db_new_copy(rzone);
}
while (listsize > 0 ) {
zone_key_purgable = 0;
if (!(deplist = zone_db_get_key_dependencies(zone))) {
/* TODO: better log error */
ods_log_error("[%s] error zone_db_get_key_dependencies()", scmd);
client_printf_err(sockfd, "%s: error zone_db_get_key_dependencies()", scmd);
free_all(key_list, keylist, deplist, deplist2, zone);
return 1;
}
if (!(key_list = zone_db_get_keys(zone))) {
/* TODO: better log error */
ods_log_error("[%s] error zone_db_get_keys()", scmd);
client_printf_err(sockfd, "%s: error zone_db_get_keys()", scmd);
free_all(key_list, keylist, deplist, deplist2, zone);
return 1;
}
keylist_size = key_data_list_size(key_list);
if (keylist_size) {
if (!(keylist = (key_data_t**)calloc(keylist_size, sizeof(key_data_t*)))) {
/* TODO: better log error */
ods_log_error("[%s] error calloc(keylist_size)", scmd);
client_printf_err(sockfd, "[%s] error calloc(keylist_size)", scmd);
free_all(key_list, keylist, deplist, deplist2, zone);
return 1;
}
for (i = 0; i < keylist_size; i++) {
if (!i)
keylist[i] = key_data_list_get_begin(key_list);
else
keylist[i] = key_data_list_get_next(key_list);
if (!keylist[i]
|| key_data_cache_hsm_key(keylist[i])
|| key_data_cache_key_states(keylist[i])) {
ods_log_error("[%s] error key_data_list cache", scmd);
client_printf_err(sockfd, "[%s] error key_data_list cache", scmd);
free_all(key_list, keylist, deplist, deplist2, zone);
return 1;
}
}
}
key_data_list_free(key_list);
key_list = NULL;
deplist2_size = key_dependency_list_size(deplist);
deplist2 = (key_dependency_t**)calloc(deplist2_size, sizeof(key_dependency_t*));
/* deplist might be NULL but is always freeable */
if (deplist2_size > 0)
deplist2[0] = key_dependency_list_get_begin(deplist);
for (i = 1; i < deplist2_size; i++)
deplist2[i] = key_dependency_list_get_next(deplist);
key_dependency_list_free(deplist);
deplist = NULL;
for (i = 0; i < keylist_size; i++) {
if (key_data_introducing(keylist[i])) continue;
key_purgable = 1;
for (j = 0; j<4; j++) {
switch(j){
case 0: state = key_data_cached_ds(keylist[i]); break;
case 1: state = key_data_cached_dnskey(keylist[i]); break;
case 2: state = key_data_cached_rrsigdnskey(keylist[i]); break;
case 3: state = key_data_cached_rrsig(keylist[i]); break;
default: state = NULL;
}
if (key_state_state(state) == KEY_STATE_STATE_NA) continue;
if (key_state_state(state) != KEY_STATE_STATE_HIDDEN) {
key_purgable = 0;
break;
}
}
if (key_purgable) {
zone_key_purgable = 1;
/* key is purgable */
ods_log_info("[%s] deleting key: %s", scmd,
hsm_key_locator(key_data_cached_hsm_key(keylist[i])));
client_printf (sockfd, "deleting key: %s\n",
hsm_key_locator(key_data_cached_hsm_key(keylist[i])));
/* FIXME: key_data_cached_ds spits out const
* key_state_delete discards that. */
if (key_state_delete(key_data_cached_ds(keylist[i]))
|| key_state_delete(key_data_cached_dnskey(keylist[i]))
|| key_state_delete(key_data_cached_rrsigdnskey(keylist[i]))
|| key_state_delete(key_data_cached_rrsig(keylist[i]))
|| key_data_delete(keylist[i])
|| hsm_key_factory_release_key_id(hsm_key_id(key_data_cached_hsm_key(keylist[i])), dbconn)) {
/* TODO: better log error */
ods_log_error("[%s] key_state_delete() || key_data_delete() || hsm_key_factory_release_key() failed", scmd);
client_printf_err(sockfd, "[%s] key_state_delete() || key_data_delete() || hsm_key_factory_release_key() failed", scmd);
free_all(key_list, keylist, deplist, deplist2, zone);
return 1;
}
/* we can clean up dependency because key is purgable */
for (j = 0; j < deplist2_size; j++) {
if (!deplist2[j]) continue;
if (db_value_cmp(key_data_id(keylist[i]), key_dependency_from_key_data_id(deplist2[j]), &cmp)) {
/* TODO: better log error */
ods_log_error("[%s] cmp deplist from failed", scmd);
client_printf_err(sockfd, "[%s] cmp deplist from failed", scmd);
break;
}
if(cmp) continue;
if (key_dependency_delete(deplist2[j])) {
/* TODO: better log error */
ods_log_error("[%s] key_dependency_delete() failed", scmd);
client_printf_err(sockfd, "[%s] key_dependency_delete() failed", scmd);
break;
}
}
}
}
if (zone_key_purgable == 0)
client_printf (sockfd, "No keys to purge for %s \n", zone_db_name(zone));
free_all(key_list, keylist, deplist, deplist2, zone);
listsize--;
if (listsize > 0) {
zone = zone_list_db_get_next(zonelist);
}
}
if(purge) {
int deleteCount = hsm_key_factory_delete_key(dbconn);
if(deleteCount > 0)
client_printf (sockfd, "Number of keys deleted from HSM is %d\n", deleteCount);
else
client_printf (sockfd, "Found no keys to delete from HSM\n");
} else
client_printf (sockfd, "Refrained from deleting keys from HSM\n");
return 0;
}
db_connection_t
struct db_connection db_connection_t
Definition db_connection.h:34
db_value_cmp
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition db_value.c:102
hsm_key_locator
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition hsm_key.c:520
hsm_key_id
const db_value_t * hsm_key_id(const hsm_key_t *hsm_key)
Definition hsm_key.c:504
hsm_key_factory_delete_key
int hsm_key_factory_delete_key(const db_connection_t *connection)
Definition hsm_key_factory.c:810
hsm_key_factory_release_key_id
int hsm_key_factory_release_key_id(const db_value_t *hsm_key_id, const db_connection_t *connection)
Definition hsm_key_factory.c:704
hsm_key_factory.h
key_data_id
const db_value_t * key_data_id(const key_data_t *key_data)
Definition key_data.c:553
key_data_list_size
size_t key_data_list_size(key_data_list_t *key_data_list)
Definition key_data.c:2461
key_data_delete
int key_data_delete(key_data_t *key_data)
Definition key_data.c:1587
key_data_free
void key_data_free(key_data_t *key_data)
Definition key_data.c:304
key_data_list_free
void key_data_list_free(key_data_list_t *key_data_list)
Definition key_data.c:1694
key_data_introducing
unsigned int key_data_introducing(const key_data_t *key_data)
Definition key_data.c:727
key_data_list_get_next
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
Definition key_data.c:2425
key_data_cache_hsm_key
int key_data_cache_hsm_key(key_data_t *key_data)
Definition key_data.c:615
key_data_list_get_begin
key_data_t * key_data_list_get_begin(key_data_list_t *key_data_list)
Definition key_data.c:2323
key_data_t
struct key_data key_data_t
Definition key_data.h:37
key_data_list_t
struct key_data_list key_data_list_t
Definition key_data.h:38
key_data_cached_rrsig
const key_state_t * key_data_cached_rrsig(key_data_t *key_data)
Definition key_data_ext.c:64
key_data_cache_key_states
int key_data_cache_key_states(key_data_t *key_data)
Definition key_data_ext.c:33
key_data_cached_dnskey
const key_state_t * key_data_cached_dnskey(key_data_t *key_data)
Definition key_data_ext.c:68
key_data_cached_hsm_key
const hsm_key_t * key_data_cached_hsm_key(const key_data_t *key_data)
Definition key_data_ext.c:108
key_data_cached_ds
const key_state_t * key_data_cached_ds(key_data_t *key_data)
Definition key_data_ext.c:60
key_data_cached_rrsigdnskey
const key_state_t * key_data_cached_rrsigdnskey(key_data_t *key_data)
Definition key_data_ext.c:72
key_dependency_free
void key_dependency_free(key_dependency_t *key_dependency)
Definition key_dependency.c:183
key_dependency_list_get_next
key_dependency_t * key_dependency_list_get_next(key_dependency_list_t *key_dependency_list)
Definition key_dependency.c:1341
key_dependency_list_free
void key_dependency_list_free(key_dependency_list_t *key_dependency_list)
Definition key_dependency.c:709
key_dependency_from_key_data_id
const db_value_t * key_dependency_from_key_data_id(const key_dependency_t *key_dependency)
Definition key_dependency.c:336
key_dependency_list_size
size_t key_dependency_list_size(key_dependency_list_t *key_dependency_list)
Definition key_dependency.c:1377
key_dependency_delete
int key_dependency_delete(key_dependency_t *key_dependency)
Definition key_dependency.c:616
key_dependency_list_get_begin
key_dependency_t * key_dependency_list_get_begin(key_dependency_list_t *key_dependency_list)
Definition key_dependency.c:1239
key_dependency_t
struct key_dependency key_dependency_t
Definition key_dependency.h:37
key_dependency_list_t
struct key_dependency_list key_dependency_list_t
Definition key_dependency.h:38
removeDeadKeysNow
int removeDeadKeysNow(int sockfd, db_connection_t *dbconn, policy_t *policy, zone_db_t *rzone, int purge)
Definition key_purge.c:65
key_purge.h
key_state_delete
int key_state_delete(const key_state_t *key_state)
Definition key_state.c:831
key_state_t
struct key_state key_state_t
Definition key_state.h:37
key_state_state
key_state_state
Definition key_state.h:49
KEY_STATE_STATE_NA
@ KEY_STATE_STATE_NA
Definition key_state.h:55
KEY_STATE_STATE_HIDDEN
@ KEY_STATE_STATE_HIDDEN
Definition key_state.h:51
policy_zone_list
zone_list_db_t * policy_zone_list(policy_t *policy)
Definition policy.c:1093
policy_name
const char * policy_name(const policy_t *policy)
Definition policy.c:813
policy_retrieve_zone_list
int policy_retrieve_zone_list(policy_t *policy)
Definition policy.c:1111
policy_t
struct policy policy_t
Definition policy.h:37
policy
Definition policy.h:60
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition zone_db.c:325
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition zone_db.c:782
zone_list_db_get_next
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition zone_db.c:2669
zone_list_db_size
size_t zone_list_db_size(zone_list_db_t *zone_list)
Definition zone_db.c:2705
zone_db_new_copy
zone_db_t * zone_db_new_copy(const zone_db_t *zone)
Definition zone_db.c:306
zone_db_t
struct zone_db zone_db_t
Definition zone_db.h:37
zone_list_db_t
struct zone_list_db zone_list_db_t
Definition zone_db.h:38
zone_db_get_key_dependencies
key_dependency_list_t * zone_db_get_key_dependencies(const zone_db_t *zone)
Definition zone_db_ext.c:76
zone_db_get_keys
key_data_list_t * zone_db_get_keys(const zone_db_t *zone)
Definition zone_db_ext.c:56