[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.
This commit is contained in:
zz-sol 2026-06-18 07:33:08 -04:00 committed by GitHub
parent ff4e6654d1
commit f08b2c94fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 7 deletions

View file

@ -218,7 +218,7 @@ impl TryFrom<&KeypairBytes> for SigningKey {
type Error = pkcs8::Error;
fn try_from(pkcs8_key: &KeypairBytes) -> pkcs8::Result<Self> {
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<Self> {
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) => {

View file

@ -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();