mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #20048 from leandrolanzieri/pr/tinydtls/check_public_key
net/sock_dtls: add public key verification
This commit is contained in:
commit
741d6b3d4a
@ -20,6 +20,10 @@ USEPKG += tinydtls
|
||||
|
||||
# Pull in sock APIs
|
||||
USEMODULE += sock_dtls
|
||||
# When using asymmetric cryptography, e.g. ecc,
|
||||
# this verifies the public key against a known set.
|
||||
# It does not affect symmetric crypto e.g. PSK.
|
||||
USEMODULE += sock_dtls_verify_public_key
|
||||
USEMODULE += sock_udp
|
||||
|
||||
# extra utilities for endpoint printing
|
||||
|
@ -52,25 +52,25 @@ for more information.
|
||||
When using Pre-Shared Key (PSK), the client registers two keys to `credman` and
|
||||
makes them available to the sock. The client registers a PSK callback function,
|
||||
which allows the application to specify which credential to use with a
|
||||
particular sock and endpoint. In this application the client will print the
|
||||
server's endpoint and the sent hint, if any. As per the sock DTLS documentation,
|
||||
if the application callback fails to determine which credential should be used,
|
||||
an Identity Hint (https://tools.ietf.org/html/rfc4279#section-5.2) match is
|
||||
attempted. `credential1` is assigned an Identity Hint, defined as
|
||||
`PSK_DEFAULT_HINT` in `tinydtls_keys.h`. This hint is used by sock to select the
|
||||
credential, in case the DTLS server sends such a hint. Finally, if none of the
|
||||
above attempts succeed in determining which credential to use, sock DTLS will
|
||||
pick the first valid credential registered in the sock.
|
||||
particular sock and endpoint, depending on the hint sent by the server. As per
|
||||
the sock DTLS documentation, if the application callback fails to determine
|
||||
which credential should be used, an Identity Hint
|
||||
(https://tools.ietf.org/html/rfc4279#section-5.2) match is attempted.
|
||||
`credential1` is assigned an Identity Hint, defined as `PSK_DEFAULT_HINT` in
|
||||
`tinydtls_keys.h`. This hint is used by sock to select the credential, in case
|
||||
the DTLS server sends such a hint. Finally, if none of the above attempts
|
||||
succeed in determining which credential to use, sock DTLS will pick the first
|
||||
valid credential registered in the sock.
|
||||
|
||||
The behaviour above can be tested, for example, by removing the hint from the
|
||||
server (`sock_dtls_set_server_psk_id_hint`). As `credential0` is the first
|
||||
server (`sock_dtls_set_server_psk_id_hint`). As `psk_credential_0` is the first
|
||||
registered credential in the client, it will be chosen. As the server does not
|
||||
have this credential, the handshake will fail.
|
||||
|
||||
### ECC
|
||||
When using ECC Raw Public Key (RPK), the server registers two keys to `credman`
|
||||
and makes them available to the sock. It also registers an RPK callback
|
||||
function, which allows the application to specify which credential to use with a
|
||||
particular sock and endpoint (the client could as well do so). In the particular
|
||||
case of this example the callback always returns the credential with tag
|
||||
`SOCK_DTLS_SERVER_TAG_1`.
|
||||
When using ECC Raw Public Key (RPK), the server registers two private keys to
|
||||
`credman` and makes them available to the sock. It also registers an RPK
|
||||
callback function, which allows the application to specify which credential to
|
||||
use. The used credential can be changed at runtime by calling `dtlss ecc <0|1>`.
|
||||
As the client also knows both public keys from the server, both options will
|
||||
work.
|
||||
|
@ -29,56 +29,60 @@
|
||||
#include "net/sock/util.h"
|
||||
#include "net/utils.h"
|
||||
|
||||
#include "tinydtls_keys.h"
|
||||
#include "dtls_client_credentials.h"
|
||||
|
||||
#ifndef DTLS_DEFAULT_PORT
|
||||
#define DTLS_DEFAULT_PORT 20220 /* DTLS default port */
|
||||
#define DTLS_DEFAULT_PORT (20220) /* DTLS default port */
|
||||
#endif
|
||||
|
||||
static bool _client_credentials_configured = false;
|
||||
|
||||
/* Credman tags to select which credentials to use */
|
||||
#define SOCK_DTLS_CLIENT_TAG_0 (2)
|
||||
#define SOCK_DTLS_CLIENT_TAG_1 (3)
|
||||
|
||||
#ifdef CONFIG_DTLS_ECC
|
||||
static const ecdsa_public_key_t other_pubkeys0[] = {
|
||||
{ .x = ecdsa_pub_key0_x, .y = ecdsa_pub_key0_y },
|
||||
static const ecdsa_public_key_t server_public_keys[] = {
|
||||
{ .x = known_server_public_key_0_x, .y = known_server_public_key_0_y },
|
||||
{ .x = known_server_public_key_1_x, .y = known_server_public_key_1_y },
|
||||
};
|
||||
|
||||
static const credman_credential_t credential0 = {
|
||||
static const credman_credential_t ecc_credential_0 = {
|
||||
.type = CREDMAN_TYPE_ECDSA,
|
||||
.tag = SOCK_DTLS_CLIENT_TAG_0,
|
||||
.params = {
|
||||
.ecdsa = {
|
||||
.private_key = ecdsa_priv_key0,
|
||||
.private_key = client_private_key_0,
|
||||
.public_key = {
|
||||
.x = ecdsa_pub_key0_x,
|
||||
.y = ecdsa_pub_key0_y,
|
||||
.x = client_public_key_0_x,
|
||||
.y = client_public_key_0_y,
|
||||
},
|
||||
.client_keys = (ecdsa_public_key_t *)other_pubkeys0,
|
||||
.client_keys_size = ARRAY_SIZE(other_pubkeys0),
|
||||
.client_keys = (ecdsa_public_key_t *)server_public_keys,
|
||||
.client_keys_size = ARRAY_SIZE(server_public_keys),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#else /* ifdef CONFIG_DTLS_PSK */
|
||||
static const uint8_t psk_id_0[] = PSK_WRONG_IDENTITY;
|
||||
static const uint8_t psk_key_0[] = PSK_WRONG_KEY;
|
||||
static const uint8_t psk_id_0[] = CLIENT_PSK_IDENTITY_0;
|
||||
static const uint8_t psk_key_0[] = CLIENT_PSK_IDENTITY_0_KEY;
|
||||
static const char psk_id_0_hint[] = CLIENT_PSK_IDENTITY_0_HINT;
|
||||
|
||||
static const uint8_t psk_id_1[] = PSK_DEFAULT_IDENTITY;
|
||||
static const uint8_t psk_key_1[] = PSK_DEFAULT_KEY;
|
||||
static const char psk_id_1_hint[] = PSK_DEFAULT_HINT;
|
||||
static const uint8_t psk_id_1[] = CLIENT_PSK_IDENTITY_1;
|
||||
static const uint8_t psk_key_1[] = CLIENT_PSK_IDENTITY_1_KEY;
|
||||
static const char psk_id_1_hint[] = CLIENT_PSK_IDENTITY_1_HINT;
|
||||
|
||||
static const credman_credential_t credential0 = {
|
||||
static const credman_credential_t psk_credential_0 = {
|
||||
.type = CREDMAN_TYPE_PSK,
|
||||
.tag = SOCK_DTLS_CLIENT_TAG_0,
|
||||
.params = {
|
||||
.psk = {
|
||||
.key = { .s = psk_key_0, .len = sizeof(psk_key_0) - 1, },
|
||||
.id = { .s = psk_id_0, .len = sizeof(psk_id_0) - 1, },
|
||||
.hint = { .s = psk_id_0_hint, .len = sizeof(psk_id_0_hint) - 1, },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static const credman_credential_t credential1 = {
|
||||
static const credman_credential_t psk_credential_1 = {
|
||||
.type = CREDMAN_TYPE_PSK,
|
||||
.tag = SOCK_DTLS_CLIENT_TAG_1,
|
||||
.params = {
|
||||
@ -89,7 +93,60 @@ static const credman_credential_t credential1 = {
|
||||
}
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static credman_tag_t _client_psk_cb(sock_dtls_t *sock, sock_udp_ep_t *ep, credman_tag_t tags[],
|
||||
unsigned tags_len, const char *hint, size_t hint_len)
|
||||
{
|
||||
(void) sock;
|
||||
(void) tags;
|
||||
(void) tags_len;
|
||||
|
||||
char addrstr[IPV6_ADDR_MAX_STR_LEN];
|
||||
uint16_t port;
|
||||
|
||||
sock_udp_ep_fmt(ep, addrstr, &port);
|
||||
printf("From [%s]:%" PRIu16" \n", addrstr, port);
|
||||
|
||||
/* if we got a hint, try to use it to determine which PSK to use */
|
||||
if (hint && hint_len) {
|
||||
printf("Client got hint: %.*s\n", (unsigned)hint_len, hint);
|
||||
|
||||
if (hint_len == sizeof(psk_id_0_hint) &&
|
||||
!memcmp(hint, psk_id_0_hint, sizeof(psk_id_0_hint) - 1)) {
|
||||
return SOCK_DTLS_CLIENT_TAG_0;
|
||||
}
|
||||
|
||||
if (hint_len == sizeof(psk_id_1_hint) &&
|
||||
!memcmp(hint, psk_id_1_hint, sizeof(psk_id_1_hint) - 1)) {
|
||||
return SOCK_DTLS_CLIENT_TAG_1;
|
||||
}
|
||||
}
|
||||
|
||||
return CREDMAN_TAG_EMPTY;
|
||||
}
|
||||
|
||||
static int _configure_client_credentials(void)
|
||||
{
|
||||
/* register the credentials on credman */
|
||||
if (IS_ACTIVE(CONFIG_DTLS_ECC)) {
|
||||
if (credman_add(&ecc_credential_0) != CREDMAN_OK) {
|
||||
puts("Error cannot add ECC credential 0 to system");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (IS_ACTIVE(CONFIG_DTLS_PSK)) {
|
||||
if (credman_add(&psk_credential_0) != CREDMAN_OK) {
|
||||
puts("Error cannot add PSK credential 0 to system");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (credman_add(&psk_credential_1) != CREDMAN_OK) {
|
||||
puts("Error cannot add PSK credential 1 to system");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_send(char *addr_str, char *data, size_t datalen)
|
||||
{
|
||||
@ -102,7 +159,6 @@ static int client_send(char *addr_str, char *data, size_t datalen)
|
||||
local.port = 12345;
|
||||
remote.port = DTLS_DEFAULT_PORT;
|
||||
uint8_t buf[DTLS_HANDSHAKE_BUFSIZE];
|
||||
credman_tag_t tag = SOCK_DTLS_CLIENT_TAG_0;
|
||||
|
||||
/* get interface */
|
||||
netif_t *netif;
|
||||
@ -115,34 +171,48 @@ static int client_send(char *addr_str, char *data, size_t datalen)
|
||||
remote.netif = netif_get_id(netif);
|
||||
}
|
||||
|
||||
res = credman_add(&credential0);
|
||||
if (res < 0 && res != CREDMAN_EXIST) {
|
||||
/* ignore duplicate credentials */
|
||||
printf("Error cannot add credential to system: %" PRIdSIZE "\n", res);
|
||||
if (sock_udp_create(&udp_sock, &local, NULL, 0) < 0) {
|
||||
puts("Error creating UDP sock");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently DTLS sock needs one and only one credential for the
|
||||
* initialization. Subsequent credentials are made available to the sock
|
||||
* by means of `sock_dtls_add_credential`.
|
||||
*/
|
||||
if (sock_dtls_create(&dtls_sock, &udp_sock, SOCK_DTLS_CLIENT_TAG_0,
|
||||
SOCK_DTLS_1_2, SOCK_DTLS_CLIENT) < 0) {
|
||||
puts("Error creating DTLS sock");
|
||||
sock_udp_close(&udp_sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if IS_ACTIVE(CONFIG_DTLS_PSK)
|
||||
/* register a second PSK credential */
|
||||
res = credman_add(&credential1);
|
||||
if (res < 0 && res != CREDMAN_EXIST) {
|
||||
/* ignore duplicate credentials */
|
||||
printf("Error cannot add credential to system: %" PRIdSIZE "\n", res);
|
||||
sock_udp_close(&udp_sock);
|
||||
return -1;
|
||||
}
|
||||
tag = SOCK_DTLS_CLIENT_TAG_1;
|
||||
#endif
|
||||
if (IS_ACTIVE(CONFIG_DTLS_PSK)) {
|
||||
/* make the new credential available to the sock */
|
||||
if (sock_dtls_add_credential(&dtls_sock, SOCK_DTLS_CLIENT_TAG_1) < 0) {
|
||||
puts("Error cannot add second PSK credential to the sock");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = sock_dtls_establish_session(&udp_sock, &dtls_sock, &session, tag,
|
||||
&local, &remote, buf, sizeof(buf));
|
||||
if (res) {
|
||||
sock_udp_close(&udp_sock);
|
||||
printf("Error establishing connection: %d\n", (int)res);
|
||||
/* register a callback for PSK credential selection */
|
||||
sock_dtls_set_client_psk_cb(&dtls_sock, _client_psk_cb);
|
||||
}
|
||||
|
||||
res = sock_dtls_session_init(&dtls_sock, &remote, &session);
|
||||
if (res <= 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = sock_dtls_recv(&dtls_sock, &session, buf, sizeof(buf),
|
||||
SOCK_NO_TIMEOUT);
|
||||
if (res != -SOCK_DTLS_HANDSHAKE) {
|
||||
printf("Error creating session: %" PRIiSIZE "\n", res);
|
||||
sock_dtls_close(&dtls_sock);
|
||||
sock_udp_close(&udp_sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Connection to server successful\n");
|
||||
|
||||
if (sock_dtls_send(&dtls_sock, &session, data, datalen, 0) < 0) {
|
||||
@ -172,5 +242,13 @@ int dtls_client_cmd(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_client_credentials_configured) {
|
||||
int res = _configure_client_credentials();
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
_client_credentials_configured = true;
|
||||
}
|
||||
|
||||
return client_send(argv[1], argv[2], strlen(argv[2]));
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
* @brief DTLS sock server example
|
||||
*
|
||||
* @author Aiman Ismail <muhammadaimanbin.ismail@haw-hamburg.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -27,59 +28,64 @@
|
||||
#include "thread.h"
|
||||
#include "timex.h"
|
||||
|
||||
#include "tinydtls_keys.h"
|
||||
#include "dtls_server_credentials.h"
|
||||
|
||||
#ifndef DTLS_DEFAULT_PORT
|
||||
#define DTLS_DEFAULT_PORT (20220) /* DTLS default port */
|
||||
#endif
|
||||
|
||||
static bool _server_credentials_configured = false;
|
||||
|
||||
/* Credman tags to select which credentials to use */
|
||||
#define SOCK_DTLS_SERVER_TAG_0 (10)
|
||||
#define SOCK_DTLS_SERVER_TAG_1 (11)
|
||||
|
||||
#define DTLS_STOP_SERVER_MSG 0x4001 /* Custom IPC type msg. */
|
||||
#define READER_QUEUE_SIZE (8U)
|
||||
|
||||
char _dtls_server_stack[THREAD_STACKSIZE_MAIN +
|
||||
THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
char _dtls_server_stack[THREAD_STACKSIZE_MAIN + THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
|
||||
static kernel_pid_t _dtls_server_pid = KERNEL_PID_UNDEF;
|
||||
|
||||
#ifdef CONFIG_DTLS_ECC
|
||||
static const ecdsa_public_key_t other_pubkeys[] = {
|
||||
{ .x = ecdsa_pub_key0_x, .y = ecdsa_pub_key0_y },
|
||||
static unsigned int _ecc_credential = 0;
|
||||
|
||||
/*
|
||||
* Each credman_credential_t acts as a sort of keyring, containing a single
|
||||
* private / public key pair and a list of public keys of clients that are
|
||||
* known.
|
||||
*/
|
||||
static const ecdsa_public_key_t known_client_pub_keys[] = {
|
||||
{ .x = known_client_public_key_0_x, .y = known_client_public_key_0_y }
|
||||
};
|
||||
|
||||
static const credman_credential_t credential0 = {
|
||||
static const credman_credential_t ecc_credential_0 = {
|
||||
.type = CREDMAN_TYPE_ECDSA,
|
||||
.tag = SOCK_DTLS_SERVER_TAG_0,
|
||||
.params = {
|
||||
.ecdsa = {
|
||||
.private_key = ecdsa_priv_key0,
|
||||
.private_key = server_private_key_0,
|
||||
.public_key = {
|
||||
.x = ecdsa_pub_key0_x,
|
||||
.y = ecdsa_pub_key0_y,
|
||||
.x = server_public_key_0_x,
|
||||
.y = server_public_key_0_y,
|
||||
},
|
||||
.client_keys = (ecdsa_public_key_t *)other_pubkeys,
|
||||
.client_keys_size = ARRAY_SIZE(other_pubkeys),
|
||||
.client_keys = (ecdsa_public_key_t *)known_client_pub_keys,
|
||||
.client_keys_size = ARRAY_SIZE(known_client_pub_keys),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const ecdsa_public_key_t other_pubkeys1[] = {
|
||||
{ .x = ecdsa_pub_key1_x, .y = ecdsa_pub_key1_y },
|
||||
};
|
||||
|
||||
static const credman_credential_t credential1 = {
|
||||
static const credman_credential_t ecc_credential_1 = {
|
||||
.type = CREDMAN_TYPE_ECDSA,
|
||||
.tag = SOCK_DTLS_SERVER_TAG_1,
|
||||
.params = {
|
||||
.ecdsa = {
|
||||
.private_key = ecdsa_priv_key1,
|
||||
.private_key = server_private_key_1,
|
||||
.public_key = {
|
||||
.x = ecdsa_pub_key1_x,
|
||||
.y = ecdsa_pub_key1_y,
|
||||
.x = server_public_key_1_x,
|
||||
.y = server_public_key_1_y,
|
||||
},
|
||||
.client_keys = (ecdsa_public_key_t *)other_pubkeys1,
|
||||
.client_keys_size = ARRAY_SIZE(other_pubkeys1),
|
||||
.client_keys = (ecdsa_public_key_t *)known_client_pub_keys,
|
||||
.client_keys_size = ARRAY_SIZE(known_client_pub_keys),
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -98,24 +104,53 @@ static credman_tag_t _rpk_cb(sock_dtls_t *sock, sock_udp_ep_t *ep, credman_tag_t
|
||||
sock_udp_ep_fmt(ep, addrstr, &port);
|
||||
printf("From [%s]:%d\n", addrstr, port);
|
||||
|
||||
return SOCK_DTLS_SERVER_TAG_1;
|
||||
if (!_ecc_credential) {
|
||||
return SOCK_DTLS_SERVER_TAG_0;
|
||||
}
|
||||
else {
|
||||
return SOCK_DTLS_SERVER_TAG_1;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* #ifdef CONFIG_DTLS_PSK */
|
||||
static const uint8_t psk_id_0[] = PSK_DEFAULT_IDENTITY;
|
||||
static const uint8_t psk_key_0[] = PSK_DEFAULT_KEY;
|
||||
/*
|
||||
* We have a single PSK.
|
||||
*/
|
||||
static const uint8_t psk_id[] = SERVER_PSK_IDENTITY;
|
||||
static const uint8_t psk_key[] = SERVER_PSK_IDENTITY_KEY;
|
||||
|
||||
static const credman_credential_t credential0 = {
|
||||
static const credman_credential_t psk_credential_0 = {
|
||||
.type = CREDMAN_TYPE_PSK,
|
||||
.tag = SOCK_DTLS_SERVER_TAG_0,
|
||||
.params = {
|
||||
.psk = {
|
||||
.key = { .s = psk_key_0, .len = sizeof(psk_key_0) - 1, },
|
||||
.id = { .s = psk_id_0, .len = sizeof(psk_id_0) - 1, },
|
||||
.key = { .s = psk_key, .len = sizeof(psk_key) - 1, },
|
||||
.id = { .s = psk_id, .len = sizeof(psk_id) - 1, },
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static int _configure_server_credentials(void)
|
||||
{
|
||||
/* register the credentials on credman */
|
||||
if (IS_ACTIVE(CONFIG_DTLS_ECC)) {
|
||||
if (credman_add(&ecc_credential_0) != CREDMAN_OK) {
|
||||
puts("Error cannot add ECC credential 0 to system");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (credman_add(&ecc_credential_1) != CREDMAN_OK) {
|
||||
puts("Error cannot add ECC credential 1 to system");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (IS_ACTIVE(CONFIG_DTLS_PSK)) {
|
||||
if (credman_add(&psk_credential_0) != CREDMAN_OK) {
|
||||
puts("Error cannot add PSK credential 0 to system");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *dtls_server_wrapper(void *arg)
|
||||
{
|
||||
@ -136,13 +171,11 @@ void *dtls_server_wrapper(void *arg)
|
||||
local.port = DTLS_DEFAULT_PORT;
|
||||
sock_udp_create(&udp_sock, &local, NULL, 0);
|
||||
|
||||
res = credman_add(&credential0);
|
||||
if (res < 0 && res != CREDMAN_EXIST) {
|
||||
/* ignore duplicate credentials */
|
||||
printf("Error cannot add credential to system: %" PRIdSIZE "\n", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently DTLS sock needs one and only one credential for the
|
||||
* initialization. Subsequent credentials are made available to the sock
|
||||
* by means of `sock_dtls_add_credential`.
|
||||
*/
|
||||
res = sock_dtls_create(&sock, &udp_sock, SOCK_DTLS_SERVER_TAG_0,
|
||||
SOCK_DTLS_1_2, SOCK_DTLS_SERVER);
|
||||
if (res < 0) {
|
||||
@ -150,33 +183,24 @@ void *dtls_server_wrapper(void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set PSK Identity hint, this is optional and application-specific */
|
||||
#if IS_ACTIVE(CONFIG_DTLS_PSK)
|
||||
if (sock_dtls_set_server_psk_id_hint(&sock, PSK_DEFAULT_HINT) < 0) {
|
||||
puts("Error setting PSK Identity hint");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (IS_ACTIVE(CONFIG_DTLS_ECC)) {
|
||||
/* make the second ECC credential available to the sock */
|
||||
if (sock_dtls_add_credential(&sock, SOCK_DTLS_SERVER_TAG_1) < 0) {
|
||||
puts("Error cannot add second ECC credential to the sock");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if IS_ACTIVE(CONFIG_DTLS_ECC)
|
||||
/* register a second RPK */
|
||||
res = credman_add(&credential1);
|
||||
if (res < 0 && res != CREDMAN_EXIST) {
|
||||
/* ignore duplicate credentials */
|
||||
printf("Error cannot add credential to system: %" PRIdSIZE "\n", res);
|
||||
return NULL;
|
||||
/* register a callback for RPK credential selection */
|
||||
sock_dtls_set_rpk_cb(&sock, _rpk_cb);
|
||||
}
|
||||
|
||||
/* make the new credential available to the sock */
|
||||
if (sock_dtls_add_credential(&sock, SOCK_DTLS_SERVER_TAG_1) < 0) {
|
||||
printf("Error cannot add credential to the sock: %" PRIdSIZE "\n", res);
|
||||
return NULL;
|
||||
else if (IS_ACTIVE(CONFIG_DTLS_PSK)) {
|
||||
/* set PSK Identity hint, this is optional and application-specific */
|
||||
if (sock_dtls_set_server_psk_id_hint(&sock, SERVER_PSK_IDENTITY_HINT) < 0) {
|
||||
puts("Error setting PSK Identity hint");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* register a callback for RPK credential selection */
|
||||
sock_dtls_set_rpk_cb(&sock, _rpk_cb);
|
||||
#endif
|
||||
|
||||
while (active) {
|
||||
if ((msg_try_receive(&msg) == 1) &&
|
||||
(msg.type == DTLS_STOP_SERVER_MSG)){
|
||||
@ -249,20 +273,55 @@ static void stop_server(void)
|
||||
puts("Success: DTLS server stopped");
|
||||
}
|
||||
|
||||
void _print_usage(const char *cmd)
|
||||
{
|
||||
if (IS_ACTIVE(CONFIG_DTLS_ECC)) {
|
||||
printf("usage: %s start | stop | ecc <0|1>\n", cmd);
|
||||
}
|
||||
else {
|
||||
printf("usage: %s start | stop\n", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
int dtls_server_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("usage: %s start | stop\n", argv[0]);
|
||||
_print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "start") == 0) {
|
||||
if (!_server_credentials_configured) {
|
||||
int res = _configure_server_credentials();
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
_server_credentials_configured = true;
|
||||
}
|
||||
start_server();
|
||||
}
|
||||
else if (strcmp(argv[1], "stop") == 0) {
|
||||
stop_server();
|
||||
}
|
||||
else if (IS_ACTIVE(CONFIG_DTLS_ECC) && strcmp(argv[1], "ecc") == 0) {
|
||||
/* if using ECC, allow choosing which key to use on handshakes at runtime */
|
||||
if (argc < 3) {
|
||||
_print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int value = atoi(argv[2]);
|
||||
if (value != 0 && value != 1) {
|
||||
printf("Error: invalid value, should be 0 or 1, got %i\n", value);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
_ecc_credential = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Error: invalid command. Usage: %s start | stop\n", argv[0]);
|
||||
printf("Error: invalid command.");
|
||||
_print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
139
examples/dtls-sock/dtls_client_credentials.h
Normal file
139
examples/dtls-sock/dtls_client_credentials.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2024 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PSK and RPK client credentials for the dtls-sock example.
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef DTLS_CLIENT_CREDENTIALS_H
|
||||
#define DTLS_CLIENT_CREDENTIALS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pre-Shared Key (PSK) credentials (client and server must have a copy)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The identity of the PSK 0
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_0 "Identity_0"
|
||||
|
||||
/**
|
||||
* @brief The PSK 0 itself.
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_0_KEY "secretPSK"
|
||||
|
||||
/**
|
||||
* @brief The identity hint of the PSK 0
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_0_HINT "Prefer_Id_0"
|
||||
|
||||
/**
|
||||
* @brief The identity of the PSK 1
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_1 "Identity_1"
|
||||
|
||||
/**
|
||||
* @brief The PSK 1 itself.
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_1_KEY "yetAnotherSecret"
|
||||
|
||||
/**
|
||||
* @brief The identity hint of the PSK 1
|
||||
*/
|
||||
#define CLIENT_PSK_IDENTITY_1_HINT "Prefer_Id_1"
|
||||
|
||||
/*
|
||||
* Raw Public Key (RPK) credentials
|
||||
*/
|
||||
/**
|
||||
* @brief The private part of the client key 0.
|
||||
*/
|
||||
static const unsigned char client_private_key_0[] = {
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the client key 0.
|
||||
*/
|
||||
static const unsigned char client_public_key_0_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
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the client key 0.
|
||||
*/
|
||||
static const unsigned char client_public_key_0_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
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the server key 0.
|
||||
*/
|
||||
static const unsigned char known_server_public_key_0_x[] = {
|
||||
0xef, 0x30, 0x0c, 0x57, 0x0a, 0x65, 0x7b, 0x98,
|
||||
0x53, 0x34, 0xfa, 0x52, 0x81, 0xd7, 0x9b, 0x72,
|
||||
0xb4, 0xe9, 0x48, 0xf0, 0x56, 0x37, 0xd0, 0x53,
|
||||
0xa7, 0x35, 0x61, 0x3c, 0x06, 0xfb, 0x9c, 0xe7,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the server key 0.
|
||||
*/
|
||||
static const unsigned char known_server_public_key_0_y[] = {
|
||||
0xd1, 0x98, 0xe6, 0x0a, 0x96, 0x41, 0xc7, 0x8a,
|
||||
0xac, 0x69, 0x09, 0x47, 0x64, 0x24, 0x30, 0x5f,
|
||||
0x1b, 0x70, 0xad, 0x2c, 0xf0, 0xba, 0xa2, 0xd7,
|
||||
0xdb, 0x6d, 0x11, 0xe0, 0x36, 0xb9, 0x1e, 0x87
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the server key 1.
|
||||
*/
|
||||
static const unsigned char known_server_public_key_1_x[] = {
|
||||
0x54, 0xe4, 0x3a, 0xa6, 0xe1, 0x19, 0xaf, 0x85,
|
||||
0xe4, 0x50, 0x0b, 0x67, 0x89, 0x57, 0x02, 0x82,
|
||||
0xad, 0x68, 0x90, 0xe1, 0xfb, 0xd0, 0x2a, 0x2b,
|
||||
0xc0, 0xfc, 0xc2, 0xeb, 0xdc, 0x48, 0x7f, 0x92
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the server key 1.
|
||||
*/
|
||||
static const unsigned char known_server_public_key_1_y[] = {
|
||||
0x25, 0x5f, 0x92, 0x94, 0x38, 0x73, 0xb4, 0xfd,
|
||||
0x17, 0x9e, 0xe0, 0x7f, 0x12, 0x93, 0xb9, 0xf4,
|
||||
0xa5, 0x70, 0x4e, 0xea, 0x09, 0x5f, 0xdf, 0xc1,
|
||||
0x8a, 0x66, 0x75, 0x86, 0xc3, 0x34, 0x39, 0x8b
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DTLS_CLIENT_CREDENTIALS_H */
|
135
examples/dtls-sock/dtls_server_credentials.h
Normal file
135
examples/dtls-sock/dtls_server_credentials.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2024 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PSK and RPK server credentials for the dtls-sock example.
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef DTLS_SERVER_CREDENTIALS_H
|
||||
#define DTLS_SERVER_CREDENTIALS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pre-Shared Key (PSK) credentials (client and server must have a copy)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The identity is used to indicate which key is used during the handshake.
|
||||
*/
|
||||
#define SERVER_PSK_IDENTITY "Identity_1"
|
||||
|
||||
/**
|
||||
* @brief The pre-shared key itself.
|
||||
*/
|
||||
#define SERVER_PSK_IDENTITY_KEY "yetAnotherSecret"
|
||||
|
||||
/**
|
||||
* @brief The identity hint is sent by the server to the client to help it decide on
|
||||
* which identity to use.
|
||||
*/
|
||||
#define SERVER_PSK_IDENTITY_HINT "Prefer_Id_1"
|
||||
|
||||
/*
|
||||
* Raw Public Key (RPK) credentials
|
||||
*/
|
||||
/**
|
||||
* @brief The private part of the server key 0.
|
||||
*/
|
||||
static const unsigned char server_private_key_0[] = {
|
||||
0x23, 0xbd, 0xd3, 0x6c, 0x10, 0x17, 0xe9, 0x0d,
|
||||
0xc1, 0x0a, 0x8f, 0x02, 0xf2, 0x0e, 0xe9, 0x5d,
|
||||
0xbe, 0x37, 0x38, 0x35, 0xb6, 0x4b, 0x8a, 0x1b,
|
||||
0x20, 0xa6, 0xa7, 0x86, 0x2f, 0xd1, 0xc8, 0xe5
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the server key 0.
|
||||
*/
|
||||
static const unsigned char server_public_key_0_x[] = {
|
||||
0xef, 0x30, 0x0c, 0x57, 0x0a, 0x65, 0x7b, 0x98,
|
||||
0x53, 0x34, 0xfa, 0x52, 0x81, 0xd7, 0x9b, 0x72,
|
||||
0xb4, 0xe9, 0x48, 0xf0, 0x56, 0x37, 0xd0, 0x53,
|
||||
0xa7, 0x35, 0x61, 0x3c, 0x06, 0xfb, 0x9c, 0xe7,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the server key 0.
|
||||
*/
|
||||
static const unsigned char server_public_key_0_y[] = {
|
||||
0xd1, 0x98, 0xe6, 0x0a, 0x96, 0x41, 0xc7, 0x8a,
|
||||
0xac, 0x69, 0x09, 0x47, 0x64, 0x24, 0x30, 0x5f,
|
||||
0x1b, 0x70, 0xad, 0x2c, 0xf0, 0xba, 0xa2, 0xd7,
|
||||
0xdb, 0x6d, 0x11, 0xe0, 0x36, 0xb9, 0x1e, 0x87
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The private part of the server key 1.
|
||||
*/
|
||||
static const unsigned char server_private_key_1[] = {
|
||||
0xac, 0x40, 0x25, 0x94, 0xd2, 0xd7, 0x33, 0x0b,
|
||||
0xaa, 0xd5, 0x51, 0x27, 0xd6, 0x76, 0xe8, 0xb7,
|
||||
0x23, 0xe3, 0x20, 0x9b, 0x90, 0xa0, 0xa0, 0xd0,
|
||||
0xcf, 0x3d, 0x8b, 0x7a, 0x0d, 0x38, 0x03, 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the server key 1.
|
||||
*/
|
||||
static const unsigned char server_public_key_1_x[] = {
|
||||
0x54, 0xe4, 0x3a, 0xa6, 0xe1, 0x19, 0xaf, 0x85,
|
||||
0xe4, 0x50, 0x0b, 0x67, 0x89, 0x57, 0x02, 0x82,
|
||||
0xad, 0x68, 0x90, 0xe1, 0xfb, 0xd0, 0x2a, 0x2b,
|
||||
0xc0, 0xfc, 0xc2, 0xeb, 0xdc, 0x48, 0x7f, 0x92
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the server key 1.
|
||||
*/
|
||||
static const unsigned char server_public_key_1_y[] = {
|
||||
0x25, 0x5f, 0x92, 0x94, 0x38, 0x73, 0xb4, 0xfd,
|
||||
0x17, 0x9e, 0xe0, 0x7f, 0x12, 0x93, 0xb9, 0xf4,
|
||||
0xa5, 0x70, 0x4e, 0xea, 0x09, 0x5f, 0xdf, 0xc1,
|
||||
0x8a, 0x66, 0x75, 0x86, 0xc3, 0x34, 0x39, 0x8b
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The x coordinate of the public part of the key 0 of a known client.
|
||||
*/
|
||||
static const unsigned char known_client_public_key_0_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
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The y coordinate of the public part of the key 0 of a known client.
|
||||
*/
|
||||
static const unsigned char known_client_public_key_0_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 __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DTLS_SERVER_CREDENTIALS_H */
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PSK and RPK keys for the dtls-sock example.
|
||||
*
|
||||
* @author Raul Fuentes <raul.fuentes-samaniego@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef TINYDTLS_KEYS_H
|
||||
#define TINYDTLS_KEYS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default keys examples for tinyDTLS (for RIOT, Linux and Contiki)
|
||||
*/
|
||||
#ifdef CONFIG_DTLS_PSK
|
||||
#define PSK_WRONG_IDENTITY "Wrong_identity"
|
||||
#define PSK_WRONG_KEY "wrong_secret"
|
||||
#define PSK_DEFAULT_IDENTITY "Client_identity"
|
||||
#define PSK_DEFAULT_KEY "secretPSK"
|
||||
#define PSK_DEFAULT_HINT "hint"
|
||||
|
||||
#endif /* CONFIG_DTLS_PSK */
|
||||
|
||||
#ifdef CONFIG_DTLS_ECC
|
||||
static const unsigned char ecdsa_priv_key0[] = {
|
||||
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_key0_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_key0_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
|
||||
};
|
||||
|
||||
static const unsigned char ecdsa_priv_key1[] = {
|
||||
0x99, 0x1b, 0x1c, 0xf1, 0x52, 0xa3, 0xf5, 0xac,
|
||||
0xce, 0x58, 0x00, 0x45, 0xdc, 0xa7, 0x45, 0x45,
|
||||
0x9e, 0xc6, 0xd8, 0x68, 0x21, 0xd4, 0x82, 0xb7,
|
||||
0x17, 0x84, 0x0a, 0xdc, 0x1d, 0xf1, 0x09, 0x57
|
||||
};
|
||||
|
||||
static const unsigned char ecdsa_pub_key1_x[] = {
|
||||
0xb7, 0x4e, 0xa0, 0x62, 0x96, 0xc5, 0xb9, 0x09,
|
||||
0xad, 0x36, 0x10, 0xab, 0xb1, 0xd8, 0x54, 0x69,
|
||||
0xef, 0x2b, 0x15, 0x5a, 0xb5, 0x28, 0x21, 0x21,
|
||||
0x9f, 0xa3, 0x9e, 0x6a, 0x02, 0xce, 0xb8, 0xb9
|
||||
};
|
||||
|
||||
static const unsigned char ecdsa_pub_key1_y[] = {
|
||||
0xcc, 0x0e, 0x88, 0x88, 0x91, 0x80, 0x7a, 0xdd,
|
||||
0xf7, 0x4e, 0x2e, 0xe6, 0x6e, 0xd4, 0x22, 0xde,
|
||||
0xbc, 0x68, 0xcd, 0x8f, 0xd9, 0x5a, 0xa0, 0xcd,
|
||||
0x5f, 0x4a, 0x1a, 0xb7, 0x2f, 0x95, 0xfc, 0x76
|
||||
};
|
||||
|
||||
#endif /* CONFIG_DTLS_ECC */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TINYDTLS_KEYS_H */
|
@ -453,6 +453,7 @@ PSEUDOMODULES += sock_aux_rssi
|
||||
PSEUDOMODULES += sock_aux_timestamp
|
||||
PSEUDOMODULES += sock_aux_ttl
|
||||
PSEUDOMODULES += sock_dtls
|
||||
PSEUDOMODULES += sock_dtls_verify_public_key
|
||||
PSEUDOMODULES += sock_ip
|
||||
PSEUDOMODULES += sock_tcp
|
||||
PSEUDOMODULES += sock_udp
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "dtls.h"
|
||||
#include "crypto.h"
|
||||
#include "log.h"
|
||||
#include "net/sock/dtls.h"
|
||||
#include "net/credman.h"
|
||||
@ -363,11 +364,59 @@ static int _get_ecdsa_key(struct dtls_context_t *ctx, const session_t *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _verify_public_ecdsa_key(credman_credential_t *credential,
|
||||
const unsigned char *other_pub_x,
|
||||
const unsigned char *other_pub_y)
|
||||
{
|
||||
/* check if any of the available client keys match the provided one */
|
||||
for (unsigned i = 0; i < credential->params.ecdsa.client_keys_size; i++) {
|
||||
if (memcmp(credential->params.ecdsa.client_keys[i].x, other_pub_x, DTLS_EC_KEY_SIZE) == 0 &&
|
||||
memcmp(credential->params.ecdsa.client_keys[i].y, other_pub_y, DTLS_EC_KEY_SIZE) == 0) {
|
||||
DEBUG("sock_dtls: client key %d matches\n", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("sock_dtls: credential does not match\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (IS_USED(MODULE_SOCK_DTLS_VERIFY_PUBLIC_KEY)) {
|
||||
int ret;
|
||||
credman_credential_t credential;
|
||||
sock_dtls_t *sock = (sock_dtls_t *)dtls_get_app_data(ctx);
|
||||
|
||||
credential.tag = CREDMAN_TAG_EMPTY;
|
||||
DEBUG("sock_dtls: verifying ECDSA public key of the other peer\n");
|
||||
|
||||
/* first check public key size */
|
||||
if (key_size != DTLS_EC_KEY_SIZE) {
|
||||
DEBUG("sock_dtls: invalid key length: %d (expected %d)\n", key_size, DTLS_EC_KEY_SIZE);
|
||||
return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE);
|
||||
}
|
||||
|
||||
/* check if any of the available credentials match the provided one */
|
||||
for (unsigned i = 0; i < sock->tags_len; i++) {
|
||||
ret = credman_get(&credential, sock->tags[i], CREDMAN_TYPE_ECDSA);
|
||||
if (ret != CREDMAN_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_verify_public_ecdsa_key(&credential, other_pub_x, other_pub_y)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* we could not find a valid credential */
|
||||
DEBUG("sock_dtls: no valid credential registered\n");
|
||||
return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE);
|
||||
}
|
||||
|
||||
(void)ctx;
|
||||
(void)session;
|
||||
(void)other_pub_y;
|
||||
|
@ -507,6 +507,13 @@
|
||||
* registered credential in the Sock's credential list, that matches the needed type. The first
|
||||
* one that matches is used.
|
||||
*
|
||||
* #### Public key verification when using ECC
|
||||
*
|
||||
* By enabling the pseudomodule `sock_dtls_verify_public_key` the DTLS sock will verify the
|
||||
* public key of the remote peer. When enabled, the DTLS sock will only accept a connection if
|
||||
* the provided public key is in the list of public keys assigned to the specified sock. This only
|
||||
* applies when using ECC ciphersuites (i.e., not PSK).
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
@ -517,6 +524,7 @@
|
||||
* @author Raul A. Fuentes Samaniego <raul.fuentes-samaniego@inria.fr>
|
||||
* @author Daniele Lacamera <daniele@wolfssl.com>
|
||||
* @author Ken Bannister <kb2ma@runbox.com>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef NET_SOCK_DTLS_H
|
||||
|
Loading…
Reference in New Issue
Block a user