Skip to content

Commit

Permalink
fixes for native Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
obgm committed Apr 19, 2012
1 parent 456c781 commit 6ee475e
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 82 deletions.
4 changes: 2 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ top_builddir = @top_builddir@
package = @PACKAGE_TARNAME@-@PACKAGE_VERSION@

# files and flags
SOURCES:= dsrv.c peer.c netq.c dtls.c crypto.c ccm.c hmac.c debug.c
SOURCES:= dtls.c crypto.c ccm.c hmac.c debug.c
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) aes/rijndael.o @OPT_OBJS@
HEADERS:=dsrv.h dtls.h hmac.h peer.h netq.h debug.h config.h uthash.h numeric.h crypto.h global.h ccm.h
HEADERS:=dtls.h hmac.h debug.h config.h uthash.h numeric.h crypto.h global.h ccm.h
CFLAGS:=-Wall -pedantic -std=c99 @CFLAGS@
CPPFLAGS:=@CPPFLAGS@ -DDTLS_CHECK_CONTENTTYPE
SUBDIRS:=tests doc md5 sha1 sha2 aes
Expand Down
6 changes: 3 additions & 3 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD

/* Define if you do not want intermix cleartext with DTLS */
#undef DSRV_NO_PROTOCOL_DEMUX

/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H

Expand Down Expand Up @@ -76,6 +73,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

Expand Down
8 changes: 3 additions & 5 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,13 @@ AC_ARG_WITH(debug,
[CPPFLAGS="${CPPFLAGS} -DNDEBUG"],
[])

AC_ARG_WITH(sha256,
[AS_HELP_STRING([--without-sha256],[disable use of SHA256])],
[],
[CPPFLAGS="${CPPFLAGS} -DWITH_SHA256" OPT_OBJS="${OPT_OBJS} sha2/sha2.o"])
CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256"
OPT_OBJS="${OPT_OBJS} sha2/sha2.o"

AC_SUBST(OPT_OBJS)

