From 7d77e551e18019694ad4a29419e3488a829e9fcb Mon Sep 17 00:00:00 2001 From: Junyeon LEE Date: Fri, 28 Apr 2017 22:16:00 +0900 Subject: [PATCH] external/wakaama: initiative TLS supporting version of lwm2m This commit ports the lwm2m connection layer with mbedTLS. Now that wakaama supports UDP, TCP, TLS connection. Change-Id: I12c6a2e43b1776301674b05d50106d5f000410a2 Signed-off-by: Junyeon LEE --- external/wakaama/examples/client/Make.defs | 4 + external/wakaama/examples/client/lwm2mclient.c | 237 ++++++++++++++++++++++++- external/wakaama/examples/server/Make.defs | 4 + external/wakaama/examples/server/lwm2mserver.c | 203 ++++++++++++++++++++- external/wakaama/examples/shared/connection.c | 33 ++-- external/wakaama/examples/shared/connection.h | 9 +- os/include/tls/config.h | 5 - os/include/tls/easy_tls.h | 9 + os/net/tls/easy_tls.c | 34 +++- 9 files changed, 503 insertions(+), 35 deletions(-) diff --git a/external/wakaama/examples/client/Make.defs b/external/wakaama/examples/client/Make.defs index 2671245..0152399 100644 --- a/external/wakaama/examples/client/Make.defs +++ b/external/wakaama/examples/client/Make.defs @@ -55,6 +55,10 @@ CFLAGS+=-I$(TOPDIR)/../external/wakaama/examples/shared CFLAGS+=-D__TINYARA__ +ifeq ($(CONFIG_LWM2M_SECURITY),y) +CFLAGS+=-DWITH_MBEDTLS +endif + DEPPATH += --dep-path wakaama/examples/client VPATH += :wakaama/examples/client diff --git a/external/wakaama/examples/client/lwm2mclient.c b/external/wakaama/examples/client/lwm2mclient.c index 12ddaa9..e6fcd32 100644 --- a/external/wakaama/examples/client/lwm2mclient.c +++ b/external/wakaama/examples/client/lwm2mclient.c @@ -61,10 +61,10 @@ #include "commandline.h" #include "connection.h" +#include #include #include #include -#include #include #include #include @@ -80,6 +80,11 @@ #include #endif +#ifdef WITH_MBEDTLS +#include "tls/certs.h" +#define LWM2M_CIPHERSUIT "TLS-PSK-WITH-AES-128-CBC-SHA" +#endif + #define MAX_PACKET_SIZE 1024 #define DEFAULT_SERVER_IPV6 "[::1]" #define DEFAULT_SERVER_IPV4 "coap://127.0.0.1" @@ -120,6 +125,18 @@ static char g_bootstrapserverPort[PORTLEN_MAX] = {0,}; static uint16_t g_lifetime = 300; bool g_bootstrapRequested = false; +/* + * Definition for handling pthread + */ +#define LWM2M_CLIENT_PRIORITY 100 +#define LWM2M_CLIENT_STACK_SIZE 16384 +#define LWM2M_CLIENT_SCHED_POLICY SCHED_RR + +struct pthread_arg { + int argc; + char **argv; +}; + #endif /* __TINYARA__ */ int g_reboot = 0; @@ -150,6 +167,10 @@ typedef struct size_t server_addrLen; int addressFamily; connection_t * connList; +#ifdef WITH_MBEDTLS + tls_ctx * tls_context; + tls_opt * tls_opt; +#endif } client_data_t; #if defined (__TINYARA__) @@ -233,6 +254,26 @@ void handle_value_changed(lwm2m_context_t * lwm2mP, } } +static char *coap_get_port_from_proto(coap_protocol_t proto) +{ + char *port = NULL; + + switch(proto) { + case COAP_TCP: + case COAP_UDP: + port = LWM2M_STANDARD_PORT_STR; + break; + case COAP_TCP_TLS: + case COAP_UDP_DTLS: + port = LWM2M_DTLS_PORT_STR; + break; + default: + break; + } + + return port; +} + static coap_protocol_t coap_get_protocol_from_uri(const char *uri) { coap_protocol_t type; @@ -298,6 +339,17 @@ void * lwm2m_connect_server(uint16_t secObjInstID, dataP->connList = newConnP; } +#ifdef WITH_MBEDTLS + if (proto == COAP_TCP_TLS || proto == COAP_UDP_DTLS) { + newConnP->session = TLSSession(dataP->sock, dataP->tls_context, dataP->tls_opt); + if (newConnP->session == NULL) { + fprintf(stderr, "Failed to create secure session. \r\n"); + goto exit; + } + fprintf(stderr, "successfully create secure session. \r\n"); + } +#endif + exit: lwm2m_free(uri); return (void *)newConnP; @@ -331,6 +383,12 @@ void lwm2m_close_connection(void * sessionH, lwm2m_free(targetP); } } + +#ifdef WITH_MBEDTLS + if (targetP->session) { + TLSSession_free(targetP->session); + } +#endif } static void prv_output_servers(char * buffer, @@ -809,6 +867,44 @@ static void close_backup_object() #endif /* LWM2M_BOOTSTRAP */ +#ifdef WITH_MBEDTLS + +#define HEX2NUM(c) \ + if (c >= '0' && c <= '9') \ + c -= '0'; \ + else if (c >= 'a' && c <= 'f') \ + c -= 'a' - 10; \ + else if (c >= 'A' && c <= 'F') \ + c -= 'A' - 10; \ + else \ + return(-1); + +int lwm2m_unhexify(unsigned char *output, const char *input, size_t *olen) +{ + unsigned char c; + size_t j; + + *olen = strlen(input); + if (*olen % 2 != 0 || *olen / 2 > MBEDTLS_PSK_MAX_LEN) { + return (-1); + } + *olen /= 2; + + for (j = 0; j < *olen * 2; j += 2) { + c = input[j]; + HEX2NUM(c); + output[j / 2] = c << 4; + + c = input[j + 1]; + HEX2NUM(c); + output[j / 2] |= c; + } + + return (0); +} +#endif + + void print_usage(void) { fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n"); @@ -822,13 +918,28 @@ void print_usage(void) fprintf(stdout, " -t TIME\tSet the lifetime of the Client. Default: 300\r\n"); fprintf(stdout, " -b\t\tBootstrap requested.\r\n"); fprintf(stdout, " -c\t\tChange battery level over time.\r\n"); +#ifdef WITH_MBEDTLS + fprintf(stdout, " -i STRING\t Set PSK identity. If not set use none secure mode\r\n"); + fprintf(stdout, " -s HEXSTRING\t Set Pre-Shared-Key. If not set use none secure mode\r\n"); +#endif fprintf(stdout, "Examples:\r\n"); fprintf(stdout, " lwm2mclient -h coap://127.0.0.1 -4\r\n"); + fprintf(stdout, " lwm2mclient -h coaps+tcp://127.0.0.1 -4 -i PSK_identity -s 4938271\r\n"); fprintf(stdout, "\r\n"); } +#ifdef __TINYARA__ +int lwm2m_client_cb(void *args) +{ + int argc; + char **argv; + + argc = ((struct pthread_arg *)args)->argc; + argv = ((struct pthread_arg *)args)->argv; +#else int lwm2m_client_main(int argc, char *argv[]) { +#endif /* __TINYARA__ */ client_data_t data; int result; lwm2mH = NULL; @@ -851,6 +962,14 @@ int lwm2m_client_main(int argc, char *argv[]) char * pskId = NULL; uint16_t pskLen = -1; char * pskBuffer = NULL; +#ifdef WITH_MBEDTLS + unsigned char psk[MBEDTLS_PSK_MAX_LEN]; + + /* set default tls option */ + tls_opt option = {MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, 2, 5, NULL, }; + option.force_ciphersuites[0] = mbedtls_ssl_get_ciphersuite_id(LWM2M_CIPHERSUIT); + option.force_ciphersuites[1] = 0; +#endif struct timeval tv = {60, 0}; @@ -927,6 +1046,26 @@ int lwm2m_client_main(int argc, char *argv[]) return 0; } break; +#ifdef WITH_MBEDTLS + case 'i': + opt++; + if (opt >= argc) + { + print_usage(); + return 0; + } + pskId = argv[opt]; + break; + case 's': + opt++; + if (opt >= argc) + { + print_usage(); + return 0; + } + pskBuffer = argv[opt]; + break; +#endif case 'n': opt++; if (opt >= argc) @@ -1007,6 +1146,7 @@ int lwm2m_client_main(int argc, char *argv[]) /* move pointer to address field */ server += strlen(coap_uri_prefix[proto]); } + serverPort = coap_get_port_from_proto(proto); } /* @@ -1127,6 +1267,47 @@ int lwm2m_client_main(int argc, char *argv[]) fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n"); return -1; } + +#ifdef WITH_MBEDTLS + if (proto == COAP_TCP_TLS || proto == COAP_UDP_DTLS) { + + /* Set Transport layer (TCP or UDP */ + switch(proto) { + case COAP_TCP_TLS: + option.transport = MBEDTLS_SSL_TRANSPORT_STREAM; + break; + case COAP_UDP_DTLS: + option.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM; + break; + default: + break; + } + data.tls_opt = &option; + + /* Set credential information */ + tls_cred cred; + memset(&cred, 0, sizeof(tls_cred)); + + if (pskBuffer) { + if (lwm2m_unhexify(psk, pskBuffer, &cred.psk_len) == 0) { + if (pskId) { + cred.psk_identity = pskId; + cred.psk = psk; + } + } + if (cred.psk_identity == NULL && cred.psk == NULL) { + fprintf(stdout, "failed to set psk info\r\n"); + return -1; + } + } + + data.tls_context = TLSCtx(&cred); + if (data.tls_context == NULL) { + fprintf(stdout, "TLS context initialize failed\r\n"); + return -1; + } + } +#endif /* * The liblwm2m library is now initialized with the functions that will be in * charge of communication @@ -1292,11 +1473,12 @@ int lwm2m_client_main(int argc, char *argv[]) if (FD_ISSET(data.sock, &readfds)) { addrLen = sizeof(addr); + client_data_t *user_data = lwm2mH->userData; /* * We retrieve the data received */ - numBytes = connection_read(proto, data.sock, buffer, MAX_PACKET_SIZE, &addr, &addrLen); + numBytes = connection_read(proto, user_data->connList,data.sock, buffer, MAX_PACKET_SIZE, &addr, &addrLen); memcpy(&addr, &data.server_addr, data.server_addrLen); addrLen = data.server_addrLen; @@ -1405,6 +1587,10 @@ int lwm2m_client_main(int argc, char *argv[]) free_object_conn_s(objArray[7]); acl_ctrl_free_object(objArray[8]); +#ifdef WITH_MBEDTLS + TLSCtx_free(data.tls_context); +#endif + #ifdef MEMORY_TRACE if (g_quit == 1) { @@ -1702,4 +1888,51 @@ static void prv_update_server(client_data_t *dataP, uint16_t secObjInstID) client_set_serverAddr(server_host, false); client_set_serverPort(server_port, false); } + +int lwm2m_client_main(int argc, char *argv[]) +{ + pthread_t tid; + pthread_attr_t attr; + struct sched_param sparam; + int r; + + struct pthread_arg args; + args.argc = argc; + args.argv = argv; + + /* Initialize the attribute variable */ + if ((r = pthread_attr_init(&attr)) != 0) { + printf("%s: pthread_attr_init failed, status=%d\n", __func__, r); + return -1; + } + + /* 1. set a priority */ + sparam.sched_priority = LWM2M_CLIENT_PRIORITY; + if ((r = pthread_attr_setschedparam(&attr, &sparam)) != 0) { + printf("%s: pthread_attr_setschedparam failed, status=%d\n", __func__, r); + return -1; + } + + if ((r = pthread_attr_setschedpolicy(&attr, LWM2M_CLIENT_SCHED_POLICY)) != 0) { + printf("%s: pthread_attr_setschedpolicy failed, status=%d\n", __func__, r); + return -1; + } + + /* 2. set a stacksize */ + if ((r = pthread_attr_setstacksize(&attr, LWM2M_CLIENT_STACK_SIZE)) != 0) { + printf("%s: pthread_attr_setstacksize failed, status=%d\n", __func__, r); + return -1; + } + + /* 3. create pthread with entry function */ + if ((r = pthread_create(&tid, &attr, (pthread_startroutine_t)lwm2m_client_cb, (void *)&args)) != 0) { + printf("%s: pthread_create failed, status=%d\n", __func__, r); + return -1; + } + + /* Wait for the threads to stop */ + pthread_join(tid, NULL); + + return 0; +} #endif /* __TINYARA__ */ diff --git a/external/wakaama/examples/server/Make.defs b/external/wakaama/examples/server/Make.defs index 11a3f26..5e1d0bb 100644 --- a/external/wakaama/examples/server/Make.defs +++ b/external/wakaama/examples/server/Make.defs @@ -42,6 +42,10 @@ CFLAGS+=-I$(TOPDIR)/../external/wakaama/examples/shared CFLAGS+=-D__TINYARA__ +ifeq ($(CONFIG_LWM2M_SECURITY),y) +CFLAGS+=-DWITH_MBEDTLS +endif + DEPPATH += --dep-path wakaama/examples/server VPATH += :wakaama/examples/server diff --git a/external/wakaama/examples/server/lwm2mserver.c b/external/wakaama/examples/server/lwm2mserver.c index e128b86..d5ec1d8 100644 --- a/external/wakaama/examples/server/lwm2mserver.c +++ b/external/wakaama/examples/server/lwm2mserver.c @@ -76,6 +76,11 @@ #include #endif +#ifdef WITH_MBEDTLS +#include "tls/certs.h" +#include "tls/easy_tls.h" +#endif + #define MAX_PACKET_SIZE 1024 #if defined(__TINYARA__) @@ -95,6 +100,18 @@ #define STDERR_FILENO 2 #endif +/* + * Definition for handling pthread + */ +#define LWM2M_SERVER_PRIORITY 100 +#define LWM2M_SERVER_STACK_SIZE 16384 +#define LWM2M_SERVER_SCHED_POLICY SCHED_RR + +struct pthread_arg { + int argc; + char **argv; +}; + #endif /* __TINYARA__ */ static int g_quit = 0; @@ -824,6 +841,43 @@ void handle_sigint(int signum) g_quit = 2; } +#ifdef WITH_MBEDTLS + +#define HEX2NUM(c) \ + if (c >= '0' && c <= '9') \ + c -= '0'; \ + else if (c >= 'a' && c <= 'f') \ + c -= 'a' - 10; \ + else if (c >= 'A' && c <= 'F') \ + c -= 'A' - 10; \ + else \ + return(-1); + +int lwm2m_unhexify(unsigned char *output, const char *input, size_t *olen) +{ + unsigned char c; + size_t j; + + *olen = strlen(input); + if (*olen % 2 != 0 || *olen / 2 > MBEDTLS_PSK_MAX_LEN) { + return (-1); + } + *olen /= 2; + + for (j = 0; j < *olen * 2; j += 2) { + c = input[j]; + HEX2NUM(c); + output[j / 2] = c << 4; + + c = input[j + 1]; + HEX2NUM(c); + output[j / 2] |= c; + } + + return (0); +} +#endif + void print_usage(void) { fprintf(stderr, "Usage: lwm2mserver [OPTION]\r\n"); @@ -832,13 +886,27 @@ void print_usage(void) fprintf(stdout, " -4\t\tUse IPv4 connection. Default: IPv6 connection\r\n"); fprintf(stdout, " -l PORT\tSet the local UDP port of the Server. Default: "LWM2M_STANDARD_PORT_STR"\r\n"); fprintf(stdout, " -p protocol \tSet protocol type, (0: UDP, 1: UDP+DTLS, 2: TCP, 3: TCP+TLS)\r\n"); +#ifdef WITH_MBEDTLS + fprintf(stdout, " -i STRING\t Set PSK identity. If not set use none secure mode\r\n"); + fprintf(stdout, " -s HEXSTRING\t Set Pre-Shared-Key. If not set use none secure mode\r\n"); +#endif fprintf(stdout, "Examples:\r\n"); fprintf(stdout, " lwm2mserver -4 -p 3\r\n"); fprintf(stdout, "\r\n"); } +#ifdef __TINYARA__ +int lwm2m_server_cb(void *args) +{ + int argc; + char **argv; + + argc = ((struct pthread_arg *)args)->argc; + argv = ((struct pthread_arg *)args)->argv; +#else int lwm2m_server_main(int argc, char *argv[]) { +#endif /* __TINYARA__ */ int sock, newsock; int reuse; fd_set readfds; @@ -853,6 +921,24 @@ int lwm2m_server_main(int argc, char *argv[]) coap_protocol_t proto = COAP_UDP; + char * pskId = NULL; + char * pskBuffer = NULL; + +#ifdef WITH_MBEDTLS + unsigned char psk[MBEDTLS_PSK_MAX_LEN]; + + /* set default tls option */ + tls_opt tls_option; + memset(&tls_option, 0, sizeof(tls_opt)); + + tls_option.server = MBEDTLS_SSL_IS_SERVER; + tls_option.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM; + tls_option.auth_mode = 2; + tls_option.debug_mode = 5; + + tls_ctx *tls_context = NULL; +#endif + struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); @@ -940,6 +1026,26 @@ int lwm2m_server_main(int argc, char *argv[]) } localPort = argv[opt]; break; +#ifdef WITH_MBEDTLS + case 'i': + opt++; + if (opt >= argc) + { + print_usage(); + return 0; + } + pskId = argv[opt]; + break; + case 's': + opt++; + if (opt >= argc) + { + print_usage(); + return 0; + } + pskBuffer = argv[opt]; + break; +#endif case 'p': opt++; if (opt >= argc) @@ -963,6 +1069,46 @@ int lwm2m_server_main(int argc, char *argv[]) opt += 1; } +#ifdef WITH_MBEDTLS + if (proto == COAP_TCP_TLS || proto == COAP_UDP_DTLS) { + + /* Set Transport layer (TCP or UDP) */ + switch(proto) { + case COAP_TCP_TLS: + tls_option.transport = MBEDTLS_SSL_TRANSPORT_STREAM; + break; + case COAP_UDP_DTLS: + tls_option.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM; + break; + default: + break; + } + + /* Set credential information */ + tls_cred cred; + memset(&cred, 0, sizeof(tls_cred)); + + if (pskBuffer) { + if (lwm2m_unhexify(psk, pskBuffer, &cred.psk_len) == 0) { + if (pskId) { + cred.psk_identity = pskId; + cred.psk = psk; + } + } + if (cred.psk_identity == NULL && cred.psk == NULL) { + fprintf(stdout, "failed to set psk info\r\n"); + return -1; + } + } + + tls_context = TLSCtx(&cred); + if (tls_context == NULL) { + fprintf(stdout, "TLS context initialize filaed\n"); + return -1; + } + localPort = LWM2M_DTLS_PORT_STR; + } +#endif sock = create_socket(proto, localPort, addressFamily); if (sock < 0) { @@ -980,8 +1126,14 @@ int lwm2m_server_main(int argc, char *argv[]) return -1; } else { fprintf(stderr, "TCP session has been created\r\n"); + connList = connection_new_incoming(connList, newsock, (struct sockaddr *)&addr, addrLen); sock = newsock; } +#ifdef WITH_MBEDTLS + if (proto == COAP_TCP_TLS) { + connList->session = TLSSession(sock, tls_context, &tls_option); + } +#endif break; default: break; @@ -1038,11 +1190,11 @@ int lwm2m_server_main(int argc, char *argv[]) else if (result > 0) { uint8_t buffer[MAX_PACKET_SIZE]; - int numBytes; + int numBytes = 0; if (FD_ISSET(sock, &readfds)) { - numBytes = connection_read(proto, sock, buffer, MAX_PACKET_SIZE, &addr, &addrLen); + numBytes = connection_read(proto, connList, sock, buffer, MAX_PACKET_SIZE, &addr, &addrLen); if (numBytes == -1) { @@ -1190,4 +1342,51 @@ static int read_input_command_line(char *buf) return pos; } + +int lwm2m_server_main(int argc, char *argv[]) +{ + pthread_t tid; + pthread_attr_t attr; + struct sched_param sparam; + int r; + + struct pthread_arg args; + args.argc = argc; + args.argv = argv; + + /* Initialize the attribute variable */ + if ((r = pthread_attr_init(&attr)) != 0) { + printf("%s: pthread_attr_init failed, status=%d\n", __func__, r); + return -1; + } + + /* 1. set a priority */ + sparam.sched_priority = LWM2M_SERVER_PRIORITY; + if ((r = pthread_attr_setschedparam(&attr, &sparam)) != 0) { + printf("%s: pthread_attr_setschedparam failed, status=%d\n", __func__, r); + return -1; + } + + if ((r = pthread_attr_setschedpolicy(&attr, LWM2M_SERVER_SCHED_POLICY)) != 0) { + printf("%s: pthread_attr_setschedpolicy failed, status=%d\n", __func__, r); + return -1; + } + + /* 2. set a stacksize */ + if ((r = pthread_attr_setstacksize(&attr, LWM2M_SERVER_STACK_SIZE)) != 0) { + printf("%s: pthread_attr_setstacksize failed, status=%d\n", __func__, r); + return -1; + } + + /* 3. create pthread with entry function */ + if ((r = pthread_create(&tid, &attr, (pthread_startroutine_t)lwm2m_server_cb, (void *)&args)) != 0) { + printf("%s: pthread_create failed, status=%d\n", __func__, r); + return -1; + } + + /* Wait for the threads to stop */ + pthread_join(tid, NULL); + + return 0; +} #endif /* __TINYARA__ */ diff --git a/external/wakaama/examples/shared/connection.c b/external/wakaama/examples/shared/connection.c index 24f3e9c..f03bbaa 100644 --- a/external/wakaama/examples/shared/connection.c +++ b/external/wakaama/examples/shared/connection.c @@ -268,31 +268,23 @@ int connection_send(connection_t *connP, { case COAP_UDP_DTLS: case COAP_TCP_TLS: - /* ToDo : need to use mbed TLS Send API - nbSent = SSL_write(connP->ssl, buffer + offset, length - offset); - if (nbSent < 1) { - fprintf(stderr, "mbed TLS Send error: %s\n", ERR_error_string(SSL_get_error(connP->ssl, nbSent), NULL)); - return -1; - } - */ +#ifdef WITH_MBEDTLS + nbSent = mbedtls_ssl_write(connP->session->ssl, buffer + offset, length - offset); +#endif break; case COAP_TCP: nbSent = send(connP->sock, buffer + offset, length - offset, 0); - if (nbSent == -1) { - fprintf(stderr, "Send error: %s\n", strerror(errno)); - return -1; - } break; case COAP_UDP: nbSent = sendto(connP->sock, buffer + offset, length - offset, 0, (struct sockaddr *)&(connP->addr), connP->addrLen); - if (nbSent == -1) { - fprintf(stderr, "Sendto error: %s\n", strerror(errno)); - return -1; - } break; default: break; } + if (nbSent < 0) { + fprintf(stderr, "Send fail nbSent : %d , error: %s\n", nbSent, strerror(errno)); + return -1; + } offset += nbSent; } @@ -330,6 +322,7 @@ bool lwm2m_session_is_equal(void * session1, } int connection_read(coap_protocol_t protocol, + connection_t *connP, int sock, uint8_t *buffer, size_t len, @@ -339,16 +332,18 @@ int connection_read(coap_protocol_t protocol, int numBytes = -1; switch(protocol) { + case COAP_TCP_TLS: + case COAP_UDP_DTLS: +#ifdef WITH_MBEDTLS + numBytes = mbedtls_ssl_read(connP->session->ssl, buffer, len); +#endif + break; case COAP_UDP: numBytes = recvfrom(sock, buffer, len, 0, (struct sockaddr *)from, fromLen); break; case COAP_TCP: numBytes = recv(sock, buffer, len, 0); break; - case COAP_TCP_TLS: - case COAP_UDP_DTLS: - /* TODO : mbed TLS API should be needed */ - break; default: fprintf(stderr, "connection_read : unsupported protocol type : %d\n", protocol); break; diff --git a/external/wakaama/examples/shared/connection.h b/external/wakaama/examples/shared/connection.h index c47c5f7..bc0a1f9 100644 --- a/external/wakaama/examples/shared/connection.h +++ b/external/wakaama/examples/shared/connection.h @@ -27,6 +27,10 @@ #include #include +#ifdef WITH_MBEDTLS +#include +#endif + #define LWM2M_STANDARD_PORT_STR "5683" #define LWM2M_STANDARD_PORT 5683 #define LWM2M_DTLS_PORT_STR "5684" @@ -40,6 +44,9 @@ typedef struct _connection_t int sock; struct sockaddr_in6 addr; size_t addrLen; +#ifdef WITH_MBEDTLS + tls_session * session; +#endif } connection_t; int create_socket(coap_protocol_t protocol, const char * portStr, int ai_family); @@ -51,5 +58,5 @@ connection_t * connection_create(coap_protocol_t protocol, connection_t * connLi void connection_free(connection_t * connList); int connection_send(connection_t *connP, uint8_t * buffer, size_t length, coap_protocol_t proto); -int connection_read(coap_protocol_t protocol, int sock, uint8_t *buffer, size_t len, struct sockaddr_storage *from, socklen_t *fromLen); +int connection_read(coap_protocol_t protocol, connection_t *connP, int sock, uint8_t *buffer, size_t len, struct sockaddr_storage *from, socklen_t *fromLen); #endif diff --git a/os/include/tls/config.h b/os/include/tls/config.h index daa09fa..472ba00 100644 --- a/os/include/tls/config.h +++ b/os/include/tls/config.h @@ -2624,11 +2624,6 @@ #undef MBEDTLS_ERROR_STRERROR_DUMMY #undef MBEDTLS_GENPRIME -#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - #undef MBEDTLS_FS_IO #undef MBEDTLS_MEMORY_DEBUG #undef MBEDTLS_HAVEGE_C diff --git a/os/include/tls/easy_tls.h b/os/include/tls/easy_tls.h index e4f40f2..51dbb54 100644 --- a/os/include/tls/easy_tls.h +++ b/os/include/tls/easy_tls.h @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef MBEDTLS_SSL_CACHE_C #include @@ -46,6 +47,7 @@ enum easy_tls_error { TLS_INVALID_CACERT, TLS_INVALID_DEVCERT, TLS_INVALID_DEVKEY, + TLS_INVALID_PSK, }; typedef struct tls_cert_and_key { @@ -55,6 +57,11 @@ typedef struct tls_cert_and_key { unsigned int ca_certlen; unsigned int dev_certlen; unsigned int dev_keylen; +#ifdef MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED + unsigned char *psk; + char *psk_identity; + size_t psk_len; +#endif } tls_cred; typedef struct tls_context { @@ -63,6 +70,7 @@ typedef struct tls_context { mbedtls_pk_context *pkey; mbedtls_entropy_context *entropy; mbedtls_ctr_drbg_context *ctr_drbg; + mbedtls_timing_delay_context *timer; #ifdef MBEDTLS_SSL_CACHE_C mbedtls_ssl_cache_context *cache; #endif @@ -74,6 +82,7 @@ typedef struct tls_options { int auth_mode; ///< select authentication level (0 ~ 2) int debug_mode; ///< select debug level (0 ~ 5) char *host_name; ///< set host_name (NULL or char *) + int force_ciphersuites[3]; ///< set force ciphersuites } tls_opt; typedef struct tls_session_context { diff --git a/os/net/tls/easy_tls.c b/os/net/tls/easy_tls.c index 45833db..a5bb339 100644 --- a/os/net/tls/easy_tls.c +++ b/os/net/tls/easy_tls.c @@ -71,6 +71,7 @@ static int tls_context_alloc(tls_ctx *ctx) TLS_MALLOC(ctx->pkey, sizeof(mbedtls_pk_context)); TLS_MALLOC(ctx->entropy, sizeof(mbedtls_entropy_context)); TLS_MALLOC(ctx->ctr_drbg, sizeof(mbedtls_ctr_drbg_context)); + TLS_MALLOC(ctx->timer, sizeof(mbedtls_timing_delay_context)); #ifdef MBEDTLS_SSL_CACHE_C TLS_MALLOC(ctx->cache, sizeof(mbedtls_ssl_cache_context)); #endif @@ -85,6 +86,7 @@ static void tls_context_free(tls_ctx *ctx) TLS_FREE(ctx->pkey); TLS_FREE(ctx->entropy); TLS_FREE(ctx->ctr_drbg); + TLS_FREE(ctx->timer); #ifdef MBEDTLS_SSL_CACHE_C TLS_FREE(ctx->cache); #endif @@ -114,16 +116,26 @@ static int tls_set_cred(tls_ctx *ctx, tls_cred *cred) { int ret = TLS_PARSE_CRED_FAIL; - if (cred == NULL || !cred->ca_cert) { + if (cred == NULL) { return TLS_INVALID_CRED; } + if (cred->psk && cred->psk_len) { + ret = mbedtls_ssl_conf_psk(ctx->conf, cred->psk, cred->psk_len, (const unsigned char *)cred->psk_identity, strlen(cred->psk_identity)); + + if (ret) { + return TLS_INVALID_PSK; + } + } + /* Mandatory */ - ret = mbedtls_x509_crt_parse(ctx->crt, cred->ca_cert, cred->ca_certlen); - if (ret) { - return TLS_INVALID_CACERT; + if (cred->ca_cert) { + ret = mbedtls_x509_crt_parse(ctx->crt, cred->ca_cert, cred->ca_certlen); + if (ret) { + return TLS_INVALID_CACERT; + } + mbedtls_ssl_conf_ca_chain(ctx->conf, ctx->crt, NULL); } - mbedtls_ssl_conf_ca_chain(ctx->conf, ctx->crt, NULL); /* Optional */ if (cred->dev_cert && cred->dev_key) { @@ -186,7 +198,17 @@ static int tls_set_default(tls_session *session, tls_ctx *ctx, tls_opt *opt) goto errout; } } - mbedtls_ssl_set_bio(session->ssl, &session->net, mbedtls_net_send, mbedtls_net_recv, NULL); + + if (opt->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { + mbedtls_ssl_set_timer_cb(session->ssl, ctx->timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); + mbedtls_ssl_set_bio(session->ssl, &session->net, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); + } else { + mbedtls_ssl_set_bio(session->ssl, &session->net, mbedtls_net_send, mbedtls_net_recv, NULL); + } + + if (opt->force_ciphersuites[0] > 0) { + mbedtls_ssl_conf_ciphersuites(ctx->conf, opt->force_ciphersuites); + } return TLS_SUCCESS; -- 2.7.4