From 4806ddac9fc1dd243f9297c031689c23be6ee8b0 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 29 Sep 2011 11:21:30 +0200 Subject: Add binary radsecproxy-hash. Split up fticks.c in order not to have to drag in too much of radsecproxy in order to just hash a MAC. --- fticks.c | 94 +----------------------------------------------------- fticks.h | 4 --- fticks_hashmac.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ fticks_hashmac.h | 7 ++++ radsecproxy-hash.1 | 30 +++++++++++++++++ 5 files changed, 128 insertions(+), 97 deletions(-) create mode 100644 fticks_hashmac.c create mode 100644 fticks_hashmac.h create mode 100644 radsecproxy-hash.1 diff --git a/fticks.c b/fticks.c index c4acac2..f8b4c20 100644 --- a/fticks.c +++ b/fticks.c @@ -2,55 +2,10 @@ * See LICENSE for information about licensing. */ -#include /* For sprintf(). */ -#include -#include -#include -#include -#include - -#include -#include -#include #include "radsecproxy.h" #include "debug.h" - #include "fticks.h" - -static void -_format_hash(const uint8_t *hash, size_t out_len, uint8_t *out) -{ - int ir, iw; - - for (ir = 0, iw = 0; iw <= out_len - 3; ir++, iw += 2) - sprintf((char *) out + iw, "%02x", hash[ir % 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); - } -} +#include "fticks_hashmac.h" int fticks_configure(struct options *options, @@ -122,53 +77,6 @@ out: return r; } -/** Hash the Ethernet MAC address in \a IN, keying a HMAC with \a KEY - unless \a KEY is NULL. If \a KEY is null \a IN is hashed with an - ordinary cryptographic hash function such as SHA-2. - - \a IN and \a KEY are NULL terminated strings. - - \a IN is supposed to be an Ethernet MAC address and is sanitised - by lowercasing it, removing all but [0-9a-f] and truncating it at - the first ';' found. The truncation is done because RADIUS - supposedly has a praxis of tacking on SSID to the MAC address in - Calling-Station-Id. - - \return 0 on success, -ENOMEM on out of memory. -*/ -int -fticks_hashmac(const uint8_t *in, - const uint8_t *key, - size_t out_len, - uint8_t *out) -{ - uint8_t *in_copy = NULL; - uint8_t *p = NULL; - int i; - - in_copy = calloc(1, strlen((const char *) in) + 1); - if (in_copy == NULL) - return -ENOMEM; - - /* Sanitise and lowercase 'in' into 'in_copy'. */ - for (i = 0, p = in_copy; in[i] != '\0'; i++) { - if (in[i] == ';') { - *p++ = '\0'; - break; - } - if (in[i] >= '0' && in[i] <= '9') { - *p++ = in[i]; - } - else if (tolower(in[i]) >= 'a' && tolower(in[i]) <= 'f') { - *p++ = tolower(in[i]); - } - } - - _hash(in_copy, key, out_len, out); - free(in_copy); - return 0; -} - void fticks_log(const struct options *options, const struct client *client, diff --git a/fticks.h b/fticks.h index eb880c0..d302cf0 100644 --- a/fticks.h +++ b/fticks.h @@ -6,10 +6,6 @@ int fticks_configure(struct options *options, uint8_t **reportingp, uint8_t **macp, uint8_t **keyp); -int fticks_hashmac(const uint8_t *in, - const uint8_t *key, - size_t out_len, - uint8_t *out); void fticks_log(const struct options *options, const struct client *client, const struct radmsg *msg, diff --git a/fticks_hashmac.c b/fticks_hashmac.c new file mode 100644 index 0000000..eb0d29b --- /dev/null +++ b/fticks_hashmac.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include "fticks_hashmac.h" + +static void +_format_hash(const uint8_t *hash, size_t out_len, uint8_t *out) +{ + int ir, iw; + + for (ir = 0, iw = 0; iw <= out_len - 3; ir++, iw += 2) + sprintf((char *) out + iw, "%02x", hash[ir % 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 Ethernet MAC address in \a IN, keying a HMAC with \a KEY + unless \a KEY is NULL. If \a KEY is null \a IN is hashed with an + ordinary cryptographic hash function such as SHA-2. + + \a IN and \a KEY are NULL terminated strings. + + \a IN is supposed to be an Ethernet MAC address and is sanitised + by lowercasing it, removing all but [0-9a-f] and truncating it at + the first ';' found. The truncation is done because RADIUS + supposedly has a praxis of tacking on SSID to the MAC address in + Calling-Station-Id. + + \return 0 on success, -ENOMEM on out of memory. +*/ +int +fticks_hashmac(const uint8_t *in, + const uint8_t *key, + size_t out_len, + uint8_t *out) +{ + uint8_t *in_copy = NULL; + uint8_t *p = NULL; + int i; + + in_copy = calloc(1, strlen((const char *) in) + 1); + if (in_copy == NULL) + return -ENOMEM; + + /* Sanitise and lowercase 'in' into 'in_copy'. */ + for (i = 0, p = in_copy; in[i] != '\0'; i++) { + if (in[i] == ';') { + *p++ = '\0'; + break; + } + if (in[i] >= '0' && in[i] <= '9') { + *p++ = in[i]; + } + else if (tolower(in[i]) >= 'a' && tolower(in[i]) <= 'f') { + *p++ = tolower(in[i]); + } + } + + _hash(in_copy, key, out_len, out); + free(in_copy); + return 0; +} diff --git a/fticks_hashmac.h b/fticks_hashmac.h new file mode 100644 index 0000000..eb40a04 --- /dev/null +++ b/fticks_hashmac.h @@ -0,0 +1,7 @@ +#include +#include + +int fticks_hashmac(const uint8_t *in, + const uint8_t *key, + size_t out_len, + uint8_t *out); diff --git a/radsecproxy-hash.1 b/radsecproxy-hash.1 new file mode 100644 index 0000000..fbe6c27 --- /dev/null +++ b/radsecproxy-hash.1 @@ -0,0 +1,30 @@ +.TH radsecproxy-hash 1 "29 Sep 2011" + +.SH "NAME" +radsecproxy-hash - print digests of Ethernet MAC addresses + +.SH "SYNOPSIS" +.HP 12 +radsecproxy-hash [-h] [-k key] [-t type] +.sp + +.SH "DESCRIPTION" +Print the hash or hmac of Ethernet MAC addresses read from standard +input. + +.SH "OPTIONS" +.TP +.B -h +\fIdisplay help and exit\fR + +.TP +.B -k key +\fIuse KEY for HMAC calculation\fR + +.TP +.B -t type +\fIprint digest of type TYPE [hash|hmac]\fR + + +.SH "SEE ALSO" +radsecproxy.conf(5) -- cgit v1.1