summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/tsig-openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/nsd/tsig-openssl.c')
-rw-r--r--usr.sbin/nsd/tsig-openssl.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/usr.sbin/nsd/tsig-openssl.c b/usr.sbin/nsd/tsig-openssl.c
new file mode 100644
index 00000000000..5773fd2a674
--- /dev/null
+++ b/usr.sbin/nsd/tsig-openssl.c
@@ -0,0 +1,127 @@
+/*
+ * tsig-openssl.h -- Interface to OpenSSL for TSIG support.
+ *
+ * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+
+#include <config.h>
+
+#if defined(TSIG) && 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(TSIG) && defined(HAVE_SSL) */