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.foriss...@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)
+       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)
-- 
2.43.0

Reply via email to