Fix neon_local public key parsing when create compute JWKS (#11602)

Finally figured out the right incantation. I had had this in my original
go, but due to some refactoring and apparently missed testing, I
committed a mistake. The reason this doesn't currently break anything is
that we bypass the authorization middleware when the "testing" cargo
feature is enabled.

Signed-off-by: Tristan Partin <tristan@neon.tech>
This commit is contained in:
Tristan Partin
2025-04-16 07:51:48 -05:00
committed by GitHub
parent b4e26a6284
commit edc11253b6
5 changed files with 11 additions and 11 deletions

3
Cargo.lock generated
View File

@@ -1432,7 +1432,6 @@ dependencies = [
"pageserver_api",
"pageserver_client",
"pem",
"pkcs8 0.10.2",
"postgres_backend",
"postgres_connection",
"regex",
@@ -1442,6 +1441,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
"spki 0.7.3",
"storage_broker",
"thiserror 1.0.69",
"tokio",
@@ -8469,7 +8469,6 @@ dependencies = [
"once_cell",
"p256 0.13.2",
"parquet",
"pkcs8 0.10.2",
"prettyplease",
"proc-macro2",
"prost 0.13.3",

View File

@@ -143,7 +143,6 @@ parquet_derive = "53"
pbkdf2 = { version = "0.12.1", features = ["simple", "std"] }
pem = "3.0.3"
pin-project-lite = "0.2"
pkcs8 = "0.10.2"
pprof = { version = "0.14", features = ["criterion", "flamegraph", "frame-pointer", "prost-codec"] }
procfs = "0.16"
prometheus = {version = "0.13", default-features=false, features = ["process"]} # removes protobuf dependency
@@ -176,6 +175,7 @@ signal-hook = "0.3"
smallvec = "1.11"
smol_str = { version = "0.2.0", features = ["serde"] }
socket2 = "0.5"
spki = "0.7.3"
strum = "0.26"
strum_macros = "0.26"
"subtle" = "2.5.0"

View File

@@ -16,7 +16,6 @@ jsonwebtoken.workspace = true
nix.workspace = true
once_cell.workspace = true
pem.workspace = true
pkcs8.workspace = true
humantime-serde.workspace = true
hyper0.workspace = true
regex.workspace = true
@@ -25,6 +24,7 @@ scopeguard.workspace = true
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
spki.workspace = true
thiserror.workspace = true
toml.workspace = true
toml_edit.workspace = true

View File

@@ -60,11 +60,12 @@ use jsonwebtoken::jwk::{
use nix::sys::signal::{Signal, kill};
use pageserver_api::shard::ShardStripeSize;
use pem::Pem;
use pkcs8::der::Decode;
use reqwest::header::CONTENT_TYPE;
use safekeeper_api::membership::SafekeeperGeneration;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use spki::der::Decode;
use spki::{SubjectPublicKeyInfo, SubjectPublicKeyInfoRef};
use tracing::debug;
use url::Host;
use utils::id::{NodeId, TenantId, TimelineId};
@@ -147,11 +148,12 @@ impl ComputeControlPlane {
/// Create a JSON Web Key Set. This ideally matches the way we create a JWKS
/// from the production control plane.
fn create_jwks_from_pem(pem: Pem) -> Result<JwkSet> {
let document = pkcs8::Document::from_der(&pem.into_contents())?;
fn create_jwks_from_pem(pem: &Pem) -> Result<JwkSet> {
let spki: SubjectPublicKeyInfoRef = SubjectPublicKeyInfo::from_der(pem.contents())?;
let public_key = spki.subject_public_key.raw_bytes();
let mut hasher = Sha256::new();
hasher.update(&document);
hasher.update(public_key);
let key_hash = hasher.finalize();
Ok(JwkSet {
@@ -169,7 +171,7 @@ impl ComputeControlPlane {
algorithm: AlgorithmParameters::OctetKeyPair(OctetKeyPairParameters {
key_type: OctetKeyPairType::OctetKeyPair,
curve: EllipticCurve::Ed25519,
x: base64::encode_config(&document, base64::URL_SAFE_NO_PAD),
x: base64::encode_config(public_key, base64::URL_SAFE_NO_PAD),
}),
}],
})
@@ -193,7 +195,7 @@ impl ComputeControlPlane {
let external_http_port = external_http_port.unwrap_or_else(|| self.get_port() + 1);
let internal_http_port = internal_http_port.unwrap_or_else(|| external_http_port + 1);
let compute_ctl_config = ComputeCtlConfig {
jwks: Self::create_jwks_from_pem(self.env.read_public_key()?)?,
jwks: Self::create_jwks_from_pem(&self.env.read_public_key()?)?,
tls: None::<TlsConfig>,
};
let ep = Arc::new(Endpoint {

View File

@@ -70,7 +70,6 @@ num-traits = { version = "0.2", features = ["i128", "libm"] }
once_cell = { version = "1" }
p256 = { version = "0.13", features = ["jwk"] }
parquet = { version = "53", default-features = false, features = ["zstd"] }
pkcs8 = { version = "0.10", default-features = false, features = ["pem", "std"] }
prost = { version = "0.13", features = ["no-recursion-limit", "prost-derive"] }
rand = { version = "0.8", features = ["small_rng"] }
regex = { version = "1" }