Skip to content

Commit

Permalink
Add cipher suite selection to test applications.
Browse files Browse the repository at this point in the history
Introduce new cli argument -c.

Signed-off-by: Achim Kraus <[email protected]>
  • Loading branch information
boaks committed Apr 17, 2023
1 parent 9eb6780 commit 90ca321
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 19 deletions.
4 changes: 2 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ cmake_minimum_required(VERSION 3.5)

project(tinydtls-tests)

add_executable(dtls-server dtls-server.c)
add_executable(dtls-server dtls-server.c dtls_ciphers_util.c)
target_link_libraries(dtls-server LINK_PUBLIC tinydtls)
target_compile_options(dtls-server PUBLIC -Wall -DTEST_INCLUDE -DDTLSv12 -DWITH_SHA256)
if(${WARNING_TO_ERROR})
Expand All @@ -37,7 +37,7 @@ if(${WARNING_TO_ERROR})
target_compile_options(ccm-test PUBLIC -Werror)
endif()

add_executable(dtls-client dtls-client.c)
add_executable(dtls-client dtls-client.c dtls_ciphers_util.c)
target_link_libraries(dtls-client LINK_PUBLIC tinydtls)
target_compile_options(dtls-client PUBLIC -Wall -DTEST_INCLUDE -DDTLSv12 -DWITH_SHA256)
if(${WARNING_TO_ERROR})
Expand Down
6 changes: 4 additions & 2 deletions tests/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ top_srcdir:= @top_srcdir@

# files and flags
SOURCES:= dtls-server.c ccm-test.c \
dtls-client.c
dtls-client.c dtls_ciphers_util.c
#cbc_aes128-test.c #dsrv-test.c
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
PROGRAMS:= $(patsubst %.c, %, $(SOURCES))
PROGRAMS:= dtls-server dtls-client ccm-test
HEADERS:=
CFLAGS:=-Wall -std=c99 @CFLAGS@ @WARNING_CFLAGS@ $(EXTRA_CFLAGS) -D_GNU_SOURCE
CPPFLAGS:=-I$(top_srcdir) @CPPFLAGS@
Expand All @@ -47,6 +47,8 @@ FILES:=Makefile.in $(SOURCES) ccm-testdata.c #cbc_aes128-testdata.c

all: $(PROGRAMS)

dtls-client dtls-server:: dtls_ciphers_util.o

check:
echo DISTDIR: $(DISTDIR)
echo top_builddir: $(top_builddir)
Expand Down
49 changes: 42 additions & 7 deletions tests/dtls-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "global.h"
#include "dtls_debug.h"
#include "dtls_ciphers_util.h"
#include "dtls.h"

#define DEFAULT_PORT 20220
Expand All @@ -59,6 +60,9 @@ static dtls_str output_file = { 0, NULL }; /* output file name */
static dtls_context_t *dtls_context = NULL;
static dtls_context_t *orig_dtls_context = NULL;

static const dtls_cipher_t* ciphers = NULL;
static unsigned int force_extended_master_secret = 0;


#ifdef DTLS_ECC
static const unsigned char ecdsa_priv_key[] = {
Expand Down Expand Up @@ -228,6 +232,27 @@ send_to_peer(struct dtls_context_t *ctx,
&session->addr.sa, session->size);
}

static void
get_user_parameters(struct dtls_context_t *ctx,
session_t *session, dtls_user_parameters_t *user_parameters) {
(void) ctx;
(void) session;
user_parameters->force_extended_master_secret = force_extended_master_secret;
if (ciphers) {
int index = 0;
while (index < DTLS_MAX_CIPHER_SUITES) {
user_parameters->cipher_suites[index] = ciphers[index];
if (ciphers[index] == TLS_NULL_WITH_NULL_NULL) {
break;
}
++index;
}
if (index == DTLS_MAX_CIPHER_SUITES) {
user_parameters->cipher_suites[index] = TLS_NULL_WITH_NULL_NULL;
}
}
}

static int
dtls_handle_read(struct dtls_context_t *ctx) {
int fd;
Expand Down Expand Up @@ -328,23 +353,27 @@ usage( const char *program, const char *version) {
fprintf(stderr, "%s v%s -- DTLS client implementation\n"
"(c) 2011-2014 Olaf Bergmann <[email protected]>\n\n"
#ifdef DTLS_PSK
"usage: %s [-i file] [-k file] [-o file] [-p port] [-v num] addr [port]\n"
"usage: %s [-c cipher suites] [-e] [-i file] [-k file] [-o file] [-p port] [-v num] addr [port]\n",
#else /* DTLS_PSK */
"usage: %s [-o file] [-p port] [-v num] addr [port]\n"
"usage: %s [-c cipher suites] [-e] [-o file] [-p port] [-v num] addr [port]\n",
#endif /* DTLS_PSK */
program, version, program);
cipher_suites_usage(stderr, "\t");
fprintf(stderr, "\t-e\t\tforce extended master secret (RFC7627)\n"
#ifdef DTLS_PSK
"\t-i file\t\tread PSK identity from file\n"
"\t-k file\t\tread pre-shared key from file\n"
#endif /* DTLS_PSK */
"\t-o file\t\toutput received data to this file (use '-' for STDOUT)\n"
"\t-p port\t\tlisten on specified port (default is %d)\n"
"\t-v num\t\tverbosity level (default: 3)\n",
program, version, program, DEFAULT_PORT);
DEFAULT_PORT);
}

