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:
14
cmd/Kconfig
14
cmd/Kconfig
@@ -2184,6 +2184,20 @@ config WGET_CACERT
|
|||||||
Adds the "cacert" sub-command to wget to provide root certificates
|
Adds the "cacert" sub-command to wget to provide root certificates
|
||||||
to the HTTPS engine. Must be in DER format.
|
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
|
endif # if CMD_NET
|
||||||
|
|
||||||
config CMD_PXE
|
config CMD_PXE
|
||||||
|
@@ -41,6 +41,10 @@ U_BOOT_CMD(wget, 4, 1, do_wget,
|
|||||||
" - provide CA certificates (0 0 to remove current)"
|
" - provide CA certificates (0 0 to remove current)"
|
||||||
"\nwget cacert none|optional|required\n"
|
"\nwget cacert none|optional|required\n"
|
||||||
" - set server certificate verification mode (default: optional)"
|
" - 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
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -6,3 +6,9 @@ obj-$(CONFIG_CMD_DNS) += dns.o
|
|||||||
obj-$(CONFIG_CMD_PING) += ping.o
|
obj-$(CONFIG_CMD_PING) += ping.o
|
||||||
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
|
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
|
||||||
obj-$(CONFIG_WGET) += wget.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
|
||||||
|
@@ -304,28 +304,34 @@ static int set_auth(enum auth_mode auth)
|
|||||||
|
|
||||||
return CMD_RET_SUCCESS;
|
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;
|
mbedtls_x509_crt crt;
|
||||||
ulong addr, sz;
|
void *p;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (cacert)
|
if (cacert)
|
||||||
free(cacert);
|
free(cacert);
|
||||||
|
|
||||||
addr = hextoul(saddr, NULL);
|
|
||||||
sz = hextoul(ssz, NULL);
|
|
||||||
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
cacert = NULL;
|
cacert = NULL;
|
||||||
cacert_size = 0;
|
cacert_size = 0;
|
||||||
return CMD_RET_SUCCESS;
|
return CMD_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
cacert = malloc(sz);
|
p = malloc(sz);
|
||||||
if (!cacert)
|
if (!p)
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
|
cacert = p;
|
||||||
cacert_size = sz;
|
cacert_size = sz;
|
||||||
|
|
||||||
memcpy(cacert, (void *)addr, sz);
|
memcpy(cacert, (void *)addr, sz);
|
||||||
@@ -340,10 +346,32 @@ static int set_cacert(char * const saddr, char * const ssz)
|
|||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
|
||||||
|
cacert_initialized = true;
|
||||||
|
#endif
|
||||||
return CMD_RET_SUCCESS;
|
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
|
#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)
|
static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||||
{
|
{
|
||||||
#if CONFIG_IS_ENABLED(WGET_HTTPS)
|
#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));
|
memset(&conn, 0, sizeof(conn));
|
||||||
#if CONFIG_IS_ENABLED(WGET_HTTPS)
|
#if CONFIG_IS_ENABLED(WGET_HTTPS)
|
||||||
if (is_https) {
|
if (is_https) {
|
||||||
char *ca = cacert;
|
char *ca;
|
||||||
size_t ca_sz = cacert_size;
|
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 (cacert_auth_mode == AUTH_REQUIRED) {
|
||||||
if (!ca || !ca_sz) {
|
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")))
|
if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert")))
|
||||||
return set_cacert(argv[2], argv[3]);
|
return set_cacert(argv[2], argv[3]);
|
||||||
if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) {
|
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")))
|
if (!strncmp(argv[2], "none", strlen("none")))
|
||||||
return set_auth(AUTH_NONE);
|
return set_auth(AUTH_NONE);
|
||||||
if (!strncmp(argv[2], "optional", strlen("optional")))
|
if (!strncmp(argv[2], "optional", strlen("optional")))
|
||||||
|
Reference in New Issue
Block a user