From 2e5a03877fa113340f2a7087870d0f98ba1b24a4 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 22 May 2025 20:24:13 +0200 Subject: [PATCH] net: tls_credentials_shell: Add credential buffer load argument Add argument to the TLS credential `cred buf` command that enables a shell bypass to write the TLS credential directly to the credential buffer. This is useful for writing load credentials that cannot fit in a single `cred buf` command and would otherwise have to be split into multiple cred buf commands. Sending multiple in succession like that from a script for example very easily causes the shell RX buffer to get full, resulting in multiple `RX ring buffer full.` warnings. This is very difficult for a script to handle. Using a bypass has much better performance and can easily avoid the RX ring buffer full condition without increasing the RX ring buffer to much. It is also easier for a script to use. Signed-off-by: Joakim Andersson --- .../tls_credentials/tls_credentials_shell.c | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/tls_credentials/tls_credentials_shell.c b/subsys/net/lib/tls_credentials/tls_credentials_shell.c index 8ab9d4a7052..fe27565fbb7 100644 --- a/subsys/net/lib/tls_credentials/tls_credentials_shell.c +++ b/subsys/net/lib/tls_credentials/tls_credentials_shell.c @@ -152,10 +152,9 @@ static bool cred_buf_clear(void) } /* Parse a (possibly incomplete) chunk into the credential buffer */ -static int cred_buf_write(char *chunk) +static int cred_buf_write(char *chunk, size_t chunk_len) { char *writehead = cred_buf + cred_written; - size_t chunk_len = strlen(chunk); /* Verify that there is room for the incoming chunk */ if ((writehead + chunk_len) >= (cred_buf + sizeof(cred_buf) - 1)) { @@ -327,7 +326,8 @@ static void shell_clear_cred_buf(const struct shell *sh) /* Write data into the credential buffer, with shell feedback. */ static int shell_write_cred_buf(const struct shell *sh, char *chunk) { - int res = cred_buf_write(chunk); + size_t chunk_len = strlen(chunk); + int res = cred_buf_write(chunk, chunk_len); /* Report results. */ @@ -515,15 +515,59 @@ cleanup: return err; } +#define ASCII_CTRL_C 0x03 + +static void tls_cred_cmd_load_bypass(const struct shell *sh, uint8_t *data, size_t len) +{ + bool terminate = false; + int res; + size_t write_len = len; + + for (size_t i = 0; i < len; i++) { + if (data[i] == ASCII_CTRL_C) { + write_len = i; + terminate = true; + break; + } + } + + res = cred_buf_write(data, write_len); + if (res == -ENOMEM) { + shell_set_bypass(sh, NULL); + shell_fprintf(sh, SHELL_ERROR, "Not enough room in credential buffer for " + "provided data. Increase " + "CONFIG_TLS_CREDENTIALS_SHELL_CRED_BUF_SIZE.\n"); + shell_clear_cred_buf(sh); + return; + } + + if (terminate) { + shell_set_bypass(sh, NULL); + shell_fprintf(sh, SHELL_NORMAL, "Stored %d bytes.\n", cred_written); + } +} + +static int tls_cred_cmd_buf_clear(const struct shell *sh, size_t argc, char *argv[]) +{ + /* If the "clear" keyword is provided, clear the buffer rather than write to it. */ + (void)cred_buf_clear(); + shell_fprintf(sh, SHELL_NORMAL, "Credential buffer cleared.\n"); + + return 0; +} + +static int tls_cred_cmd_buf_load(const struct shell *sh, size_t argc, char *argv[]) +{ + shell_clear_cred_buf(sh); + + shell_fprintf(sh, SHELL_NORMAL, "Input credential, finish with CTRL+C.\n"); + shell_set_bypass(sh, tls_cred_cmd_load_bypass); + return 0; +} + /* Buffers credential data into the credential buffer. */ static int tls_cred_cmd_buf(const struct shell *sh, size_t argc, char *argv[]) { - /* If the "clear" keyword is provided, clear the buffer rather than write to it. */ - if (strcmp(argv[1], "clear") == 0) { - shell_clear_cred_buf(sh); - return 0; - } - /* Otherwise, assume provided arg is base64 and attempt to write it into the credential * buffer. */ @@ -793,8 +837,15 @@ cleanup: return 0; } +SHELL_STATIC_SUBCMD_SET_CREATE(tls_cred_buf_cmds, + SHELL_CMD(clear, NULL, "Clear the credential buffer", tls_cred_cmd_buf_clear), + SHELL_CMD(load, NULL, "Load credential directly to buffer so it can be added.", + tls_cred_cmd_buf_load), + SHELL_SUBCMD_SET_END +); + SHELL_STATIC_SUBCMD_SET_CREATE(tls_cred_cmds, - SHELL_CMD_ARG(buf, NULL, "Buffer in credential data so it can be added.", + SHELL_CMD_ARG(buf, &tls_cred_buf_cmds, "Buffer in credential data so it can be added.", tls_cred_cmd_buf, 2, 0), SHELL_CMD_ARG(add, NULL, "Add a TLS credential.", tls_cred_cmd_add, 5, 1),