net: lwip: add support for built-in root certificates

Introduce Kconfig symbols WGET_BUILTIN_CACERT and
WGET_BUILTIN_CACERT_PATH to provide root certificates at build time.

Usage example:

 wget -O cacert.crt https://cacerts.digicert.com/DigiCertTLSECCP384RootG5.crt
 make qemu_arm64_lwip_defconfig
 echo CONFIG_WGET_BUILTIN_CACERT=y >>.config
 echo CONFIG_WGET_BUILTIN_CACERT_PATH=cacert.crt >>.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://digicert-tls-ecc-p384-root-g5.chain-demos.digicert.com/
 1867 bytes transferred in 1 ms (1.8 MiB/s)
 Bytes transferred = 1867 (74b hex)

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
Jerome Forissier 2025-03-05 15:26:45 +01:00
parent 7a15ccb662
commit 12cc6531a1
4 changed files with 72 additions and 9 deletions

View file

@ -2184,6 +2184,20 @@ config WGET_CACERT
Adds the "cacert" sub-command to wget to provide root certificates
to the HTTPS engine. Must be in DER format.
config WGET_BUILTIN_CACERT
bool "Built-in CA certificates"
depends on WGET_HTTPS
select BUILD_BIN2C
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-encoded X509 file containing
Certification Authority certificates, a.k.a. root certificates, for
the purpose of authenticating HTTPS connections.
endif # if CMD_NET
config CMD_PXE

View file

@ -41,6 +41,10 @@ U_BOOT_CMD(wget, 4, 1, do_wget,
" - provide CA certificates (0 0 to remove current)"
"\nwget cacert none|optional|required\n"
" - set server certificate verification mode (default: optional)"
#if defined(CONFIG_WGET_BUILTIN_CACERT)
"\nwget cacert builtin\n"
" - use the builtin CA certificates"
#endif
#endif
);
#endif

View file

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

View file

@ -304,28 +304,34 @@ static int set_auth(enum auth_mode auth)
return CMD_RET_SUCCESS;
}
#endif
static int set_cacert(char * const saddr, char * const ssz)
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
extern const char builtin_cacert[];
extern const size_t builtin_cacert_size;
static bool cacert_initialized;
#endif
#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
static int _set_cacert(const 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);
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);
@ -340,10 +346,32 @@ static int set_cacert(char * const saddr, char * const ssz)
return CMD_RET_FAILURE;
}
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
cacert_initialized = true;
#endif
return CMD_RET_SUCCESS;
}
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
static int set_cacert_builtin(void)
{
return _set_cacert(builtin_cacert, builtin_cacert_size);
}
#endif
#if CONFIG_IS_ENABLED(WGET_CACERT)
static int set_cacert(char * const saddr, char * const ssz)
{
ulong addr, sz;
addr = hextoul(saddr, NULL);
sz = hextoul(ssz, NULL);
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 CONFIG_IS_ENABLED(WGET_HTTPS)
@ -373,8 +401,15 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
memset(&conn, 0, sizeof(conn));
#if CONFIG_IS_ENABLED(WGET_HTTPS)
if (is_https) {
char *ca = cacert;
size_t ca_sz = cacert_size;
char *ca;
size_t ca_sz;
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
if (!cacert_initialized)
set_cacert_builtin();
#endif
ca = cacert;
ca_sz = cacert_size;
if (cacert_auth_mode == AUTH_REQUIRED) {
if (!ca || !ca_sz) {
@ -455,6 +490,10 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert")))
return set_cacert(argv[2], argv[3]);
if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) {
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
if (!strncmp(argv[2], "builtin", strlen("builtin")))
return set_cacert_builtin();
#endif
if (!strncmp(argv[2], "none", strlen("none")))
return set_auth(AUTH_NONE);
if (!strncmp(argv[2], "optional", strlen("optional")))