diff options
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | fticks.c | 67 | ||||
-rw-r--r-- | fticks.h | 7 |
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); |