1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/*
* tsig-openssl.h -- Interface to OpenSSL for TSIG support.
*
* Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#include "config.h"
#if defined(HAVE_SSL)
#include "tsig-openssl.h"
#include "tsig.h"
#include "util.h"
static void *create_context(region_type *region);
static void init_context(void *context,
tsig_algorithm_type *algorithm,
tsig_key_type *key);
static void update(void *context, const void *data, size_t size);
static void final(void *context, uint8_t *digest, size_t *size);
static int
tsig_openssl_init_algorithm(region_type* region,
const char* digest, const char* name, const char* wireformat)
{
tsig_algorithm_type* algorithm;
const EVP_MD *hmac_algorithm;
hmac_algorithm = EVP_get_digestbyname(digest);
if (!hmac_algorithm) {
log_msg(LOG_ERR, "%s digest not available", digest);
return 0;
}
algorithm = (tsig_algorithm_type *) region_alloc(
region, sizeof(tsig_algorithm_type));
algorithm->short_name = name;
algorithm->wireformat_name
= dname_parse(region, wireformat);
if (!algorithm->wireformat_name) {
log_msg(LOG_ERR, "cannot parse %s algorithm", wireformat);
return 0;
}
algorithm->maximum_digest_size = EVP_MAX_MD_SIZE;
algorithm->data = hmac_algorithm;
algorithm->hmac_create_context = create_context;
algorithm->hmac_init_context = init_context;
algorithm->hmac_update = update;
algorithm->hmac_final = final;
tsig_add_algorithm(algorithm);
return 1;
}
int
tsig_openssl_init(region_type *region)
{
OpenSSL_add_all_digests();
/* TODO: walk lookup supported algorithms table */
if (!tsig_openssl_init_algorithm(region, "md5", "hmac-md5","hmac-md5.sig-alg.reg.int."))
return 0;
#ifdef HAVE_EVP_SHA1
if (!tsig_openssl_init_algorithm(region, "sha1", "hmac-sha1", "hmac-sha1."))
return 0;
#endif /* HAVE_EVP_SHA1 */
#ifdef HAVE_EVP_SHA256
if (!tsig_openssl_init_algorithm(region, "sha256", "hmac-sha256", "hmac-sha256."))
return 0;
#endif /* HAVE_EVP_SHA256 */
return 1;
}
static void
cleanup_context(void *data)
{
HMAC_CTX *context = (HMAC_CTX *) data;
HMAC_CTX_cleanup(context);
}
static void *
create_context(region_type *region)
{
HMAC_CTX *context
= (HMAC_CTX *) region_alloc(region, sizeof(HMAC_CTX));
region_add_cleanup(region, cleanup_context, context);
HMAC_CTX_init(context);
return context;
}
static void
init_context(void *context,
tsig_algorithm_type *algorithm,
tsig_key_type *key)
{
HMAC_CTX *ctx = (HMAC_CTX *) context;
const EVP_MD *md = (const EVP_MD *) algorithm->data;
HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
}
static void
update(void *context, const void *data, size_t size)
{
HMAC_CTX *ctx = (HMAC_CTX *) context;
HMAC_Update(ctx, (unsigned char *) data, (int) size);
}
static void
final(void *context, uint8_t *digest, size_t *size)
{
HMAC_CTX *ctx = (HMAC_CTX *) context;
unsigned len = (unsigned) *size;
HMAC_Final(ctx, digest, &len);
*size = (size_t) len;
}
void
tsig_openssl_finalize()
{
EVP_cleanup();
}
#endif /* defined(HAVE_SSL) */
|