# Checks for header files.
AC_CHECK_HEADERS([assert.h arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h])
AC_CHECK_HEADERS([assert.h arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h time.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
Expand Down
1 change: 1 addition & 0 deletions crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct {
} aes128_ccm_t;

#ifndef WITH_CONTIKI
#include <stdlib.h>

static inline dtls_cipher_context_t *
dtls_cipher_context_new() {
Expand Down
7 changes: 5 additions & 2 deletions debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* SOFTWARE.
*/

#include "config.h"

#if defined(HAVE_ASSERT_H) && !defined(assert)
#include <assert.h>
#endif
Expand Down Expand Up @@ -92,13 +94,14 @@ print_timestamp(char *s, size_t len, clock_time_t t) {
void
dsrv_log(log_t level, char *format, ...) {
static char timebuf[32];
struct tm *tmp;
time_t now;
va_list ap;
FILE *log_fd;

if (maxlog < level)
return;

log_fd = level <= LOG_CRIT ? stderr : stdout;

if (print_timestamp(timebuf,sizeof(timebuf), time(NULL)))
fprintf(log_fd, "%s ", timebuf);

Expand Down
122 changes: 94 additions & 28 deletions dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,27 @@
* SOFTWARE.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_ASSERT_H
#include <assert.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#define clock_time() (time(NULL))
#endif
#ifndef WITH_CONTIKI
#include <stdlib.h>
#include "uthash.h"
#endif /* WITH_CONTIKI */

#include "debug.h"
#include "numeric.h"
#include "dtls.h"

#ifdef WITH_MD5
# include "md5/md5.h"
#endif

#ifdef WITH_SHA1
# include "sha1/sha.h"
#endif

#if defined(WITH_SHA256) || defined(WITH_SHA384) || defined(WITH_SHA512)
#ifdef WITH_SHA256
# include "sha2/sha2.h"
#endif

Expand All @@ -55,6 +57,15 @@
#define dtls_get_sequence_number(H) dtls_uint48_to_ulong(&(H)->sequence_number)
#define dtls_get_fragment_length(H) dtls_uint24_to_int(&(H)->fragment_length)

#ifndef WITH_CONTIKI
#define HASH_FIND_PEER(head,sess,out) \
HASH_FIND(hh,head,sess,sizeof(session_t),out)
#define HASH_ADD_PEER(head,sess,add) \
HASH_ADD(hh,head,sess,sizeof(session_t),add)
#define HASH_DEL_PEER(head,delptr) \
HASH_DELETE(hh,head,delptr)
#endif /* WITH_CONTIKI */

#define DTLS_RH_LENGTH sizeof(dtls_record_header_t)
#define DTLS_HS_LENGTH sizeof(dtls_handshake_header_t)
#define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */
Expand Down Expand Up @@ -113,12 +124,37 @@ extern void crypto_init();

dtls_context_t the_dtls_context;

#ifndef WITH_CONTIKI
static inline dtls_peer_t *
dtls_malloc_peer() {
return (dtls_peer_t *)malloc(sizeof(dtls_peer_t));
}

static inline void
dtls_free_peer(dtls_peer_t *peer) {
free(peer);
}
#else /* WITH_CONTIKI */
#include "memb.h"
MEMB(peer_storage, dtls_peer_t, DTLS_PEER_MAX);

static inline dtls_peer_t *
dtls_malloc_peer() {
return memb_alloc(&peer_storage);
}
static inline void
dtls_free_peer(dtls_peer_t *peer) {
memb_free(&peer_storage, peer);
}
#endif /* WITH_CONTIKI */

void
dtls_init() {
memb_init(&peer_storage);
crypto_init();

#ifdef WITH_CONTIKI
memb_init(&peer_storage);
#endif /* WITH_CONTIKI */
}

/* Calls cb_write() with given arguments if defined, otherwise an
Expand Down Expand Up @@ -149,13 +185,17 @@ int dtls_send(dtls_context_t *ctx, dtls_peer_t *peer, unsigned char type,

dtls_peer_t *
dtls_get_peer(struct dtls_context_t *ctx, session_t *session) {
dtls_peer_t *p;
dtls_peer_t *p = NULL;

#ifndef WITH_CONTIKI
HASH_FIND_PEER(ctx->peers, session, p);
#else /* WITH_CONTIKI */
for (p = list_head(ctx->peers); p; p = list_item_next(p))
if (dtls_session_equals(&p->session, session))
return p;
#endif /* WITH_CONTIKI */

return NULL;
return p;
}

int
Expand Down Expand Up @@ -641,7 +681,6 @@ static int
check_ccs(dtls_context_t *ctx,
dtls_peer_t *peer,
uint8 *record, uint8 *data, size_t data_length) {
size_t pre_master_len = 0;

if (DTLS_RECORD_HEADER(record)->content_type != DTLS_CT_CHANGE_CIPHER_SPEC
|| data_length < 1 || data[0] != 1)
Expand Down Expand Up @@ -686,14 +725,12 @@ check_ccs(dtls_context_t *ctx,
return 1;
}


dtls_peer_t *
dtls_new_peer(dtls_context_t *ctx,
session_t *session) {
dtls_peer_t *peer;

/* FIXME: use malloc on native Linux/Unix */
peer = memb_alloc(&peer_storage);
peer = dtls_malloc_peer();
if (peer) {
memset(peer, 0, sizeof(dtls_peer_t));
memcpy(&peer->session, session, sizeof(session_t));
Expand Down Expand Up @@ -733,11 +770,6 @@ clear_hs_hash(dtls_peer_t *peer) {
dtls_hash_init(peer->hs_hash);
}

/** Releases the storage occupied by peer. */
void
dtls_free_peer(dtls_peer_t *peer) {
}

/**
*Checks if \p record + \p data contain a Finished message with valid
* verify_data.
Expand Down Expand Up @@ -1267,8 +1299,6 @@ static int
check_server_hellodone(dtls_context_t *ctx,
dtls_peer_t *peer,
uint8 *data, size_t data_length) {
unsigned char pre_master_secret[DTLS_MASTER_SECRET_LENGTH];
size_t pre_master_len = 0;

/* calculate master key, send CCS */
if (!IS_SERVERHELLODONE(data, data_length))
Expand Down Expand Up @@ -1710,11 +1740,15 @@ dtls_handle_message(dtls_context_t *ctx,
size_t data_length; /* length of decrypted payload
(without MAC and padding) */

/* check if we have DTLS state for raddr/ifindex */
/* check if we have DTLS state for addr/port/ifindex */
#ifndef WITH_CONTIKI
HASH_FIND_PEER(ctx->peers, session, peer);
#else /* WITH_CONTIKI */
for (peer = list_head(ctx->peers);
peer && !dtls_session_equals(&peer->session, session);
peer = list_item_next(peer))
;
#endif /* WITH_CONTIKI */

if (!peer) {

Expand Down Expand Up @@ -1782,7 +1816,11 @@ dtls_handle_message(dtls_context_t *ctx,
return -1;
}

#ifndef WITH_CONTIKI
HASH_ADD_PEER(ctx->peers, session, peer);
#else /* WITH_CONTIKI */
list_add(ctx->peers, peer);
#endif /* WITH_CONTIKI */

/* update finish MAC */
update_hs_hash(peer, msg + DTLS_RH_LENGTH, rlen - DTLS_RH_LENGTH);
Expand Down Expand Up @@ -1841,7 +1879,11 @@ dtls_handle_message(dtls_context_t *ctx,
if (handle_alert(ctx, peer, msg, data, data_length)) {

/* invalidate peer */
#ifndef WITH_CONTIKI
HASH_DEL_PEER(ctx->peers, peer);
#else /* WITH_CONTIKI */
list_remove(ctx->peers, peer);
#endif /* WITH_CONTIKI */

dtls_free_peer(peer);

Expand Down Expand Up @@ -1882,9 +1924,11 @@ dtls_new_context(void *app_data) {
memset(c, 0, sizeof(dtls_context_t));
c->app = app_data;

#ifdef WITH_CONTIKI
LIST_STRUCT_INIT(c, peers);
/* LIST_STRUCT_INIT(c, key_store); */

#endif /* WITH_CONTIKI */

if (prng(c->cookie_secret, DTLS_COOKIE_SECRET_LENGTH))
c->cookie_secret_age = clock_time();
else
Expand Down Expand Up @@ -1927,13 +1971,24 @@ dtls_remove_psk(dtls_context_t *ctx,

void dtls_free_context(dtls_context_t *ctx) {
dtls_peer_t *p;
int i;

#ifndef WITH_CONTIKI
dtls_peer_t *tmp;

if (ctx->peers) {
HASH_ITER(hh, ctx->peers, p, tmp) {
dtls_free_peer(p);
}
}
#else /* WITH_CONTIKI */
int i;

p = (dtls_peer_t *)peer_storage.mem;
for (i = 0; i < peer_storage.num; ++i, ++p) {
if (peer_storage.count[i])
dtls_free_peer(p);
}
#endif /* WITH_CONTIKI */

dtls_remove_psk(ctx, ctx->psk_id, ctx->psk_id_length);
}
Expand All @@ -1945,9 +2000,16 @@ dtls_connect(dtls_context_t *ctx, session_t *dst) {
size_t size;
int res;

/* check if we have DTLS state for raddr/ifindex */
/* check if we have DTLS state for addr/port/ifindex */
#ifndef WITH_CONTIKI
HASH_FIND_PEER(ctx->peers, dst, peer);
#else /* WITH_CONTIKI */
for (peer = list_head(ctx->peers); peer; peer = list_item_next(peer))
if (dtls_session_equals(&peer->session, dst)) {
if (dtls_session_equals(&peer->session, dst))
break;
#endif /* WITH_CONTIKI */

if (peer) {
debug("found peer, try to re-connect\n");
/* FIXME: send HelloRequest if we are server,
ClientHello with good cookie if client */
Expand All @@ -1960,7 +2022,11 @@ dtls_connect(dtls_context_t *ctx, session_t *dst) {
OTHER_CONFIG(peer)->role = DTLS_SERVER;
CURRENT_CONFIG(peer)->role = DTLS_SERVER;

#ifndef WITH_CONTIKI
HASH_ADD_PEER(ctx->peers, session, peer);
#else /* WITH_CONTIKI */
list_add(ctx->peers, peer);
#endif /* WITH_CONTIKI */

/* send ClientHello with some Cookie */

Expand Down
14 changes: 14 additions & 0 deletions dtls.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@

#include <stdint.h>

#ifndef WITH_CONTIKI
#include "uthash.h"
#else /* WITH_CONTIKI */
#include "list.h"
#endif /* WITH_CONTIKI */

#include "crypto.h"
#include "hmac.h"

#include "config.h"
#include "global.h"
#ifndef DTLSv12
#define DTLS_VERSION 0xfeff /* DTLS v1.1 */
#else
Expand All @@ -64,7 +70,11 @@ typedef enum {
* Holds security parameters, local state and the transport address
* for each peer. */
typedef struct dtls_peer_t {
#ifndef WITH_CONTIKI
UT_hash_handle hh;
#else /* WITH_CONTIKI */
struct dtls_peer_t *next;
#endif /* WITH_CONTIKI */

session_t session; /**< peer address and local interface */

Expand Down Expand Up @@ -109,7 +119,11 @@ typedef struct dtls_context_t {
unsigned char cookie_secret[DTLS_COOKIE_SECRET_LENGTH];
clock_time_t cookie_secret_age; /**< the time the secret has been generated */

#ifndef WITH_CONTIKI
dtls_peer_t *peers; /**< peer hash map */
#else /* WITH_CONTIKI */
LIST_STRUCT(peers);
#endif /* WITH_CONTIKI */

void *app; /**< application-specific data */
int (*cb_write)(struct dtls_context_t *ctx,
Expand Down
Loading

0 comments on commit 6ee475e

Please sign in to comment.