From 8ae7ce25f292ad7085eb317af817527a41edbe9d Mon Sep 17 00:00:00 2001 From: Kevin Biju Date: Thu, 16 Oct 2025 20:31:24 +0530 Subject: [PATCH 1/2] [nexus] base64 decode SSH private key before use --- nexus/Cargo.lock | 1 + nexus/postgres-connection/Cargo.toml | 1 + nexus/postgres-connection/src/lib.rs | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/nexus/Cargo.lock b/nexus/Cargo.lock index c511054532..e3d42d7b17 100644 --- a/nexus/Cargo.lock +++ b/nexus/Cargo.lock @@ -3036,6 +3036,7 @@ name = "postgres-connection" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.22.1", "futures-util", "pt", "rustls 0.23.34", diff --git a/nexus/postgres-connection/Cargo.toml b/nexus/postgres-connection/Cargo.toml index 679ead60e8..0afa2ff8e1 100644 --- a/nexus/postgres-connection/Cargo.toml +++ b/nexus/postgres-connection/Cargo.toml @@ -18,3 +18,4 @@ tokio-util = { version = "0.7", features = ["compat"] } tokio-stream = "0.1" tracing.workspace = true urlencoding = "2" +base64 = "0.22" diff --git a/nexus/postgres-connection/src/lib.rs b/nexus/postgres-connection/src/lib.rs index fefe443120..dcd2a39ca4 100644 --- a/nexus/postgres-connection/src/lib.rs +++ b/nexus/postgres-connection/src/lib.rs @@ -1,3 +1,4 @@ +use base64::Engine; use pt::peerdb_peers::{PostgresConfig, SshConfig}; use rustls::pki_types::{CertificateDer, ServerName, UnixTime}; use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore, SignatureScheme}; @@ -94,7 +95,21 @@ pub async fn create_tunnel( session.userauth_password(&ssh_config.user, &ssh_config.password)?; } if !ssh_config.private_key.is_empty() { - session.userauth_pubkey_memory(&ssh_config.user, None, &ssh_config.private_key, None)?; + let private_key_bytes = base64::engine::general_purpose::STANDARD + .decode(&ssh_config.private_key) + .map_err(|e| { + io::Error::new( + io::ErrorKind::InvalidData, + format!("Failed to decode private key: {e}"), + ) + })?; + let private_key = String::from_utf8(private_key_bytes).map_err(|e| { + io::Error::new( + io::ErrorKind::InvalidData, + format!("Invalid UTF-8 in private key: {e}"), + ) + })?; + session.userauth_pubkey_memory(&ssh_config.user, None, &private_key, None)?; } if !ssh_config.host_key.is_empty() { let mut known_hosts = session.known_hosts()?; From 43da8547014a19a5466ab1acc6d4c63ee7e31173 Mon Sep 17 00:00:00 2001 From: Kevin Biju Date: Thu, 16 Oct 2025 22:16:37 +0530 Subject: [PATCH 2/2] review feedback --- nexus/postgres-connection/Cargo.toml | 3 ++- nexus/postgres-connection/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nexus/postgres-connection/Cargo.toml b/nexus/postgres-connection/Cargo.toml index 0afa2ff8e1..184df1c8a2 100644 --- a/nexus/postgres-connection/Cargo.toml +++ b/nexus/postgres-connection/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" [dependencies] anyhow = "1" +base64 = "0.22" futures-util = { version = "0.3", default-features = false, features = ["io"] } pt = { path = "../pt" } rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs"] } @@ -18,4 +19,4 @@ tokio-util = { version = "0.7", features = ["compat"] } tokio-stream = "0.1" tracing.workspace = true urlencoding = "2" -base64 = "0.22" + diff --git a/nexus/postgres-connection/src/lib.rs b/nexus/postgres-connection/src/lib.rs index dcd2a39ca4..8d1f302296 100644 --- a/nexus/postgres-connection/src/lib.rs +++ b/nexus/postgres-connection/src/lib.rs @@ -103,13 +103,13 @@ pub async fn create_tunnel( format!("Failed to decode private key: {e}"), ) })?; - let private_key = String::from_utf8(private_key_bytes).map_err(|e| { + let private_key = str::from_utf8(private_key_bytes.as_slice()).map_err(|e| { io::Error::new( io::ErrorKind::InvalidData, format!("Invalid UTF-8 in private key: {e}"), ) })?; - session.userauth_pubkey_memory(&ssh_config.user, None, &private_key, None)?; + session.userauth_pubkey_memory(&ssh_config.user, None, private_key, None)?; } if !ssh_config.host_key.is_empty() { let mut known_hosts = session.known_hosts()?;