OpenDNSSEC-signer  2.1.9
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 
39 static const char* tsig_str = "tsig-ssl";
41 static void *create_context();
42 static void init_context(void *context,
43  tsig_algo_type *algorithm,
44  tsig_key_type *key);
45 static void update(void *context, const void *data, size_t size);
46 static void final(void *context, uint8_t *digest, size_t *size);
47 
48 typedef struct tsig_cleanup_table_struct tsig_cleanup_table_type;
49 struct tsig_cleanup_table_struct {
50  tsig_cleanup_table_type* next;
51  void* cleanup;
52 };
53 static tsig_cleanup_table_type* tsig_cleanup_table = NULL;
54 
55 
60 static int
61 tsig_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 
97 ods_status
98 tsig_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 
125 static void
126 cleanup_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 
136 static void
137 context_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 
149 static void*
150 create_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 
164 static void
165 init_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 
172 static void
173 update(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 
179 static void
180 final(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 
193 void
194 tsig_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
void *(* hmac_create)(void)
Definition: tsig.h:95
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
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