public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Jerome Forissier <jerome.forissier@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Tom Rini <trini@konsulko.com>,
	Joe Hershberger <joe.hershberger@ni.com>,
	Ramon Fried <rfried.dev@gmail.com>,
	Simon Glass <sjg@chromium.org>,
	Mattijs Korpershoek <mkorpershoek@baylibre.com>,
	Ibai Erkiaga <ibai.erkiaga-elorza@amd.com>,
	Michal Simek <michal.simek@amd.com>,
	Adriano Cordova <adrianox@gmail.com>,
	u-boot@lists.denx.de
Subject: Re: [PATCH v2 1/6] net: lwip: extend wget to support CA (root) certificates
Date: Wed, 5 Mar 2025 16:13:39 +0100	[thread overview]
Message-ID: <26ec5905-e96a-4ff2-bdea-652eb9031ee3@linaro.org> (raw)
In-Reply-To: <cb301142-b76a-45ff-ace4-39e58d9a8de7@gmx.de>

Hi Heinrich,

On 3/5/25 16:07, Heinrich Schuchardt wrote:
> On 05.03.25 15:26, Jerome Forissier wrote:
>> 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://cacerts.digicert.com/DigiCertTLSECCP384RootG5.crt
>>   # Provide root certificates
>>   => wget cacert $fileaddr $filesize
>>   # Enforce verification (it is optional by default)
>>   => wget cacert required
>>   # Forget the root certificates
>>   => wget cacert 0 0
>>   # Disable verification
>>   => wget cacert none
>>
>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
>> ---
>>   cmd/Kconfig     |   8 ++++
>>   cmd/net-lwip.c  |  17 ++++++--
>>   net/lwip/wget.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++--
>>   3 files changed, 121 insertions(+), 6 deletions(-)
>>
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index 8dd42571abc..d469217c0ea 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -2177,6 +2177,14 @@ 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. Must be in DER format.
>> +
> 
> Shouldn't we build CA certs into U-Boot?
> Downloading certs from unsafe media is not a good replacement.

That's the purpose of patch 4/6 [1]. Although downloading may still be a
valid option when used with hash verification as I mentioned in a reply to
Ilias in v1 [2].

[1] https://lists.denx.de/pipermail/u-boot/2025-March/582567.html
[2] https://lists.denx.de/pipermail/u-boot/2025-February/582102.html

Best,
-- 
Jerome

