diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index 9f1ecc7..b27e02a 100644 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -14,11 +14,11 @@ use rand::{CryptoRng, RngCore}; use zeroize::Zeroize; pub trait KeyExchange { - type KE1State: FromBytes + ToBytesWithPointers + Zeroize; - type KE2State: FromBytes + ToBytesWithPointers + Zeroize; - type KE1Message: FromBytes + ToBytes; - type KE2Message: FromBytes + ToBytes; - type KE3Message: FromBytes + ToBytes; + type KE1State: FromBytes + ToBytesWithPointers + Zeroize + Clone; + type KE2State: FromBytes + ToBytesWithPointers + Zeroize + Clone; + type KE1Message: FromBytes + ToBytes + Clone; + type KE2Message: FromBytes + ToBytes + Clone; + type KE3Message: FromBytes + ToBytes + Clone; fn generate_ke1( info: Vec, diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index d69ff3b..259e3b1 100644 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -237,7 +237,7 @@ impl KeyExchange for TripleDH { } /// The client state produced after the first key exchange message -#[derive(PartialEq, Eq, Zeroize)] +#[derive(PartialEq, Eq, Zeroize, Clone)] #[zeroize(drop)] pub struct Ke1State { client_e_sk: Key, @@ -245,7 +245,7 @@ pub struct Ke1State { } /// The first key exchange message -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone)] pub struct Ke1Message { pub(crate) client_nonce: GenericArray, pub(crate) info: Vec, @@ -317,6 +317,7 @@ impl FromBytes for Ke1Message { } } /// The server state produced after the second key exchange message +#[derive(Clone)] pub struct Ke2State> { km3: GenericArray, hashed_transcript: GenericArray, @@ -359,6 +360,7 @@ impl> ToBytesWithPointers for Ke2State { } /// The second key exchange message +#[derive(Clone)] pub struct Ke2Message> { server_nonce: GenericArray, server_e_pk: Key, @@ -446,6 +448,7 @@ type TripleDHDerivationResult = ( ); /// The third key exchange message +#[derive(Clone)] pub struct Ke3Message> { mac: GenericArray, } diff --git a/src/messages.rs b/src/messages.rs index 20f27f1..428aa42 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -28,6 +28,13 @@ pub struct RegistrationRequest { pub(crate) alpha: CS::Group, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for RegistrationRequest { + fn clone(&self) -> Self { + Self { alpha: self.alpha } + } +} + impl RegistrationRequest { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -57,6 +64,16 @@ pub struct RegistrationResponse { pub(crate) server_s_pk: Vec, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for RegistrationResponse { + fn clone(&self) -> Self { + Self { + beta: self.beta, + server_s_pk: self.server_s_pk.clone(), + } + } +} + impl RegistrationResponse { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -94,6 +111,16 @@ pub struct RegistrationUpload { pub(crate) client_s_pk: Key, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for RegistrationUpload { + fn clone(&self) -> Self { + Self { + envelope: self.envelope.clone(), + client_s_pk: self.client_s_pk.clone(), + } + } +} + impl RegistrationUpload { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -134,6 +161,16 @@ pub struct CredentialRequest { pub(crate) ke1_message: >::KE1Message, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for CredentialRequest { + fn clone(&self) -> Self { + Self { + alpha: self.alpha, + ke1_message: self.ke1_message.clone(), + } + } +} + impl CredentialRequest { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -173,6 +210,18 @@ pub struct CredentialResponse { pub(crate) ke2_message: >::KE2Message, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for CredentialResponse { + fn clone(&self) -> Self { + Self { + beta: self.beta, + server_s_pk: self.server_s_pk.clone(), + envelope: self.envelope.clone(), + ke2_message: self.ke2_message.clone(), + } + } +} + impl CredentialResponse { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -240,6 +289,15 @@ pub struct CredentialFinalization { pub(crate) ke3_message: >::KE3Message, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for CredentialFinalization { + fn clone(&self) -> Self { + Self { + ke3_message: self.ke3_message.clone(), + } + } +} + impl CredentialFinalization { /// Serialization into bytes pub fn serialize(&self) -> Vec { diff --git a/src/opaque.rs b/src/opaque.rs index 058fc41..822ba57 100644 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -36,6 +36,15 @@ pub struct ClientRegistration { pub(crate) token: oprf::Token, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientRegistration { + fn clone(&self) -> Self { + Self { + token: self.token.clone(), + } + } +} + impl ClientRegistration { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -86,6 +95,7 @@ impl ClientRegistration { impl_serialize_and_deserialize_for!(ClientRegistration); /// Optional parameters for client registration finish +#[derive(Clone)] pub enum ClientRegistrationFinishParameters { /// Specifying the identifiers idU and idS (corresponding to custom identifier mode) WithIdentifiers(Vec, Vec), @@ -107,6 +117,16 @@ pub struct ClientRegistrationStartResult { pub state: ClientRegistration, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientRegistrationStartResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + state: self.state.clone(), + } + } +} + impl ClientRegistration { /// Returns an initial "blinded" request to send to the server, as well as a ClientRegistration /// @@ -155,6 +175,18 @@ pub struct ClientRegistrationFinishResult { pub state: ClientRegistration, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientRegistrationFinishResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + export_key: self.export_key.clone(), + #[cfg(test)] + state: self.state.clone(), + } + } +} + impl ClientRegistration { /// "Unblinds" the server's answer and returns a final message containing /// cryptographic identifiers, to be sent to the server on setup finalization @@ -230,6 +262,16 @@ pub struct ServerRegistrationStartResult { pub state: ServerRegistration, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ServerRegistrationStartResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + state: self.state.clone(), + } + } +} + /// The state elements the server holds to record a registration pub struct ServerRegistration { envelope: Option>, @@ -237,6 +279,17 @@ pub struct ServerRegistration { pub(crate) oprf_key: ::Scalar, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ServerRegistration { + fn clone(&self) -> Self { + Self { + envelope: self.envelope.clone(), + client_s_pk: self.client_s_pk.clone(), + oprf_key: self.oprf_key.clone(), + } + } +} + impl ServerRegistration { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -400,6 +453,17 @@ pub struct ClientLogin { serialized_credential_request: Vec, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientLogin { + fn clone(&self) -> Self { + Self { + token: self.token.clone(), + ke1_state: self.ke1_state.clone(), + serialized_credential_request: self.serialized_credential_request.clone(), + } + } +} + impl ClientLogin { /// Serialization into bytes pub fn serialize(&self) -> Vec { @@ -462,6 +526,7 @@ impl ClientLogin { impl_serialize_and_deserialize_for!(ClientLogin); /// Optional parameters for client login start +#[derive(Clone)] pub enum ClientLoginStartParameters { /// Specifying a plaintext info field that will be sent to the server WithInfo(Vec), @@ -481,7 +546,18 @@ pub struct ClientLoginStartResult { pub state: ClientLogin, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientLoginStartResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + state: self.state.clone(), + } + } +} + /// Optional parameters for client login finish +#[derive(Clone)] pub enum ClientLoginFinishParameters { /// Specifying a user identifier and server identifier that will be matched against the client WithIdentifiers(Vec, Vec), @@ -512,6 +588,21 @@ pub struct ClientLoginFinishResult { pub state: ClientLogin, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ClientLoginFinishResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + session_key: self.session_key.clone(), + export_key: self.export_key.clone(), + server_s_pk: self.server_s_pk.clone(), + confidential_info: self.confidential_info.clone(), + #[cfg(test)] + state: self.state.clone(), + } + } +} + impl ClientLogin { /// Returns an initial "blinded" password request to send to the server, as well as a ClientLogin /// @@ -660,7 +751,18 @@ pub struct ServerLogin { _cs: PhantomData, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ServerLogin { + fn clone(&self) -> Self { + Self { + ke2_state: self.ke2_state.clone(), + _cs: PhantomData, + } + } +} + /// Optional parameters for server login start +#[derive(Clone)] pub enum ServerLoginStartParameters { /// Specifying a confidential info field that will be sent to the client WithInfo(Vec), @@ -688,6 +790,17 @@ pub struct ServerLoginStartResult { pub plain_info: Vec, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ServerLoginStartResult { + fn clone(&self) -> Self { + Self { + message: self.message.clone(), + state: self.state.clone(), + plain_info: self.plain_info.clone(), + } + } +} + /// Contains the fields that are returned by a server login finish pub struct ServerLoginFinishResult { /// The session key between client and server @@ -698,6 +811,18 @@ pub struct ServerLoginFinishResult { pub state: ServerLogin, } +// Cannot be derived because it would require for CS to be Clone. +impl Clone for ServerLoginFinishResult { + fn clone(&self) -> Self { + Self { + session_key: self.session_key.clone(), + _cs: PhantomData, + #[cfg(test)] + state: self.state.clone(), + } + } +} + impl ServerLogin { /// Serialization into bytes pub fn serialize(&self) -> Vec { diff --git a/src/oprf.rs b/src/oprf.rs index ad1e883..e9f7347 100644 --- a/src/oprf.rs +++ b/src/oprf.rs @@ -12,6 +12,7 @@ use generic_array::GenericArray; use rand::{CryptoRng, RngCore}; /// Used to store the OPRF input and blinding factor +#[derive(Clone)] pub struct Token { pub(crate) data: Vec, pub(crate) blind: Grp::Scalar,