mirror of
https://github.com/eclipse/tinydtls.git
synced 2025-10-14 03:10:09 +08:00
Add Windows support
This commit is contained in:
12
.github/workflows/main.yml
vendored
12
.github/workflows/main.yml
vendored
@@ -62,3 +62,15 @@ jobs:
|
||||
run: |
|
||||
cmake -Dmake_tests=ON .
|
||||
make
|
||||
|
||||
build-windows:
|
||||
name: Build for Windows using CMake
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build tinydtls
|
||||
run: |
|
||||
cmake -G "Unix Makefiles" .
|
||||
make
|
||||
|
||||
|
21
.gitignore
vendored
21
.gitignore
vendored
@@ -51,6 +51,7 @@ dtls_config.h
|
||||
*.cooja
|
||||
*.econotag
|
||||
*.eval-adf7xxxmb4z
|
||||
*.exe
|
||||
*.exp5438
|
||||
*.iris
|
||||
*.mbxxx
|
||||
@@ -70,3 +71,23 @@ dtls_config.h
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
CMakeFiles
|
||||
|
||||
# Windows build files
|
||||
*.dll
|
||||
|
||||
# Visual Studio Build Files
|
||||
*.VC.db*
|
||||
.vs
|
||||
*.obj
|
||||
*.tlog
|
||||
*.log
|
||||
*.recipe
|
||||
*.vcxproj
|
||||
*.sln
|
||||
*.pdb
|
||||
*.vcxproj.user
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.FileListAbsolute.txt
|
||||
tinydtls.dir
|
||||
Debug
|
||||
Release
|
||||
|
@@ -31,7 +31,7 @@ option(make_tests "Make test programs and examples" OFF)
|
||||
if(NOT PLATFORM)
|
||||
# PLATFORM seems to be not used
|
||||
set(PLATFORM "posix" CACHE STRING "Choose platform." FORCE)
|
||||
set_property(CACHE PLATFORM PROPERTY STRINGS "contiki" "espidf" "posix" "riot" "zephyr")
|
||||
set_property(CACHE PLATFORM PROPERTY STRINGS "contiki" "espidf" "posix" "riot" "zephyr" "windows")
|
||||
endif()
|
||||
|
||||
set(PACKAGE_NAME "tinydtls")
|
||||
@@ -64,8 +64,11 @@ target_sources(tinydtls PRIVATE
|
||||
target_include_directories(tinydtls PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_compile_definitions(tinydtls PUBLIC DTLSv12 WITH_SHA256 SHA2_USE_INTTYPES_H DTLS_CHECK_CONTENTTYPE)
|
||||
|
||||
if(NOT ZEPHYR_BASE)
|
||||
target_compile_options(tinydtls PRIVATE -fPIC -pedantic -std=c99 -Wall -Wextra -Wformat-security -Winline -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wunused)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
option(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "Export all symbols when compiling to a .dll" ON)
|
||||
target_compile_options(tinydtls PRIVATE -Wall)
|
||||
elseif(NOT ZEPHYR_BASE)
|
||||
target_compile_options(tinydtls PRIVATE -fPIC -pedantic -std=c99 -Wall -Wextra -Wformat-security -Winline -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wunused)
|
||||
endif()
|
||||
|
||||
set_target_properties(tinydtls PROPERTIES VERSION ${PACKAGE_VERSION} SOVERSION ${SOVERSION})
|
||||
|
39
README.md
39
README.md
@@ -18,6 +18,12 @@ C99. The following components are available:
|
||||
|
||||
# BUILDING
|
||||
|
||||
tinydtls supports multiple platforms, including both Real-time
|
||||
and general-purpose Operating Systems. Below you find build instructions for
|
||||
all supported environments.
|
||||
|
||||
## POSIX-oriented Operating Systems
|
||||
|
||||
When using the code from the git
|
||||
[repository](https://github.com/eclipse/tinydtls) at GitHub, invoke
|
||||
|
||||
@@ -68,6 +74,39 @@ Available options:
|
||||
| DTLS_ECC | enable/disable ECDHE_ECDSA cipher suites | ON |
|
||||
| DTLS_PSK | enable/disable PSK cipher suites | ON |
|
||||
|
||||
## Windows
|
||||
|
||||
Using CMake, you can also build on and for Windows using either GCC or Visual
|
||||
Studio.
|
||||
Note, however, that the `make_tests` option is currently not supported when
|
||||
compiling with Visual Studio, as parts of the tests rely on POSIX APIs.
|
||||
|
||||
For Visual Studio, you can apply the CMake instructions outlined above from the
|
||||
command line or use the CMake GUI application.
|
||||
|
||||
In order to be able to use GCC, you need to specify a different generator than
|
||||
the default.
|
||||
For instance, you can use the `Unix Makefiles` generator, which creates a
|
||||
Makefile for controlling the build process using GCC.
|
||||
The example below leads to the output of a shared library file
|
||||
`libtinydtls.dll`.
|
||||
|
||||
```
|
||||
cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=ON .
|
||||
make
|
||||
```
|
||||
|
||||
Using MinGW64, you can also cross compile from a POSIX-oriented
|
||||
platform for Windows using Autotools by providing a corresponding `--host`
|
||||
argument:
|
||||
|
||||
```
|
||||
./autogen.sh
|
||||
./configure --host x86_64-w64-mingw32
|
||||
make
|
||||
mv libtinydtls.so libtinydtls.dll # Apply Windows file extension
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
Copyright (c) 2011–2022 Olaf Bergmann (TZI) and others.
|
||||
|
6
dtls.c
6
dtls.c
@@ -213,7 +213,7 @@ static inline void free_context(dtls_context_t *context) {
|
||||
}
|
||||
#endif /* RIOT_VERSION */
|
||||
|
||||
#ifdef WITH_POSIX
|
||||
#if defined(WITH_POSIX) || defined(IS_WINDOWS)
|
||||
|
||||
static inline dtls_context_t *
|
||||
malloc_context(void) {
|
||||
@@ -1610,9 +1610,11 @@ dtls_0_send_hello_verify_request(dtls_context_t *ctx,
|
||||
dtls_ephemeral_peer_t *ephemeral_peer,
|
||||
uint8 *data, size_t data_length)
|
||||
{
|
||||
uint8 buf[DTLS_RH_LENGTH + DTLS_HS_LENGTH + data_length];
|
||||
uint8 buf[DTLS_RH_LENGTH + DTLS_HS_LENGTH + DTLS_HV_LENGTH + DTLS_COOKIE_LENGTH];
|
||||
uint8 *p = dtls_set_record_header(DTLS_CT_HANDSHAKE, 0, &(ephemeral_peer->rseq), buf);
|
||||
|
||||
assert(data_length == DTLS_HV_LENGTH + DTLS_COOKIE_LENGTH);
|
||||
|
||||
/* Signal DTLS version 1.0 in the record layer of ClientHello and
|
||||
* HelloVerifyRequest handshake messages according to Section 4.2.1
|
||||
* of RFC 6347.
|
||||
|
16
dtls.h
16
dtls.h
@@ -341,8 +341,16 @@ void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next);
|
||||
#define DTLS_CT_HANDSHAKE 22
|
||||
#define DTLS_CT_APPLICATION_DATA 23
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
|
||||
#elif defined(_MSC_VER)
|
||||
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
|
||||
#else
|
||||
#error "Structure packing is not available for the used compiler."
|
||||
#endif
|
||||
|
||||
/** Generic header structure of the DTLS record layer. */
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
PACK(typedef struct) {
|
||||
uint8 content_type; /**< content type of the included message */
|
||||
uint16 version; /**< Protocol version */
|
||||
uint16 epoch; /**< counter for cipher state changes */
|
||||
@@ -371,7 +379,7 @@ typedef struct __attribute__((__packed__)) {
|
||||
#define DTLS_HT_NO_OPTIONAL_MESSAGE -1
|
||||
|
||||
/** Header structure for the DTLS handshake protocol. */
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
PACK(typedef struct) {
|
||||
uint8 msg_type; /**< Type of handshake message (one of DTLS_HT_) */
|
||||
uint24 length; /**< length of this message */
|
||||
uint16 message_seq; /**< Message sequence number */
|
||||
@@ -381,7 +389,7 @@ typedef struct __attribute__((__packed__)) {
|
||||
} dtls_handshake_header_t;
|
||||
|
||||
/** Structure of the Client Hello message. */
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
PACK(typedef struct) {
|
||||
uint16 version; /**< Client version */
|
||||
uint32 gmt_random; /**< GMT time of the random byte creation */
|
||||
unsigned char random[28]; /**< Client random bytes */
|
||||
@@ -392,7 +400,7 @@ typedef struct __attribute__((__packed__)) {
|
||||
} dtls_client_hello_t;
|
||||
|
||||
/** Structure of the Hello Verify Request. */
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
PACK(typedef struct) {
|
||||
uint16 version; /**< Server version */
|
||||
uint8 cookie_length; /**< Length of the included cookie */
|
||||
uint8 cookie[]; /**< up to 32 bytes making up the cookie */
|
||||
|
@@ -222,12 +222,13 @@ dsrv_print_addr(const session_t *addr, char *buf, size_t len) {
|
||||
|
||||
#endif /* WITH_CONTIKI */
|
||||
|
||||
#ifdef RIOT_VERSION
|
||||
#if defined(RIOT_VERSION) || defined(IS_WINDOWS)
|
||||
/* FIXME: Switch to RIOT own DEBUG lines */
|
||||
/* TODO: Check if inet_ntop can be used on Windows */
|
||||
(void) addr;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
#endif /* RIOT_VERSION */
|
||||
#endif /* RIOT_VERSION || IS_WINDOWS */
|
||||
|
||||
#ifdef WITH_POSIX
|
||||
/* TODO: output addresses manually */
|
||||
@@ -240,7 +241,7 @@ dsrv_print_addr(const session_t *addr, char *buf, size_t len) {
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
#if !defined(WITH_CONTIKI) && !defined(_MSC_VER)
|
||||
void
|
||||
dsrv_log(log_t level, const char *format, ...) {
|
||||
static char timebuf[32];
|
||||
|
@@ -78,11 +78,11 @@ void dtls_set_log_level(log_t level);
|
||||
* level is below or equal to the log level that set by
|
||||
* set_log_level(). */
|
||||
#ifdef HAVE_VPRINTF
|
||||
#if (defined(__GNUC__))
|
||||
#if (defined(__GNUC__) && !defined(__MINGW32__))
|
||||
void dsrv_log(log_t level, const char *format, ...) __attribute__ ((format(printf, 2, 3)));
|
||||
#else /* !__GNUC__ */
|
||||
#else /* !__GNUC__ && !__MINGW32__ */
|
||||
void dsrv_log(log_t level, const char *format, ...);
|
||||
#endif /* !__GNUC__ */
|
||||
#endif /* !__GNUC__ && !__MINGW32__ */
|
||||
#else
|
||||
#define dsrv_log(level, format, ...) PRINTF(format, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
@@ -42,10 +42,12 @@ typedef int dtls_mutex_t;
|
||||
#define dtls_mutex_trylock(a) *(a) = 1
|
||||
#define dtls_mutex_unlock(a) *(a) = 0
|
||||
|
||||
#elif defined(WITH_ZEPHYR)
|
||||
#elif defined(WITH_ZEPHYR) || defined(IS_WINDOWS)
|
||||
|
||||
/* zephyr supports mutex, but this port doesn't use it */
|
||||
|
||||
// TODO: Add Windows compatible mutex definitions
|
||||
|
||||
typedef int dtls_mutex_t;
|
||||
#define DTLS_MUTEX_INITIALIZER 0
|
||||
#define dtls_mutex_lock(a) *(a) = 1
|
||||
@@ -53,7 +55,7 @@ typedef int dtls_mutex_t;
|
||||
#define dtls_mutex_unlock(a) *(a) = 0
|
||||
|
||||
|
||||
#else /* ! RIOT_VERSION && ! WITH_CONTIKI && ! WITH_ZEPHYR */
|
||||
#else /* ! RIOT_VERSION && ! WITH_CONTIKI && ! WITH_ZEPHYR && ! IS_WINDOWS */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -63,6 +65,6 @@ typedef pthread_mutex_t dtls_mutex_t;
|
||||
#define dtls_mutex_trylock(a) pthread_mutex_trylock(a)
|
||||
#define dtls_mutex_unlock(a) pthread_mutex_unlock(a)
|
||||
|
||||
#endif /* ! RIOT_VERSION && ! WITH_CONTIKI */
|
||||
#endif /* ! RIOT_VERSION && ! WITH_CONTIKI && ! IS_WINDOWS */
|
||||
|
||||
#endif /* _DTLS_MUTEX_H_ */
|
||||
|
@@ -30,6 +30,9 @@
|
||||
#elif defined (WITH_ZEPHYR)
|
||||
#include "platform-specific/dtls_prng_zephyr.c"
|
||||
|
||||
#elif defined (IS_WINDOWS)
|
||||
#include "platform-specific/dtls_prng_win.c"
|
||||
|
||||
#elif defined (WITH_POSIX)
|
||||
#include "platform-specific/dtls_prng_posix.c"
|
||||
|
||||
|
12
dtls_time.c
12
dtls_time.c
@@ -22,6 +22,11 @@
|
||||
#include "tinydtls.h"
|
||||
#include "dtls_time.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CONTIKI
|
||||
clock_time_t dtls_clock_offset;
|
||||
|
||||
@@ -64,7 +69,7 @@ dtls_ticks(dtls_tick_t *t) {
|
||||
*t = k_uptime_get();
|
||||
}
|
||||
|
||||
#elif defined(WITH_POSIX)
|
||||
#elif defined(WITH_POSIX) || defined(IS_WINDOWS)
|
||||
|
||||
time_t dtls_clock_offset;
|
||||
|
||||
@@ -88,6 +93,11 @@ void dtls_ticks(dtls_tick_t *t) {
|
||||
gettimeofday(&tv, NULL);
|
||||
*t = (tv.tv_sec - dtls_clock_offset) * DTLS_TICKS_PER_SECOND
|
||||
+ (tv.tv_usec * DTLS_TICKS_PER_SECOND / 1000000);
|
||||
#elif defined(_MSC_VER)
|
||||
SYSTEMTIME current_time;
|
||||
GetSystemTime(¤t_time);
|
||||
*t = (current_time.wSecond - dtls_clock_offset) * DTLS_TICKS_PER_SECOND
|
||||
+ (current_time.wMilliseconds * DTLS_TICKS_PER_SECOND / 1000);
|
||||
#else
|
||||
#error "clock not implemented"
|
||||
#endif
|
||||
|
@@ -39,6 +39,7 @@
|
||||
//big number functions
|
||||
#include "ecc.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
static uint32_t add( const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length){
|
||||
uint64_t d = 0; //carry
|
||||
@@ -157,7 +158,8 @@ static int fieldSub(const uint32_t *x, const uint32_t *y, const uint32_t *modulu
|
||||
//finite Field multiplication
|
||||
//32bit * 32bit = 64bit
|
||||
static int fieldMult(const uint32_t *x, const uint32_t *y, uint32_t *result, uint8_t length){
|
||||
uint32_t temp[length * 2];
|
||||
uint32_t temp[(arrayLength + 1) * 2];
|
||||
assert(length <= arrayLength + 1);
|
||||
setZero(temp, length * 2);
|
||||
setZero(result, length * 2);
|
||||
uint8_t k, n;
|
||||
|
50
platform-specific/dtls_prng_win.c
Normal file
50
platform-specific/dtls_prng_win.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2022 Jan Romann 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "tinydtls.h"
|
||||
#include "dtls_prng.h"
|
||||
#include "dtls_debug.h"
|
||||
|
||||
#define _CRT_RAND_S
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
/** Missing function declaration for rand_s under MingW. */
|
||||
__declspec(dllimport) int __cdecl rand_s(unsigned int*);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Fills @p buf with @p len random bytes. Returns a non-zero
|
||||
* value on error.
|
||||
*/
|
||||
int
|
||||
dtls_prng(unsigned char *buf, size_t len) {
|
||||
errno_t err;
|
||||
unsigned int number;
|
||||
size_t klen = len;
|
||||
while (len--) {
|
||||
err = rand_s(&number);
|
||||
if (err != 0) {
|
||||
dtls_emerg("PRNG failed\n");
|
||||
return err;
|
||||
}
|
||||
*buf++ = number & 0xFF;
|
||||
}
|
||||
return klen;
|
||||
}
|
||||
|
||||
void
|
||||
dtls_prng_init(unsigned seed) {
|
||||
srand(seed);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2011-2019 Olaf Bergmann (TZI) and others.
|
||||
* Copyright (c) 2011-2022 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.
|
||||
@@ -64,7 +64,11 @@ typedef struct {
|
||||
#undef read
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
#else /* ! WITH_ZEPHYR && ! WITH_LWIP */
|
||||
#elif defined(IS_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#else /* ! WITH_ZEPHYR && ! WITH_LWIP && ! IS_WINDOWS */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
10
sha2/sha2.h
10
sha2/sha2.h
@@ -48,6 +48,16 @@ extern "C" {
|
||||
#include <sys/types.h>
|
||||
#include "tinydtls.h"
|
||||
|
||||
#ifdef IS_WINDOWS
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u_int8_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
typedef uint32_t u_int32_t;
|
||||
typedef uint64_t u_int64_t;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SHA2_USE_INTTYPES_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
@@ -7,19 +7,27 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif /* HAVE_SYS_TIME_H */
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "tinydtls.h"
|
||||
#include "dtls.h"
|
||||
#include "dtls_debug.h"
|
||||
|
||||
#ifdef IS_WINDOWS
|
||||
#include <winsock2.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#define MSG_DONTWAIT 0
|
||||
#define MSG_TRUNC 0
|
||||
#else /* ! IS_WINDOWS */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#endif /* ! IS_WINDOWS */
|
||||
|
||||
#define DEFAULT_PORT 20220
|
||||
|
||||
static dtls_context_t *the_context = NULL;
|
||||
@@ -277,7 +285,9 @@ main(int argc, char **argv) {
|
||||
int on = 1;
|
||||
int off = 0;
|
||||
struct sockaddr_in6 listen_addr;
|
||||
#ifndef IS_WINDOWS
|
||||
struct sigaction sa;
|
||||
#endif /* ! IS_WINDOWS */
|
||||
uint16_t port = htons(DEFAULT_PORT);
|
||||
|
||||
memset(&listen_addr, 0, sizeof(struct sockaddr_in6));
|
||||
@@ -357,6 +367,7 @@ main(int argc, char **argv) {
|
||||
|
||||
dtls_init();
|
||||
|
||||
#ifndef IS_WINDOWS
|
||||
memset (&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = dtls_handle_signal;
|
||||
@@ -366,6 +377,7 @@ main(int argc, char **argv) {
|
||||
/* So we do not exit on a SIGPIPE */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction (SIGPIPE, &sa, NULL);
|
||||
#endif /* ! IS_WINDOWS */
|
||||
|
||||
the_context = dtls_new_context(&fd);
|
||||
|
||||
|
@@ -32,12 +32,18 @@
|
||||
#include "platform-specific/platform.h"
|
||||
#endif /* CONTIKI */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define IS_WINDOWS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONTIKI
|
||||
#ifndef RIOT_VERSION
|
||||
#ifndef IS_WINDOWS
|
||||
#ifndef WITH_POSIX
|
||||
/* TODO: To remove in a future */
|
||||
#define WITH_POSIX 1
|
||||
#endif /* WITH_POSIX */
|
||||
#endif /* IS_WINDOWS */
|
||||
#include "dtls_config.h"
|
||||
#endif /* RIOT_VERSION */
|
||||
#endif /* CONTIKI */
|
||||
|
Reference in New Issue
Block a user