From 6ea81fb3f6d62c1f16230700a269582a58357c08 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 27 Jun 2022 16:48:14 +0200 Subject: [PATCH] Keypair: implement clone() This was not implemented upstream in ed25519-dalek to force everyone to think twice before creating another copy of a potentially sensitive private key in memory. See https://github.com/dalek-cryptography/ed25519-dalek/issues/76 However, there are now 9 instances of Keypair::from_bytes(&keypair.to_bytes()) in the solana codebase and it would be preferable to have a function. In particular since this also comes up when writing programs and can cause users to either start messing with lifetimes or discover the from_bytes() workaround themselves. This patch opts to not implement the Clone trait. This avoids automatic use in order to preserve some of the original "let developers think twice about this" intention. --- sdk/src/signer/keypair.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sdk/src/signer/keypair.rs b/sdk/src/signer/keypair.rs index 4ee5c51b07232a..2bf4548552b417 100644 --- a/sdk/src/signer/keypair.rs +++ b/sdk/src/signer/keypair.rs @@ -97,6 +97,26 @@ where } } +/// Allows Keypair cloning +/// +/// Note that the `Clone` trait is intentionally unimplemented because making a +/// second copy of sensitive secret keys in memory is usually a bad idea. +/// +/// Only use this in tests or when strictly required. +pub trait KeypairInsecureClone { + fn clone(&self) -> Self; +} + +impl KeypairInsecureClone for Keypair { + fn clone(&self) -> Self { + Self(ed25519_dalek::Keypair { + // This will never error since self is a valid keypair + secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes()).unwrap(), + public: self.0.public, + }) + } +} + /// Reads a JSON-encoded `Keypair` from a `Reader` implementor pub fn read_keypair(reader: &mut R) -> Result> { let bytes: Vec = serde_json::from_reader(reader)?;