aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--oxish-aws-lc/Cargo.toml1
-rw-r--r--oxish-aws-lc/src/lib.rs15
-rw-r--r--oxish-graviola/src/lib.rs12
-rw-r--r--oxish-proto/src/crypto.rs13
5 files changed, 41 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2c3adb7..36773f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -549,6 +549,7 @@ version = "0.1.0"
dependencies = [
"aws-lc-rs",
"oxish-proto",
+ "zeroize",
]
[[package]]
diff --git a/oxish-aws-lc/Cargo.toml b/oxish-aws-lc/Cargo.toml
index c8628db..fa7c62b 100644
--- a/oxish-aws-lc/Cargo.toml
+++ b/oxish-aws-lc/Cargo.toml
@@ -17,6 +17,7 @@ fips = ["aws-lc-rs/fips"]
[dependencies]
aws-lc-rs = { workspace = true }
proto = { package = "oxish-proto", version = "0.1", path = "../oxish-proto" }
+zeroize = { workspace = true }
[lints]
workspace = true
diff --git a/oxish-aws-lc/src/lib.rs b/oxish-aws-lc/src/lib.rs
index f7e95cc..b203c56 100644
--- a/oxish-aws-lc/src/lib.rs
+++ b/oxish-aws-lc/src/lib.rs
@@ -4,6 +4,7 @@ use ::aws_lc_rs::{
aead::{AES_128_GCM, Aad, LessSafeKey, NONCE_LEN, Nonce, UnboundKey},
agreement::{self, EphemeralPrivateKey, X25519},
digest,
+ encoding::{AsBigEndian, Curve25519SeedBin, EcPrivateKeyBin},
kem::ML_KEM_768,
rand,
signature::{self, EcdsaKeyPair, Ed25519KeyPair, KeyPair, UnparsedPublicKey},
@@ -17,6 +18,7 @@ use proto::{
},
named::{EncryptionAlgorithm, KeyExchangeAlgorithm, MacAlgorithm, PublicKeyAlgorithm},
};
+use zeroize::Zeroizing;
pub const DEFAULT_PROVIDER: &'static dyn CryptoProvider = &Provider;
@@ -404,6 +406,13 @@ impl SigningKey for Ed25519SigningKey {
fn algorithm(&self) -> PublicKeyAlgorithm<'static> {
PublicKeyAlgorithm::Ed25519
}
+
+ fn private_key(&self) -> Result<Zeroizing<Vec<u8>>, CryptoError> {
+ let seed = self.key_pair.seed().map_err(|_| CryptoError::Unspecified)?;
+ let bytes = AsBigEndian::<Curve25519SeedBin<'_>>::as_be_bytes(&seed)
+ .map_err(|_| CryptoError::Unspecified)?;
+ Ok(Zeroizing::new(bytes.as_ref().to_vec()))
+ }
}
struct EcdsaP256SigningKey {
@@ -439,6 +448,12 @@ impl SigningKey for EcdsaP256SigningKey {
fn algorithm(&self) -> PublicKeyAlgorithm<'static> {
PublicKeyAlgorithm::EcdsaSha2Nistp256
}
+
+ fn private_key(&self) -> Result<Zeroizing<Vec<u8>>, CryptoError> {
+ let d = AsBigEndian::<EcPrivateKeyBin<'_>>::as_be_bytes(&self.key_pair.private_key())
+ .map_err(|_| CryptoError::Unspecified)?;
+ Ok(Zeroizing::new(d.as_ref().to_vec()))
+ }
}
struct EcdsaP256VerifyingKey {
diff --git a/oxish-graviola/src/lib.rs b/oxish-graviola/src/lib.rs
index 7cccdbf..ebe1fc9 100644
--- a/oxish-graviola/src/lib.rs
+++ b/oxish-graviola/src/lib.rs
@@ -385,6 +385,12 @@ impl SigningKey for Ed25519Key {
fn algorithm(&self) -> PublicKeyAlgorithm<'static> {
PublicKeyAlgorithm::Ed25519
}
+
+ fn private_key(&self) -> Result<Zeroizing<Vec<u8>>, CryptoError> {
+ // as_seed() returns an owned copy, so wrap it too
+ let seed = Zeroizing::new(self.key.as_seed());
+ Ok(Zeroizing::new(seed.to_vec()))
+ }
}
struct EcdsaP256Key {
@@ -418,6 +424,12 @@ impl SigningKey for EcdsaP256Key {
fn algorithm(&self) -> PublicKeyAlgorithm<'static> {
PublicKeyAlgorithm::EcdsaSha2Nistp256
}
+
+ fn private_key(&self) -> Result<Zeroizing<Vec<u8>>, CryptoError> {
+ // as_bytes() returns an owned copy, so wrap it too
+ let d = Zeroizing::new(self.key.private_key.as_bytes());
+ Ok(Zeroizing::new(d.to_vec()))
+ }
}
struct EcdsaP256VerifyingKey(ecdsa::VerifyingKey<P256>);
diff --git a/oxish-proto/src/crypto.rs b/oxish-proto/src/crypto.rs
index 9e9c247..f2d6d9d 100644
--- a/oxish-proto/src/crypto.rs
+++ b/oxish-proto/src/crypto.rs
@@ -1,7 +1,7 @@
use core::{error::Error as StdError, fmt};
use std::sync::Arc;
-use zeroize::Zeroize;
+use zeroize::{Zeroize, Zeroizing};
use crate::named::{EncryptionAlgorithm, KeyExchangeAlgorithm, MacAlgorithm, PublicKeyAlgorithm};
@@ -425,6 +425,17 @@ pub trait SigningKey: Send + Sync {
/// The public key algorithm of this key
fn algorithm(&self) -> PublicKeyAlgorithm<'static>;
+
+ /// The private key material, in the form the key is stored in
+ ///
+ /// For Ed25519 this is the 32-byte seed, not the derived signing
+ /// scalar. For ECDSA, it is the scalar `d` as a big-endian
+ /// fixed-length integer.
+ ///
+ /// Returns `Err` for keys held in hardware or by an agent.
+ fn private_key(&self) -> Result<Zeroizing<Vec<u8>>, CryptoError> {
+ Err(CryptoError::Unspecified)
+ }
}
/// A public key that can verify signatures