Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
35b9e58
Add missing compile-time guard
gilles-peskine-arm Jun 14, 2019
3ecc807
Remove spurious dependencies on RSA and BIGNUM
gilles-peskine-arm Apr 22, 2020
fa1cb71
Run demo scripts and check that they work
gilles-peskine-arm Jun 14, 2019
1b4f4e2
Demo script for cert_write and cert_req
gilles-peskine-arm Jun 14, 2019
7603ac2
Not all .sh, .pl or .py files are executables
gilles-peskine-arm Apr 23, 2020
744dad3
Move common code of demo scripts into a library
gilles-peskine-arm Apr 23, 2020
6fdf50b
Demo scripts: create a seedfile if the configuration requires it
gilles-peskine-arm Apr 23, 2020
8ad0400
Let demo scripts declare their dependencies
gilles-peskine-arm Apr 23, 2020
964af03
Declare the dependencies of cert_write_demo.sh
gilles-peskine-arm Apr 22, 2020
62d35f4
Declare the dependencies of key_ladder_demo.sh
gilles-peskine-arm Apr 22, 2020
131e98b
Run demo scripts in some builds
gilles-peskine-arm Jun 14, 2019
1884d87
Use cert_app instead of openssl
gilles-peskine-arm Apr 26, 2020
7c75abd
cleanup is part of the external interface
gilles-peskine-arm Apr 26, 2020
a81b28c
Print only missing dependencies
gilles-peskine-arm Apr 26, 2020
af3249b
Explain why $root_dir needs a complicated calculation
gilles-peskine-arm Apr 26, 2020
c203212
Minor readability improvements
gilles-peskine-arm Apr 26, 2020
0910d43
Make should_be_executable a separate method
gilles-peskine-arm Apr 26, 2020
fe6e8a3
Fix some mistakes in descriptive messages
gilles-peskine-arm Apr 26, 2020
0277803
Add --quiet option to suppress demos' output
gilles-peskine-arm Apr 26, 2020
b5b5a39
Error out if run from the wrong directory
gilles-peskine-arm Apr 27, 2020
041e694
Make --quiet a little less quiet
gilles-peskine-arm Apr 27, 2020
a95761f
Pacify Pylint
gilles-peskine-arm Apr 27, 2020
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
2 changes: 1 addition & 1 deletion programs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This subdirectory mostly contains sample programs that illustrate specific featu

### Generic public-key cryptography (`pk`) examples

* [`pkey/gen_key.c`](pkey/gen_key.c): generates a key for any of the supported public-key algorithms (RSA or ECC) and writes it to a file that can be used by the other pk sample programs.
* [`pkey/gen_key.c`](pkey/gen_key.c): generates a key for any of the supported public-key algorithms (RSA or ECC) and writes it to a file that can be used by the other pk and x509 sample programs.

* [`pkey/key_app.c`](pkey/key_app.c): loads a PEM or DER public key or private key file and dumps its content.

Expand Down
137 changes: 137 additions & 0 deletions programs/demo_common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
## Common shell functions used by demo scripts programs/*/*.sh.

## How to write a demo script
## ==========================
##
## Include this file near the top of each demo script:
## . "${0%/*}/../demo_common.sh"
##
## Start with a "msg" call that explains the purpose of the script.
## Then call the "depends_on" function to ensure that all config
## dependencies are met.
##
## As the last thing in the script, call the cleanup function.
##
## You can use the functions and variables described below.

set -e -u

