xref: /openbsd/usr.sbin/nsd/tsig-openssl.c (revision e5dd7070)
1 /*
2  * tsig-openssl.h -- Interface to OpenSSL for TSIG support.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #include "config.h"
11 
12 #if defined(HAVE_SSL)
13 
14 #include "tsig-openssl.h"
15 #include "tsig.h"
16 #include "util.h"
17 
18 static void *create_context(region_type *region);
19 static void init_context(void *context,
20 			 tsig_algorithm_type *algorithm,
21 			 tsig_key_type *key);
22 static void update(void *context, const void *data, size_t size);
23 static void final(void *context, uint8_t *digest, size_t *size);
24 
25 static int
26 tsig_openssl_init_algorithm(region_type* region,
27 	const char* digest, const char* name, const char* wireformat)
28 {
29 	tsig_algorithm_type* algorithm;
30 	const EVP_MD *hmac_algorithm;
31 
32 	hmac_algorithm = EVP_get_digestbyname(digest);
33 	if (!hmac_algorithm) {
34 		/* skip but don't error */
35 		return 0;
36 	}
37 
38 	algorithm = (tsig_algorithm_type *) region_alloc(
39 		region, sizeof(tsig_algorithm_type));
40 	algorithm->short_name = name;
41 	algorithm->wireformat_name
42 		= dname_parse(region, wireformat);
43 	if (!algorithm->wireformat_name) {
44 		log_msg(LOG_ERR, "cannot parse %s algorithm", wireformat);
45 		return 0;
46 	}
47 	algorithm->maximum_digest_size = EVP_MD_size(hmac_algorithm);
48 	if(algorithm->maximum_digest_size < 20)
49 		algorithm->maximum_digest_size = EVP_MAX_MD_SIZE;
50 	algorithm->data = hmac_algorithm;
51 	algorithm->hmac_create_context = create_context;
52 	algorithm->hmac_init_context = init_context;
53 	algorithm->hmac_update = update;
54 	algorithm->hmac_final = final;
55 	tsig_add_algorithm(algorithm);
56 
57 	return 1;
58 }
59 
60 int
61 tsig_openssl_init(region_type *region)
62 {
63 	int count = 0;
64 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
65 	OpenSSL_add_all_digests();
66 #else
67 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
68 #endif
69 
70 	count += tsig_openssl_init_algorithm(region,
71 	    "md5", "hmac-md5","hmac-md5.sig-alg.reg.int.");
72 	count += tsig_openssl_init_algorithm(region,
73 	    "sha1", "hmac-sha1", "hmac-sha1.");
74 	count += tsig_openssl_init_algorithm(region,
75 	    "sha224", "hmac-sha224", "hmac-sha224.");
76 	count += tsig_openssl_init_algorithm(region,
77 	    "sha256", "hmac-sha256", "hmac-sha256.");
78 	count += tsig_openssl_init_algorithm(region,
79 	    "sha384", "hmac-sha384", "hmac-sha384.");
80 	count += tsig_openssl_init_algorithm(region,
81 	    "sha512", "hmac-sha512", "hmac-sha512.");
82 
83 	return count;
84 }
85 
86 static void
87 cleanup_context(void *data)
88 {
89 	HMAC_CTX *context = (HMAC_CTX *) data;
90 #ifdef HAVE_HMAC_CTX_NEW
91 	HMAC_CTX_free(context);
92 #else
93 	HMAC_CTX_cleanup(context);
94 	free(context);
95 #endif
96 }
97 
98 static void *
99 create_context(region_type *region)
100 {
101 #ifdef HAVE_HMAC_CTX_NEW
102 	HMAC_CTX *context = HMAC_CTX_new();
103 #else
104 	HMAC_CTX *context = (HMAC_CTX *) malloc(sizeof(HMAC_CTX));
105 #endif
106 	region_add_cleanup(region, cleanup_context, context);
107 #ifdef HAVE_HMAC_CTX_RESET
108 	HMAC_CTX_reset(context);
109 #else
110 	HMAC_CTX_init(context);
111 #endif
112 	return context;
113 }
114 
115 static void
116 init_context(void *context,
117 			  tsig_algorithm_type *algorithm,
118 			  tsig_key_type *key)
119 {
120 	HMAC_CTX *ctx = (HMAC_CTX *) context;
121 	const EVP_MD *md = (const EVP_MD *) algorithm->data;
122 	HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
123 }
124 
125 static void
126 update(void *context, const void *data, size_t size)
127 {
128 	HMAC_CTX *ctx = (HMAC_CTX *) context;
129 	HMAC_Update(ctx, (unsigned char *) data, (int) size);
130 }
131 
132 static void
133 final(void *context, uint8_t *digest, size_t *size)
134 {
135 	HMAC_CTX *ctx = (HMAC_CTX *) context;
136 	unsigned len = (unsigned) *size;
137 	HMAC_Final(ctx, digest, &len);
138 	*size = (size_t) len;
139 }
140 
141 void
142 tsig_openssl_finalize()
143 {
144 #ifdef HAVE_EVP_CLEANUP
145 	EVP_cleanup();
146 #endif
147 }
148 
149 #endif /* defined(HAVE_SSL) */
150