Message ID | fc96dd94cb39b60571b43ef80c5c89ff7999e94b.1740672437.git.jerome.forissier@linaro.org |
---|---|
State | New |
Headers | show |
Series | net: lwip: root certificates | expand |
Sorry for replying to myself, I spotted a small mistake. On 2/27/25 17:09, Jerome Forissier wrote: > Introduce Kconfig symbols WGET_BUILTIN_CACERT and > WGET_BUILTIN_CACERT_PATH to provide root certificates at build time. The > file may be a DER-encoded (.crt) or PEM-encoded (.pem) X509 collection > of one or more certificates. PEM encoding needs MBEDTLS_LIB_X509_PEM. > > Usage example: > > wget https://curl.se/ca/cacert.pem > make qemu_arm64_lwip_defconfig > echo CONFIG_WGET_BUILTIN_CACERT=y >>.config > echo CONFIG_WGET_BUILTIN_CACERT_PATH=cacert.pem >>.config > echo CONFIG_MBEDTLS_LIB_X509_PEM=y >>.config > make olddefconfig > make -j$(nproc) CROSS_COMPILE="ccache aarch64-linux-gnu-" > qemu-system-aarch64 -M virt -nographic -cpu max \ > -object rng-random,id=rng0,filename=/dev/urandom \ > -device virtio-rng-pci,rng=rng0 -bios u-boot.bin > => dhcp > # HTTPS transfer using the builtin CA certificates > => wget https://www.google.com/ > 18724 bytes transferred in 15 ms (1.2 MiB/s) > Bytes transferred = 18724 (4924 hex) > > Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > --- > cmd/Kconfig | 16 +++++++++++++- > cmd/net-lwip.c | 4 ++++ > net/lwip/Makefile | 6 ++++++ > net/lwip/wget.c | 53 +++++++++++++++++++++++++++++++++++++++-------- > 4 files changed, 69 insertions(+), 10 deletions(-) > > diff --git a/cmd/Kconfig b/cmd/Kconfig > index a188a2ef24b..cb3cc859616 100644 > --- a/cmd/Kconfig > +++ b/cmd/Kconfig > @@ -2186,12 +2186,26 @@ config WGET_CACERT > to the HTTPS engine. > > config MBEDTLS_LIB_X509_PEM > - depends on WGET_CACERT > + depends on WGET_HTTPS > 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. > > +config WGET_BUILTIN_CACERT > + bool "Built-in CA certificates" > + depends on WGET_HTTPS > + > +config WGET_BUILTIN_CACERT_PATH > + string "Path to root certificates" > + depends on WGET_BUILTIN_CACERT > + default "cacert.crt" > + help > + Set this to the path to a DER- or PEM-encoded X509 file containing > + Certification Authority certificates, a.k.a. root certificates, for > + the purpose of authenticating HTTPS connections. Do not forget to > + enable MBEDTLS_LIB_X509_PEM if the file is PEM. > + > endif # if CMD_NET > > config CMD_PXE > diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c > index 0672f48a7a8..a848d0b1dcf 100644 > --- a/cmd/net-lwip.c > +++ b/cmd/net-lwip.c > @@ -39,6 +39,10 @@ U_BOOT_CMD(wget, 4, 1, do_wget, > #if defined(CONFIG_WGET_CACERT) > "\nwget cacert <address> <length>\n" > " - provide CA certificates (0 0 to disable verification)" > +#if defined(CONFIG_WGET_BUILTIN_CACERT) > + "\nwget cacert builtin\n" > + " - use the builtin CA certificates" > +#endif > #endif > ); > #endif > diff --git a/net/lwip/Makefile b/net/lwip/Makefile > index 79dd6b3fb50..950c5316bb9 100644 > --- a/net/lwip/Makefile > +++ b/net/lwip/Makefile > @@ -6,3 +6,9 @@ obj-$(CONFIG_CMD_DNS) += dns.o > obj-$(CONFIG_CMD_PING) += ping.o > obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o > obj-$(CONFIG_WGET) += wget.o > + > +ifeq (y,$(CONFIG_WGET_BUILTIN_CACERT)) > +$(obj)/builtin_cacert.c: $(CONFIG_WGET_BUILTIN_CACERT_PATH:"%"=%) FORCE > + $(call if_changed,bin2c,builtin_cacert) > +obj-y += builtin_cacert.o > +endif > diff --git a/net/lwip/wget.c b/net/lwip/wget.c > index 14466598d7c..f24aa9c2380 100644 > --- a/net/lwip/wget.c > +++ b/net/lwip/wget.c > @@ -288,31 +288,34 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct > #if defined CONFIG_WGET_HTTPS > static char *cacert; > size_t cacert_size; > + > +#if defined CONFIG_WGET_BUILTIN_CACERT > +extern char builtin_cacert[]; > +extern const size_t builtin_cacert_size; > +static bool cacert_initialized; > +#endif > #endif > > -#if defined CONFIG_WGET_CACERT > -static int set_cacert(char * const saddr, char * const ssz) > +#if defined CONFIG_WGET_CACERT || defined CONFIG_WGET_BUILTIN_CACERT > +static int _set_cacert(void *addr, size_t sz) > { > mbedtls_x509_crt crt; > - ulong addr, sz; > + void *p; > 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) HERE... > + p = malloc(sz); > + if (!p) > return CMD_RET_FAILURE; > + cacert = p; > cacert_size = sz; > > memcpy(cacert, (void *)addr, sz - 1); > @@ -328,10 +331,33 @@ static int set_cacert(char * const saddr, char * const ssz) > return CMD_RET_FAILURE; > } > > +#if defined CONFIG_WGET_BUILTIN_CACERT > + cacert_initialized = true; > +#endif > return CMD_RET_SUCCESS; > } > + > +#if defined CONFIG_WGET_BUILTIN_CACERT > +static int set_cacert_builtin(void) > +{ > + return _set_cacert(builtin_cacert, builtin_cacert_size); > +} > #endif > > +#if defined CONFIG_WGET_CACERT > +static int set_cacert(char * const saddr, char * const ssz) > +{ > + ulong addr, sz; > + > + addr = hextoul(saddr, NULL); > + sz = hextoul(ssz, NULL); > + sz++; /* For the trailing '\0' in case of a text (PEM) file */ This line should have been moved to _set_cacert() at the place I marked "HERE" above. The reason for this hack is, before even attempting to parse a file as PEM format (which is text-based), mbedtls_x509_crt_parse() checks that buf[buflen - 1] == '\0'. When a text file is obtained via wget there is no null terminator. Same when using bin2c. So adding the '\0' is necessary. I decided to always add a null byte because it appears to not cause any problem with binary (DER) files anyways. > + > + return _set_cacert((void *)addr, sz); > +} > +#endif > +#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */ > + > static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) > { > #if defined CONFIG_WGET_HTTPS > @@ -361,6 +387,10 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) > memset(&conn, 0, sizeof(conn)); > #if defined CONFIG_WGET_HTTPS > if (is_https) { > +#if defined CONFIG_WGET_BUILTIN_CACERT > + if (!cacert_initialized) > + set_cacert_builtin(); > +#endif > tls_allocator.alloc = &altcp_tls_alloc; > tls_allocator.arg = > altcp_tls_create_config_client(cacert, cacert_size, > @@ -420,6 +450,11 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) > #if defined CONFIG_WGET_CACERT > if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) > return set_cacert(argv[2], argv[3]); > +#if defined CONFIG_WGET_BUILTIN_CACERT > + if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert")) && > + !strncmp(argv[2], "builtin", strlen("builtin"))) > + return set_cacert_builtin(); > +#endif > #endif > > if (argc < 2 || argc > 3)
diff --git a/cmd/Kconfig b/cmd/Kconfig index a188a2ef24b..cb3cc859616 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2186,12 +2186,26 @@ config WGET_CACERT to the HTTPS engine. config MBEDTLS_LIB_X509_PEM - depends on WGET_CACERT + depends on WGET_HTTPS 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. +config WGET_BUILTIN_CACERT + bool "Built-in CA certificates" + depends on WGET_HTTPS + +config WGET_BUILTIN_CACERT_PATH + string "Path to root certificates" + depends on WGET_BUILTIN_CACERT + default "cacert.crt" + help + Set this to the path to a DER- or PEM-encoded X509 file containing + Certification Authority certificates, a.k.a. root certificates, for + the purpose of authenticating HTTPS connections. Do not forget to + enable MBEDTLS_LIB_X509_PEM if the file is PEM. + endif # if CMD_NET config CMD_PXE diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index 0672f48a7a8..a848d0b1dcf 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -39,6 +39,10 @@ U_BOOT_CMD(wget, 4, 1, do_wget, #if defined(CONFIG_WGET_CACERT) "\nwget cacert <address> <length>\n" " - provide CA certificates (0 0 to disable verification)" +#if defined(CONFIG_WGET_BUILTIN_CACERT) + "\nwget cacert builtin\n" + " - use the builtin CA certificates" +#endif #endif ); #endif diff --git a/net/lwip/Makefile b/net/lwip/Makefile index 79dd6b3fb50..950c5316bb9 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -6,3 +6,9 @@ obj-$(CONFIG_CMD_DNS) += dns.o obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o obj-$(CONFIG_WGET) += wget.o + +ifeq (y,$(CONFIG_WGET_BUILTIN_CACERT)) +$(obj)/builtin_cacert.c: $(CONFIG_WGET_BUILTIN_CACERT_PATH:"%"=%) FORCE + $(call if_changed,bin2c,builtin_cacert) +obj-y += builtin_cacert.o +endif diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 14466598d7c..f24aa9c2380 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -288,31 +288,34 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct #if defined CONFIG_WGET_HTTPS static char *cacert; size_t cacert_size; + +#if defined CONFIG_WGET_BUILTIN_CACERT +extern char builtin_cacert[]; +extern const size_t builtin_cacert_size; +static bool cacert_initialized; +#endif #endif -#if defined CONFIG_WGET_CACERT -static int set_cacert(char * const saddr, char * const ssz) +#if defined CONFIG_WGET_CACERT || defined CONFIG_WGET_BUILTIN_CACERT +static int _set_cacert(void *addr, size_t sz) { mbedtls_x509_crt crt; - ulong addr, sz; + void *p; 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) + p = malloc(sz); + if (!p) return CMD_RET_FAILURE; + cacert = p; cacert_size = sz; memcpy(cacert, (void *)addr, sz - 1); @@ -328,10 +331,33 @@ static int set_cacert(char * const saddr, char * const ssz) return CMD_RET_FAILURE; } +#if defined CONFIG_WGET_BUILTIN_CACERT + cacert_initialized = true; +#endif return CMD_RET_SUCCESS; } + +#if defined CONFIG_WGET_BUILTIN_CACERT +static int set_cacert_builtin(void) +{ + return _set_cacert(builtin_cacert, builtin_cacert_size); +} #endif +#if defined CONFIG_WGET_CACERT +static int set_cacert(char * const saddr, char * const ssz) +{ + ulong addr, sz; + + addr = hextoul(saddr, NULL); + sz = hextoul(ssz, NULL); + sz++; /* For the trailing '\0' in case of a text (PEM) file */ + + return _set_cacert((void *)addr, sz); +} +#endif +#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */ + static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) { #if defined CONFIG_WGET_HTTPS @@ -361,6 +387,10 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) memset(&conn, 0, sizeof(conn)); #if defined CONFIG_WGET_HTTPS if (is_https) { +#if defined CONFIG_WGET_BUILTIN_CACERT + if (!cacert_initialized) + set_cacert_builtin(); +#endif tls_allocator.alloc = &altcp_tls_alloc; tls_allocator.arg = altcp_tls_create_config_client(cacert, cacert_size, @@ -420,6 +450,11 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) #if defined CONFIG_WGET_CACERT if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) return set_cacert(argv[2], argv[3]); +#if defined CONFIG_WGET_BUILTIN_CACERT + if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert")) && + !strncmp(argv[2], "builtin", strlen("builtin"))) + return set_cacert_builtin(); +#endif #endif if (argc < 2 || argc > 3)
Introduce Kconfig symbols WGET_BUILTIN_CACERT and WGET_BUILTIN_CACERT_PATH to provide root certificates at build time. The file may be a DER-encoded (.crt) or PEM-encoded (.pem) X509 collection of one or more certificates. PEM encoding needs MBEDTLS_LIB_X509_PEM. Usage example: wget https://curl.se/ca/cacert.pem make qemu_arm64_lwip_defconfig echo CONFIG_WGET_BUILTIN_CACERT=y >>.config echo CONFIG_WGET_BUILTIN_CACERT_PATH=cacert.pem >>.config echo CONFIG_MBEDTLS_LIB_X509_PEM=y >>.config make olddefconfig make -j$(nproc) CROSS_COMPILE="ccache aarch64-linux-gnu-" qemu-system-aarch64 -M virt -nographic -cpu max \ -object rng-random,id=rng0,filename=/dev/urandom \ -device virtio-rng-pci,rng=rng0 -bios u-boot.bin => dhcp # HTTPS transfer using the builtin CA certificates => wget https://www.google.com/ 18724 bytes transferred in 15 ms (1.2 MiB/s) Bytes transferred = 18724 (4924 hex) Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> --- cmd/Kconfig | 16 +++++++++++++- cmd/net-lwip.c | 4 ++++ net/lwip/Makefile | 6 ++++++ net/lwip/wget.c | 53 +++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 69 insertions(+), 10 deletions(-)