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