diff --git a/Cargo.lock b/Cargo.lock index f2f6cc8..c0c4d96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,7 @@ dependencies = [ "opaque-debug", "p256", "p384", + "pkcs8", "ring", "signature", ] diff --git a/Cargo.toml b/Cargo.toml index af093e2..ff53669 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,14 @@ generic-array = { version = "0.14", default-features = false } opaque-debug = "0.3" ring = { version = "0.16", default-features = false } -# optional features +# optional dependencies aead = { version = "0.5", optional = true, default-features = false } digest = { version = "0.10", optional = true } ecdsa = { version = "0.14", optional = true, default-features = false } ed25519 = { version = "1.4", optional = true, default-features = false } p256 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa-core"] } p384 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa-core"] } +pkcs8 = { version = "0.9", optional = true, default-features = false } signature = { version = "1", optional = true, default-features = false } [dev-dependencies] @@ -35,9 +36,9 @@ digest = { version = "0.10", features = ["dev"] } [features] default = ["aead", "alloc", "digest", "signature"] -alloc = ["aead?/alloc"] -signature = ["dep:ecdsa", "dep:ed25519", "dep:p256", "dep:p384", "dep:signature"] -std = ["digest?/std", "ecdsa?/std", "ed25519?/std"] +alloc = ["aead?/alloc", "pkcs8?/alloc"] +signature = ["dep:ecdsa", "dep:ed25519", "dep:p256", "dep:p384", "dep:pkcs8", "dep:signature"] +std = ["digest?/std", "ecdsa?/std", "ed25519?/std", "pkcs8?/std"] [package.metadata.docs.rs] all-features = true diff --git a/src/lib.rs b/src/lib.rs index 2c79fc0..30d74f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,4 +36,6 @@ pub mod digest; pub mod signature; pub use generic_array; -pub use ring; + +#[cfg(feature = "signature")] +pub use pkcs8; diff --git a/src/signature/ecdsa/signing_key.rs b/src/signature/ecdsa/signing_key.rs index e34a762..734f3da 100644 --- a/src/signature/ecdsa/signing_key.rs +++ b/src/signature/ecdsa/signing_key.rs @@ -8,6 +8,7 @@ use ::ecdsa::{ }; use core::marker::PhantomData; use generic_array::ArrayLength; +use pkcs8::{DecodePrivateKey, PrivateKeyInfo}; use ring::{ self, rand::SystemRandom, @@ -35,17 +36,6 @@ where C: PrimeCurve + CurveAlg, SignatureSize: ArrayLength, { - /// Initialize a [`SigningKey`] from a PKCS#8-encoded private key - pub fn from_pkcs8(pkcs8_key: &[u8]) -> Result { - EcdsaKeyPair::from_pkcs8(C::signing_alg(), pkcs8_key) - .map(|keypair| Self { - keypair, - csrng: SystemRandom::new(), - curve: PhantomData, - }) - .map_err(|_| Error::new()) - } - /// Initialize a [`SigningKey`] from a raw keypair pub fn from_keypair_bytes(signing_key: &[u8], verifying_key: &[u8]) -> Result { EcdsaKeyPair::from_private_key_and_public_key(C::signing_alg(), signing_key, verifying_key) @@ -66,6 +56,34 @@ where } } +impl DecodePrivateKey for SigningKey +where + C: PrimeCurve + CurveAlg, + SignatureSize: ArrayLength, +{ + fn from_pkcs8_der(pkcs8_bytes: &[u8]) -> Result { + EcdsaKeyPair::from_pkcs8(C::signing_alg(), pkcs8_bytes) + .map(|keypair| Self { + keypair, + csrng: SystemRandom::new(), + curve: PhantomData, + }) + .map_err(|_| pkcs8::Error::KeyMalformed) + } +} + +impl TryFrom> for SigningKey +where + C: PrimeCurve + CurveAlg, + SignatureSize: ArrayLength, +{ + type Error = pkcs8::Error; + + fn try_from(_: PrivateKeyInfo<'_>) -> Result { + todo!() + } +} + impl Signer> for SigningKey where C: PrimeCurve + CurveAlg, diff --git a/src/signature/ed25519.rs b/src/signature/ed25519.rs index 40de293..d81dca2 100644 --- a/src/signature/ed25519.rs +++ b/src/signature/ed25519.rs @@ -6,6 +6,7 @@ pub use ed25519::Signature; use super::{Error, Signer, Verifier}; use core::convert::TryInto; +use pkcs8::{DecodePrivateKey, PrivateKeyInfo}; use ring::{ self, signature::{Ed25519KeyPair, KeyPair, UnparsedPublicKey}, @@ -25,19 +26,28 @@ impl SigningKey { .map_err(|_| Error::new()) } - /// Create a new [`SigningKey`] from a PKCS#8 encoded key. - pub fn from_pkcs8(pkcs8_key: &[u8]) -> Result { - Ed25519KeyPair::from_pkcs8(pkcs8_key) - .map(SigningKey) - .map_err(|_| Error::new()) - } - /// Get the [`VerifyingKey`] for this [`SigningKey`]. pub fn verifying_key(&self) -> VerifyingKey { VerifyingKey(self.0.public_key().as_ref().try_into().unwrap()) } } +impl DecodePrivateKey for SigningKey { + fn from_pkcs8_der(pkcs8_bytes: &[u8]) -> Result { + Ed25519KeyPair::from_pkcs8(pkcs8_bytes) + .map(SigningKey) + .map_err(|_| pkcs8::Error::KeyMalformed) + } +} + +impl TryFrom> for SigningKey { + type Error = pkcs8::Error; + + fn try_from(_: PrivateKeyInfo<'_>) -> Result { + todo!() + } +} + impl Signer for SigningKey { fn try_sign(&self, msg: &[u8]) -> Result { Ok(Signature::from_bytes(self.0.sign(msg).as_ref()).unwrap())