summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac3
-rw-r--r--fticks.c67
-rw-r--r--fticks.h7
4 files changed, 80 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index cd40c2a..420b7ae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,7 @@ radsecproxy_SOURCES = radsecproxy.c \
tcp.c \
tls.c \
dtls.c \
+ fticks.c \
radsecproxy.h \
tlscommon.h \
gconfig.h \
@@ -30,7 +31,8 @@ radsecproxy_SOURCES = radsecproxy.c \
udp.h \
tcp.h \
tls.h \
- dtls.h
+ dtls.h \
+ fticks.h
catgconf_SOURCES = debug.c \
util.c \
diff --git a/configure.ac b/configure.ac
index d3d901b..973148f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,6 +46,9 @@ AC_ARG_ENABLE(dtls,
exit -1
fi
])
+
+AC_CHECK_LIB([nettle], [nettle_sha256_init],,
+ AC_MSG_ERROR([required library nettle not found]))
dnl Check if we're on Solaris and set CFLAGS accordingly
AC_CANONICAL_SYSTEM
diff --git a/fticks.c b/fticks.c
new file mode 100644
index 0000000..ab750a3
--- /dev/null
+++ b/fticks.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 2011 NORDUnet A/S
+ * See LICENSE for information about licensing.
+ */
+
+#include <stdio.h> /* For sprintf(). */
+#include <string.h>
+#include <nettle/sha.h>
+#include <nettle/hmac.h>
+
+static void
+format_hash(const uint8_t *hash, size_t out_len, uint8_t *out)
+{
+ int i;
+
+ for (i = 0; i < out_len / 2; i++)
+ sprintf((char *) out + i*2, "%02x", hash[i % SHA256_DIGEST_SIZE]);
+}
+
+static void
+hash(const uint8_t *in,
+ const uint8_t *key,
+ size_t out_len,
+ uint8_t *out)
+{
+ if (key == NULL) {
+ struct sha256_ctx ctx;
+ uint8_t hash[SHA256_DIGEST_SIZE];
+
+ sha256_init(&ctx);
+ sha256_update(&ctx, strlen((char *) in), in);
+ sha256_digest(&ctx, sizeof(hash), hash);
+ format_hash(hash, out_len, out);
+ }
+ else {
+ struct hmac_sha256_ctx ctx;
+ uint8_t hash[SHA256_DIGEST_SIZE];
+
+ hmac_sha256_set_key(&ctx, strlen((char *) key), key);
+ hmac_sha256_update(&ctx, strlen((char *) in), in);
+ hmac_sha256_digest(&ctx, sizeof(hash), hash);
+ format_hash(hash, out_len, out);
+ }
+}
+
+/** Hash the MAC in \a IN, keying with \a KEY if it's not NULL.
+
+ \a IN and \a KEY are NULL terminated strings.
+
+ \a IN is sanitised by lowercasing it, removing all but [0-9a-f]
+ and truncating it at first ';' (due to RADIUS praxis with tacking
+ on SSID to MAC in Calling-Station-Id). */
+void
+fticks_hashmac(const uint8_t *in,
+ const uint8_t *key,
+ size_t out_len,
+ uint8_t *out)
+{
+ /* TODO: lowercase */
+ /* TODO: s/[!0-9a-f]//1 */
+ /* TODO: truncate after first ';', if any */
+
+ hash(in, key, out_len, out);
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/fticks.h b/fticks.h
new file mode 100644
index 0000000..4098fb5
--- /dev/null
+++ b/fticks.h
@@ -0,0 +1,7 @@
+/* Copyright (C) 2011 NORDUnet A/S
+ * See LICENSE for information about licensing.
+ */
+int fticks_hashmac(const uint8_t *in,
+ const uint8_t *key,
+ size_t out_len,
+ uint8_t *out);