Skip to content

Commit e0517c7

Browse files
authored
Merge pull request #6999 from jepler/picow-ssl
pico_w: implement ssl with caveats
2 parents ee28658 + ecd1402 commit e0517c7

40 files changed

+2573
-35
lines changed

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
url = https://github.com/adafruit/esp-idf.git
149149
branch = circuitpython8
150150
[submodule "ports/espressif/certificates/nina-fw"]
151-
path = ports/espressif/certificates/nina-fw
151+
path = lib/certificates/nina-fw
152152
url = https://github.com/adafruit/nina-fw.git
153153
[submodule "frozen/Adafruit_CircuitPython_ST7789"]
154154
path = frozen/Adafruit_CircuitPython_ST7789
@@ -316,3 +316,6 @@
316316
[submodule "ports/raspberrypi/lib/lwip"]
317317
path = ports/raspberrypi/lib/lwip
318318
url = https://github.com/lwip-tcpip/lwip.git
319+
[submodule "lib/mbedtls"]
320+
path = lib/mbedtls
321+
url = https://github.com/ARMmbed/mbedtls.git

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repos:
1010
- id: end-of-file-fixer
1111
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)'
1212
- id: trailing-whitespace
13-
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)'
13+
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)'
1414
- repo: local
1515
hooks:
1616
- id: translations
File renamed without changes.

lib/mbedtls

Submodule mbedtls added at 1bc2c9c

