xref: /openbsd-src/usr.sbin/nsd/tsig-openssl.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*
2  * tsig-openssl.h -- Interface to OpenSSL for TSIG support.
3  *
4  * Copyright (c) 2001-2011, 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 		log_msg(LOG_ERR, "%s digest not available", digest);
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_MAX_MD_SIZE;
48 	algorithm->data = hmac_algorithm;
49 	algorithm->hmac_create_context = create_context;
50 	algorithm->hmac_init_context = init_context;
51 	algorithm->hmac_update = update;
52 	algorithm->hmac_final = final;
53 	tsig_add_algorithm(algorithm);
54 
55 	return 1;
56 }
57 
58 int
59 tsig_openssl_init(region_type *region)
60 {
61 	OpenSSL_add_all_digests();
62 
63 	/* TODO: walk lookup supported algorithms table */
64 	if (!tsig_openssl_init_algorithm(region, "md5", "hmac-md5","hmac-md5.sig-alg.reg.int."))
65 		return 0;
66 #ifdef HAVE_EVP_SHA1
67 	if (!tsig_openssl_init_algorithm(region, "sha1", "hmac-sha1", "hmac-sha1."))
68 		return 0;
69 #endif /* HAVE_EVP_SHA1 */
70 
71 #ifdef HAVE_EVP_SHA256
72 	if (!tsig_openssl_init_algorithm(region, "sha256", "hmac-sha256", "hmac-sha256."))
73 		return 0;
74 #endif /* HAVE_EVP_SHA256 */
75 	return 1;
76 }
77 
78 static void
79 cleanup_context(void *data)
80 {
81 	HMAC_CTX *context = (HMAC_CTX *) data;
82 	HMAC_CTX_cleanup(context);
83 }
84 
85 static void *
86 create_context(region_type *region)
87 {
88 	HMAC_CTX *context
89 		= (HMAC_CTX *) region_alloc(region, sizeof(HMAC_CTX));
90 	region_add_cleanup(region, cleanup_context, context);
91 	HMAC_CTX_init(context);
92 	return context;
93 }
94 
95 static void
96 init_context(void *context,
97 			  tsig_algorithm_type *algorithm,
98 			  tsig_key_type *key)
99 {
100 	HMAC_CTX *ctx = (HMAC_CTX *) context;
101 	const EVP_MD *md = (const EVP_MD *) algorithm->data;
102 	HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
103 }
104 
105 static void
106 update(void *context, const void *data, size_t size)
107 {
108 	HMAC_CTX *ctx = (HMAC_CTX *) context;
109 	HMAC_Update(ctx, (unsigned char *) data, (int) size);
110 }
111 
112 static void
113 final(void *context, uint8_t *digest, size_t *size)
114 {
115 	HMAC_CTX *ctx = (HMAC_CTX *) context;
116 	unsigned len = (unsigned) *size;
117 	HMAC_Final(ctx, digest, &len);
118 	*size = (size_t) len;
119 }
120 
121 void
122 tsig_openssl_finalize()
123 {
124 	EVP_cleanup();
125 }
126 
127 #endif /* defined(HAVE_SSL) */
128