-
Notifications
You must be signed in to change notification settings - Fork 930
Add DTLS example #615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Add DTLS example #615
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Pick DTLS server from environment | ||
if (DEFINED ENV{DTLS_SERVER} AND (NOT DTLS_SERVER)) | ||
set(DTLS_SERVER $ENV{DTLS_SERVER}) | ||
message("Using DTLS_SERVER from environment ('${DTLS_SERVER}')") | ||
endif() | ||
if (NOT DTLS_SERVER) | ||
message("Skipping DTLS example as DTLS_SERVER is not defined") | ||
return() | ||
endif() | ||
set(DTLS_SERVER "${DTLS_SERVER}" CACHE INTERNAL "DTLS server for examples") | ||
if (NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/certs/${DTLS_SERVER}") | ||
message("Generate DTLS certs by running ${CMAKE_CURRENT_LIST_DIR}/certs/makecerts.sh") | ||
return() | ||
endif() | ||
|
||
set(RANDOM_DATA_LEN 32) | ||
string(RANDOM LENGTH ${RANDOM_DATA_LEN} RANDOM_DATA) | ||
|
||
pico_add_library(pico_dtls) | ||
target_include_directories(pico_dtls_headers INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
) | ||
target_sources(pico_dtls INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/dtls_common.c | ||
) | ||
pico_mirrored_target_link_libraries(pico_dtls INTERFACE | ||
pico_lwip_mbedtls | ||
pico_mbedtls | ||
) | ||
target_compile_definitions(pico_dtls INTERFACE | ||
CUSTOM_MBEDTLS_ENTROPY_PTR=\"${RANDOM_DATA}\" | ||
CUSTOM_MBEDTLS_ENTROPY_LEN=${RANDOM_DATA_LEN} | ||
) | ||
|
||
set(TARGET_NAME dtls_echo_server) | ||
|
||
add_executable(${TARGET_NAME} | ||
dtls_echo_server.c | ||
) | ||
target_include_directories(${TARGET_NAME} PRIVATE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
${CMAKE_CURRENT_LIST_DIR}/.. | ||
) | ||
target_link_libraries(${TARGET_NAME} PRIVATE | ||
pico_cyw43_arch_lwip_threadsafe_background | ||
pico_lwip_nosys | ||
pico_stdlib | ||
pico_dtls | ||
) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
DTLS_CERT_INC=\"certs/${DTLS_SERVER}/dtls_server.inc\" | ||
) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
CYW43_HOST_NAME=\"pico_dtls_example\" | ||
WIFI_SSID=\"${WIFI_SSID}\" | ||
WIFI_PASSWORD=\"${WIFI_PASSWORD}\" | ||
) | ||
pico_add_extra_outputs(${TARGET_NAME}) | ||
|
||
set(TARGET_NAME dtls_echo_client) | ||
|
||
add_executable(${TARGET_NAME} | ||
dtls_echo_client.c | ||
) | ||
target_include_directories(${TARGET_NAME} PRIVATE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
${CMAKE_CURRENT_LIST_DIR}/.. | ||
) | ||
target_link_libraries(${TARGET_NAME} PRIVATE | ||
pico_cyw43_arch_lwip_threadsafe_background | ||
pico_lwip_nosys | ||
pico_stdlib | ||
pico_dtls | ||
) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
DTLS_SERVER=\"${DTLS_SERVER}\" | ||
DTLS_CERT_INC=\"certs/${DTLS_SERVER}/dtls_client.inc\" | ||
) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
WIFI_SSID=\"${WIFI_SSID}\" | ||
WIFI_PASSWORD=\"${WIFI_PASSWORD}\" | ||
) | ||
pico_add_extra_outputs(${TARGET_NAME}) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,65 @@ | ||||||
# Setup | ||||||
|
||||||
These examples demonstrate how to use dtls via mbedtls on a Pico W device. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
You need to define DTLS_SERVER and run the makecerts.sh script to generate the certificates and keys needed for the server and client. | ||||||
``` | ||||||
export DTLS_SERVER=myserver | ||||||
cd dtls/certs | ||||||
./makecerts.sh | ||||||
``` | ||||||
The examples should now build. | ||||||
|
||||||
# Running the dtls examples | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
The client connects to a server and sends it a few lines of text which it expects to be sent back. | ||||||
|
||||||
You can build and run the client and server examples on two Pico W devices. To make testing easier to test with just one Pico W device, you can run the server or client on a Linux host. | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
The client.sh and server.sh scripts show how to run the client or server with openssl. The host folder contains source code for a version of the client and server using mbedtls. | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
## Using openssl | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
The host/server.sh and host/client/sh scripts demonstrate how to use DTLS with openssl, although you will have to echo text manually. | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
For example, run dtls_echo_client on a Pico W device and the server.sh on a linux PC. | ||||||
``` | ||||||
export DTLS_SERVER=myserver | ||||||
cd host | ||||||
./server.sh | ||||||
``` | ||||||
The scripts use the keys in certs/myserver | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Or run dtls_echo_server on a Pico W device and client.sh on a linux PC. The host name for the server on Pico W is set to `pico_dtls_example`"`. Make sure you build the code for the Pico W and run the client with the right DTLS_SERVER name (and matching keys in the client and server) or else the SSL handshake will fail. | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
``` | ||||||
export DTLS_SERVER=pico_dtls_example | ||||||
ping pico_dtls_example # make sure you can reach it! | ||||||
cd host | ||||||
./client.sh | ||||||
``` | ||||||
The scripts use the keys in certs/pico_dtls_example. Type a sentence into the client.sh console and the server should send it back as a reply. | ||||||
|
||||||
## Using mbedtls | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
The host folder contains C versions of the examples that can be compiled natively for the host. They are modified versions of mbedtls examples. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
You can build these on a rpi linux device to act as the server or client. The mbedtls library in PICO_SDK_PATH will be used to build the host code. | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
For example, run dtls_echo_client on a Pico W device and the dtls_host_echo_server on a linux PC. | ||||||
``` | ||||||
export DTLS_SERVER=myserver | ||||||
cd host | ||||||
mkdir build | ||||||
cd build | ||||||
cmake .. | ||||||
make -j8 | ||||||
./dtls_host_echo_server | ||||||
|
||||||
``` | ||||||
Or run dtls_echo_server on a Pico W device and dtls_host_echo_client on a linux PC. | ||||||
``` | ||||||
export DTLS_SERVER=pico_dtls_example | ||||||
cd host | ||||||
mkdir build | ||||||
cd build | ||||||
cmake .. | ||||||
make -j8 | ||||||
./dtls_host_echo_client | ||||||
``` | ||||||
Remember to build the client and server for the host and Pico W with the correct value of DTLS_SERVER or else the handshake will fail. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*/ |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,57 @@ | ||||||
#!/usr/bin/bash | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
if [ "${PWD##*/}" != "certs" ]; then | ||||||
echo Run this in the certs folder | ||||||
exit 1 | ||||||
fi | ||||||
if [ -z "$DTLS_SERVER" ]; then | ||||||
echo Define DTLS_SERVER | ||||||
exit 1 | ||||||
fi | ||||||
SERVER_NAME=$DTLS_SERVER | ||||||
|
||||||
if [ -d "$SERVER_NAME" ]; then | ||||||
echo Run \"rm -fr $SERVER_NAME\" to regenerate these keys | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(no functional difference, this is just convention) |
||||||
exit 1 | ||||||
fi | ||||||
mkdir $SERVER_NAME | ||||||
echo Generating keys in $PWD/$SERVER_NAME | ||||||
|
||||||
openssl genrsa -out $SERVER_NAME/ca.key 2048 | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
openssl req -new -x509 -days 99999 -key $SERVER_NAME/ca.key -out $SERVER_NAME/ca.crt -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=rpiroot" | ||||||
|
||||||
openssl genrsa -out $SERVER_NAME/server.key 2048 | ||||||
openssl req -new -out $SERVER_NAME/server.csr -key $SERVER_NAME/server.key -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=$SERVER_NAME" | ||||||
openssl x509 -req -in $SERVER_NAME/server.csr -CA $SERVER_NAME/ca.crt -CAkey $SERVER_NAME/ca.key -CAcreateserial -out $SERVER_NAME/server.crt -days 9999 | ||||||
|
||||||
openssl genrsa -out $SERVER_NAME/client.key 2048 | ||||||
openssl req -new -out $SERVER_NAME/client.csr -key $SERVER_NAME/client.key -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=$SERVER_NAME" | ||||||
openssl x509 -req -in $SERVER_NAME/client.csr -CA $SERVER_NAME/ca.crt -CAkey $SERVER_NAME/ca.key -CAcreateserial -out $SERVER_NAME/client.crt -days 999 | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
echo -n \#define DTLS_ROOT_CERT \" > $SERVER_NAME/dtls_client.inc | ||||||
cat $SERVER_NAME/ca.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_client.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_client.inc | ||||||
echo >> $SERVER_NAME/dtls_client.inc | ||||||
peterharperuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
echo -n \#define DTLS_KEY \" >> $SERVER_NAME/dtls_client.inc | ||||||
cat $SERVER_NAME/client.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_client.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_client.inc | ||||||
echo >> $SERVER_NAME/dtls_client.inc | ||||||
|
||||||
echo -n \#define DTLS_CERT \" >> $SERVER_NAME/dtls_client.inc | ||||||
cat $SERVER_NAME/client.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_client.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_client.inc | ||||||
|
||||||
echo -n \#define DTLS_ROOT_CERT \" > $SERVER_NAME/dtls_server.inc | ||||||
cat $SERVER_NAME/ca.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_server.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_server.inc | ||||||
echo >> $SERVER_NAME/dtls_server.inc | ||||||
|
||||||
echo -n \#define DTLS_KEY \" >> $SERVER_NAME/dtls_server.inc | ||||||
cat $SERVER_NAME/server.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_server.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_server.inc | ||||||
echo >> $SERVER_NAME/dtls_server.inc | ||||||
|
||||||
echo -n \#define DTLS_CERT \" >> $SERVER_NAME/dtls_server.inc | ||||||
cat $SERVER_NAME/server.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/dtls_server.inc | ||||||
echo "\"" >> $SERVER_NAME/dtls_server.inc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably ought to add
-DDTLS_SERVER=something
to https://github.com/raspberrypi/pico-examples/blob/develop/.github/workflows/cmake.yml#L56 so that the CI will at least check that these examples compile correctly?