Skip to content

Commit

Permalink
Add DTLS support to libcoap using TinyDTLS
Browse files Browse the repository at this point in the history
As TinyDTLS is already a submodule to libcoap, adding in DTLS support is
straightforward, but only supports PSK at this point in time.

components/coap/CMakeLists.txt:
components/coap/component.mk:

Add in the new files that have to be built
Replace libcoap/src/coap_notls.c with libcoap/src/coap_tinydtls.c

components/coap/libcoap:

Update the version to include the correct version of tinydtls submodule

components/coap/port/include/coap/dtls_config.h:

New port file for DTLS

components/coap/port/include/coap_config_posix.h:
components/coap/port/rijndael.c

Include building with TinyDTLS

examples/protocols/coap_client/README.md:
examples/protocols/coap_client/main/Kconfig.projbuild:
examples/protocols/coap_client/main/coap_client_example_main.c:

Update CoAP client to support DTLS

examples/protocols/coap_server/README.md:
examples/protocols/coap_server/main/Kconfig.projbuild:
examples/protocols/coap_server/main/coap_server_example_main.c:

Update CoAP server to support DTLS
Change "no data" to "Hello World!" to prevent confusion

See Issue espressif#1379
  • Loading branch information
mrdeep1 committed Apr 16, 2019
1 parent 70eda3d commit 517340d
Show file tree
Hide file tree
Showing 12 changed files with 468 additions and 46 deletions.
19 changes: 16 additions & 3 deletions components/coap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(COMPONENT_ADD_INCLUDEDIRS port/include port/include/coap libcoap/include libcoap/include/coap2)
set(COMPONENT_ADD_INCLUDEDIRS port/include port/include/coap libcoap/include libcoap/include/coap2 libcoap/ext/tinydtls libcoap/ext/tinydtls/aes)

set(COMPONENT_SRCS "libcoap/src/address.c"
"libcoap/src/async.c"
Expand All @@ -17,8 +17,21 @@ set(COMPONENT_SRCS "libcoap/src/address.c"
"libcoap/src/str.c"
"libcoap/src/subscribe.c"
"libcoap/src/uri.c"
"libcoap/src/coap_notls.c"
"port/coap_io.c")
"libcoap/src/coap_tinydtls.c"
"port/coap_io.c"
"libcoap/ext/tinydtls/ccm.c"
"libcoap/ext/tinydtls/crypto.c"
"libcoap/ext/tinydtls/dtls.c"
"libcoap/ext/tinydtls/dtls_debug.c"
"libcoap/ext/tinydtls/dtls_prng.c"
"libcoap/ext/tinydtls/dtls_time.c"
"libcoap/ext/tinydtls/hmac.c"
"libcoap/ext/tinydtls/netq.c"
"libcoap/ext/tinydtls/peer.c"
"libcoap/ext/tinydtls/session.c"
"port/rijndael.c"
"libcoap/ext/tinydtls/ecc/ecc.c"
"libcoap/ext/tinydtls/sha2/sha2.c")

set(COMPONENT_REQUIRES lwip)

Expand Down
8 changes: 5 additions & 3 deletions components/coap/component.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
# Component Makefile
#

COMPONENT_ADD_INCLUDEDIRS := port/include port/include/coap libcoap/include libcoap/include/coap2
COMPONENT_ADD_INCLUDEDIRS := port/include port/include/coap libcoap/include libcoap/include/coap2 libcoap/ext/tinydtls libcoap/ext/tinydtls/aes

COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_session.o libcoap/src/coap_time.o libcoap/src/coap_debug.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o libcoap/src/coap_notls.o port/coap_io.o
COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_session.o libcoap/src/coap_time.o libcoap/src/coap_debug.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o libcoap/src/coap_tinydtls.o port/coap_io.o \
libcoap/ext/tinydtls/ccm.o libcoap/ext/tinydtls/crypto.o libcoap/ext/tinydtls/dtls.o libcoap/ext/tinydtls/dtls_debug.o libcoap/ext/tinydtls/dtls_prng.o libcoap/ext/tinydtls/dtls_time.o libcoap/ext/tinydtls/hmac.o libcoap/ext/tinydtls/netq.o libcoap/ext/tinydtls/peer.o libcoap/ext/tinydtls/session.o \
port/rijndael.o libcoap/ext/tinydtls/ecc/ecc.o libcoap/ext/tinydtls/sha2/sha2.o

