OpenDNSSEC-signer  1.4.5
tsig-openssl.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 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 "config.h"
33 
34 #ifdef HAVE_SSL
35 #include "shared/log.h"
36 #include "wire/tsig.h"
37 #include "wire/tsig-openssl.h"
38 
39 static const char* tsig_str = "tsig-ssl";
41 static allocator_type* tsig_allocator = NULL;
43 static void *create_context(allocator_type* allocator);
44 static void init_context(void *context,
45  tsig_algo_type *algorithm,
46  tsig_key_type *key);
47 static void update(void *context, const void *data, size_t size);
48 static void final(void *context, uint8_t *digest, size_t *size);
49 
50 typedef struct tsig_cleanup_table_struct tsig_cleanup_table_type;
51 struct tsig_cleanup_table_struct {
52  tsig_cleanup_table_type* next;
53  void* cleanup;
54 };
55 static tsig_cleanup_table_type* tsig_cleanup_table = NULL;
56 
57 
62 static int
63 tsig_openssl_init_algorithm(allocator_type* allocator,
64  const char* digest, const char* name, const char* wireformat)
65 {
66  tsig_algo_type* algorithm = NULL;
67  const EVP_MD *hmac_algorithm = NULL;
68  ods_log_assert(allocator);
69  ods_log_assert(digest);
70  ods_log_assert(name);
71  ods_log_assert(wireformat);
72  hmac_algorithm = EVP_get_digestbyname(digest);
73  if (!hmac_algorithm) {
74  ods_log_error("[%s] %s digest not available", tsig_str, digest);
75  return 0;
76  }
77  algorithm = (tsig_algo_type *) allocator_alloc(allocator,
78  sizeof(tsig_algo_type));
79  algorithm->txt_name = name;
80  algorithm->wf_name = ldns_dname_new_frm_str(wireformat);
81  if (!algorithm->wf_name) {
82  ods_log_error("[%s] unable to parse %s algorithm", tsig_str,
83  wireformat);
84  return 0;
85  }
86  algorithm->max_digest_size = EVP_MAX_MD_SIZE;
87  algorithm->data = hmac_algorithm;
88  algorithm->hmac_create = create_context;
89  algorithm->hmac_init = init_context;
90  algorithm->hmac_update = update;
91  algorithm->hmac_final = final;
92  tsig_handler_add_algo(algorithm);
93  return 1;
94 }
95 
96 
102 tsig_handler_openssl_init(allocator_type* allocator)
103 {
104  tsig_cleanup_table = NULL;
105  tsig_allocator = allocator;
106  OpenSSL_add_all_digests();
107  ods_log_debug("[%s] add md5", tsig_str);
108  if (!tsig_openssl_init_algorithm(allocator, "md5", "hmac-md5",
109  "hmac-md5.sig-alg.reg.int.")) {
110  return ODS_STATUS_ERR;
111  }
112 #ifdef HAVE_EVP_SHA1
113  ods_log_debug("[%s] add sha1", tsig_str);
114  if (!tsig_openssl_init_algorithm(allocator, "sha1", "hmac-sha1",
115  "hmac-sha1.")) {
116  return ODS_STATUS_ERR;
117  }
118 #endif /* HAVE_EVP_SHA1 */
119 
120 #ifdef HAVE_EVP_SHA256
121  ods_log_debug("[%s] add sha256", tsig_str);
122  if (!tsig_openssl_init_algorithm(allocator, "sha256", "hmac-sha256",
123  "hmac-sha256.")) {
124  return ODS_STATUS_ERR;
125  }
126 #endif /* HAVE_EVP_SHA256 */
127  return ODS_STATUS_OK;
128 }
129 
130 static void
131 cleanup_context(void *data)
132 {
133  HMAC_CTX* context = (HMAC_CTX*) data;
134  HMAC_CTX_cleanup(context);
135  return;
136 }
137 
138 static void
139 context_add_cleanup(void* context)
140 {
141  tsig_cleanup_table_type* entry = NULL;
142  if (!context) {
143  return;
144  }
145  entry = (tsig_cleanup_table_type *) allocator_alloc(tsig_allocator,
146  sizeof(tsig_cleanup_table_type));
147  if (entry) {
148  entry->cleanup = context;
149  entry->next = tsig_cleanup_table;
150  tsig_cleanup_table = entry;
151  }
152  return;
153 }
154 
155 static void*
156 create_context(allocator_type* allocator)
157 {
158  HMAC_CTX* context = (HMAC_CTX*) allocator_alloc(allocator,
159  sizeof(HMAC_CTX));
160  HMAC_CTX_init(context);
161  context_add_cleanup(context);
162  return context;
163 }
164 
165 static void
166 init_context(void* context, tsig_algo_type *algorithm, tsig_key_type *key)
167 {
168  HMAC_CTX* ctx = (HMAC_CTX*) context;
169  const EVP_MD* md = (const EVP_MD*) algorithm->data;
170  HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
171  return;
172 }
173 
174 static void
175 update(void* context, const void* data, size_t size)
176 {
177  HMAC_CTX* ctx = (HMAC_CTX*) context;
178  HMAC_Update(ctx, (unsigned char*) data, (int) size);
179  return;
180 }
181 
182 static void
183 final(void* context, uint8_t* digest, size_t* size)
184 {
185  HMAC_CTX* ctx = (HMAC_CTX*) context;
186  unsigned len = (unsigned) *size;
187  HMAC_Final(ctx, digest, &len);
188  *size = (size_t) len;
189  return;
190 }
191 
192 
197 void
198 tsig_handler_openssl_finalize(void)
199 {
200  tsig_cleanup_table_type* entry = tsig_cleanup_table;
201 
202  while (entry) {
203  cleanup_context(entry->cleanup);
204  entry = entry->next;
205  }
206  EVP_cleanup();
207  return;
208 }
209 
210 #endif /* HAVE_SSL */
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:101
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:98
size_t max_digest_size
Definition: tsig.h:93
void ods_log_debug(const char *format,...)
Definition: log.c:270
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:66
enum ods_enum_status ods_status
Definition: status.h:90
void ods_log_error(const char *format,...)
Definition: log.c:334
ldns_rdf * wf_name
Definition: tsig.h:92
const void * data
Definition: tsig.h:94
void *(* hmac_create)(allocator_type *allocator)
Definition: tsig.h:96
size_t size
Definition: tsig.h:81
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:103
const uint8_t * data
Definition: tsig.h:82
#define ods_log_assert(x)
Definition: log.h:154
const char * txt_name
Definition: tsig.h:91
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:108