## $root_dir is the root directory of the Mbed TLS source tree.
root_dir="${0%/*}"
# Find a nice path to the root directory, avoiding unnecessary "../".
# The code supports demo scripts nested up to 4 levels deep.
# The code works no matter where the demo script is relative to the current
# directory, even if it is called with a relative path.
n=4 # limit the search depth
while ! [ -d "$root_dir/programs" ] || ! [ -d "$root_dir/library" ]; do
if [ $n -eq 0 ]; then
echo >&2 "This doesn't seem to be an Mbed TLS source tree."
exit 125
fi
n=$((n - 1))
case $root_dir in
.) root_dir="..";;
..|?*/..) root_dir="$root_dir/..";;
?*/*) root_dir="${root_dir%/*}";;
/*) root_dir="/";;
*) root_dir=".";;
esac
done

## $programs_dir is the directory containing the sample programs.
# Assume an in-tree build.
programs_dir="$root_dir/programs"

## msg LINE...
## msg <TEXT_ORIGIN
## Display an informational message.
msg () {
if [ $# -eq 0 ]; then
sed 's/^/# /'
else
for x in "$@"; do
echo "# $x"
done
fi
}

## run "Message" COMMAND ARGUMENT...
## Display the message, then run COMMAND with the specified arguments.
run () {
echo
echo "# $1"
shift
echo "+ $*"
"$@"
}

## Like '!', but stop on failure with 'set -e'
not () {
if "$@"; then false; fi
}

## run_bad "Message" COMMAND ARGUMENT...
## Like run, but the command is expected to fail.
run_bad () {
echo
echo "$1 This must fail."
shift
echo "+ ! $*"
not "$@"
}

## config_has SYMBOL...
## Succeeds if the library configuration has all SYMBOLs set.
config_has () {
for x in "$@"; do
"$programs_dir/test/query_compile_time_config" "$x"
done
}

## depends_on SYMBOL...
## Exit if the library configuration does not have all SYMBOLs set.
depends_on () {
m=
for x in "$@"; do
if ! config_has "$x"; then
m="$m $x"
fi
done
if [ -n "$m" ]; then
cat >&2 <<EOF
$0: this demo requires the following
configuration options to be enabled at compile time:
$m
EOF
# Exit with a success status so that this counts as a pass for run_demos.py.
exit
fi
}

## Add the names of files to clean up to this whitespace-separated variable.
## The file names must not contain whitespace characters.
files_to_clean=

## Call this function at the end of each script.
## It is called automatically if the script is killed by a signal.
cleanup () {
rm -f -- $files_to_clean
}



################################################################
## End of the public interfaces. Code beyond this point is not
## meant to be called directly from a demo script.

trap 'cleanup; trap - HUP; kill -HUP $$' HUP
trap 'cleanup; trap - INT; kill -INT $$' INT
trap 'cleanup; trap - TERM; kill -TERM $$' TERM

if config_has MBEDTLS_ENTROPY_NV_SEED; then
# Create a seedfile that's sufficiently long in all library configurations.
# This is necessary for programs that use randomness.
# Assume that the name of the seedfile is the default name.
files_to_clean="$files_to_clean seedfile"
dd if=/dev/urandom of=seedfile ibs=64 obs=64 count=1
fi
8 changes: 4 additions & 4 deletions programs/pkey/key_app_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_FS_IO)
#include "mbedtls/error.h"
#include "mbedtls/pk.h"
#include "mbedtls/error.h"

#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -88,12 +87,13 @@
USAGE_OUT \
"\n"

#if !defined(MBEDTLS_PK_PARSE_C) || \
#if !defined(MBEDTLS_ERROR_C) || \
!defined(MBEDTLS_PK_PARSE_C) || \
!defined(MBEDTLS_PK_WRITE_C) || \
!defined(MBEDTLS_FS_IO)
int main( void )
{
mbedtls_printf( "MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
mbedtls_printf( "MBEDTLS_ERROR_C and/or MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
return( 0 );
}
#else
Expand Down Expand Up @@ -438,4 +438,4 @@ int main( int argc, char *argv[] )

return( exit_code );
}
#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
#endif /* MBEDTLS_ERROR_C && MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
24 changes: 11 additions & 13 deletions programs/psa/key_ladder_demo.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
#!/bin/sh
set -e -u
. "${0%/*}/../demo_common.sh"

program="${0%/*}"/key_ladder_demo
files_to_clean=
msg <<'EOF'
This script demonstrates the use of the PSA cryptography interface to
create a master key, derive a key from it and use that derived key to
wrap some data using an AEAD algorithm.
EOF

depends_on MBEDTLS_SHA256_C MBEDTLS_MD_C MBEDTLS_AES_C MBEDTLS_CCM_C MBEDTLS_PSA_CRYPTO_C MBEDTLS_FS_IO

run () {
echo
echo "# $1"
shift
echo "+ $*"
"$@"
}
program="${0%/*}"/key_ladder_demo

if [ -e master.key ]; then
echo "# Reusing the existing master.key file."
Expand All @@ -34,7 +33,7 @@ run "Compare the unwrapped data with the original input." \
cmp input.txt hello_world.txt

files_to_clean="$files_to_clean hellow_orld.txt"
! run "Derive a different key and attempt to unwrap the data. This must fail." \
run_bad "Derive a different key and attempt to unwrap the data." \
"$program" unwrap master=master.key input=hello_world.wrap output=hellow_orld.txt label=hellow label=orld

files_to_clean="$files_to_clean hello.key"
Expand All @@ -45,5 +44,4 @@ run "Check that we get the same key by unwrapping data made by the other key." \
"$program" unwrap master=hello.key label=world \
input=hello_world.wrap output=hello_world.txt

# Cleanup
rm -f $files_to_clean
cleanup
12 changes: 6 additions & 6 deletions programs/x509/cert_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif /* MBEDTLS_PLATFORM_C */

