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