OpenDNSSEC-signer  1.4.10
hsm.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "daemon/engine.h"
33 #include "shared/hsm.h"
34 #include "shared/log.h"
35 #include "cryptoki_compat/pkcs11.h"
36 
37 static const char* hsm_str = "hsm";
38 
43 static void
44 lhsm_clear_key_cache(key_type* key)
45 {
46  if (!key) {
47  return;
48  }
49  if (key->dnskey) {
50  /* DNSKEY still exists in zone */
51  key->dnskey = NULL;
52  }
53  if (key->params) {
54  hsm_sign_params_free(key->params);
55  key->params = NULL;
56  }
57 }
58 
59 static const hsm_key_t*
60 keylookup(hsm_ctx_t* ctx, const char* locator)
61 {
62  const hsm_key_t* key;
63  key = keycache_lookup(ctx, locator);
64  if (key == NULL) {
65  char* error = hsm_get_error(ctx);
66  if (error) {
67  ods_log_error("[%s] %s", hsm_str, error);
68  free((void*)error);
69  }
70  /* could not find key */
71  ods_log_error("[%s] unable to get key: key %s not found", hsm_str, locator);
72  }
73  return key;
74 }
75 
76 
82 lhsm_get_key(hsm_ctx_t* ctx, ldns_rdf* owner, key_type* key_id)
83 {
84  char *error = NULL;
85  int retries = 0;
86 
87  if (!owner || !key_id) {
88  ods_log_error("[%s] unable to get key: missing required elements",
89  hsm_str);
90  return ODS_STATUS_ASSERT_ERR;
91  }
92 
93 lhsm_key_start:
94 
95  /* set parameters */
96  if (!key_id->params) {
97  key_id->params = hsm_sign_params_new();
98  if (key_id->params) {
99  key_id->params->owner = ldns_rdf_clone(owner);
100  key_id->params->algorithm = key_id->algorithm;
101  key_id->params->flags = key_id->flags;
102  } else {
103  /* could not create params */
104  error = hsm_get_error(ctx);
105  if (error) {
106  ods_log_error("[%s] %s", hsm_str, error);
107  free((void*)error);
108  } else if (!retries) {
109  lhsm_clear_key_cache(key_id);
110  retries++;
111  goto lhsm_key_start;
112  }
113  ods_log_error("[%s] unable to get key: create params for key %s "
114  "failed", hsm_str, key_id->locator?key_id->locator:"(null)");
115  return ODS_STATUS_ERR;
116  }
117  }
118  /* get dnskey */
119  if (!key_id->dnskey) {
120  key_id->dnskey = hsm_get_dnskey(ctx, keylookup(ctx, key_id->locator), key_id->params);
121  }
122  if (!key_id->dnskey) {
123  error = hsm_get_error(ctx);
124  if (error) {
125  ods_log_error("[%s] %s", hsm_str, error);
126  free((void*)error);
127  } else if (!retries) {
128  lhsm_clear_key_cache(key_id);
129  retries++;
130  goto lhsm_key_start;
131  }
132  ods_log_error("[%s] unable to get key: hsm failed to create dnskey",
133  hsm_str);
134  return ODS_STATUS_ERR;
135  }
136  key_id->params->keytag = ldns_calc_keytag(key_id->dnskey);
137  return ODS_STATUS_OK;
138 }
139 
140 
145 ldns_rr*
146 lhsm_sign(hsm_ctx_t* ctx, ldns_rr_list* rrset, key_type* key_id,
147  ldns_rdf* owner, time_t inception, time_t expiration)
148 {
149  char* error = NULL;
150  ldns_rr* result = NULL;
151  hsm_sign_params_t* params = NULL;
152 
153  if (!owner || !key_id || !rrset || !inception || !expiration) {
154  ods_log_error("[%s] unable to sign: missing required elements",
155  hsm_str);
156  return NULL;
157  }
158  ods_log_assert(key_id->dnskey);
159  ods_log_assert(key_id->params);
160  /* adjust parameters */
161  params = hsm_sign_params_new();
162  params->owner = ldns_rdf_clone(key_id->params->owner);
163  params->algorithm = key_id->algorithm;
164  params->flags = key_id->flags;
165  params->inception = inception;
166  params->expiration = expiration;
167  params->keytag = key_id->params->keytag;
168  ods_log_deeebug("[%s] sign RRset[%i] with key %s tag %u", hsm_str,
169  ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)),
170  key_id->locator?key_id->locator:"(null)", params->keytag);
171  result = hsm_sign_rrset(ctx, rrset, keylookup(ctx, key_id->locator), params);
172  hsm_sign_params_free(params);
173  if (!result) {
174  error = hsm_get_error(ctx);
175  if (error) {
176  ods_log_error("[%s] %s", hsm_str, error);
177  free((void*)error);
178  }
179  ods_log_crit("[%s] error signing rrset with libhsm", hsm_str);
180  }
181  return result;
182 }
ldns_rr * dnskey
Definition: keys.h:55
ldns_rr * lhsm_sign(hsm_ctx_t *ctx, ldns_rr_list *rrset, key_type *key_id, ldns_rdf *owner, time_t inception, time_t expiration)
Definition: hsm.c:146
enum ods_enum_status ods_status
Definition: status.h:90
void ods_log_error(const char *format,...)
Definition: log.c:334
void ods_log_crit(const char *format,...)
Definition: log.c:350
const char * locator
Definition: keys.h:57
ods_status lhsm_get_key(hsm_ctx_t *ctx, ldns_rdf *owner, key_type *key_id)
Definition: hsm.c:82
uint8_t algorithm
Definition: keys.h:58
hsm_sign_params_t * params
Definition: keys.h:56
void ods_log_deeebug(const char *format,...)
Definition: log.c:254
#define ods_log_assert(x)
Definition: log.h:154
uint32_t flags
Definition: keys.h:59