#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \
#if !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
!defined(MBEDTLS_CTR_DRBG_C)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_NET_C and/or "
"MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_FS_IO and/or "
"MBEDTLS_CTR_DRBG_C not defined.\n");
return( 0 );
Expand Down Expand Up @@ -499,6 +499,6 @@ int main( int argc, char *argv[] )

return( exit_code );
}
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
#endif /* MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C &&
MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO && MBEDTLS_CTR_DRBG_C */
55 changes: 55 additions & 0 deletions programs/x509/cert_write_demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh
. "${0%/*}/../demo_common.sh"

msg <<'EOF'
This script demonstrates the use of x509 tools to generate a certificate
for a private key. It shows both the case of a self-signed certificate and
the case of a certificate signed by a different key using a certificate
signing request.
EOF

depends_on MBEDTLS_CTR_DRBG_C MBEDTLS_ENTROPY_C MBEDTLS_ERROR_C MBEDTLS_FS_IO MBEDTLS_PEM_WRITE_C MBEDTLS_PK_PARSE_C MBEDTLS_PK_WRITE_C MBEDTLS_SHA256_C MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRT_WRITE_C MBEDTLS_X509_CSR_PARSE_C MBEDTLS_X509_CSR_WRITE_C

ca_key="demo_ca.key"
server_key="demo_server.key"
csr="demo_csr.req"
ca_crt="demo_ca.crt"
server_crt="demo_server.crt"

files_to_clean="$ca_key $server_key $csr $ca_crt $server_crt"

run 'Generate a CA (certificate authority) key.' \
"$programs_dir/pkey/gen_key" filename="$ca_key" type=ec

run 'Self-sign the CA certificate.' \
"$programs_dir/x509/cert_write" issuer_key="$ca_key" output_file="$ca_crt" \
selfsign=1 is_ca=1 \
issuer_name="CN=Demo CA,O=Mbed TLS,C=UK"

run 'The CA certificate is:' \
cat "$ca_crt"

run 'Dump of the CA certificate:' \
"$programs_dir/x509/cert_app" mode=file filename="$ca_crt"

run 'Generate a server key.' \
"$programs_dir/pkey/gen_key" filename="$server_key" type=ec

run 'Issue a signing request for the server key.' \
"$programs_dir/x509/cert_req" filename="$server_key" output_file="$csr" \
subject_name="CN=Demo server,O=Mbed TLS,C=UK"

run 'Show information about the certificate signing request' \
"$programs_dir/x509/req_app" filename="$csr"

