OpenDNSSEC-signer  2.0.2
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  HMAC_CTX_free(context);
130 }
131 
132 static void
133 context_add_cleanup(void* context)
134 {
135  tsig_cleanup_table_type* entry = NULL;
136  if (!context) {
137  return;
138  }
139  CHECKALLOC(entry = (tsig_cleanup_table_type *) malloc(sizeof(tsig_cleanup_table_type)));
140  entry->cleanup = context;
141  entry->next = tsig_cleanup_table;
142  tsig_cleanup_table = entry;
143 }
144 
145 static void*
146 create_context()
147 {
148  HMAC_CTX* context;
149  CHECKALLOC(context = HMAC_CTX_new());
150  context_add_cleanup(context);
151  return context;
152 }
153 
154 static void
155 init_context(void* context, tsig_algo_type *algorithm, tsig_key_type *key)
156 {
157  HMAC_CTX* ctx = (HMAC_CTX*) context;
158  const EVP_MD* md = (const EVP_MD*) algorithm->data;
159  HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
160 }
161 
162 static void
163 update(void* context, const void* data, size_t size)
164 {
165  HMAC_CTX* ctx = (HMAC_CTX*) context;
166  HMAC_Update(ctx, (unsigned char*) data, (int) size);
167 }
168 
169 static void
170 final(void* context, uint8_t* digest, size_t* size)
171 {
172  HMAC_CTX* ctx = (HMAC_CTX*) context;
173  unsigned len = (unsigned) *size;
174  HMAC_Final(ctx, digest, &len);
175  *size = (size_t) len;
176 }
177 
178 
183 void
184 tsig_handler_openssl_finalize(void)
185 {
186  tsig_cleanup_table_type* entry = tsig_cleanup_table;
187 
188  while (entry) {
189  cleanup_context(entry->cleanup);
190  entry = entry->next;
191  }
192  EVP_cleanup();
193 }
194 
195 #endif /* HAVE_SSL */
size_t max_digest_size
Definition: tsig.h:92
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:100
ldns_rdf * wf_name
Definition: tsig.h:91
const void * data
Definition: tsig.h:93
void *(* hmac_create)(void)
Definition: tsig.h:95
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:102
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:97
size_t size
Definition: tsig.h:80
const uint8_t * data
Definition: tsig.h:81
const char * txt_name
Definition: tsig.h:90
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:93