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