run 'The CA signs the server key.' \
"$programs_dir/x509/cert_write" issuer_key="$ca_key" request_file="$csr" \
output_file="$server_crt"

run 'The server certificate is:' \
cat "$server_crt"

run 'Dump of the server certificate:' \
"$programs_dir/x509/cert_app" mode=file filename="$server_crt"

cleanup
9 changes: 3 additions & 6 deletions programs/x509/crl_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif /* MBEDTLS_PLATFORM_C */

#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRL_PARSE_C) || !defined(MBEDTLS_FS_IO)
#if !defined(MBEDTLS_X509_CRL_PARSE_C) || !defined(MBEDTLS_FS_IO)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_X509_CRL_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
mbedtls_printf("MBEDTLS_X509_CRL_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
return( 0 );
}
#else
Expand Down Expand Up @@ -149,5 +147,4 @@ int main( int argc, char *argv[] )

return( exit_code );
}
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_X509_CRL_PARSE_C &&
MBEDTLS_FS_IO */
#endif /* MBEDTLS_X509_CRL_PARSE_C && MBEDTLS_FS_IO */
9 changes: 3 additions & 6 deletions programs/x509/req_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif /* MBEDTLS_PLATFORM_C */

#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CSR_PARSE_C) || !defined(MBEDTLS_FS_IO)
#if !defined(MBEDTLS_X509_CSR_PARSE_C) || !defined(MBEDTLS_FS_IO)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_X509_CSR_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
mbedtls_printf("MBEDTLS_X509_CSR_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
return( 0 );
}
#else
Expand Down Expand Up @@ -149,5 +147,4 @@ int main( int argc, char *argv[] )

return( exit_code );
}
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_X509_CSR_PARSE_C &&
MBEDTLS_FS_IO */
#endif /* MBEDTLS_X509_CSR_PARSE_C && MBEDTLS_FS_IO */
15 changes: 15 additions & 0 deletions tests/scripts/all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,9 @@ component_test_default_out_of_box () {
msg "selftest: make, default config (out-of-box)" # ~10s
programs/test/selftest

msg "program demos: make, default config (out-of-box)" # ~10s
if_build_succeeded tests/scripts/run_demos.py

export MBEDTLS_TEST_OUTCOME_FILE="$SAVE_MBEDTLS_TEST_OUTCOME_FILE"
unset SAVE_MBEDTLS_TEST_OUTCOME_FILE
}
Expand All @@ -659,6 +662,9 @@ component_test_default_cmake_gcc_asan () {
msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s
make test

msg "program demos (ASan build)" # ~10s
if_build_succeeded tests/scripts/run_demos.py

msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
if_build_succeeded tests/ssl-opt.sh

Expand Down Expand Up @@ -896,6 +902,9 @@ component_test_full_cmake_clang () {
msg "test: main suites (full config, clang)" # ~ 5s
make test

msg "program demos (full config)" # ~10s
if_build_succeeded tests/scripts/run_demos.py

msg "test: psa_constant_names (full config, clang)" # ~ 1s
record_status tests/scripts/test_psa_constant_names.py

Expand Down Expand Up @@ -929,6 +938,9 @@ component_build_deprecated () {
# Build with -O -Wextra to catch a maximum of issues.
make CC=clang CFLAGS='-O -Werror -Wall -Wextra' lib programs
make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests

msg "program demos: full config + DEPRECATED_REMOVED" # ~10s
if_build_succeeded tests/scripts/run_demos.py
}

# Check that the specified libraries exist and are empty.
Expand Down Expand Up @@ -1667,6 +1679,9 @@ component_test_memsan () {
msg "test: main suites (MSan)" # ~ 10s
make test

msg "program demos (MSan)" # ~20s
if_build_succeeded tests/scripts/run_demos.py

msg "test: ssl-opt.sh (MSan)" # ~ 1 min
if_build_succeeded tests/ssl-opt.sh

Expand Down
Loading