> 
> Best regards
> 
> Heinrich
> 
>>   endif  # if CMD_NET
>>
>>   config CMD_PXE
>> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
>> index 0fd446ecb20..1152c94a6dc 100644
>> --- a/cmd/net-lwip.c
>> +++ b/cmd/net-lwip.c
>> @@ -27,9 +27,20 @@ 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 remove current)"
>> +       "\nwget cacert none|optional|required\n"
>> +       "    - set server certificate verification mode (default: optional)"
>> +#endif
>>   );
>>   #endif
>> diff --git a/net/lwip/wget.c b/net/lwip/wget.c
>> index 14f27d42998..c22843ee10d 100644
>> --- a/net/lwip/wget.c
>> +++ b/net/lwip/wget.c
>> @@ -285,9 +285,68 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct
>>       return ERR_OK;
>>   }
>>
>> +#if CONFIG_IS_ENABLED(WGET_HTTPS)
>> +enum auth_mode {
>> +    AUTH_NONE,
>> +    AUTH_OPTIONAL,
>> +    AUTH_REQUIRED,
>> +};
>> +
>> +static char *cacert;
>> +static size_t cacert_size;
>> +static enum auth_mode cacert_auth_mode = AUTH_OPTIONAL;
>> +#endif
>> +
>> +#if CONFIG_IS_ENABLED(WGET_CACERT)
>> +static int set_auth(enum auth_mode auth)
>> +{
>> +    cacert_auth_mode = auth;
>> +
>> +    return CMD_RET_SUCCESS;
>> +}
>> +
>> +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);
>> +
>> +    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);
>> +
>> +    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
>> +#if CONFIG_IS_ENABLED(WGET_HTTPS)
>>       altcp_allocator_t tls_allocator;
>>   #endif
>>       httpc_connection_t conn;
>> @@ -312,11 +371,34 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
>>           return -1;
>>
>>       memset(&conn, 0, sizeof(conn));
>> -#if defined CONFIG_WGET_HTTPS
>> +#if CONFIG_IS_ENABLED(WGET_HTTPS)
>>       if (is_https) {
>> +        char *ca = cacert;
>> +        size_t ca_sz = cacert_size;
>> +
>> +        if (cacert_auth_mode == AUTH_REQUIRED) {
>> +            if (!ca || !ca_sz) {
>> +                printf("Error: cacert authentication mode is "
>> +                       "'required' but no CA certificates "
>> +                       "given\n");
>> +                return CMD_RET_FAILURE;
>> +               }
>> +        } else if (cacert_auth_mode == AUTH_NONE) {
>> +            ca = NULL;
>> +            ca_sz = 0;
>> +        } else if (cacert_auth_mode == AUTH_OPTIONAL) {
>> +            /*
>> +             * Nothing to do, this is the default behavior of
>> +             * altcp_tls to check server certificates against CA
>> +             * certificates when the latter are provided and proceed
>> +             * with no verification if not.
>> +             */
>> +        }
>> +
>>           tls_allocator.alloc = &altcp_tls_alloc;
>>           tls_allocator.arg =
>> -            altcp_tls_create_config_client(NULL, 0, ctx.server_name);
>> +            altcp_tls_create_config_client(ca, ca_sz,
>> +                               ctx.server_name);
>>
>>           if (!tls_allocator.arg) {
>>               log_err("error: Cannot create a TLS connection\n");
>> @@ -369,6 +451,20 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
>>       ulong dst_addr;
>>       char nurl[1024];
>>
>> +#if CONFIG_IS_ENABLED(WGET_CACERT)
>> +    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 (!strncmp(argv[2], "none", strlen("none")))
>> +            return set_auth(AUTH_NONE);
>> +        if (!strncmp(argv[2], "optional", strlen("optional")))
>> +            return set_auth(AUTH_OPTIONAL);
>> +        if (!strncmp(argv[2], "required", strlen("required")))
>> +            return set_auth(AUTH_REQUIRED);
>> +        return CMD_RET_USAGE;
>> +    }
>> +#endif
>> +
>>       if (argc < 2 || argc > 3)
>>           return CMD_RET_USAGE;
>>
> 

  reply	other threads:[~2025-03-05 15:13 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-05 14:26 [PATCH v2 0/6] net: lwip: root certificates Jerome Forissier
2025-03-05 14:26 ` [PATCH v2 1/6] net: lwip: extend wget to support CA (root) certificates Jerome Forissier
2025-03-05 15:07   ` Heinrich Schuchardt
2025-03-05 15:13     ` Jerome Forissier [this message]
2025-03-09 10:58       ` Ilias Apalodimas
2025-03-09 11:00         ` Ilias Apalodimas
2025-03-10  8:08           ` Jerome Forissier
2025-03-10 11:49             ` Ilias Apalodimas
2025-03-10 12:10               ` Jerome Forissier
2025-03-05 14:26 ` [PATCH v2 2/6] lwip: tls: enforce checking of server certificates based on CA availability Jerome Forissier
2025-03-05 14:26 ` [PATCH v2 3/6] lwip: tls: warn when no CA exists amd log certificate validation errors Jerome Forissier
2025-03-05 14:26 ` [PATCH v2 4/6] net: lwip: add support for built-in root certificates Jerome Forissier
2025-03-09 11:33   ` Ilias Apalodimas
2025-03-10  8:05     ` Jerome Forissier
2025-03-10 11:52       ` Ilias Apalodimas
2025-03-10 12:12         ` Jerome Forissier
2025-03-10 12:38           ` Ilias Apalodimas
2025-03-10 12:48             ` Jerome Forissier
2025-03-10 13:04               ` Ilias Apalodimas
2025-03-10 13:48                 ` Jerome Forissier
2025-03-10 13:57                   ` Ilias Apalodimas
2025-03-05 14:26 ` [PATCH v2 5/6] doc: cmd: wget: document cacert subcommand Jerome Forissier
2025-03-09 11:34   ` Ilias Apalodimas
2025-03-05 14:26 ` [PATCH v2 6/6] configs: qemu_arm64_lwip_defconfig: enable WGET_CACERT Jerome Forissier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=26ec5905-e96a-4ff2-bdea-652eb9031ee3@linaro.org \
    --to=jerome.forissier@linaro.org \
    --cc=adrianox@gmail.com \
    --cc=ibai.erkiaga-elorza@amd.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=joe.hershberger@ni.com \
    --cc=michal.simek@amd.com \
    --cc=mkorpershoek@baylibre.com \
    --cc=rfried.dev@gmail.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox