Skip to content

Commit

Permalink
Implement HMAC authentication.
Browse files Browse the repository at this point in the history
Known issues:

  - we create a neighbour entry before the first successful challenge;
  - we compute HMAC for each HMAC TLV rather than just once;
  - we only support sending one HMAC TLV;
  - we don't support key rotation.

Co-authored-by: Clara Do <[email protected]>
Co-authored-by: Weronika Kolodziejak <[email protected]>
  • Loading branch information
3 people committed May 20, 2021
1 parent e3adf47 commit 739f76a
Show file tree
Hide file tree
Showing 16 changed files with 762 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ LDLIBS = -lrt

SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
route.c xroute.c message.c resend.c configuration.c local.c \
rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c
hmac.c rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c

OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
route.o xroute.o message.o resend.o configuration.o local.o \
rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o
hmac.o rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o

babeld: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
Expand Down
5 changes: 3 additions & 2 deletions babeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,10 @@ main(int argc, char **argv)
}

if(FD_ISSET(protocol_socket, &readfds)) {
unsigned char to[16];
rc = babel_recv(protocol_socket,
receive_buffer, receive_buffer_size,
(struct sockaddr*)&sin6, sizeof(sin6));
(struct sockaddr*)&sin6, sizeof(sin6), to);
if(rc < 0) {
if(errno != EAGAIN && errno != EINTR) {
perror("recv");
Expand All @@ -652,7 +653,7 @@ main(int argc, char **argv)
continue;
if(ifp->ifindex == sin6.sin6_scope_id) {
parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
receive_buffer, rc);
receive_buffer, rc, to);
VALGRIND_MAKE_MEM_UNDEFINED(receive_buffer,
receive_buffer_size);
break;
Expand Down
127 changes: 127 additions & 0 deletions configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ THE SOFTWARE.
#include "interface.h"
#include "route.h"
#include "kernel.h"
#include "hmac.h"
#include "configuration.h"

static struct filter *input_filters = NULL;
Expand Down Expand Up @@ -321,6 +322,35 @@ get_interface_type(int c, int *type_r, gnc_t gnc, void *closure)
return c;
}

static int
gethex(int c, unsigned char **value_r, int *len_r, gnc_t gnc, void *closure)
{
char *t;
unsigned char *value;
int len, rc;
c = getword(c, &t, gnc, closure);
if(c < -1)
return c;
len = strlen(t);
if(len % 2 != 0) {
free(t);
return -2;
}
value = malloc(len / 2);
if(value == NULL)
return -2;

rc = fromhex(value, t, len);
free(t);
if(rc < 0) {
free(value);
return -2;
}
*value_r = value;
*len_r = len / 2;
return c;
}

static void
free_filter(struct filter *f)
{
Expand Down Expand Up @@ -646,6 +676,17 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure,
if(c < -1 || penalty <= 0 || penalty > 0xFFFF)
goto error;
if_conf->max_rtt_penalty = penalty;
} else if(strcmp(token, "hmac") == 0) {
char *key_id;
struct key *key;
c = getword(c, &key_id, gnc, closure);
if(c < -1) {
free(key_id);
goto error;
}
key = find_key(key_id);
if_conf->key = key;
free(key_id);
} else {
goto error;
}
Expand Down Expand Up @@ -693,6 +734,65 @@ parse_ifconf(int c, gnc_t gnc, void *closure,
return -2;
}

static int
parse_key(int c, gnc_t gnc, void *closure, struct key **key_return)
{
char *token = NULL;
struct key *key;

key = calloc(1, sizeof(struct key));
if(key == NULL)
goto error;
while(1) {
c = skip_whitespace(c, gnc, closure);
if(c < 0 || c == '\n' || c == '#') {
c = skip_to_eol(c, gnc, closure);
break;
}
c = getword(c, &token, gnc, closure);
if(c < -1) {
goto error;
}
if(strcmp(token, "id") == 0) {
c = getword(c, &key->id, gnc, closure);
if(c < -1 || key->id == NULL) {
goto error;
}
} else if(strcmp(token, "type") == 0) {
char *auth_type;
c = getword(c, &auth_type, gnc, closure);
if(c < -1 || auth_type == NULL)
goto error;
if(strcmp(auth_type, "none") == 0) {
key->type = AUTH_TYPE_NONE;
} else if(strcmp(auth_type, "sha256") == 0) {
key->type = AUTH_TYPE_SHA256;
} else if(strcmp(auth_type, "blake2s") == 0) {
key->type = AUTH_TYPE_BLAKE2S;
} else {
key->type = 0;
free(auth_type);
goto error;
}
free(auth_type);
} else if(strcmp(token, "value") == 0) {
c = gethex(c, &key->value, &key->len, gnc, closure);
if(c < -1 || key->value == NULL)
goto error;
} else {
goto error;
}
free(token);
}
*key_return = key;
return c;

error:
free(token);
free(key);
return -2;
}

static void
add_filter(struct filter *filter, struct filter **filters)
{
Expand Down Expand Up @@ -738,6 +838,7 @@ merge_ifconf(struct interface_conf *dest,
MERGE(rtt_min);
MERGE(rtt_max);
MERGE(max_rtt_penalty);
MERGE(key);

#undef MERGE
}
Expand Down Expand Up @@ -1093,6 +1194,32 @@ parse_config_line(int c, gnc_t gnc, void *closure,
if(c < -1 || !action_return)
goto fail;
reopen_logfile();
} else if(strcmp(token, "key") == 0) {
struct key *key = NULL;
c = parse_key(c, gnc, closure, &key);
if(c < -1)
goto fail;
if(key->id == NULL)
goto fail;
switch(key->type) {
case AUTH_TYPE_SHA256:
if(key->len != 32) {
free(key);
goto fail;
}
break;
case AUTH_TYPE_BLAKE2S:
if(key->len != 16) {
free(key);
goto fail;
}
break;
default:
free(key);
goto fail;
}
add_key(key->id, key->type, key->len, key->value);
free(key);
} else {
c = parse_option(c, gnc, closure, token);
if(c < -1)
Expand Down
4 changes: 4 additions & 0 deletions configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ THE SOFTWARE.
#define CONFIG_ACTION_UNMONITOR 4
#define CONFIG_ACTION_NO 5

#define AUTH_TYPE_NONE 0
#define AUTH_TYPE_SHA256 1
#define AUTH_TYPE_BLAKE2S 2

struct filter_result {
unsigned int add_metric; /* allow = 0, deny = INF, metric = <0..INF> */
unsigned char *src_prefix;
Expand Down
Loading

0 comments on commit 739f76a

Please sign in to comment.