OpenDNSSEC-enforcer 2.1.13
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"
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
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
61static pthread_once_t __hsm_key_factory_once = PTHREAD_ONCE_INIT;
62static pthread_mutex_t* __hsm_key_factory_lock = NULL;
63
64static 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
93int
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
346int hsm_key_factory_generate_policy(engine_type* engine, const db_connection_t* connection, const policy_t* policy, time_t duration) {
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
386int hsm_key_factory_generate_all(engine_type* engine, const db_connection_t* connection, time_t duration) {
388 const policy_t* policy;
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
435static time_t
436hsm_key_factory_generate_cb(task_type* task, char const *owner, void* userdata, void* context)
437{
438 struct __hsm_key_factory_task* task2;
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");
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
467static time_t
468hsm_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
489static time_t
490hsm_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
520static int
521hsm_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
559int
561 const policy_t* policy_orig, time_t duration)
562{
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
597int
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");
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");
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
809int
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_info("[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
839 size_t numhsmkeys = 0;
840 db_clause_list_t* lookup_clause_list;
841 if(!(lookup_clause_list = db_clause_list_new())
842 || !(key_data = key_data_new(connection))
843 || !key_data_hsm_key_id_clause(lookup_clause_list, hsm_key_id(hsm_key))
844 || key_data_count(key_data, lookup_clause_list, &numhsmkeys)) {
845 ods_log_error("[hsm_key_factory_delete_key] unable to check usage of hsm_key, database or memory allocation error");
846 numhsmkeys = -1;
847 }
849 db_clause_list_free(lookup_clause_list);
850 if(numhsmkeys != 0)
851 continue;
852
853 hsmkey = hsm_find_key_by_id(hsm_ctx, hsm_key_locator(hsm_key));
854 if(hsm_remove_key(hsm_ctx, hsmkey)) {
855 // report on error
856 ods_log_error("[hsm_key_factory_delete_key] unable to remove key %s", hsm_key_locator(hsm_key));
857 } else {
858 clause_list = db_clause_list_new();
859 db_clause_t* clause;
860 clause = db_clause_new();
861 db_clause_set_field(clause, "locator");
865 db_clause_list_add(clause_list, clause);
866 clause = db_clause_new();
867 db_clause_set_field(clause, "rev");
871 db_clause_list_add(clause_list, clause);
872 db_object_delete(hsm_key->dbo, clause_list);
873 db_clause_list_free(clause_list);
874 ods_log_info("[hsm_key_factory_delete_key] removing key %s from HSM", hsm_key_locator(hsm_key));
875 ++count;
876 }
877 }
879 hsm_destroy_context(hsm_ctx);
880 return count;
881}
db_clause_list_t * db_clause_list_new(void)
Definition db_clause.c:202
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
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)
void enforce_task_flush_policy(engine_type *engine, db_connection_t *dbconn, policy_t const *policy)
void hsm_key_free(hsm_key_t *hsm_key)
Definition hsm_key.c:286
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
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition hsm_key.c:520
int hsm_key_set_inception(hsm_key_t *hsm_key, unsigned int inception)
Definition hsm_key.c:671
hsm_key_t * hsm_key_new(const db_connection_t *connection)
Definition hsm_key.c:244
int hsm_key_set_bits(hsm_key_t *hsm_key, unsigned int bits)
Definition hsm_key.c:638
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_policy_id_clause(db_clause_list_t *clause_list, const db_value_t *policy_id)
Definition hsm_key.c:729
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_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
db_clause_t * hsm_key_algorithm_clause(db_clause_list_t *clause_list, unsigned int algorithm)
Definition hsm_key.c:798
db_clause_t * hsm_key_repository_clause(db_clause_list_t *clause_list, const char *repository_text)
Definition hsm_key.c:882
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_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_key_type_clause(db_clause_list_t *clause_list, hsm_key_key_type_t key_type)
Definition hsm_key.c:861
hsm_key_t * hsm_key_list_get_next(hsm_key_list_t *hsm_key_list)
Definition hsm_key.c:1990
db_clause_t * hsm_key_bits_clause(db_clause_list_t *clause_list, unsigned int bits)
Definition hsm_key.c:777
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_role_clause(db_clause_list_t *clause_list, hsm_key_role_t role)
Definition hsm_key.c:819
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)
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)
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)
void key_data_free(key_data_t *key_data)
Definition key_data.c:304
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
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
policy_t * policy_new(const db_connection_t *connection)
Definition policy.c:479
void policy_list_free(policy_list_t *policy_list)
Definition policy.c:2664
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition policy.c:3214
policy_list_t * policy_list_new_get(const db_connection_t *connection)
Definition policy.c:3079
policy_t * policy_new_copy(const policy_t *policy)
Definition policy.c:499
const char * policy_name(const policy_t *policy)
Definition policy.c:813
const db_value_t * policy_id(const policy_t *policy)
Definition policy.c:805
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
unsigned int policy_key_lifetime(const policy_key_t *policy_key)
Definition policy_key.c:526
policy_key_list_t * policy_key_list_new_get_by_policy_id(const db_connection_t *connection, const db_value_t *policy_id)
const db_value_t * policy_key_policy_id(const policy_key_t *policy_key)
Definition policy_key.c:478
const policy_key_t * policy_key_list_next(policy_key_list_t *policy_key_list)
policy_key_t * policy_key_new_copy(const policy_key_t *policy_key)
Definition policy_key.c:227
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)
const char * policy_key_role_text(const policy_key_t *policy_key)
Definition policy_key.c:494
void policy_key_free(policy_key_t *policy_key)
Definition policy_key.c:246
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_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
void zone_db_free(zone_db_t *zone)
Definition zone_db.c:325
int zone_db_count(zone_db_t *zone, db_clause_list_t *clause_list, size_t *count)
Definition zone_db.c:1930
zone_db_t * zone_db_new(const db_connection_t *connection)
Definition zone_db.c:287
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