mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
9a2ccd51f4
thread.h gnrc/netif.h
194 lines
5.4 KiB
C
194 lines
5.4 KiB
C
/*
|
|
* Copyright (C) 2019 Daniele Lacamera
|
|
*
|
|
* 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 Demonstrating DTLS 1.2 client using wolfSSL
|
|
*
|
|
* @author Daniele Lacamera <daniele@wolfssl.com>
|
|
* @}
|
|
*/
|
|
|
|
#include <wolfssl/ssl.h>
|
|
#include <wolfssl/error-ssl.h>
|
|
#include <sock_tls.h>
|
|
#include <net/sock.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "net/gnrc/netif.h"
|
|
#include "log.h"
|
|
|
|
#define SERVER_PORT 11111
|
|
#define APP_DTLS_BUF_SIZE 64
|
|
|
|
extern const unsigned char server_cert[];
|
|
extern const unsigned long server_cert_len;
|
|
|
|
static sock_tls_t skv;
|
|
static sock_tls_t *sk = &skv;
|
|
|
|
static void usage(const char *cmd_name)
|
|
{
|
|
LOG(LOG_ERROR, "Usage: %s <server-address>\n", cmd_name);
|
|
}
|
|
|
|
#ifdef MODULE_WOLFSSL_PSK
|
|
/* identity is OpenSSL testing default for openssl s_client, keep same */
|
|
static const char* kIdentityStr = "Client_identity";
|
|
|
|
static inline unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
|
|
char* identity, unsigned int id_max_len, unsigned char* key,
|
|
unsigned int key_max_len)
|
|
{
|
|
(void)ssl;
|
|
(void)hint;
|
|
(void)key_max_len;
|
|
|
|
/* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
|
|
strncpy(identity, kIdentityStr, id_max_len);
|
|
|
|
if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
|
|
/* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
|
|
unsigned binary */
|
|
key[0] = 0x1a;
|
|
key[1] = 0x2b;
|
|
key[2] = 0x3c;
|
|
key[3] = 0x4d;
|
|
|
|
return 4; /* length of key in octets or 0 for error */
|
|
}
|
|
else {
|
|
int i;
|
|
int b = 0x01;
|
|
|
|
for (i = 0; i < 32; i++, b += 0x22) {
|
|
if (b >= 0x100)
|
|
b = 0x01;
|
|
key[i] = b;
|
|
}
|
|
|
|
return 32; /* length of key in octets or 0 for error */
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int dtls_client(int argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
char buf[APP_DTLS_BUF_SIZE] = "Hello from DTLS client!";
|
|
char *iface;
|
|
char *addr_str;
|
|
int connect_timeout = 0;
|
|
const int max_connect_timeouts = 5;
|
|
|
|
if (argc != 2) {
|
|
usage(argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
addr_str = argv[1];
|
|
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
|
|
sock_udp_ep_t remote = SOCK_IPV6_EP_ANY;
|
|
|
|
/* Parsing <address> */
|
|
iface = ipv6_addr_split_iface(addr_str);
|
|
if (!iface) {
|
|
if (gnrc_netif_numof() == 1) {
|
|
/* assign the single interface found in gnrc_netif_numof() */
|
|
remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
|
|
}
|
|
}
|
|
else {
|
|
gnrc_netif_t *netif = gnrc_netif_get_by_pid(atoi(iface));
|
|
if (netif == NULL) {
|
|
LOG(LOG_ERROR, "ERROR: interface not valid\n");
|
|
usage(argv[0]);
|
|
return -1;
|
|
}
|
|
remote.netif = (uint16_t)netif->pid;
|
|
}
|
|
if (ipv6_addr_from_str((ipv6_addr_t *)remote.addr.ipv6, addr_str) == NULL) {
|
|
LOG(LOG_ERROR, "ERROR: unable to parse destination address\n");
|
|
usage(argv[0]);
|
|
return -1;
|
|
}
|
|
remote.port = SERVER_PORT;
|
|
if (sock_dtls_create(sk, &local, &remote, 0, wolfDTLSv1_2_client_method()) != 0) {
|
|
LOG(LOG_ERROR, "ERROR: Unable to create DTLS sock\n");
|
|
return -1;
|
|
}
|
|
|
|
#ifndef MODULE_WOLFSSL_PSK
|
|
/* Disable certificate validation from the client side */
|
|
wolfSSL_CTX_set_verify(sk->ctx, SSL_VERIFY_NONE, 0);
|
|
|
|
/* Load certificate file for the DTLS client */
|
|
if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert,
|
|
server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
|
|
{
|
|
LOG(LOG_ERROR, "Error loading cert buffer\n");
|
|
return -1;
|
|
}
|
|
|
|
#else /* !def MODULE_WOLFSSL_PSK */
|
|
wolfSSL_CTX_set_psk_client_callback(sk->ctx, my_psk_client_cb);
|
|
#endif
|
|
|
|
if (sock_dtls_session_create(sk) < 0)
|
|
return -1;
|
|
wolfSSL_dtls_set_timeout_init(sk->ssl, 5);
|
|
LOG(LOG_INFO, "connecting to server...\n");
|
|
/* attempt to connect until the connection is successful */
|
|
do {
|
|
ret = wolfSSL_connect(sk->ssl);
|
|
if ((ret != SSL_SUCCESS)) {
|
|
if(wolfSSL_get_error(sk->ssl, ret) == SOCKET_ERROR_E) {
|
|
LOG(LOG_WARNING, "Socket error: reconnecting...\n");
|
|
sock_dtls_session_destroy(sk);
|
|
connect_timeout = 0;
|
|
if (sock_dtls_session_create(sk) < 0)
|
|
return -1;
|
|
}
|
|
if ((wolfSSL_get_error(sk->ssl, ret) == WOLFSSL_ERROR_WANT_READ) &&
|
|
(connect_timeout++ >= max_connect_timeouts)) {
|
|
LOG(LOG_WARNING, "Server not responding: reconnecting...\n");
|
|
sock_dtls_session_destroy(sk);
|
|
connect_timeout = 0;
|
|
if (sock_dtls_session_create(sk) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
} while(ret != SSL_SUCCESS);
|
|
|
|
/* set remote endpoint */
|
|
sock_dtls_set_endpoint(sk, &remote);
|
|
|
|
/* send the hello message */
|
|
wolfSSL_write(sk->ssl, buf, strlen(buf));
|
|
|
|
/* wait for a reply, indefinitely */
|
|
do {
|
|
ret = wolfSSL_read(sk->ssl, buf, APP_DTLS_BUF_SIZE - 1);
|
|
LOG(LOG_INFO, "wolfSSL_read returned %d\n", ret);
|
|
} while (ret <= 0);
|
|
buf[ret] = (char)0;
|
|
LOG(LOG_INFO, "Received: '%s'\n", buf);
|
|
|
|
/* Clean up and exit. */
|
|
LOG(LOG_INFO, "Closing connection.\n");
|
|
sock_dtls_session_destroy(sk);
|
|
sock_dtls_close(sk);
|
|
return 0;
|
|
}
|