Skip to content

Commit aeaa27d

Browse files
committed
lib: tls_credentials_shell: protect private key
Add kconfig option to decide whether private keys are allowed to be read out. Signed-off-by: Maximilian Deubel <[email protected]>
1 parent dbce3eb commit aeaa27d

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

subsys/net/lib/tls_credentials/Kconfig.shell

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ config TLS_CREDENTIALS_SHELL_DIGEST_BUF_SIZE
3232

3333
Also used to print error messages if digest generation fails.
3434

35+
config TLS_CREDENTIALS_ALLOW_READ_PK
36+
int "Allow reading out private keys"
37+
help
38+
Allow reading out private keys. If disabled, public key is read out instead.
39+
3540
if TLS_CREDENTIALS_BACKEND_VOLATILE
3641

3742
config HEAP_MEM_POOL_ADD_SIZE_TLS_CRED_SHELL

subsys/net/lib/tls_credentials/tls_credentials_shell.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,73 @@ static int tls_cred_cmd_get(const struct shell *sh, size_t argc, char *argv[])
765765
*/
766766
cred_written = cred_len;
767767

768+
#if !defined(CONFIG_TLS_CREDENTIALS_ALLOW_READ_PK)
769+
/* If private key retrieval is not allowed, extract public key from the private key */
770+
if (type == TLS_CREDENTIAL_PRIVATE_KEY) {
771+
shell_fprintf(sh, SHELL_WARNING,
772+
"Private key retrieval is not allowed. Extracting public key from "
773+
"private key.\n");
774+
775+
#if defined(CONFIG_PSA_CRYPTO) && defined(MBEDTLS_PEM_WRITE_C)
776+
/* Extract public key from PEM-encoded private key */
777+
size_t pub_key_der_len = sizeof(cred_buf) / 2;
778+
uint8_t pub_key_der[sizeof(cred_buf) / 2];
779+
780+
int pk_err = 0;
781+
mbedtls_pk_context pk;
782+
mbedtls_pk_init(&pk);
783+
784+
/* Parse the PEM private key */
785+
pk_err = mbedtls_pk_parse_key(&pk, (const unsigned char *)cred_buf,
786+
cred_written + 1, NULL, 0);
787+
if (pk_err != 0) {
788+
shell_fprintf(sh, SHELL_ERROR, "Failed to parse private key (Error: %d)\n",
789+
pk_err);
790+
err = pk_err;
791+
mbedtls_pk_free(&pk);
792+
goto cleanup;
793+
}
794+
795+
/* Write the public key in DER format */
796+
pk_err = mbedtls_pk_write_pubkey_der(&pk, pub_key_der, pub_key_der_len);
797+
if (pk_err < 0) {
798+
shell_fprintf(sh, SHELL_ERROR, "Failed to extract public key (Error: %d)\n",
799+
pk_err);
800+
err = pk_err;
801+
mbedtls_pk_free(&pk);
802+
goto cleanup;
803+
}
804+
805+
pub_key_der_len = pk_err;
806+
mbedtls_pk_free(&pk);
807+
808+
/* Convert DER public key to PEM */
809+
size_t pub_key_pem_len;
810+
uint8_t pub_key_pem[sizeof(cred_buf)];
811+
812+
pk_err = mbedtls_pem_write_buffer(
813+
"-----BEGIN PUBLIC KEY-----\n", "-----END PUBLIC KEY-----\n", pub_key_der,
814+
pub_key_der_len, pub_key_pem, sizeof(pub_key_pem), &pub_key_pem_len);
815+
if (pk_err != 0) {
816+
shell_fprintf(sh, SHELL_ERROR,
817+
"Failed to convert public key to PEM (Error: %d)\n", pk_err);
818+
err = pk_err;
819+
goto cleanup;
820+
}
821+
822+
/* Replace the buffer contents with the public key */
823+
memcpy(cred_buf, pub_key_pem, pub_key_pem_len);
824+
cred_written = pub_key_pem_len;
825+
#else
826+
shell_fprintf(sh, SHELL_ERROR,
827+
"Cannot extract public key: PSA_CRYPTO or MBEDTLS_PEM_WRITE_C not "
828+
"enabled\n");
829+
err = -ENOTSUP;
830+
goto cleanup;
831+
#endif
832+
}
833+
#endif
834+
768835
/* If the stored credential is NULL-terminated, do not include NULL termination in output */
769836
if (terminated) {
770837
if (cred_buf[cred_written - 1] != 0) {

0 commit comments

Comments
 (0)