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

components/coap/Makefile.projbuild:

Update the compiler options with -DESPIDF_VERSION

components/coap/libcoap:

Update the version to include the correct version of tinydtls submodule

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

New port files for DTLS

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

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

See Issue espressif#1379
  • Loading branch information
mrdeep1 committed Mar 27, 2019
1 parent e2ed49c commit 1405c8d
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 41 deletions.
21 changes: 17 additions & 4 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"
"port/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"
"libcoap/ext/tinydtls/aes/rijndael.c"
"libcoap/ext/tinydtls/ecc/ecc.c"
"libcoap/ext/tinydtls/sha2/sha2.c")

set(COMPONENT_REQUIRES lwip)

Expand All @@ -27,5 +40,5 @@ register_component()
# Needed for coap headers in public builds, also.
#
# TODO: find a way to move this to a port header
target_compile_definitions(${COMPONENT_TARGET} PUBLIC WITH_POSIX)
target_compile_definitions(${COMPONENT_TARGET} PUBLIC WITH_POSIX ESPIDF_VERSION)

2 changes: 1 addition & 1 deletion components/coap/Makefile.projbuild
Original file line number Diff line number Diff line change
@@ -1 +1 @@
CPPFLAGS += -DWITH_POSIX
CPPFLAGS += -DWITH_POSIX -DESPIDF_VERSION
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 port/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 \
libcoap/ext/tinydtls/aes/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

42 changes: 42 additions & 0 deletions components/coap/port/dtls_prng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
*
* Copyright (c) 2011-2019 Olaf Bergmann (TZI) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
*
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Olaf Bergmann - initial API and implementation
* Hauke Mehrtens - memory optimization, ECC integration
* Achim Kraus - session recovery
* Sachin Agrawal - rehandshake support
* Jon Shallow - platform dependent prng support
*
*******************************************************************************/

#include "tinydtls.h"
#include "dtls_prng.h"
#include <esp_system.h>

#include <stdlib.h>

/**
* Fills \p buf with \p len random bytes. This is the default
* implementation for prng(). You might want to change prng() to use
* a better PRNG on your specific platform.
*/
int
dtls_prng(unsigned char *buf, size_t len) {
esp_fill_random(buf, len);
return 1;
}

void
dtls_prng_init(unsigned seed) {
return;
}

153 changes: 153 additions & 0 deletions components/coap/port/include/coap/dtls_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/* 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 rijndaelEncrypt rijndaelEncrypt_dtls
#define rijndaelKeySetupEnc rijndaelKeySetupEnc_dtls
1 change: 1 addition & 0 deletions components/coap/port/include/coap_config_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define PACKAGE_VERSION "?"

#define COAP_BAD_RECVMSG
#define HAVE_LIBTINYDTLS

#endif /* WITH_POSIX */
#endif /* COAP_CONFIG_POSIX_H_ */
22 changes: 16 additions & 6 deletions examples/protocols/coap_client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@
# CoAP client example

(See the README.md file in the upper level 'examples' directory for more information about examples.)
this CoAP client example is adaptation of one of the [libcoap](https://github.com/obgm/libcoap) example.
This CoAP client example is very simplified adaptation of one of the
[libcoap](https://github.com/obgm/libcoap) examples.

CoAP client example would connect your ESP32 device to any CoAP server, fetch data from CoAP server and upstream data to CoAP server.
CoAP client example will connect your ESP32 device to a CoAP server, send off a GET request and
fetch the response data from CoAP server. The client can be extended to PUT / POST / DELETE requests,
as well as supporting the Observer extensions [RFC7641](https://tools.ietf.org/html/rfc7641).

The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with constrained nodes and constrained networks in the Internet of Things.
The protocol is designed for machine-to-machine (M2M) applications such as smart energy and building automation.
If the URI is prefixed with coaps:// instead of coap://, then the CoAP client will attempt to use
the DTLS protocol using the defined Preshared Keys which the CoAP server needs to know about.

please refer to [RFC7252](https://www.rfc-editor.org/rfc/pdfrfc/rfc7252.txt.pdf) for more details.
The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with
constrained nodes and constrained networks in the Internet of Things.
The protocol is designed for machine-to-machine (M2M) applications such as smart energy and
building automation.

Please refer to [RFC7252](https://www.rfc-editor.org/rfc/pdfrfc/rfc7252.txt.pdf) for more details.

## How to use example

Expand All @@ -23,6 +31,8 @@ make menuconfig
* Set Target Uri under Example Configuration
* Set WiFi SSID under Example Configuration
* Set WiFi Password under Example Configuration
* Set Preshared Key to use in connection to the server
* Set PSK Client identity (username)

### Build and Flash

Expand Down Expand Up @@ -77,4 +87,4 @@ with `coap://` or `coap+tcp://` for a coap server that supports TCP
(not all do including coap+tcp://californium.eclipse.org).

* libcoap logging can be increased by changing `#define COAP_LOGGING_LEVEL 0`
to `#define COAP_LOGGING_LEVEL 9`
to `#define COAP_LOGGING_LEVEL 7`
19 changes: 17 additions & 2 deletions examples/protocols/coap_client/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ menu "Example Configuration"
string "Target Uri"
default "coap://californium.eclipse.org"
help
Target uri for the example to use.
Target uri for the example to use. Use coaps:// prefix for encrypted traffic using the PSK.

config WIFI_SSID
string "WiFi SSID"
Expand All @@ -18,4 +18,19 @@ menu "Example Configuration"
help
WiFi password (WPA or WPA2) for the example to use.

endmenu
config COAP_PSK_KEY
string "Preshared Key (PSK) to used in the connection to the CoAP server"
default "secret-key"
help
The Preshared Key to use to encrypt the communicatons. The same key must be
used at both ends of the CoAP connection, and the CoaP client must request
an URI prefixed with coaps:// instead of coap:// for DTLS to be used.

config COAP_PSK_IDENTITY
string "PSK Client identity (username)"
default "coap-client"
help
The identity (or username) to use to identify to the CoAP server which
PSK key to use.

endmenu
Loading

0 comments on commit 1405c8d

Please sign in to comment.