static dtls_handler_t cb = {
.write = send_to_peer,
.read = read_from_peer,
.get_user_parameters = get_user_parameters,
.event = NULL,
#ifdef DTLS_PSK
.get_psk_info = get_psk_info,
Expand Down Expand Up @@ -393,7 +422,7 @@ main(int argc, char **argv) {
memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length);
#endif /* DTLS_PSK */

while ((opt = getopt(argc, argv, "p:o:v:" PSK_OPTIONS)) != -1) {
while ((opt = getopt(argc, argv, "c:eo:p:v:" PSK_OPTIONS)) != -1) {
switch (opt) {
#ifdef DTLS_PSK
case 'i' :
Expand All @@ -413,9 +442,11 @@ main(int argc, char **argv) {
}
break;
#endif /* DTLS_PSK */
case 'p' :
strncpy(port_str, optarg, NI_MAXSERV-1);
port_str[NI_MAXSERV - 1] = '\0';
case 'c' :
ciphers = init_cipher_suites(optarg);
break;
case 'e' :
force_extended_master_secret = 1;
break;
case 'o' :
output_file.length = strlen(optarg);
Expand All @@ -429,6 +460,10 @@ main(int argc, char **argv) {
memcpy(output_file.s, optarg, output_file.length + 1);
}
break;
case 'p' :
strncpy(port_str, optarg, NI_MAXSERV-1);
port_str[NI_MAXSERV - 1] = '\0';
break;
case 'v' :
log_level = strtol(optarg, NULL, 10);
break;
Expand Down
49 changes: 41 additions & 8 deletions tests/dtls-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
#include <signal.h>

#include "tinydtls.h"
#include "dtls.h"
#include "dtls_debug.h"
#include "dtls_ciphers_util.h"
#include "dtls.h"

#ifdef IS_WINDOWS
#include <winsock2.h>
Expand All @@ -44,6 +45,9 @@
#define DEFAULT_PORT 20220

static dtls_context_t *the_context = NULL;
static volatile int cmd_exit = 0;
static const dtls_cipher_t* ciphers = NULL;
static unsigned int force_extended_master_secret = 0;

#ifdef DTLS_ECC
static const unsigned char ecdsa_priv_key[] = {
Expand Down Expand Up @@ -151,8 +155,6 @@ verify_ecdsa_key(struct dtls_context_t *ctx,
#define DTLS_SERVER_CMD_CLOSE "server:close"
#define DTLS_SERVER_CMD_EXIT "server:exit"

static volatile int cmd_exit = 0;

static int
is_command(const char* cmd, const uint8 *data, size_t len) {
size_t cmd_len = strlen(cmd);
Expand Down Expand Up @@ -191,6 +193,27 @@ send_to_peer(struct dtls_context_t *ctx,
&session->addr.sa, session->size);
}

static void
get_user_parameters(struct dtls_context_t *ctx,
session_t *session, dtls_user_parameters_t *user_parameters) {
(void) ctx;
(void) session;
user_parameters->force_extended_master_secret = force_extended_master_secret;
if (ciphers) {
int index = 0;
while (index < DTLS_MAX_CIPHER_SUITES) {
user_parameters->cipher_suites[index] = ciphers[index];
if (ciphers[index] == TLS_NULL_WITH_NULL_NULL) {
break;
}
++index;
}
if (index == DTLS_MAX_CIPHER_SUITES) {
user_parameters->cipher_suites[index] = TLS_NULL_WITH_NULL_NULL;
}
}
}

static int
dtls_handle_read(struct dtls_context_t *ctx) {
int *fd;
Expand Down Expand Up @@ -283,17 +306,21 @@ usage(const char *program, const char *version) {
program = ++p;

fprintf(stderr, "%s v%s -- DTLS server implementation\n"
"(c) 2011-2014 Olaf Bergmann <[email protected]>\n\n"
"usage: %s [-A address] [-p port] [-v num]\n"
"\t-A address\t\tlisten on specified address (default is ::)\n"
"(c) 2011-2014 Olaf Bergmann <[email protected]>\n\n"
"usage: %s [-A address] [-c cipher suites] [-e] [-p port] [-v num]\n"
"\t-A address\t\tlisten on specified address (default is ::)\n",
program, version, program);
cipher_suites_usage(stderr, "\t");
fprintf(stderr, "\t-e\t\tforce extended master secret (RFC7627)\n"
"\t-p port\t\tlisten on specified port (default is %d)\n"
"\t-v num\t\tverbosity level (default: 3)\n",
program, version, program, DEFAULT_PORT);
DEFAULT_PORT);
}

static dtls_handler_t cb = {
.write = send_to_peer,
.read = read_from_peer,
.get_user_parameters = get_user_parameters,
.event = NULL,
#ifdef DTLS_PSK
.get_psk_info = get_psk_info,
Expand Down Expand Up @@ -328,14 +355,20 @@ main(int argc, char **argv) {
listen_addr.sin6_family = AF_INET6;
listen_addr.sin6_addr = in6addr_any;

while ((opt = getopt(argc, argv, "A:p:v:")) != -1) {
while ((opt = getopt(argc, argv, "A:c:ep:v:")) != -1) {
switch (opt) {
case 'A' :
if (resolve_address(optarg, (struct sockaddr *)&listen_addr) < 0) {
fprintf(stderr, "cannot resolve address\n");
exit(-1);
}
break;
case 'c' :
ciphers = init_cipher_suites(optarg);
break;
case 'e' :
force_extended_master_secret = 1;
break;
case 'p' :
port = htons(atoi(optarg));
break;
Expand Down
96 changes: 96 additions & 0 deletions tests/dtls_ciphers_util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*******************************************************************************
*
* Copyright (c) 2022 Contributors to the Eclipse Foundation.
*
* 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 <string.h>
#include <math.h>

#include "dtls_ciphers_util.h"


struct cipher_entry {
const char* name;
const dtls_cipher_t cipher;
};

#define CIPHER_ENTRY(X) { .name = #X, .cipher = X }
#define ARRAY_LENGTH (sizeof(map)/sizeof(struct cipher_entry))
#define SEP ':'

static const struct cipher_entry map[] = {
#ifdef DTLS_PSK
CIPHER_ENTRY(TLS_PSK_WITH_AES_128_CCM),
CIPHER_ENTRY(TLS_PSK_WITH_AES_128_CCM_8),
#endif /* DTLS_PSK */
#ifdef DTLS_ECC
CIPHER_ENTRY(TLS_ECDHE_ECDSA_WITH_AES_128_CCM),
CIPHER_ENTRY(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8),
#endif /* DTLS_ECC */
{ .name = NULL, .cipher = TLS_NULL_WITH_NULL_NULL}
};

static dtls_cipher_t ciphers_table[ARRAY_LENGTH] = { TLS_NULL_WITH_NULL_NULL };

static dtls_cipher_t find_cipher_suite(const char *arg) {
if (arg) {
size_t arg_len = strlen(arg);
for (size_t index=0; index < ARRAY_LENGTH - 1; ++index) {
size_t len = strlen(map[index].name);
if (len <= arg_len) {
if (strncmp(arg, map[index].name, len) == 0 && (arg[len] == 0 || arg[len] == SEP)) {
return map[index].cipher;
}
}
}
}
return TLS_NULL_WITH_NULL_NULL;
}

static void add_cipher_suite(dtls_cipher_t cipher) {
for (size_t index=0; index < ARRAY_LENGTH - 1; ++index) {
if (ciphers_table[index] == cipher) {
return;
}
if (ciphers_table[index] == TLS_NULL_WITH_NULL_NULL) {
ciphers_table[index] = cipher;
ciphers_table[index + 1] = TLS_NULL_WITH_NULL_NULL;
return;
}
}
}

const dtls_cipher_t*
init_cipher_suites(const char* arg) {
while (arg) {
dtls_cipher_t cipher = find_cipher_suite(arg);
if (cipher != TLS_NULL_WITH_NULL_NULL) {
add_cipher_suite(cipher);
}
arg = strchr(arg, SEP);
if (arg) {
++arg;
}
}
return ciphers_table;
}

void
cipher_suites_usage(FILE* file, const char* head) {
fprintf(file, "%s-c ciphers\tlist of cipher suites separated by ':'\n", head);
fprintf(file, "%s\t\t(default is %s", head, map[0].name);
for (int index = 1; map[index].name; ++index) {
fprintf(file, "\n%s\t\t :%s", head, map[index].name);
}
fprintf(file, ")\n");
}

26 changes: 26 additions & 0 deletions tests/dtls_ciphers_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
*
* Copyright (c) 2022 Contributors to the Eclipse Foundation.
*
* 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.
*
*******************************************************************************/

#ifndef _DTLS_CIPHERS_UTIL_H_
#define _DTLS_CIPHERS_UTIL_H_

#include <stdio.h>

#include "global.h"

const dtls_cipher_t* init_cipher_suites(const char* arg);

void cipher_suites_usage(FILE* file, const char* head);

#endif /* _DTLS_CIPHERS_UTIL_H_ */

0 comments on commit 90ca321

Please sign in to comment.