OpenDNSSEC-enforcer  2.1.9
hsm_key_factory.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
3  * Copyright (c) 2014 OpenDNSSEC AB (svb)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 #include "config.h"
30 
31 #include "db/hsm_key.h"
32 #include "db/policy.h"
33 #include "db/policy_key.h"
34 #include "db/key_data.h"
35 #include "log.h"
36 #include "scheduler/schedule.h"
37 #include "scheduler/task.h"
38 #include "enforcer/enforce_task.h"
39 #include "daemon/engine.h"
40 #include "duration.h"
41 #include "libhsm.h"
42 
43 #include <math.h>
44 #include <pthread.h>
45 #include <ldns/ldns.h>
46 #include <ldns/util.h>
47 
48 #include "hsmkey/hsm_key_factory.h"
49 
50 
53  /* YBS: I find it scary that these database objects are carried
54  * around in our scheduler. Is that safe? */
57  time_t duration;
59 };
60 
61 static pthread_once_t __hsm_key_factory_once = PTHREAD_ONCE_INIT;
62 static pthread_mutex_t* __hsm_key_factory_lock = NULL;
63 
64 static void hsm_key_factory_init(void) {
65  pthread_mutexattr_t attr;
66 
67  if (!__hsm_key_factory_lock) {
68  if (!(__hsm_key_factory_lock = calloc(1, sizeof(pthread_mutex_t)))
69  || pthread_mutexattr_init(&attr)
70  || pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)
71  || pthread_mutex_init(__hsm_key_factory_lock, &attr))
72  {
73  /* TODO: This should be fatal */
74  ods_log_error("[hsm_key_factory_init] mutex error");
75  if (__hsm_key_factory_lock) {
76  pthread_mutex_destroy(__hsm_key_factory_lock);
77  free(__hsm_key_factory_lock);
78  __hsm_key_factory_lock = NULL;
79  }
80  }
81  }
82 }
83 
85 {
86  if (__hsm_key_factory_lock) {
87  (void)pthread_mutex_destroy(__hsm_key_factory_lock);
88  free(__hsm_key_factory_lock);
89  __hsm_key_factory_lock = NULL;
90  }
91 }
92 
93 int
95  const policy_t* policy, const policy_key_t* policy_key, time_t duration)
96 {
97  db_clause_list_t* clause_list;
98  hsm_key_t* hsm_key = NULL;
99  size_t num_keys;
100  zone_db_t* zone = NULL;
101  size_t num_zones;
102  ssize_t generate_keys;
103  libhsm_key_t *key = NULL;
104  hsm_ctx_t *hsm_ctx;
105  char* key_id;
106  hsm_repository_t* hsm;
107  char* hsm_err;
108 
109  if (!engine) {
110  return 1;
111  }
112  if (!policy_key) {
113  return 1;
114  }
115 
116  if (!__hsm_key_factory_lock) {
117  pthread_once(&__hsm_key_factory_once, hsm_key_factory_init);
118  if (!__hsm_key_factory_lock) {
119  ods_log_error("[hsm_key_factory_generate] mutex init error");
120  return 1;
121  }
122  }
123  if (pthread_mutex_lock(__hsm_key_factory_lock)) {
124  ods_log_error("[hsm_key_factory_generate] mutex lock error");
125  return 1;
126  }
127 
128  ods_log_debug("[hsm_key_factory_generate] repository %s role %s", policy_key_repository(policy_key), policy_key_role_text(policy_key));
129 
130  /*
131  * Get a count of unused keys that match our policy key to determine how
132  * many keys we need to make if any
133  */
134  if (!(clause_list = db_clause_list_new())
135  || !(hsm_key = hsm_key_new(connection))
141  || !hsm_key_is_revoked_clause(clause_list, 0)
144  || hsm_key_count(hsm_key, clause_list, &num_keys))
145  {
146  ods_log_error("[hsm_key_factory_generate] unable to count unused keys, database or memory allocation error");
148  db_clause_list_free(clause_list);
149  pthread_mutex_unlock(__hsm_key_factory_lock);
150  return 1;
151  }
152  db_clause_list_free(clause_list);
154 
155  /*
156  * Get the count of zones we have for the policy
157  */
158  if (!(clause_list = db_clause_list_new())
159  || !(zone = zone_db_new(connection))
161  || zone_db_count(zone, clause_list, &num_zones))
162  {
163  ods_log_error("[hsm_key_factory_generate] unable to count zones for policy, database or memory allocation error");
164  zone_db_free(zone);
165  db_clause_list_free(clause_list);
166  pthread_mutex_unlock(__hsm_key_factory_lock);
167  return 1;
168  }
169  zone_db_free(zone);
170  db_clause_list_free(clause_list);
171 
172  /*
173  * Calculate the number of keys we need to generate now but exit if we do
174  * not have to generate any keys
175  */
177  pthread_mutex_unlock(__hsm_key_factory_lock);
178  return 1;
179  }
180  /* OPENDNSSEC-690: this function is called per-zone, and the policy id differs per zone, thus the
181  * keys generated will never be shared.
182  * Additionally, this used to calculate the number of keys to be generated based upon the
183  * duration, times the number of zones. Not only is this wrong when using shared keys, but
184  * also for non-shared keys, this function would be called per-zone, with a different id for each
185  * zone.
186  */
187  duration = (duration ? duration : engine->config->automatic_keygen_duration);
188  generate_keys = (ssize_t)ceil(duration / (double)policy_key_lifetime(policy_key));
189  if (num_zones == 0 || (ssize_t)num_keys >= generate_keys) {
190  pthread_mutex_unlock(__hsm_key_factory_lock);
191  return 0;
192  }
193 
194  if (policy != NULL) {
195  ods_log_info("%lu zone(s) found on policy \"%s\"", num_zones, policy_name(policy));
196  } else {
197  ods_log_info("%lu zone(s) found on policy <unknown>", num_zones);
198  }
199  ods_log_info("[hsm_key_factory_generate] %lu keys needed for %lu "
200  "zones covering %lld seconds, generating %lu keys for policy %s",
201  generate_keys, num_zones, (long long)duration,
202  (unsigned long)(generate_keys-num_keys), /* This is safe because we checked num_keys < generate_keys */
204  generate_keys -= num_keys;
205  ods_log_info("%ld new %s(s) (%d bits) need to be created.", (long) generate_keys, policy_key_role_text(policy_key), policy_key_bits(policy_key));
206 
207  /*
208  * Create a HSM context and check that the repository exists
209  */
210  if (!(hsm_ctx = hsm_create_context())) {
211  pthread_mutex_unlock(__hsm_key_factory_lock);
212  return 1;
213  }
214  if (!hsm_token_attached(hsm_ctx, policy_key_repository(policy_key))) {
215  if ((hsm_err = hsm_get_error(hsm_ctx))) {
216  ods_log_error("[hsm_key_factory_generate] unable to check for repository %s, HSM error: %s", policy_key_repository(policy_key), hsm_err);
217  free(hsm_err);
218  }
219  else {
220  ods_log_error("[hsm_key_factory_generate] unable to find repository %s in HSM", policy_key_repository(policy_key));
221  }
222  hsm_destroy_context(hsm_ctx);
223  pthread_mutex_unlock(__hsm_key_factory_lock);
224  return 1;
225  }
226 
227  /*
228  * Generate a HSM keys
229  */
230  while (generate_keys--) {
231  /*
232  * Find the HSM repository to get the backup configuration
233  */
234  hsm = engine->config->repositories;
235  while (hsm) {
236  if (!strcmp(hsm->name, policy_key_repository(policy_key))) {
237  break;
238  }
239  hsm = hsm->next;
240  }
241  if (!hsm) {
242  ods_log_error("[hsm_key_factory_generate] unable to find repository %s needed for key generation", policy_key_repository(policy_key));
243  hsm_destroy_context(hsm_ctx);
244  pthread_mutex_unlock(__hsm_key_factory_lock);
245  return 1;
246  }
247 
249  case LDNS_DSA: /* */
250  key = hsm_generate_dsa_key(hsm_ctx, policy_key_repository(policy_key), policy_key_bits(policy_key));
251  break;
252  case LDNS_RSASHA1:
253  case LDNS_RSASHA1_NSEC3:
254  case LDNS_RSASHA256:
255  case LDNS_RSASHA512:
256  key = hsm_generate_rsa_key(hsm_ctx, policy_key_repository(policy_key), policy_key_bits(policy_key));
257  break;
258  case LDNS_ECC_GOST:
259  key = hsm_generate_gost_key(hsm_ctx, policy_key_repository(policy_key));
260  break;
261  case LDNS_ECDSAP256SHA256:
262  key = hsm_generate_ecdsa_key(hsm_ctx, policy_key_repository(policy_key), "P-256");
263  break;
264  case LDNS_ECDSAP384SHA384:
265  key = hsm_generate_ecdsa_key(hsm_ctx, policy_key_repository(policy_key), "P-384");
266  break;
267 #if (LDNS_REVISION >= ((1<<16)|(7<<8)|(0)))
268  case LDNS_ED25519:
269  key = hsm_generate_eddsa_key(hsm_ctx, policy_key_repository(policy_key), "edwards25519");
270  break;
271  case LDNS_ED448:
272  key = hsm_generate_eddsa_key(hsm_ctx, policy_key_repository(policy_key), "edwards448");
273  break;
274 #endif
275  default:
276  key = NULL;
277  }
278 
279  if (key) {
280  /*
281  * The key ID is the locator and we check first that we can get it
282  */
283  if (!(key_id = hsm_get_key_id(hsm_ctx, key))) {
284  if ((hsm_err = hsm_get_error(hsm_ctx))) {
285  ods_log_error("[hsm_key_factory_generate] unable to get the ID of the key generated, HSM error: %s", hsm_err);
286  free(hsm_err);
287  }
288  else {
289  ods_log_error("[hsm_key_factory_generate] unable to get the ID of the key generated");
290  }
291  libhsm_key_free(key);
292  hsm_destroy_context(hsm_ctx);
293  pthread_mutex_unlock(__hsm_key_factory_lock);
294  return 1;
295  }
296 
297  /*
298  * Create the HSM key (database object)
299  */
300  if (!(hsm_key = hsm_key_new(connection))
304  || hsm_key_set_inception(hsm_key, time_now())
306  || hsm_key_set_locator(hsm_key, key_id)
312  {
313  ods_log_error("[hsm_key_factory_generate] hsm key creation failed, database or memory error");
315  free(key_id);
316  free(key);
317  hsm_destroy_context(hsm_ctx);
318  pthread_mutex_unlock(__hsm_key_factory_lock);
319  return 1;
320  }
321 
322  ods_log_debug("[hsm_key_factory_generate] generated key %s successfully", key_id);
323 
325  free(key_id);
326  libhsm_key_free(key);
327  }
328  else {
329  if ((hsm_err = hsm_get_error(hsm_ctx))) {
330  ods_log_error("[hsm_key_factory_generate] key generation failed, HSM error: %s", hsm_err);
331  free(hsm_err);
332  }
333  else {
334  ods_log_error("[hsm_key_factory_generate] key generation failed");
335  }
336  hsm_destroy_context(hsm_ctx);
337  pthread_mutex_unlock(__hsm_key_factory_lock);
338  return 1;
339  }
340  }
341  hsm_destroy_context(hsm_ctx);
342  pthread_mutex_unlock(__hsm_key_factory_lock);
343  return 0;
344 }
345 
346 int hsm_key_factory_generate_policy(engine_type* engine, const db_connection_t* connection, const policy_t* policy, time_t duration) {
348  const policy_key_t* policy_key;
349  int error = 0;
350 
351  if (!engine || !policy || !connection) {
352  return 1;
353  }
354 
355  if (!__hsm_key_factory_lock) {
356  pthread_once(&__hsm_key_factory_once, hsm_key_factory_init);
357  if (!__hsm_key_factory_lock) {
358  ods_log_error("[hsm_key_factory_generate_policy] mutex init error");
359  return 1;
360  }
361  }
362  if (pthread_mutex_lock(__hsm_key_factory_lock)) {
363  ods_log_error("[hsm_key_factory_generate_policy] mutex lock error");
364  return 1;
365  }
366 
367  ods_log_debug("[hsm_key_factory_generate_policy] policy %s", policy_name(policy));
368 
369  /*
370  * Get all policy keys for the specified policy and generate new keys if
371  * needed
372  */
374  pthread_mutex_unlock(__hsm_key_factory_lock);
375  return 1;
376  }
377 
379  error |= hsm_key_factory_generate(engine, connection, policy, policy_key, duration);
380  }
382  pthread_mutex_unlock(__hsm_key_factory_lock);
383  return error;
384 }
385 
386 int hsm_key_factory_generate_all(engine_type* engine, const db_connection_t* connection, time_t duration) {
388  const policy_t* policy;
390  const policy_key_t* policy_key;
391  int error;
392 
393  if (!engine || !connection) {
394  return 1;
395  }
396 
397  if (!__hsm_key_factory_lock) {
398  pthread_once(&__hsm_key_factory_once, hsm_key_factory_init);
399  if (!__hsm_key_factory_lock) {
400  ods_log_error("[hsm_key_factory_generate_all] mutex init error");
401  return 1;
402  }
403  }
404  if (pthread_mutex_lock(__hsm_key_factory_lock)) {
405  ods_log_error("[hsm_key_factory_generate_all] mutex lock error");
406  return 1;
407  }
408 
409  ods_log_debug("[hsm_key_factory_generate_all] generating keys");
410 
411  /*
412  * Get all the policies and for each get all the policy keys and generate
413  * new keys for them if needed
414  */
415  if (!(policy_list = policy_list_new_get(connection))) {
416  pthread_mutex_unlock(__hsm_key_factory_lock);
417  return 1;
418  }
419  error = 0;
420  while ((policy = policy_list_next(policy_list))) {
422  continue;
423  }
424 
426  error |= hsm_key_factory_generate(engine, connection, policy, policy_key, duration);
427  }
429  }
431  pthread_mutex_unlock(__hsm_key_factory_lock);
432  return error;
433 }
434 
435 static time_t
436 hsm_key_factory_generate_cb(task_type* task, char const *owner, void* userdata, void* context)
437 {
438  struct __hsm_key_factory_task* task2;
439  policy_t* policy;
440  db_connection_t *dbconn = (db_connection_t*) context;
441  (void)owner;
442  int error;
443 
444  if (!userdata) {
445  return schedule_SUCCESS;
446  }
447  task2 = (struct __hsm_key_factory_task*) userdata;
448 
449  if ((policy = policy_new(dbconn)) != NULL) {
452  policy = NULL;
453  }
454  }
455 
456  ods_log_debug("[hsm_key_factory_generate_cb] generate for policy key [duration: %lu]", (unsigned long)task2->duration);
457  error = hsm_key_factory_generate(task2->engine, dbconn, policy, task2->policy_key, task2->duration);
458  ods_log_debug("[hsm_key_factory_generate_cb] generate for policy key done");
459  policy_key_free(task2->policy_key);
460  task2->policy_key = NULL;
461  if (task2->reschedule_enforce_task && policy && !error)
462  enforce_task_flush_policy(task2->engine, dbconn, policy);
464  return schedule_SUCCESS;
465 }
466 
467 static time_t
468 hsm_key_factory_generate_policy_cb(task_type* task, char const *owner, void *userdata,
469  void *context)
470 {
471  struct __hsm_key_factory_task* task2;
472  db_connection_t* dbconn = (db_connection_t*) context;
473  (void)owner;
474  int error;
475 
476  if (!userdata) {
477  return schedule_SUCCESS;
478  }
479  task2 = (struct __hsm_key_factory_task*)userdata;
480 
481  ods_log_debug("[hsm_key_factory_generate_policy_cb] generate for policy [duration: %lu]", (unsigned long) task2->duration);
482  error = hsm_key_factory_generate_policy(task2->engine, dbconn, task2->policy, task2->duration);
483  ods_log_debug("[hsm_key_factory_generate_policy_cb] generate for policy done");
484  if (task2->reschedule_enforce_task && task2->policy && !error)
485  enforce_task_flush_policy(task2->engine, dbconn, task2->policy);
486  return schedule_SUCCESS;
487 }
488 
489 static time_t
490 hsm_key_factory_generate_all_cb(task_type* task, char const *owner, void *userdata,
491  void* context)
492 {
493  struct __hsm_key_factory_task* task2;
494  db_connection_t *dbconn = (db_connection_t *) context;
495  (void)owner;
496  int error;
497 
498  if (!userdata) {
499  return schedule_SUCCESS;
500  }
501  task2 = (struct __hsm_key_factory_task*)userdata;
502 
503  ods_log_debug("[hsm_key_factory_generate_all_cb] generate for all policies [duration: %lu]", (unsigned long)task2->duration);
504  error = hsm_key_factory_generate_all(task2->engine, dbconn, task2->duration);
505  ods_log_debug("[hsm_key_factory_generate_all_cb] generate for all policies done");
506  if (task2->reschedule_enforce_task && !error)
507  enforce_task_flush_all(task2->engine, dbconn);
508  return schedule_SUCCESS;
509 }
510 
520 static int
521 hsm_key_factory_schedule_generate(engine_type* engine,
522  const policy_key_t* policy_key_orig, time_t duration,
524 {
526  task_type* task;
527  struct __hsm_key_factory_task* task2 = NULL;
528 
529  if (!(task2 = calloc(1, sizeof(struct __hsm_key_factory_task)))) {
530  return 1;
531  }
532  if (!(policy_key = policy_key_new_copy(policy_key_orig))) {
533  free(task2);
534  return 1;
535  }
536 
537  task2->engine = engine;
538  task2->duration = duration;
539  task2->policy_key = policy_key;
540  task2->policy = NULL;
542 
543  task = task_create(strdup("hsm_key_factory_schedule_generation"),
544  TASK_CLASS_ENFORCER, TASK_TYPE_HSMKEYGEN,
545  hsm_key_factory_generate_cb, task2,
546  free, time_now());
547 
548  if (schedule_task(engine->taskq, task, 1, 0) != ODS_STATUS_OK) {
549  if (!task) {
550  free(task2);
552  }
553  task_destroy(task);
554  return 1;
555  }
556  return 0;
557 }
558 
559 int
561  const policy_t* policy_orig, time_t duration)
562 {
563  policy_t* policy;
564  task_type* task;
565  struct __hsm_key_factory_task* task2 = NULL;
566 
567  if (!(task2 = calloc(1, sizeof(struct __hsm_key_factory_task)))) {
568  return 1;
569  }
570  if (!(policy = policy_new_copy(policy_orig))) {
571  free(task2);
572  return 1;
573  }
574 
575  task2->engine = engine;
576  task2->duration = duration;
577  task2->policy_key = NULL;
578  task2->policy = policy;
579  task2->reschedule_enforce_task = 1;
580 
581  task = task_create(strdup("hsm_key_factory_schedule_generation_policy"),
582  TASK_CLASS_ENFORCER, TASK_TYPE_HSMKEYGEN,
583  hsm_key_factory_generate_policy_cb, task2,
584  free, time_now());
585 
586  if (schedule_task(engine->taskq, task, 1, 0) != ODS_STATUS_OK) {
587  if (!task) {
588  free(task2);
590  }
591  task_destroy(task);
592  return 1;
593  }
594  return 0;
595 }
596 
597 int
599 {
600  task_type* task;
601  struct __hsm_key_factory_task* task2 = NULL;
602 
603  if (!(task2 = calloc(1, sizeof(struct __hsm_key_factory_task)))) {
604  return 1;
605  }
606 
607  task2->engine = engine;
608  task2->duration = duration;
609  task2->policy_key = NULL;
610  task2->policy = NULL;
611  task2->reschedule_enforce_task = 1;
612 
613  task = task_create(strdup("hsm_key_factory_schedule_generation"),
614  TASK_CLASS_ENFORCER, TASK_TYPE_HSMKEYGEN,
615  hsm_key_factory_generate_all_cb, task2,
616  free, time_now());
617 
618  if (schedule_task(engine->taskq, task, 1, 0) != ODS_STATUS_OK) {
619  if (!task) {
620  free(task2);
621  }
622  task_destroy(task);
623  return 1;
624  }
625  return 0;
626 }
627 
628 
630  const db_connection_t* connection, const policy_key_t* policy_key,
632 {
633  db_clause_list_t* clause_list;
636 
637  if (!connection) {
638  return NULL;
639  }
640  if (!policy_key) {
641  return NULL;
642  }
645  {
646  return NULL;
647  }
648 
649  ods_log_debug("[hsm_key_factory_get_key] get %s key", (hsm_key_state == HSM_KEY_STATE_PRIVATE ? "private" : "shared"));
650 
651  /*
652  * Get a list of unused HSM keys matching our requirments
653  */
654  if (!(clause_list = db_clause_list_new())
660  || !hsm_key_is_revoked_clause(clause_list, 0)
663  || !(hsm_key_list = hsm_key_list_new_get_by_clauses(connection, clause_list)))
664  {
665  ods_log_error("[hsm_key_factory_get_key] unable to list keys, database or memory allocation error");
666  db_clause_list_free(clause_list);
667  return NULL;
668  }
669  db_clause_list_free(clause_list);
670 
671  /*
672  * If there are no keys returned in the list we schedule generation and
673  * return NULL
674  */
676  ods_log_warning("[hsm_key_factory_get_key] no keys available");
677  if (!engine->config->manual_keygen)
678  hsm_key_factory_schedule_generate(engine, policy_key, 0, 1);
680  return NULL;
681  }
683 
684  /*
685  * Update the state of the returned HSM key
686  */
689  {
690  ods_log_debug("[hsm_key_factory_get_key] unable to update fetched key");
692  return NULL;
693  }
694 
695  /*
696  * Schedule generation because we used up a key and return the HSM key
697  */
698  ods_log_debug("[hsm_key_factory_get_key] key allocated");
699  if (!engine->config->manual_keygen)
700  hsm_key_factory_schedule_generate(engine, policy_key, 0, 0);
701  return hsm_key;
702 }
703 
706  db_clause_list_t* clause_list = NULL;
707  key_data_t* key_data = NULL;
708  size_t count;
709 
710  if (!hsm_key_id) {
711  return 1;
712  }
713  if (!connection) {
714  return 1;
715  }
716 
717  if (!(hsm_key = hsm_key_new(connection))
718  || !(clause_list = db_clause_list_new())
719  || !(key_data = key_data_new(connection))
720  || !key_data_hsm_key_id_clause(clause_list, hsm_key_id)
721  || key_data_count(key_data, clause_list, &count))
722  {
723  ods_log_debug("[hsm_key_factory_release_key_id] unable to check usage of hsm_key, database or memory allocation error");
725  db_clause_list_free(clause_list);
727  return 1;
728  }
730  db_clause_list_free(clause_list);
731 
732  if (count > 0) {
733  ods_log_debug("[hsm_key_factory_release_key_id] unable to release hsm_key, in use");
735  return 0;
736  }
737 
739  ods_log_debug("[hsm_key_factory_release_key_id] unable to fetch hsm_key");
741  return 1;
742  }
743 
745  ods_log_debug("[hsm_key_factory_release_key_id] hsm_key already DELETE (?)");
747  return 0;
748  }
749 
752  {
753  ods_log_debug("[hsm_key_factory_release_key_id] unable to change hsm_key state to DELETE");
755  return 1;
756  }
757  ods_log_debug("[hsm_key_factory_release_key_id] key %s marked DELETE", hsm_key_locator(hsm_key));
758 
760  return 0;
761 }
762 
764  db_clause_list_t* clause_list = NULL;
765  key_data_t* key_data = NULL;
766  size_t count;
767 
768  if (!hsm_key) {
769  return 1;
770  }
771  if (!connection) {
772  return 1;
773  }
774 
775  if (!(clause_list = db_clause_list_new())
776  || !(key_data = key_data_new(connection))
778  || key_data_count(key_data, clause_list, &count))
779  {
780  ods_log_debug("[hsm_key_factory_release_key] unable to check usage of hsm_key, database or memory allocation error");
782  db_clause_list_free(clause_list);
783  return 1;
784  }
786  db_clause_list_free(clause_list);
787 
788  if (count > 0) {
789  ods_log_debug("[hsm_key_factory_release_key] unable to release hsm_key, in use");
790  return 0;
791  }
792 
794  ods_log_debug("[hsm_key_factory_release_key] hsm_key already DELETE (?)");
795  return 0;
796  }
797 
800  {
801  ods_log_debug("[hsm_key_factory_release_key] unable to change hsm_key state to DELETE");
802  return 1;
803  }
804  ods_log_debug("[hsm_key_factory_release_key] key %s marked DELETE", hsm_key_locator(hsm_key));
805 
806  return 0;
807 }
808 
809 int
811 {
812  db_clause_list_t* clause_list;
814  libhsm_key_t* hsmkey;
816  hsm_ctx_t *hsm_ctx;
817  int count = 0;
818 
819  if (!(hsm_ctx = hsm_create_context())) {
820  /* might be a transient error, not important for this action so do not log */
821  return -1;
822  }
823 
824  ods_log_error("[hsm_key_factory_delete_key] looking for keys to purge from HSM");
825  if (!(clause_list = db_clause_list_new())
827  //|| !hsm_key_is_revoked_clause(clause_list, 0)
828  || !(hsm_key_list = hsm_key_list_new_get_by_clauses(connection, clause_list)))
829  {
830  ods_log_error("[hsm_key_factory_delete_key] unable to list keys, database or memory allocation error");
831  db_clause_list_free(clause_list);
832  return -2;
833  }
834  db_clause_list_free(clause_list);
835 
837  hsmkey = hsm_find_key_by_id(hsm_ctx, hsm_key_locator(hsm_key));
838  if(hsm_remove_key(hsm_ctx, hsmkey)) {
839  // report on error
840  ods_log_error("[hsm_key_factory_delete_key] unable to remove key %s", hsm_key_locator(hsm_key));
841  } else {
842  clause_list = db_clause_list_new();
843  db_clause_t* clause;
844  clause = db_clause_new();
845  db_clause_set_field(clause, "locator");
849  db_clause_list_add(clause_list, clause);
850  clause = db_clause_new();
851  db_clause_set_field(clause, "rev");
855  db_clause_list_add(clause_list, clause);
856  db_object_delete(hsm_key->dbo, clause_list);
857  db_clause_list_free(clause_list);
858  ods_log_info("[hsm_key_factory_get_key] removing key %s from HSM", hsm_key_locator(hsm_key));
859  ++count;
860  }
861  }
863  hsm_destroy_context(hsm_ctx);
864  return count;
865 }
db_clause_t * db_clause_new(void)
Definition: db_clause.c:43
db_value_t * db_clause_get_value(db_clause_t *clause)
Definition: db_clause.c:187
db_clause_list_t * db_clause_list_new(void)
Definition: db_clause.c:202
int db_clause_list_add(db_clause_list_t *clause_list, db_clause_t *clause)
Definition: db_clause.c:226
void db_clause_list_free(db_clause_list_t *clause_list)
Definition: db_clause.c:209
int db_clause_set_operator(db_clause_t *clause, db_clause_operator_t clause_operator)
Definition: db_clause.c:142
int db_clause_set_field(db_clause_t *clause, const char *field)
Definition: db_clause.c:109
int db_clause_set_type(db_clause_t *clause, db_clause_type_t type)
Definition: db_clause.c:130
@ DB_CLAUSE_OPERATOR_AND
Definition: db_clause.h:97
@ DB_CLAUSE_EQUAL
Definition: db_clause.h:44
int db_object_delete(const db_object_t *object, const db_clause_list_t *clause_list)
Definition: db_object.c:464
int db_value_from_text(db_value_t *value, const char *from_text)
Definition: db_value.c:531
int db_value_copy(db_value_t *value, const db_value_t *from_value)
Definition: db_value.c:77
void enforce_task_flush_all(engine_type *engine, db_connection_t *dbconn)
Definition: enforce_task.c:179
void enforce_task_flush_policy(engine_type *engine, db_connection_t *dbconn, policy_t const *policy)
Definition: enforce_task.c:158
db_clause_t * hsm_key_role_clause(db_clause_list_t *clause_list, hsm_key_role_t role)
Definition: hsm_key.c:819
hsm_key_t * hsm_key_new(const db_connection_t *connection)
Definition: hsm_key.c:244
void hsm_key_free(hsm_key_t *hsm_key)
Definition: hsm_key.c:286
db_clause_t * hsm_key_is_revoked_clause(db_clause_list_t *clause_list, unsigned int is_revoked)
Definition: hsm_key.c:840
int hsm_key_set_role(hsm_key_t *hsm_key, hsm_key_role_t role)
Definition: hsm_key.c:658
int hsm_key_count(hsm_key_t *hsm_key, db_clause_list_t *clause_list, size_t *count)
Definition: hsm_key.c:1435
int hsm_key_set_state(hsm_key_t *hsm_key, hsm_key_state_t state)
Definition: hsm_key.c:625
db_clause_t * hsm_key_policy_id_clause(db_clause_list_t *clause_list, const db_value_t *policy_id)
Definition: hsm_key.c:729
int hsm_key_set_inception(hsm_key_t *hsm_key, unsigned int inception)
Definition: hsm_key.c:671
db_clause_t * hsm_key_bits_clause(db_clause_list_t *clause_list, unsigned int bits)
Definition: hsm_key.c:777
int hsm_key_set_bits(hsm_key_t *hsm_key, unsigned int bits)
Definition: hsm_key.c:638
hsm_key_t * hsm_key_list_get_next(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1990
int hsm_key_update(hsm_key_t *hsm_key)
Definition: hsm_key.c:1225
int hsm_key_create(hsm_key_t *hsm_key)
Definition: hsm_key.c:927
int hsm_key_set_key_type(hsm_key_t *hsm_key, hsm_key_key_type_t key_type)
Definition: hsm_key.c:681
void hsm_key_list_free(hsm_key_list_t *hsm_key_list)
Definition: hsm_key.c:1496
db_clause_t * hsm_key_key_type_clause(db_clause_list_t *clause_list, hsm_key_key_type_t key_type)
Definition: hsm_key.c:861
db_clause_t * hsm_key_algorithm_clause(db_clause_list_t *clause_list, unsigned int algorithm)
Definition: hsm_key.c:798
int hsm_key_set_repository(hsm_key_t *hsm_key, const char *repository_text)
Definition: hsm_key.c:694
int hsm_key_set_backup(hsm_key_t *hsm_key, hsm_key_backup_t backup)
Definition: hsm_key.c:716
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition: hsm_key.c:520
int hsm_key_set_policy_id(hsm_key_t *hsm_key, const db_value_t *policy_id)
Definition: hsm_key.c:584
const db_value_t * hsm_key_id(const hsm_key_t *hsm_key)
Definition: hsm_key.c:504
db_clause_t * hsm_key_repository_clause(db_clause_list_t *clause_list, const char *repository_text)
Definition: hsm_key.c:882
hsm_key_list_t * hsm_key_list_new_get_by_clauses(const db_connection_t *connection, const db_clause_list_t *clause_list)
Definition: hsm_key.c:1726
int hsm_key_get_by_id(hsm_key_t *hsm_key, const db_value_t *id)
Definition: hsm_key.c:1102
db_clause_t * hsm_key_state_clause(db_clause_list_t *clause_list, hsm_key_state_t state)
Definition: hsm_key.c:756
int hsm_key_set_locator(hsm_key_t *hsm_key, const char *locator_text)
Definition: hsm_key.c:603
int hsm_key_set_algorithm(hsm_key_t *hsm_key, unsigned int algorithm)
Definition: hsm_key.c:648
enum hsm_key_state hsm_key_state_t
enum hsm_key_role hsm_key_role_t
hsm_key_state
Definition: hsm_key.h:40
@ HSM_KEY_STATE_UNUSED
Definition: hsm_key.h:42
@ HSM_KEY_STATE_PRIVATE
Definition: hsm_key.h:43
@ HSM_KEY_STATE_SHARED
Definition: hsm_key.h:44
@ HSM_KEY_STATE_DELETE
Definition: hsm_key.h:45
@ HSM_KEY_BACKUP_NO_BACKUP
Definition: hsm_key.h:66
@ HSM_KEY_BACKUP_BACKUP_REQUIRED
Definition: hsm_key.h:67
@ HSM_KEY_KEY_TYPE_RSA
Definition: hsm_key.h:61
int hsm_key_factory_schedule_generate_policy(engine_type *engine, const policy_t *policy_orig, time_t duration)
int hsm_key_factory_generate(engine_type *engine, const db_connection_t *connection, const policy_t *policy, const policy_key_t *policy_key, time_t duration)
hsm_key_t * hsm_key_factory_get_key(engine_type *engine, const db_connection_t *connection, const policy_key_t *policy_key, hsm_key_state_t hsm_key_state)
int hsm_key_factory_delete_key(const db_connection_t *connection)
int hsm_key_factory_release_key_id(const db_value_t *hsm_key_id, const db_connection_t *connection)
int hsm_key_factory_generate_all(engine_type *engine, const db_connection_t *connection, time_t duration)
int hsm_key_factory_generate_policy(engine_type *engine, const db_connection_t *connection, const policy_t *policy, time_t duration)
void hsm_key_factory_deinit(void)
int hsm_key_factory_release_key(hsm_key_t *hsm_key, const db_connection_t *connection)
int hsm_key_factory_schedule_generate_all(engine_type *engine, time_t duration)
void key_data_free(key_data_t *key_data)
Definition: key_data.c:304
key_data_t * key_data_new(const db_connection_t *connection)
Definition: key_data.c:264
int key_data_count(key_data_t *key_data, db_clause_list_t *clause_list, size_t *count)
Definition: key_data.c:1633
db_clause_t * key_data_hsm_key_id_clause(db_clause_list_t *clause_list, const db_value_t *hsm_key_id)
Definition: key_data.c:1003
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition: policy.c:3214
void policy_list_free(policy_list_t *policy_list)
Definition: policy.c:2664
policy_list_t * policy_list_new_get(const db_connection_t *connection)
Definition: policy.c:3079
const db_value_t * policy_id(const policy_t *policy)
Definition: policy.c:805
policy_t * policy_new_copy(const policy_t *policy)
Definition: policy.c:499
int policy_get_by_id(policy_t *policy, const db_value_t *id)
Definition: policy.c:1987
void policy_free(policy_t *policy)
Definition: policy.c:518
policy_t * policy_new(const db_connection_t *connection)
Definition: policy.c:479
policy_key_t * policy_key_new_copy(const policy_key_t *policy_key)
Definition: policy_key.c:227
const db_value_t * policy_key_policy_id(const policy_key_t *policy_key)
Definition: policy_key.c:478
unsigned int policy_key_lifetime(const policy_key_t *policy_key)
Definition: policy_key.c:526
const policy_key_t * policy_key_list_next(policy_key_list_t *policy_key_list)
Definition: policy_key.c:1378
const char * policy_key_repository(const policy_key_t *policy_key)
Definition: policy_key.c:534
void policy_key_list_free(policy_key_list_t *policy_key_list)
Definition: policy_key.c:1006
void policy_key_free(policy_key_t *policy_key)
Definition: policy_key.c:246
const char * policy_key_role_text(const policy_key_t *policy_key)
Definition: policy_key.c:494
unsigned int policy_key_algorithm(const policy_key_t *policy_key)
Definition: policy_key.c:510
unsigned int policy_key_bits(const policy_key_t *policy_key)
Definition: policy_key.c:518
policy_key_list_t * policy_key_list_new_get_by_policy_id(const db_connection_t *connection, const db_value_t *policy_id)
Definition: policy_key.c:1299
policy_key_role
Definition: policy_key.h:40
policy_key_t * policy_key
schedule_type * taskq
Definition: engine.h:60
engineconfig_type * config
Definition: engine.h:48
hsm_repository_t * repositories
Definition: cfg.h:79
time_t automatic_keygen_duration
Definition: cfg.h:77
int manual_keygen
Definition: cfg.h:74
db_value_t rev
Definition: hsm_key.h:82
db_object_t * dbo
Definition: hsm_key.h:80
Definition: policy.h:60
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
zone_db_t * zone_db_new(const db_connection_t *connection)
Definition: zone_db.c:287
int zone_db_count(zone_db_t *zone, db_clause_list_t *clause_list, size_t *count)
Definition: zone_db.c:1930
db_clause_t * zone_db_policy_id_clause(db_clause_list_t *clause_list, const db_value_t *policy_id)
Definition: zone_db.c:1179