Skip to content

Commit

Permalink
Impl pkcs8::DecodePrivateKey for ECDSA and Ed25519 signing keys (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarcieri committed Dec 11, 2022
1 parent 6cfe019 commit d04d3a9
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 23 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions Cargo.toml
Expand Up @@ -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]
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Expand Up @@ -36,4 +36,6 @@ pub mod digest;
pub mod signature;

pub use generic_array;
pub use ring;

#[cfg(feature = "signature")]
pub use pkcs8;
40 changes: 29 additions & 11 deletions src/signature/ecdsa/signing_key.rs
Expand Up @@ -8,6 +8,7 @@ use ::ecdsa::{
};
use core::marker::PhantomData;
use generic_array::ArrayLength;
use pkcs8::{DecodePrivateKey, PrivateKeyInfo};
use ring::{
self,
rand::SystemRandom,
Expand Down Expand Up @@ -35,17 +36,6 @@ where
C: PrimeCurve + CurveAlg,
SignatureSize<C>: ArrayLength<u8>,
{
/// Initialize a [`SigningKey`] from a PKCS#8-encoded private key
pub fn from_pkcs8(pkcs8_key: &[u8]) -> Result<Self, Error> {
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<Self, Error> {
EcdsaKeyPair::from_private_key_and_public_key(C::signing_alg(), signing_key, verifying_key)
Expand All @@ -66,6 +56,34 @@ where
}
}

impl<C> DecodePrivateKey for SigningKey<C>
where
C: PrimeCurve + CurveAlg,
SignatureSize<C>: ArrayLength<u8>,
{
fn from_pkcs8_der(pkcs8_bytes: &[u8]) -> Result<Self, pkcs8::Error> {
EcdsaKeyPair::from_pkcs8(C::signing_alg(), pkcs8_bytes)
.map(|keypair| Self {
keypair,
csrng: SystemRandom::new(),
curve: PhantomData,
})
.map_err(|_| pkcs8::Error::KeyMalformed)
}
}

impl<C> TryFrom<PrivateKeyInfo<'_>> for SigningKey<C>
where
C: PrimeCurve + CurveAlg,
SignatureSize<C>: ArrayLength<u8>,
{
type Error = pkcs8::Error;

fn try_from(_: PrivateKeyInfo<'_>) -> Result<Self, pkcs8::Error> {
todo!()
}
}

impl<C> Signer<Signature<C>> for SigningKey<C>
where
C: PrimeCurve + CurveAlg,
Expand Down
24 changes: 17 additions & 7 deletions src/signature/ed25519.rs
Expand Up @@ -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},
Expand All @@ -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<Self, Error> {
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<Self, pkcs8::Error> {
Ed25519KeyPair::from_pkcs8(pkcs8_bytes)
.map(SigningKey)
.map_err(|_| pkcs8::Error::KeyMalformed)
}
}

impl TryFrom<PrivateKeyInfo<'_>> for SigningKey {
type Error = pkcs8::Error;

fn try_from(_: PrivateKeyInfo<'_>) -> Result<Self, pkcs8::Error> {
todo!()
}
}

impl Signer<Signature> for SigningKey {
fn try_sign(&self, msg: &[u8]) -> Result<Signature, Error> {
Ok(Signature::from_bytes(self.0.sign(msg).as_ref()).unwrap())
Expand Down

0 comments on commit d04d3a9

Please sign in to comment.