1 /* Copyright (C) 2011 NORDUnet A/S
2 * See LICENSE for information about licensing.
5 #include <stdio.h> /* For sprintf(). */
7 #include <nettle/sha.h>
8 #include <nettle/hmac.h>
14 #include "radsecproxy.h"
20 format_hash(const uint8_t *hash, size_t out_len, uint8_t *out)
24 for (i = 0; i < out_len / 2; i++)
25 sprintf((char *) out + i*2, "%02x", hash[i % SHA256_DIGEST_SIZE]);
29 hash(const uint8_t *in,
35 struct sha256_ctx ctx;
36 uint8_t hash[SHA256_DIGEST_SIZE];
39 sha256_update(&ctx, strlen((char *) in), in);
40 sha256_digest(&ctx, sizeof(hash), hash);
41 format_hash(hash, out_len, out);
44 struct hmac_sha256_ctx ctx;
45 uint8_t hash[SHA256_DIGEST_SIZE];
47 hmac_sha256_set_key(&ctx, strlen((char *) key), key);
48 hmac_sha256_update(&ctx, strlen((char *) in), in);
49 hmac_sha256_digest(&ctx, sizeof(hash), hash);
50 format_hash(hash, out_len, out);
54 /** Hash the MAC in \a IN, keying with \a KEY if it's not NULL.
56 \a IN and \a KEY are NULL terminated strings.
58 \a IN is sanitised by lowercasing it, removing all but [0-9a-f]
59 and truncating it at first ';' (due to RADIUS praxis with tacking
60 on SSID to MAC in Calling-Station-Id). */
62 fticks_hashmac(const uint8_t *in,
68 /* TODO: s/[!0-9a-f]//1 */
69 /* TODO: truncate after first ';', if any */
71 hash(in, key, out_len, out);
75 fticks_log(const struct options *options,
76 const struct client *client,
77 const struct radmsg *msg,
78 const struct rqout *rqout)
80 unsigned char *username = NULL;
81 unsigned char *realm = NULL;
82 uint8_t visinst[8+40+1+1]; /* Room for 40 octets of VISINST. */
83 uint8_t *macin = NULL;
84 uint8_t macout[2*32+1]; /* Room for ASCII representation of SHA256. */
86 username = radattr2ascii(radmsg_gettype(rqout->rq->msg,
88 if (username != NULL) {
89 realm = (unsigned char *) strrchr((char *) username, '@');
93 realm = (unsigned char *) "";
96 memset(visinst, 0, sizeof(visinst));
97 if (options->fticks_reporting == RSP_FTICKS_REPORTING_FULL)
98 snprintf((char *) visinst, sizeof(visinst), "VISINST=%s#",
101 #define BOGUS_MAC "00:00:00:00:00:00" /* FIXME: Is there a standard
102 * for bogus MAC addresses? */
103 memset(macout, 0, sizeof(macout));
104 strncpy((char *) macout, BOGUS_MAC, sizeof(macout) - 1);
105 if (options->fticks_mac != RSP_FTICKS_MAC_STATIC) {
106 macin = radattr2ascii(radmsg_gettype(rqout->rq->msg,
107 RAD_Attr_Calling_Station_Id));
111 macin = (uint8_t *) strdup(BOGUS_MAC);
112 #endif /* RS_TESTING */
114 switch (options->fticks_mac)
116 case RSP_FTICKS_MAC_STATIC:
117 memcpy(macout, BOGUS_MAC, sizeof(BOGUS_MAC));
119 case RSP_FTICKS_MAC_ORIGINAL:
120 memcpy(macout, macin, sizeof(macout));
122 case RSP_FTICKS_MAC_VENDOR_HASHED:
123 fticks_hashmac(macin + 3, NULL, sizeof(macout), macout);
125 case RSP_FTICKS_MAC_VENDOR_KEY_HASHED:
126 fticks_hashmac(macin + 3, options->fticks_key, sizeof(macout),
129 case RSP_FTICKS_MAC_FULLY_HASHED:
130 fticks_hashmac(macin, NULL, sizeof(macout), macout);
132 case RSP_FTICKS_MAC_FULLY_KEY_HASHED:
133 fticks_hashmac(macin, options->fticks_key, sizeof(macout), macout);
136 debugx(2, DBG_ERR, "invalid fticks mac configuration: %d",
137 options->fticks_mac);
140 "F-TICKS/eduroam/1.0#REALM=%s#VISCOUNTRY=%s#%sCSI=%s#RESULT=%s#",
142 client->conf->fticks_viscountry,
145 msg->code == RAD_Access_Accept ? "OK" : "FAIL");
148 if (username != NULL)
152 /* Local Variables: */
153 /* c-file-style: "stroustrup" */