Make keys clone-able

Due to some lifetime shenanigans on the rustls side, we need to make
keys clone-able so that we can satisfies the 'static lifetime
requirement on key exchange types.

Change-Id: I0616432d88305ac079b25295cf3c0cf99c57adba
Signed-off-by: Xiangfei Ding <xfding@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/87109
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-crypto/src/ec.rs b/rust/bssl-crypto/src/ec.rs
index ee42713..d939bf75 100644
--- a/rust/bssl-crypto/src/ec.rs
+++ b/rust/bssl-crypto/src/ec.rs
@@ -520,6 +520,15 @@
     }
 }
 
+impl Clone for Key {
+    fn clone(&self) -> Self {
+        unsafe {
+            bssl_sys::EC_KEY_up_ref(self.0);
+        }
+        Self(self.0)
+    }
+}
+
 /// Serialize a finite point to X9.62 format.
 ///
 /// Callers must ensure that the arguments are valid, that the point has the
diff --git a/rust/bssl-crypto/src/ecdh.rs b/rust/bssl-crypto/src/ecdh.rs
index e3f1395..832b87a 100644
--- a/rust/bssl-crypto/src/ecdh.rs
+++ b/rust/bssl-crypto/src/ecdh.rs
@@ -69,6 +69,15 @@
     marker: PhantomData<C>,
 }
 
+impl<C: ec::Curve> Clone for PrivateKey<C> {
+    fn clone(&self) -> Self {
+        Self {
+            key: self.key.clone(),
+            marker: PhantomData,
+        }
+    }
+}
+
 impl<C: ec::Curve> PrivateKey<C> {
     /// Generate a random private key.
     pub fn generate() -> Self {
diff --git a/rust/bssl-crypto/src/ecdsa.rs b/rust/bssl-crypto/src/ecdsa.rs
index 6cdfb84..a07bf93 100644
--- a/rust/bssl-crypto/src/ecdsa.rs
+++ b/rust/bssl-crypto/src/ecdsa.rs
@@ -149,6 +149,15 @@
     marker: PhantomData<C>,
 }
 
+impl<C: ec::Curve> Clone for PrivateKey<C> {
+    fn clone(&self) -> Self {
+        Self {
+            key: self.key.clone(),
+            marker: PhantomData,
+        }
+    }
+}
+
 impl<C: ec::Curve> PrivateKey<C> {
     /// Generate a random private key.
     pub fn generate() -> Self {
diff --git a/rust/bssl-crypto/src/ed25519.rs b/rust/bssl-crypto/src/ed25519.rs
index 2056a74..cf76fef 100644
--- a/rust/bssl-crypto/src/ed25519.rs
+++ b/rust/bssl-crypto/src/ed25519.rs
@@ -54,6 +54,7 @@
 const KEYPAIR_LEN: usize = bssl_sys::ED25519_PRIVATE_KEY_LEN as usize;
 
 /// An Ed25519 private key.
+#[derive(Clone)]
 pub struct PrivateKey([u8; KEYPAIR_LEN]);
 
 /// An Ed25519 public key used to verify a signature + message.
diff --git a/rust/bssl-crypto/src/rsa.rs b/rust/bssl-crypto/src/rsa.rs
index f894059..614f942 100644
--- a/rust/bssl-crypto/src/rsa.rs
+++ b/rust/bssl-crypto/src/rsa.rs
@@ -60,6 +60,7 @@
     ForeignTypeRef, InvalidSignatureError,
 };
 use alloc::vec::Vec;
+use bssl_sys::RSA_up_ref;
 use core::ptr::null_mut;
 
 /// An RSA public key.
@@ -182,6 +183,16 @@
 /// An RSA private key.
 pub struct PrivateKey(*mut bssl_sys::RSA);
 
+impl Clone for PrivateKey {
+    fn clone(&self) -> Self {
+        // Safety:
+        // `self.0` is valid by construction and
+        // at this point we definitely own one reference to the object.
+        unsafe { RSA_up_ref(self.0) };
+        Self(self.0)
+    }
+}
+
 impl PrivateKey {
     /// Generate a fresh RSA private key of the given size.
     pub fn generate(size: KeySize) -> Self {