From 7c4cb6f007d1bd332c00528d897db1a46197f83d Mon Sep 17 00:00:00 2001 From: incubator4 Date: Wed, 12 Feb 2025 17:26:26 +0800 Subject: [PATCH] feat: add pem dependency and implement public key parsing from PEM format --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/signer.rs | 42 ++++++++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a765cb9..42ddf2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3110,9 +3110,9 @@ dependencies = [ name = "solana-signer-gcp" version = "0.1.0" dependencies = [ - "base64 0.22.1", "ed25519 2.2.3", "gcloud-sdk", + "pem", "solana-sdk", "thiserror 2.0.11", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 199cccc..aaec38c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ solana-sdk = { version = "2.1.13" } thiserror = "2.0.11" tracing = "0.1" tokio = { version = "1.0", features = ["full"] } -base64 = "0.22.1" +pem = "3.0.4" [dev-dependencies] tokio = { version = "1.0", features = ["full"] } diff --git a/src/signer.rs b/src/signer.rs index 4f6384b..1c79dad 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -2,7 +2,6 @@ use core::fmt; use std::{cell::OnceCell, sync::Arc}; -use base64::Engine; use gcloud_sdk::{ google::cloud::kms::{ // self, @@ -24,7 +23,6 @@ use solana_sdk::{ signer::{Signer, SignerError}, }; use thiserror::Error; -// use ed25519::pkcs8::Pubkey; type Client = GoogleApi>; @@ -100,7 +98,10 @@ pub enum GcpSignerError { RequestError(#[from] tonic::Status), #[error(transparent)] - Base64Error(#[from] base64::DecodeError), + PemError(#[from] pem::PemError), + + #[error("Invalid pubkey length {0}")] + InvalidPubkeyLength(usize), } impl Into for GcpSignerError { @@ -136,22 +137,10 @@ impl GcpSigner { let key_name = key_specifier.0; let pubkey = request_get_pubkey(&client, &key_name).await?; - let clean_b64 = pubkey - .pem - .replace("-----BEGIN PUBLIC KEY-----", "") - .replace("-----END PUBLIC KEY-----", "") - .replace('\n', "") - .trim() - .to_string(); - - let der_bytes = base64::engine::general_purpose::STANDARD.decode(clean_b64)?; - Ok(Self { client, key_name, - pubkey: Arc::new(OnceCell::from(Pubkey::from_str_const( - std::str::from_utf8(&der_bytes).unwrap(), - ))), + pubkey: Arc::new(OnceCell::from(from_public_key_pem(pubkey)?)), address: String::from(""), }) } @@ -182,6 +171,27 @@ async fn request_get_pubkey( .map_err(Into::into) } +#[instrument(err)] +fn from_public_key_pem(key: PublicKey) -> Result { + let pkey = pem::parse(key.pem)?; + + let content = pkey.contents(); + + let mut array = [0u8; 32]; + + match content.len() { + 32 => { + array.copy_from_slice(content); + Ok(Pubkey::new_from_array(array)) + } + 44 => { + array.copy_from_slice(&content[12..]); + Ok(Pubkey::new_from_array(array)) + } + size => Err(GcpSignerError::InvalidPubkeyLength(size)), + } +} + #[cfg(test)] mod test { use solana_sdk::signer::Signer;