From f08b2c94fcacebb70fe09965c4555afd9676bf4a Mon Sep 17 00:00:00 2001 From: zz-sol Date: Thu, 18 Jun 2026 07:33:08 -0400 Subject: [PATCH] [ed25519] fix pkcs8 (#52) * fix pkcs8 * Propagate PKCS#8 errors; add decoding test Replace unwraps with ? to propagate pkcs8::Error when parsing PKCS#8 key material (in TryFrom<&KeypairBytes> and from_pkcs8_der), use the parsed SigningKey directly for public-key verification, and return Ok(signing_key). Add a test to ensure malformed/non-PKCS#8 bytes are rejected without panicking, and import BitStringRef in tests to simplify references. --- curve25519/solana-ed25519/src/ed_sigs/signing_key.rs | 9 ++++----- .../solana-ed25519/src/ed_sigs/tests/decoding.rs | 12 ++++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/curve25519/solana-ed25519/src/ed_sigs/signing_key.rs b/curve25519/solana-ed25519/src/ed_sigs/signing_key.rs index dedea24..e2aaa71 100644 --- a/curve25519/solana-ed25519/src/ed_sigs/signing_key.rs +++ b/curve25519/solana-ed25519/src/ed_sigs/signing_key.rs @@ -218,7 +218,7 @@ impl TryFrom<&KeypairBytes> for SigningKey { type Error = pkcs8::Error; fn try_from(pkcs8_key: &KeypairBytes) -> pkcs8::Result { - let signing_key = SigningKey::from_der(&pkcs8_key.secret_key); + let signing_key = SigningKey::from_der(&pkcs8_key.secret_key)?; // Validate the public key in the PKCS#8 document if present if let Some(public_bytes) = &pkcs8_key.public_key { @@ -226,13 +226,12 @@ impl TryFrom<&KeypairBytes> for SigningKey { VerificationKey::from_public_key_der(public_bytes.as_ref()) .map_err(|_| pkcs8::Error::KeyMalformed)?; - if VerificationKey::from(&signing_key.unwrap()).A_bytes != expected_verifying_key.into() - { + if VerificationKey::from(&signing_key).A_bytes != expected_verifying_key.into() { return Err(pkcs8::Error::KeyMalformed); } } - signing_key + Ok(signing_key) } } @@ -279,7 +278,7 @@ impl DecodePrivateKey for SigningKey { /// fail if the public key doesn't match the private key's true accompanying public /// key. fn from_pkcs8_der(bytes: &[u8]) -> pkcs8::Result { - let keypair = KeypairBytes::from_pkcs8_der(bytes).unwrap(); + let keypair = KeypairBytes::from_pkcs8_der(bytes)?; let sk = SigningKey::from(keypair.secret_key); match keypair.public_key { Some(vk2) => { diff --git a/curve25519/solana-ed25519/src/ed_sigs/tests/decoding.rs b/curve25519/solana-ed25519/src/ed_sigs/tests/decoding.rs index cdeb41b..4d9ba6c 100644 --- a/curve25519/solana-ed25519/src/ed_sigs/tests/decoding.rs +++ b/curve25519/solana-ed25519/src/ed_sigs/tests/decoding.rs @@ -1,6 +1,8 @@ #[cfg(any(feature = "pem", feature = "pkcs8"))] use crate::ed_sigs::*; +#[cfg(feature = "pkcs8")] +use pkcs8::der::asn1::BitStringRef; #[cfg(feature = "pkcs8")] use pkcs8::{DecodePrivateKey, DecodePublicKey}; @@ -53,6 +55,12 @@ fn decode_der_to_signing_key() { assert!(SigningKey::from_pkcs8_der(PKCS8_V2_DER_BAD).is_err()); } +#[test] +#[cfg(feature = "pkcs8")] +fn reject_malformed_private_key_der_without_panicking() { + assert!(SigningKey::from_pkcs8_der(b"not a pkcs8 key").is_err()); +} + #[test] #[cfg(feature = "pem")] fn decode_doc_to_signing_key() { @@ -88,7 +96,7 @@ fn reject_public_key_der_with_wrong_algorithm_oid() { oid, parameters: None, }, - subject_public_key: pkcs8::der::asn1::BitStringRef::from_bytes(vk.as_ref()).unwrap(), + subject_public_key: BitStringRef::from_bytes(vk.as_ref()).unwrap(), }; let doc = pkcs8::Document::try_from(spki).unwrap(); @@ -107,7 +115,7 @@ fn reject_public_key_der_with_malformed_key_bytes() { oid, parameters: None, }, - subject_public_key: pkcs8::der::asn1::BitStringRef::from_bytes(&[0u8; 31]).unwrap(), + subject_public_key: BitStringRef::from_bytes(&[0u8; 31]).unwrap(), }; let doc = pkcs8::Document::try_from(spki).unwrap();