Add the "cacert" (Certification Authority certificates) subcommand to wget to pass root certificates to the code handling the HTTPS protocol. The subcommand is enabled by the WGET_CACERT Kconfig symbol.
Usage example: => dhcp # Download some root certificates (note: not authenticated!) => wget https://curl.se/ca/cacert.pem # Enable certificate verification => wget cacert $loadaddr $filesize # Disable certificate verification => wget cacert 0 0 Signed-off-by: Jerome Forissier <jerome.foriss...@linaro.org> --- cmd/Kconfig | 15 +++++++++ cmd/net-lwip.c | 15 +++++++-- lib/mbedtls/Makefile | 3 ++ lib/mbedtls/mbedtls_def_config.h | 5 +++ net/lwip/wget.c | 55 +++++++++++++++++++++++++++++++- 5 files changed, 89 insertions(+), 4 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 8dd42571abc..a188a2ef24b 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2177,6 +2177,21 @@ config WGET_HTTPS help Enable TLS over http for wget. +config WGET_CACERT + bool "wget cacert" + depends on CMD_WGET + depends on WGET_HTTPS + help + Adds the "cacert" sub-command to wget to provide root certificates + to the HTTPS engine. + +config MBEDTLS_LIB_X509_PEM + depends on WGET_CACERT + bool "Support for PEM-encoded X509 certificates" + help + This option enables MbedTLS to parse PEM-encoded X509 certificates. + When disabled, only DER format is accepted. + endif # if CMD_NET config CMD_PXE diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index 0fd446ecb20..0672f48a7a8 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -27,9 +27,18 @@ U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", #endif #if defined(CONFIG_CMD_WGET) -U_BOOT_CMD(wget, 3, 1, do_wget, - "boot image via network using HTTP/HTTPS protocol", +U_BOOT_CMD(wget, 4, 1, do_wget, + "boot image via network using HTTP/HTTPS protocol" +#if defined(CONFIG_WGET_CACERT) + "\nwget cacert - configure wget root certificates" +#endif + , "[loadAddress] url\n" - "wget [loadAddress] [host:]path" + "wget [loadAddress] [host:]path\n" + " - load file" +#if defined(CONFIG_WGET_CACERT) + "\nwget cacert <address> <length>\n" + " - provide CA certificates (0 0 to disable verification)" +#endif ); #endif diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile index e66c2018d97..8a0a984e149 100644 --- a/lib/mbedtls/Makefile +++ b/lib/mbedtls/Makefile @@ -57,6 +57,9 @@ mbedtls_lib_x509-$(CONFIG_$(SPL_)X509_CERTIFICATE_PARSER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/x509_crt.o mbedtls_lib_x509-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/pkcs7.o +mbedtls_lib_x509-$(CONFIG_MBEDTLS_LIB_X509_PEM) += \ + $(MBEDTLS_LIB_DIR)/base64.o \ + $(MBEDTLS_LIB_DIR)/pem.o #mbedTLS TLS support obj-$(CONFIG_MBEDTLS_LIB_TLS) += mbedtls_lib_tls.o diff --git a/lib/mbedtls/mbedtls_def_config.h b/lib/mbedtls/mbedtls_def_config.h index fd440c392f9..7b6a7f482f0 100644 --- a/lib/mbedtls/mbedtls_def_config.h +++ b/lib/mbedtls/mbedtls_def_config.h @@ -138,6 +138,11 @@ #define MBEDTLS_ECP_DP_BP384R1_ENABLED #define MBEDTLS_ECP_DP_BP512R1_ENABLED +/* CA certificates parsing */ +#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509_PEM) +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_BASE64_C +#endif #endif /* #if defined CONFIG_MBEDTLS_LIB_TLS */ #endif /* #if defined CONFIG_MBEDTLS_LIB */ diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 14f27d42998..14466598d7c 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -285,6 +285,53 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct return ERR_OK; } +#if defined CONFIG_WGET_HTTPS +static char *cacert; +size_t cacert_size; +#endif + +#if defined CONFIG_WGET_CACERT +static int set_cacert(char * const saddr, char * const ssz) +{ + mbedtls_x509_crt crt; + ulong addr, sz; + int ret; + + if (cacert) + free(cacert); + + addr = hextoul(saddr, NULL); + sz = hextoul(ssz, NULL); + sz++; /* For the trailing '\0' in case of a text (PEM) file */ + + if (!addr) { + cacert = NULL; + cacert_size = 0; + return CMD_RET_SUCCESS; + } + + cacert = malloc(sz); + if (!cacert) + return CMD_RET_FAILURE; + cacert_size = sz; + + memcpy(cacert, (void *)addr, sz - 1); + cacert[sz] = '\0'; + + mbedtls_x509_crt_init(&crt); + ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size); + if (ret) { + printf("Could not parse certificates (%d)\n", ret); + free(cacert); + cacert = NULL; + cacert_size = 0; + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} +#endif + static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) { #if defined CONFIG_WGET_HTTPS @@ -316,7 +363,8 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) if (is_https) { tls_allocator.alloc = &altcp_tls_alloc; tls_allocator.arg = - altcp_tls_create_config_client(NULL, 0, ctx.server_name); + altcp_tls_create_config_client(cacert, cacert_size, + ctx.server_name); if (!tls_allocator.arg) { log_err("error: Cannot create a TLS connection\n"); @@ -369,6 +417,11 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) ulong dst_addr; char nurl[1024]; +#if defined CONFIG_WGET_CACERT + if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) + return set_cacert(argv[2], argv[3]); +#endif + if (argc < 2 || argc > 3) return CMD_RET_USAGE; -- 2.43.0