COMPONENT_SRCDIRS := libcoap/src libcoap port
COMPONENT_SRCDIRS := libcoap/ext/tinydtls/aes libcoap/ext/tinydtls/ecc libcoap/ext/tinydtls/sha2 libcoap/ext/tinydtls libcoap/src libcoap port

COMPONENT_SUBMODULES += libcoap

Expand Down
50 changes: 48 additions & 2 deletions components/coap/port/coap_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "pdu.h"
#include "utlist.h"
#include "resource.h"
#include "coap_mutex.h"

#if !defined(WITH_CONTIKI)
/* define generic PKTINFO for IPv4 */
Expand Down Expand Up @@ -971,6 +972,7 @@ coap_network_read(coap_socket_t *sock, coap_packet_t *packet) {
#ifndef COAP_BAD_RECVMSG
/* a buffer large enough to hold all packet info types, ipv6 is the largest */
char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
struct cmsghdr *cmsg;
struct msghdr mhdr;
struct iovec iov[1];

Expand All @@ -987,6 +989,12 @@ coap_network_read(coap_socket_t *sock, coap_packet_t *packet) {

mhdr.msg_control = buf;
mhdr.msg_controllen = sizeof(buf);
/* set a big first length incase recvmsg() does not implement updating
msg_control as well as preset the first cmsg with bad data */
cmsg = (struct cmsghdr *)buf;
cmsg->cmsg_len = CMSG_LEN(sizeof(buf));
cmsg->cmsg_level = -1;
cmsg->cmsg_type = -1;

#if defined(_WIN32)
if (!lpWSARecvMsg) {
Expand Down Expand Up @@ -1023,6 +1031,7 @@ coap_network_read(coap_socket_t *sock, coap_packet_t *packet) {
} else {
#ifndef COAP_BAD_RECVMSG
struct cmsghdr *cmsg;
int dst_found = 0;

packet->src.size = mhdr.msg_namelen;
packet->length = (size_t)len;
Expand All @@ -1040,6 +1049,7 @@ coap_network_read(coap_socket_t *sock, coap_packet_t *packet) {
u.c = CMSG_DATA(cmsg);
packet->ifindex = (int)(u.p->ipi6_ifindex);
memcpy(&packet->dst.addr.sin6.sin6_addr, &u.p->ipi6_addr, sizeof(struct in6_addr));
dst_found = 1;
break;
}

Expand All @@ -1060,15 +1070,34 @@ coap_network_read(coap_socket_t *sock, coap_packet_t *packet) {
} else {
memcpy(&packet->dst.addr.sin.sin_addr, &u.p->ipi_addr, sizeof(struct in_addr));
}
dst_found = 1;
break;
}
#elif defined(IP_RECVDSTADDR)
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
packet->ifindex = 0;
packet->ifindex = sock->fd;
memcpy(&packet->dst.addr.sin.sin_addr, CMSG_DATA(cmsg), sizeof(struct in_addr));
dst_found = 1;
break;
}
#endif /* IP_PKTINFO */
if (!dst_found) {
/* cmsg_level / cmsg_type combination we do not understand
(ignore preset case for bad recvmsg() not updating cmsg) */
if (cmsg->cmsg_level != -1 && cmsg->cmsg_type != -1) {
coap_log(LOG_DEBUG,
"cmsg_level = %d and cmsg_type = %d not supported - fix\n",
cmsg->cmsg_level, cmsg->cmsg_type);
}
}
}
if (!dst_found) {
/* Not expected, but cmsg_level and cmsg_type don't match above and
may need a new case */
packet->ifindex = sock->fd;
if (getsockname(sock->fd, &packet->dst.addr.sa, &packet->dst.size) < 0) {
coap_log(LOG_DEBUG, "Cannot determine local port\n");
}
}
#else /* COAP_BAD_RECVMSG */
packet->length = (size_t)len;
Expand Down Expand Up @@ -1304,14 +1333,24 @@ coap_write(coap_context_t *ctx,

int
coap_run_once(coap_context_t *ctx, unsigned timeout_ms) {
#if COAP_CONSTRAINED_STACK
static coap_mutex_t static_mutex = COAP_MUTEX_INITIALIZER;
static fd_set readfds, writefds, exceptfds;
static coap_socket_t *sockets[64];
#else /* ! COAP_CONSTRAINED_STACK */
fd_set readfds, writefds, exceptfds;
coap_socket_t *sockets[64];
#endif /* ! COAP_CONSTRAINED_STACK */
coap_fd_t nfds = 0;
struct timeval tv;
coap_tick_t before, now;
int result;
coap_socket_t *sockets[64];
unsigned int num_sockets = 0, i, timeout;

#if COAP_CONSTRAINED_STACK
coap_mutex_lock(&static_mutex);
#endif /* COAP_CONSTRAINED_STACK */

coap_ticks(&before);

timeout = coap_write(ctx, sockets, (unsigned int)(sizeof(sockets) / sizeof(sockets[0])), &num_sockets, before);
Expand Down Expand Up @@ -1350,6 +1389,9 @@ coap_run_once(coap_context_t *ctx, unsigned timeout_ms) {
if (errno != EINTR) {
#endif
coap_log(LOG_DEBUG, "%s", coap_socket_strerror());
#if COAP_CONSTRAINED_STACK
coap_mutex_unlock(&static_mutex);
#endif /* COAP_CONSTRAINED_STACK */
return -1;
}
}
Expand All @@ -1370,6 +1412,10 @@ coap_run_once(coap_context_t *ctx, unsigned timeout_ms) {
coap_ticks(&now);
coap_read(ctx, now);

#if COAP_CONSTRAINED_STACK
coap_mutex_unlock(&static_mutex);
#endif /* COAP_CONSTRAINED_STACK */

return (int)(((now - before) * 1000) / COAP_TICKS_PER_SECOND);
}

Expand Down
156 changes: 156 additions & 0 deletions components/coap/port/include/coap/dtls_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/* dtls_config.h. Generated from dtls_config.h.in by configure. */
/* dtls_config.h.in. Generated from configure.ac by autoheader. */

/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */

/* Define to 1 if building with ECC support. */
#define DTLS_ECC 1

/* Define to 1 if building with PSK support */
#define DTLS_PSK 1

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

/* Define to 1 if you have the <assert.h> header file. */
#ifndef HAVE_ASSERT_H
#define HAVE_ASSERT_H 1
#endif

/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1

/* Define to 1 if you have the `fls' function. */
/* #undef HAVE_FLS */

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1

/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1

/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1

/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1

/* Define to 1 if struct sockaddr_in6 has a member sin6_len. */
/* #undef HAVE_SOCKADDR_IN6_SIN6_LEN */

/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1

/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1

/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1

/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1

/* Define to 1 if you have the <sys/socket.h> header file. */
#ifndef HAVE_SYS_SOCKET_H
#define HAVE_SYS_SOCKET_H 1
#endif

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

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

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

/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Define to the full name of this package. */
#define PACKAGE_NAME "tinydtls"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "tinydtls 0.8.6"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "tinydtls"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "0.8.6"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif

/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

#define WITH_SHA256
#define SHA2_USE_INTTYPES_H
#define DTLSv12
#define DTLS_CHECK_CONTENTTYPE
#define DTLS_CONSTRAINED_STACK 1
#define ESPIDF_VERSION
#define DTLS_EXT_RIJNDAEL

#define rijndaelEncrypt rijndaelEncrypt_dtls
#define rijndaelKeySetupEnc rijndaelKeySetupEnc_dtls
7 changes: 7 additions & 0 deletions components/coap/port/include/coap_config_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifdef WITH_POSIX

#include <sys/socket.h>
#include <net/if.h>

#define HAVE_SYS_SOCKET_H
#define HAVE_MALLOC
Expand All @@ -34,6 +35,12 @@
#define PACKAGE_VERSION "?"

#define COAP_BAD_RECVMSG
#define HAVE_LIBTINYDTLS
#define COAP_CONSTRAINED_STACK 1
#define ESPIDF_VERSION
#define DTLS_EXT_RIJNDAEL

#define gai_strerror(x) "gai_strerror() not supported"

#endif /* WITH_POSIX */
#endif /* COAP_CONFIG_POSIX_H_ */
Loading

0 comments on commit 517340d

Please sign in to comment.