OpenDNSSEC-signer  1.4.1
nsec3params.c
Go to the documentation of this file.
1 /*
2  * $Id: nsec3params.c 7040 2013-02-15 08:19:53Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. 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 
34 #include "shared/allocator.h"
35 #include "shared/log.h"
36 #include "shared/util.h"
37 #include "signer/backup.h"
38 #include "signer/nsec3params.h"
39 #include "signer/signconf.h"
40 
41 #include <ctype.h>
42 #include <ldns/ldns.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 static const char* nsec3_str = "nsec3";
47 
48 
54 nsec3params_create_salt(const char* salt_str, uint8_t* salt_len,
55  uint8_t** salt)
56 {
57  uint8_t c;
58  uint8_t* salt_tmp;
59 
60  if (!salt_str) {
61  *salt_len = 0;
62  *salt = NULL;
63  return ODS_STATUS_OK;
64  }
65  *salt_len = (uint8_t) strlen(salt_str);
66  if (*salt_len == 1 && salt_str[0] == '-') {
67  *salt_len = 0;
68  *salt = NULL;
69  return ODS_STATUS_OK;
70  } else if (*salt_len % 2 != 0) {
71  ods_log_error("[%s] invalid salt %s", nsec3_str, salt_str);
72  *salt = NULL;
73  return ODS_STATUS_ERR;
74  }
75  /* construct salt data */
76  salt_tmp = (uint8_t*) calloc(*salt_len / 2, sizeof(uint8_t));
77  if (!salt_tmp) {
78  ods_log_error("[%s] construct salt data for %s failed", nsec3_str,
79  salt_str);
80  *salt = NULL;
81  return ODS_STATUS_MALLOC_ERR;
82  }
83  for (c = 0; c < *salt_len; c += 2) {
84  if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
85  salt_tmp[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
86  ldns_hexdigit_to_int(salt_str[c+1]);
87  } else {
88  ods_log_error("[%s] invalid salt %s", nsec3_str, salt_str);
89  free((void*)salt_tmp);
90  *salt = NULL;
91  return ODS_STATUS_ERR;
92  }
93  }
94  *salt_len = *salt_len / 2; /* update length */
95  *salt = salt_tmp;
96  return ODS_STATUS_OK;
97 }
98 
99 
105 nsec3params_create(void* sc, uint8_t algo, uint8_t flags, uint16_t iter,
106  const char* salt)
107 {
108  nsec3params_type* nsec3params = NULL;
109  signconf_type* signconf = (signconf_type*) sc;
110  uint8_t salt_len; /* calculate salt len */
111  uint8_t* salt_data; /* calculate salt data */
112 
113  if (!sc) {
114  return NULL;
115  }
116  nsec3params = (nsec3params_type*) allocator_alloc(signconf->allocator,
117  sizeof(nsec3params_type));
118  if (!nsec3params) {
119  ods_log_error("[%s] unable to create: allocator_alloc() failed",
120  nsec3_str);
121  return NULL;
122  }
123  nsec3params->sc = sc;
124  nsec3params->algorithm = algo;
125  nsec3params->flags = flags;
126  nsec3params->iterations = iter;
127  /* construct the salt from the string */
128  if (nsec3params_create_salt(salt, &salt_len, &salt_data) != 0) {
129  ods_log_error("[%s] unable to create: create salt failed", nsec3_str);
130  allocator_deallocate(signconf->allocator, (void*)nsec3params);
131  return NULL;
132  }
133  nsec3params->salt_len = salt_len;
134  nsec3params->salt_data = salt_data;
135  nsec3params->rr = NULL;
136  return nsec3params;
137 }
138 
139 
144 void
145 nsec3params_backup(FILE* fd, uint8_t algo, uint8_t flags,
146  uint16_t iter, const char* salt, ldns_rr* rr, const char* version)
147 {
148  if (!fd) {
149  return;
150  }
151  fprintf(fd, ";;Nsec3parameters: salt %s algorithm %u optout %u "
152  "iterations %u\n", salt?salt:"-", (unsigned) algo,
153  (unsigned) flags, (unsigned) iter);
154  if (strcmp(version, ODS_SE_FILE_MAGIC_V2) == 0) {
155  if (rr) {
156  (void)util_rr_print(fd, rr);
157  }
158  fprintf(fd, ";;Nsec3done\n");
159  fprintf(fd, ";;\n");
160  }
161  return;
162 }
163 
164 
169 const char*
171 {
172  uint8_t *data;
173  uint8_t salt_length = 0;
174  uint8_t salt_pos = 0;
175  int written = 0;
176  char* str = NULL;
177  ldns_buffer* buffer = NULL;
178 
179  salt_length = nsec3params->salt_len;
180  data = nsec3params->salt_data;
181  /* from now there are variable length entries so remember pos */
182  if (salt_length == 0) {
183  buffer = ldns_buffer_new(2);
184  written = ldns_buffer_printf(buffer, "-");
185  } else {
186  buffer = ldns_buffer_new(salt_pos+1);
187  for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
188  written = ldns_buffer_printf(buffer, "%02x", data[salt_pos]);
189  }
190  }
191  if (ldns_buffer_status(buffer) == LDNS_STATUS_OK) {
192  str = ldns_buffer2str(buffer);
193  } else if (written) {
194  ods_log_error("[%s] unable to convert nsec3 salt to string: %s",
195  nsec3_str, ldns_get_errorstr_by_id(ldns_buffer_status(buffer)));
196  } else {
197  ods_log_error("[%s] unable to convert nsec3 salt to string: zero "
198  "bytes written", nsec3_str);
199  }
200  ldns_buffer_free(buffer);
201  return (const char*) str;
202 }
203 
204 
209 void
211 {
212  signconf_type* sc = NULL;
213  if (!nsec3params) {
214  return;
215  }
216  sc = (signconf_type*) nsec3params->sc;
217  allocator_deallocate(sc->allocator, (void*) nsec3params->salt_data);
218  allocator_deallocate(sc->allocator, (void*) nsec3params);
219  return;
220 }