-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
642 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# name of your application | ||
APPLICATION = gnrc_networking | ||
|
||
# If no BOARD is found in the environment, use this default: | ||
BOARD ?= native | ||
|
||
# This has to be the absolute path to the RIOT base directory: | ||
RIOTBASE ?= $(CURDIR)/../.. | ||
|
||
BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \ | ||
nrf6310 nucleo-f334 pca10000 pca10005 spark-core \ | ||
stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \ | ||
yunjia-nrf51822 z1 | ||
|
||
# Include packages that pull up and auto-init the link layer. | ||
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present | ||
USEMODULE += gnrc_netif_default | ||
USEMODULE += auto_init_gnrc_netif | ||
# Specify the mandatory networking modules for IPv6 and UDP | ||
USEMODULE += gnrc_ipv6_router_default | ||
USEMODULE += gnrc_conn_udp | ||
USEMODULE += posix_sockets | ||
# Add a routing protocol | ||
# This application dumps received packets to STDIO using the pktdump module | ||
USEMODULE += gnrc_pktdump | ||
# Additional networking modules that can be dropped if not needed | ||
USEMODULE += gnrc_icmpv6_echo | ||
# Add also the shell, some shell commands | ||
USEMODULE += shell | ||
USEMODULE += shell_commands | ||
USEMODULE += ps | ||
USEPKG += tinydtls | ||
|
||
# Comment this out to disable code in RIOT that does safety checking | ||
# which is not needed in a production environment but helps in the | ||
# development process: | ||
CFLAGS += -DDEVELHELP -DWITH_SHA256 | ||
|
||
# Change this to 0 show compiler invocation lines by default: | ||
QUIET ?= 1 | ||
|
||
include $(RIOTBASE)/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
#include "tinydtls.h" | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <unistd.h> | ||
#include <ctype.h> | ||
#include <netinet/in.h> | ||
#include <sys/types.h> | ||
#include <sys/socket.h> | ||
#include <sys/time.h> | ||
#include <arpa/inet.h> | ||
#include <signal.h> | ||
|
||
#include "thread.h" | ||
#include "assert.h" | ||
#include "byteorder.h" | ||
#include "global.h" | ||
#include "tinydtls_debug.h" | ||
#include "dtls.h" | ||
#include "riot_tinydtls.h" | ||
|
||
#include "dtls_app.h" | ||
|
||
#define DEFAULT_PORT 20220 | ||
|
||
#define PSK_DEFAULT_IDENTITY "Client_identity" | ||
#define PSK_DEFAULT_KEY "secretPSK" | ||
#define PSK_OPTIONS "i:k:" | ||
|
||
char client_reader[THREAD_STACKSIZE_DEFAULT]; | ||
|
||
typedef struct { | ||
size_t length; /* length of string */ | ||
unsigned char *s; /* string data */ | ||
} dtls_str; | ||
|
||
static dtls_context_t *dtls_context = NULL; | ||
static session_t dst; | ||
|
||
|
||
static const unsigned char ecdsa_priv_key[] = { | ||
0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, | ||
0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, | ||
0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, | ||
0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA | ||
}; | ||
|
||
static const unsigned char ecdsa_pub_key_x[] = { | ||
0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, | ||
0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, | ||
0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, | ||
0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52 | ||
}; | ||
|
||
static const unsigned char ecdsa_pub_key_y[] = { | ||
0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, | ||
0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, | ||
0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, | ||
0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29 | ||
}; | ||
|
||
#ifdef DTLS_PSK | ||
/* The PSK information for DTLS */ | ||
#define PSK_ID_MAXLEN 256 | ||
#define PSK_MAXLEN 256 | ||
static unsigned char psk_id[PSK_ID_MAXLEN]; | ||
static size_t psk_id_length = 0; | ||
static unsigned char psk_key[PSK_MAXLEN]; | ||
static size_t psk_key_length = 0; | ||
|
||
/* This function is the "key store" for tinyDTLS. It is called to | ||
* retrieve a key for the given identity within this particular | ||
* session. */ | ||
static int get_psk_info(struct dtls_context_t *ctx, const session_t *session, | ||
dtls_credentials_type_t type, const unsigned char *id, | ||
size_t id_len, unsigned char *result, size_t result_length) | ||
{ | ||
(void) ctx; | ||
(void) session; | ||
|
||
switch (type) { | ||
case DTLS_PSK_IDENTITY: | ||
if (id_len) { | ||
dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id); | ||
} | ||
|
||
if (result_length < psk_id_length) { | ||
dtls_warn("cannot set psk_identity -- buffer too small\n"); | ||
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); | ||
} | ||
|
||
memcpy(result, psk_id, psk_id_length); | ||
return psk_id_length; | ||
case DTLS_PSK_KEY: | ||
if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { | ||
dtls_warn("PSK for unknown id requested, exiting\n"); | ||
return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); | ||
} | ||
else if (result_length < psk_key_length) { | ||
dtls_warn("cannot set psk -- buffer too small\n"); | ||
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); | ||
} | ||
|
||
memcpy(result, psk_key, psk_key_length); | ||
return psk_key_length; | ||
default: | ||
dtls_warn("unsupported request type: %d\n", type); | ||
} | ||
|
||
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); | ||
} | ||
#endif /* DTLS_PSK */ | ||
|
||
#ifdef DTLS_ECC | ||
static int get_ecdsa_key(struct dtls_context_t *ctx, const session_t *session, | ||
const dtls_ecdsa_key_t **result) | ||
{ | ||
(void) ctx; | ||
(void) session; | ||
static const dtls_ecdsa_key_t ecdsa_key = { | ||
.curve = DTLS_ECDH_CURVE_SECP256R1, | ||
.priv_key = ecdsa_priv_key, | ||
.pub_key_x = ecdsa_pub_key_x, | ||
.pub_key_y = ecdsa_pub_key_y | ||
}; | ||
|
||
*result = &ecdsa_key; | ||
return 0; | ||
} | ||
|
||
static int verify_ecdsa_key(struct dtls_context_t *ctx, | ||
const session_t *session, | ||
const unsigned char *other_pub_x, | ||
const unsigned char *other_pub_y, size_t key_size) | ||
{ | ||
(void) ctx; | ||
(void) session; | ||
(void) other_pub_x; | ||
(void) other_pub_y; | ||
(void) key_size; | ||
return 0; | ||
} | ||
#endif /* DTLS_ECC */ | ||
|
||
static int try_send(struct dtls_context_t *ctx, session_t *dst, char *buf, int len) | ||
{ | ||
return dtls_write(ctx, dst, (uint8_t *)buf, len); | ||
} | ||
|
||
|
||
static int read_from_peer(struct dtls_context_t *ctx, session_t *session, | ||
uint8_t *data, size_t len) | ||
{ | ||
(void) ctx; | ||
(void) session; | ||
size_t i; | ||
|
||
for (i = 0; i < len; i++) | ||
{ | ||
printf("%c", data[i]); | ||
} | ||
return 0; | ||
} | ||
|
||
static dtls_handler_t cb = { | ||
.write = send_to_peer, | ||
.read = read_from_peer, | ||
.event = NULL, | ||
#ifdef DTLS_PSK | ||
.get_psk_info = get_psk_info, | ||
#endif /* DTLS_PSK */ | ||
#ifdef DTLS_ECC | ||
.get_ecdsa_key = get_ecdsa_key, | ||
.verify_ecdsa_key = verify_ecdsa_key | ||
#endif /* DTLS_ECC */ | ||
}; | ||
|
||
#define DTLS_CLIENT_CMD_CLOSE "client:close" | ||
#define DTLS_CLIENT_CMD_RENEGOTIATE "client:renegotiate" | ||
|
||
static int fd; | ||
int dtls_client_cmd(int argc, char **argv) | ||
{ | ||
log_t log_level = DTLS_LOG_DEBUG; | ||
|
||
if (argc < 0) { | ||
printf("Usage: %s <dst>\n", argv[0]); | ||
return -1; | ||
} | ||
|
||
dtls_init(); | ||
|
||
#ifdef DTLS_PSK | ||
psk_id_length = strlen(PSK_DEFAULT_IDENTITY); | ||
psk_key_length = strlen(PSK_DEFAULT_KEY); | ||
memcpy(psk_id, PSK_DEFAULT_IDENTITY, psk_id_length); | ||
memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length); | ||
#endif /* DTLS_PSK */ | ||
|
||
dtls_set_log_level(log_level); | ||
|
||
memset(&dst, 0, sizeof(session_t)); | ||
dst.size = sizeof(struct sockaddr_in6); | ||
dst.addr.sin6.sin6_family = AF_INET6; | ||
|
||
/* parse destination address */ | ||
if (inet_pton(AF_INET6, argv[1], &dst.addr.sin6.sin6_addr) != 1) { | ||
puts("Error: unable to parse destination address"); | ||
return 1; | ||
} | ||
|
||
/* use port number from command line when specified or the listen | ||
port, otherwise */ | ||
dst.addr.sin6.sin6_port = byteorder_htons(DEFAULT_PORT).u16; | ||
|
||
/* init socket and set it to non-blocking */ | ||
fd = socket(dst.addr.sa.sa_family, SOCK_DGRAM, 0); | ||
|
||
if (fd < 0) { | ||
dtls_alert("socket: %s\n", strerror(errno)); | ||
return 0; | ||
} | ||
|
||
dtls_context = dtls_new_context(&fd); | ||
if (!dtls_context) { | ||
dtls_emerg("cannot create context\n"); | ||
exit(-1); | ||
} | ||
|
||
dtls_set_handler(dtls_context, &cb); | ||
|
||
dtls_connect(dtls_context, &dst); | ||
|
||
thread_create(client_reader, sizeof(client_reader), THREAD_PRIORITY_MAIN - 1, | ||
CREATE_STACKTEST, dtls_reader, dtls_context, "DTLS client"); | ||
|
||
|
||
return 0; | ||
} | ||
|
||
int dtls_send_cmd(int argc, char **argv) | ||
{ | ||
if (argc < 2) { | ||
printf("Usage: %s <data>\n", argv[1]); | ||
return -1; | ||
} | ||
try_send(dtls_context, &dst, argv[1], strlen(argv[1])); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#include "assert.h" | ||
|
||
#include "tinydtls_debug.h" | ||
#include "tinydtls.h" | ||
#include "dtls.h" | ||
#include "dtls_app.h" | ||
|
||
static int dtls_handle_read(struct dtls_context_t *ctx) | ||
{ | ||
int *fd; | ||
session_t session; | ||
static uint8 buf[DTLS_MAX_BUF]; | ||
ssize_t len; | ||
|
||
fd = dtls_get_app_data(ctx); | ||
|
||
assert(fd); | ||
|
||
memset(&session, 0, sizeof(session_t)); | ||
session.size = sizeof(session.addr.sin6); | ||
len = recvfrom(*fd, buf, sizeof(buf), 0, (struct sockaddr*) &session.addr.sin6, | ||
&session.size); | ||
|
||
if (len < 0) { | ||
perror("recvfrom"); | ||
return -1; | ||
} | ||
else { | ||
dtls_debug("got %d bytes from port %d\n", len, | ||
ntohs(session.addr.sin6.sin6_port)); | ||
if (sizeof(buf) < (size_t) len) { | ||
dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf)); | ||
} | ||
} | ||
|
||
return dtls_handle_message(ctx, &session, buf, len); | ||
} | ||
|
||
msg_t _reader_queue[READER_QUEUE_SIZE]; | ||
|
||
void *dtls_reader(void *args) | ||
{ | ||
/* calling it twice shouldn't do any harm */ | ||
msg_init_queue(_reader_queue, READER_QUEUE_SIZE); | ||
dtls_context_t *dtls_context = (dtls_context_t*) args; | ||
|
||
while (1) { | ||
dtls_handle_read(dtls_context); | ||
} | ||
|
||
dtls_free_context(dtls_context); | ||
return NULL; | ||
} | ||
|
Oops, something went wrong.