Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ App|Description
[picow_http_client](pico_w/wifi/http_client) | Demonstrates how to make http and https requests
[picow_http_client_verify](pico_w/wifi/http_client) | Demonstrates how to make a https request with server authentication
[picow_mqtt_client](pico_w/wifi/mqtt) | Demonstrates how to implement a MQTT client application
[picow_dtls](pico_w/wifi/dtls) | Demonstrates how to implement a simple DTLS client and server

#### FreeRTOS examples

Expand Down
1 change: 1 addition & 0 deletions pico_w/wifi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ else()
add_subdirectory_exclude_platforms(udp_beacon)
add_subdirectory_exclude_platforms(http_client)
add_subdirectory_exclude_platforms(mqtt)
add_subdirectory_exclude_platforms(dtls)

if (NOT PICO_MBEDTLS_PATH)
message("Skipping tls examples as PICO_MBEDTLS_PATH is not defined")
Expand Down
83 changes: 83 additions & 0 deletions pico_w/wifi/dtls/CMakeLists.txt
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")
Copy link
Contributor

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?

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})
65 changes: 65 additions & 0 deletions pico_w/wifi/dtls/README.md
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
These examples demonstrate how to use dtls via mbedtls on a Pico W device.
These examples demonstrate how to use DTLS via Mbed TLS on a Pico W device.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Running the dtls examples
# Running the DTLS examples


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.
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.

## Using openssl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Using openssl
## Using OpenSSL


The host/server.sh and host/client/sh scripts demonstrate how to use DTLS with openssl, although you will have to echo text manually.
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The scripts use the keys in certs/myserver
The scripts use the keys in `certs/myserver`.


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.
```
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Using mbedtls
## Using Mbed TLS


The host folder contains C versions of the examples that can be compiled natively for the host. They are modified versions of mbedtls examples.
Copy link
Contributor

Choose a reason for hiding this comment

The 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.
The `host` folder contains C versions of the examples that can be compiled natively for the host. They are modified versions of Mbed TLS examples.

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.

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.
1 change: 1 addition & 0 deletions pico_w/wifi/dtls/certs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/
57 changes: 57 additions & 0 deletions pico_w/wifi/dtls/certs/makecerts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#!/usr/bin/bash
#!/bin/bash

/bin/bash is the usual Bash shebang line. On my Ubuntu Linux laptop /usr/bin/bash doesn't even exist!


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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
echo Run \"rm -fr $SERVER_NAME\" to regenerate these keys
echo Run \"rm -rf $SERVER_NAME\" to regenerate these keys

(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
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

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

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
Loading