lib/mbedtls_errors/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
MBEDTLS Error Strings for MicroPython
2+
=====================================
3+
4+
This directory contains source code and tools to rework the Mbedtls error strings for
5+
micropython to use less space. In short, instead of storing and printing something like
6+
"SSL - Our own certificate(s) is/are too large to send in an SSL message" it prints
7+
the name of the error #define, which would be "MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE" in
8+
this case, and only stores `SSL_CERTIFICATE_TOO_LARGE` in flash. The exact Mbedtls error
9+
defines are used because they're easy to search for to find more detailed information.
10+
11+
Mbedtls defines a specific format for error value #defines and
12+
includes a Perl script to gather all `MBEDTLS_ERR` defines from includes files together with
13+
english error text. From that the Perl script generates `mbedtls_strerror()`. The files in this
14+
directory modify this process to produce a more space efficient error lookup table with
15+
shorter error strings.
16+
17+
The files are as follows:
18+
- `generate_errors.diff` - diff for original mbedtls perl script
19+
- `error.fmt` - modified code template for MicroPython
20+
- `mp_mbedtls_errors.c` - source file with `mbedtls_strerror` this is built using the include
21+
files in `../mbedtls`
22+
- `do-mp.sh` - shell script to produce `mp_mbedtls_errors.c`
23+
- `tester.c` - simple C main to test `mp_mbedtls_errors.c` locally on a dev box
24+
- `do-test.sh` - shell script to produce `mp_mbedtls_errors.c` and compile the `tester` app
25+
- `do-esp32.sh` - shell script to produce `esp32_mbedtls_errors.c` -- see below
26+
27+
In order not to store multiple copies of `mbedtls_errors.c`
28+
([https://github.com/micropython/micropython/pull/5819#discussion_r445528006](see))
29+
it is assumed that all ports use the same version of mbedtls with the same error #defines.
30+
This is true as of MP v1.13, and ESP-IDF versions 3.3.2 and 4.0.1. If anything changes in the
31+
future the `do-esp32.sh` script can be used to generate an esp32-specific version.
32+
33+
### How-to
34+
35+
- To build MicroPython all that is needed is to include the `mp_mbedtls_errors.c` into the build
36+
(the Makefiles do this automatically). Note that Perl is not needed for routine MicroPython
37+
builds.
38+
- When a new version of Mbedtls is pulled-in the `do-mp.sh` script should be run to
39+
re-generate `mp_mbedtls_errors.c`.
40+
- The `tester` app should be run if changes to the string handling in `error.fmt` are made:
41+
it tests that there is not an off-by-one error in the string copying/appending, etc.
42+
- To include `mbedtls_strerror` error strings define `MBEDTLS_ERROR_C` in the build.

lib/mbedtls_errors/do-esp32.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#! /bin/bash -e
2+
# Generate esp32_mbedtls_errors.c for use in the Esp32 port, with the ESP-IDF version of mbedtls
3+
# The IDF_PATH env var must be set to the top-level dir of ESPIDF
4+
echo "IDF_PATH=$IDF_PATH"
5+
MBEDTLS=$IDF_PATH/components/mbedtls/mbedtls
6+
patch -o esp32_generate_errors.pl $MBEDTLS/scripts/generate_errors.pl <generate_errors.diff
7+
perl ./esp32_generate_errors.pl $MBEDTLS/include/mbedtls . esp32_mbedtls_errors.c

lib/mbedtls_errors/do-mp.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#! /bin/bash -e
2+
# Generate mp_mbedtls_errors.c for inclusion in ports that use $MPY/lib/mbedtls
3+
patch -o mp_generate_errors.pl ../mbedtls/scripts/generate_errors.pl <generate_errors.diff
4+
perl ./mp_generate_errors.pl ../mbedtls/include/mbedtls . mp_mbedtls_errors.c

lib/mbedtls_errors/do-test.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#! /bin/bash -e
2+
# Generate mp_mbedtls_errors.c and build the tester app
3+
./do-mp.sh
4+
cc -o tester -I../mbedtls/include/ mp_mbedtls_errors.c tester.c

lib/mbedtls_errors/error.fmt

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Error message information
3+
*
4+
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*
19+
* This file is part of mbed TLS (https://tls.mbed.org)
20+
*/
21+
22+
#if !defined(MBEDTLS_CONFIG_FILE)
23+
#include "mbedtls/config.h"
24+
#else
25+
#include MBEDTLS_CONFIG_FILE
26+
#endif
27+
28+
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
29+
#include "mbedtls/error.h"
30+
#include <string.h>
31+
#endif
32+
33+
#if defined(MBEDTLS_PLATFORM_C)
34+
#include "mbedtls/platform.h"
35+
#else
36+
#define mbedtls_snprintf snprintf
37+
#define mbedtls_time_t time_t
38+
#endif
39+
40+
#if defined(MBEDTLS_ERROR_C)
41+
42+
#include <stdio.h>
43+
44+
HEADER_INCLUDED
45+
46+
// Error code table type
47+
struct ssl_errs {
48+
int16_t errnum;
49+
const char *errstr;
50+
};
51+
52+
// Table of high level error codes
53+
static const struct ssl_errs mbedtls_high_level_error_tab[] = {
54+
// BEGIN generated code
55+
HIGH_LEVEL_CODE_CHECKS
56+
// END generated code
57+
};
58+
59+
static const struct ssl_errs mbedtls_low_level_error_tab[] = {
60+
// Low level error codes
61+
//
62+
// BEGIN generated code
63+
LOW_LEVEL_CODE_CHECKS
64+
// END generated code
65+
};
66+
67+
static const char *mbedtls_err_prefix = "MBEDTLS_ERR_";
68+
#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 )
69+
70+
// copy error text into buffer, ensure null termination, return strlen of result
71+
static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) {
72+
if (buflen == 0) return 0;
73+
74+
// prefix for all error names
75+
strncpy(buf, mbedtls_err_prefix, buflen);
76+
if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) {
77+
buf[buflen-1] = 0;
78+
return buflen-1;
79+
}
80+
81+
// append error name from table
82+
for (int i = 0; i < tab_len; i++) {
83+
if (tab[i].errnum == err) {
84+
strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN);
85+
buf[buflen-1] = 0;
86+
return strlen(buf);
87+
}
88+
}
89+
90+
mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)",
91+
err);
92+
return strlen(buf);
93+
}
94+
95+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
96+
97+
void mbedtls_strerror(int ret, char *buf, size_t buflen) {
98+
int use_ret;
99+
100+
if (buflen == 0) return;
101+
102+
buf[buflen-1] = 0;
103+
104+
if (ret < 0) ret = -ret;
105+
106+
//
107+
// High-level error codes
108+
//
109+
uint8_t got_hl = (ret & 0xFF80) != 0;
110+
if (got_hl) {
111+
use_ret = ret & 0xFF80;
112+
113+
// special case
114+
#if defined(MBEDTLS_SSL_TLS_C)
115+
if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) {
116+
strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen);
117+
buf[buflen-1] = 0;
118+
return;
119+
}
120+
#endif
121+
122+
size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab,
123+
ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen);
124+
125+
buf += len;
126+
buflen -= len;
127+
if (buflen == 0) return;
128+
}
129+
130+
//
131+
// Low-level error codes
132+
//
133+
use_ret = ret & ~0xFF80;
134+
135+
if (use_ret == 0) return;
136+
137+
// If high level code is present, make a concatenation between both error strings.
138+
if (got_hl) {
139+
if (buflen < 2) return;
140+
*buf++ = '+';
141+
buflen--;
142+
}
143+
144+
mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab,
145+
ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen);
146+
}
147+
148+
#else /* MBEDTLS_ERROR_C */
149+
150+
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
151+
152+
/*
153+
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
154+
*/
155+
void mbedtls_strerror( int ret, char *buf, size_t buflen )
156+
{
157+
((void) ret);
158+
159+
if( buflen > 0 )
160+
buf[0] = '\0';
161+
}
162+
163+
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
164+
165+
#endif /* MBEDTLS_ERROR_C */
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--- generate_errors_orig.pl 2020-06-20 08:40:38.819060379 -0700
2+
+++ generate_errors.pl 2020-06-20 08:47:26.511163591 -0700
3+
@@ -162,16 +162,12 @@
4+
5+
if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
6+
{
7+
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
8+
- "${white_space}\{\n".
9+
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n".
10+
- "${white_space} return;\n".
11+
- "${white_space}}\n"
12+
+ # no-op, this case is hard-coded in error.fmt
13+
}
14+
else
15+
{
16+
- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
17+
- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n"
18+
+ my $error_text = $error_name =~ s/^MBEDTLS_ERR_//r;
19+
+ ${$code_check} .= "${white_space}{ -($error_name), \"$error_text\" },\n"
20+
}
21+
};
22+

0 commit comments

Comments
 (0)