OpenDNSSEC-signer  2.0.3
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 "hsm.h"
34 #include "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 libhsm_key_t*
60 keylookup(hsm_ctx_t* ctx, const char* locator)
61 {
62  const libhsm_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 
80 ods_status
81 lhsm_get_key(hsm_ctx_t* ctx, ldns_rdf* owner, key_type* key_id)
82 {
83  char *error = NULL;
84  int retries = 0;
85 
86  if (!owner || !key_id) {
87  ods_log_error("[%s] unable to get key: missing required elements",
88  hsm_str);
89  return ODS_STATUS_ASSERT_ERR;
90  }
91 
92 llibhsm_key_start:
93 
94  /* set parameters */
95  if (!key_id->params) {
96  key_id->params = hsm_sign_params_new();
97  if (key_id->params) {
98  key_id->params->owner = ldns_rdf_clone(owner);
99  key_id->params->algorithm = key_id->algorithm;
100  key_id->params->flags = key_id->flags;
101  } else {
102  /* could not create params */
103  error = hsm_get_error(ctx);
104  if (error) {
105  ods_log_error("[%s] %s", hsm_str, error);
106  free((void*)error);
107  } else if (!retries) {
108  lhsm_clear_key_cache(key_id);
109  retries++;
110  goto llibhsm_key_start;
111  }
112  ods_log_error("[%s] unable to get key: create params for key %s "
113  "failed", hsm_str, key_id->locator?key_id->locator:"(null)");
114  return ODS_STATUS_ERR;
115  }
116  }
117  /* get dnskey */
118  if (!key_id->dnskey) {
119  key_id->dnskey = hsm_get_dnskey(ctx, keylookup(ctx, key_id->locator), key_id->params);
120  }
121  if (!key_id->dnskey) {
122  error = hsm_get_error(ctx);
123  if (error) {
124  ods_log_error("[%s] %s", hsm_str, error);
125  free((void*)error);
126  } else if (!retries) {
127  lhsm_clear_key_cache(key_id);
128  retries++;
129  goto llibhsm_key_start;
130  }
131  ods_log_error("[%s] unable to get key: hsm failed to create dnskey",
132  hsm_str);
133  return ODS_STATUS_ERR;
134  }
135  key_id->params->keytag = ldns_calc_keytag(key_id->dnskey);
136  return ODS_STATUS_OK;
137 }
138 
139 
144 ldns_rr*
145 lhsm_sign(hsm_ctx_t* ctx, ldns_rr_list* rrset, key_type* key_id,
146  ldns_rdf* owner, time_t inception, time_t expiration)
147 {
148  char* error = NULL;
149  ldns_rr* result = NULL;
150  hsm_sign_params_t* params = NULL;
151 
152  if (!owner || !key_id || !rrset || !inception || !expiration) {
153  ods_log_error("[%s] unable to sign: missing required elements",
154  hsm_str);
155  return NULL;
156  }
157  ods_log_assert(key_id->dnskey);
158  ods_log_assert(key_id->params);
159  /* adjust parameters */
160  params = hsm_sign_params_new();
161  params->owner = ldns_rdf_clone(key_id->params->owner);
162  params->algorithm = key_id->algorithm;
163  params->flags = key_id->flags;
164  params->inception = inception;
165  params->expiration = expiration;
166  params->keytag = key_id->params->keytag;
167  ods_log_deeebug("[%s] sign RRset[%i] with key %s tag %u", hsm_str,
168  ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)),
169  key_id->locator?key_id->locator:"(null)", params->keytag);
170  result = hsm_sign_rrset(ctx, rrset, keylookup(ctx, key_id->locator), params);
171  hsm_sign_params_free(params);
172  if (!result) {
173  error = hsm_get_error(ctx);
174  if (error) {
175  ods_log_error("[%s] %s", hsm_str, error);
176  free((void*)error);
177  }
178  ods_log_crit("[%s] error signing rrset with libhsm", hsm_str);
179  }
180  return result;
181 }
ldns_rr * dnskey
Definition: keys.h:51
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:145
const char * locator
Definition: keys.h:53
ods_status lhsm_get_key(hsm_ctx_t *ctx, ldns_rdf *owner, key_type *key_id)
Definition: hsm.c:81
uint8_t algorithm
Definition: keys.h:55
hsm_sign_params_t * params
Definition: keys.h:52
uint32_t flags
Definition: keys.h:56