From 210e0e99dfbe096fa9161c00aeb2cfae93ee76a2 Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Tue, 15 Jun 2021 10:48:29 +0200 Subject: [PATCH] Enforce public vs private keys via types --- src/envelope.rs | 6 +- src/key_exchange/traits.rs | 10 +-- src/key_exchange/tripledh.rs | 36 +++++------ src/keypair.rs | 101 +++++++++++++++++++++++++------ src/messages.rs | 29 ++++----- src/opaque.rs | 18 +++--- src/tests/full_test.rs | 6 +- src/tests/opaque_test_vectors.rs | 10 +-- 8 files changed, 139 insertions(+), 77 deletions(-) diff --git a/src/envelope.rs b/src/envelope.rs index fcce8aa..bfed3d9 100644 --- a/src/envelope.rs +++ b/src/envelope.rs @@ -6,7 +6,7 @@ use crate::{ errors::{utils::check_slice_size_atleast, InternalPakeError, PakeError, ProtocolError}, hash::Hash, - keypair::Key, + keypair::PublicKey, serialization::serialize, }; use digest::Digest; @@ -64,7 +64,7 @@ impl InnerEnvelope { } let mode = InnerEnvelopeMode::try_from(input[0])?; - let key_len = ::Len::to_usize(); + let key_len = ::Len::to_usize(); let bytes = &input[1..]; if bytes.len() < NONCE_LEN + key_len { @@ -248,7 +248,7 @@ impl Envelope { let aad = construct_aad(server_s_pk, optional_ids); let opened = self.open_raw(key, &aad)?; - if opened.plaintext.len() != ::Len::to_usize() { + if opened.plaintext.len() != ::Len::to_usize() { // Plaintext should consist of a single key return Err(InternalPakeError::UnexpectedEnvelopeContentsError); } diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index b27e02a..bb68fc3 100644 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -8,7 +8,7 @@ use crate::{ errors::{PakeError, ProtocolError}, group::Group, hash::Hash, - keypair::Key, + keypair::{PrivateKey, PublicKey}, }; use rand::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -31,8 +31,8 @@ pub trait KeyExchange { l1_bytes: Vec, l2_bytes: Vec, ke1_message: Self::KE1Message, - client_s_pk: Key, - server_s_sk: Key, + client_s_pk: PublicKey, + server_s_sk: PrivateKey, id_u: Vec, id_s: Vec, e_info: Vec, @@ -44,8 +44,8 @@ pub trait KeyExchange { ke2_message: Self::KE2Message, ke1_state: &Self::KE1State, serialized_credential_request: &[u8], - server_s_pk: Key, - client_s_sk: Key, + server_s_pk: PublicKey, + client_s_sk: PrivateKey, id_u: Vec, id_s: Vec, ) -> Result<(Vec, Vec, Self::KE3Message), ProtocolError>; diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index 259e3b1..0ddd1a8 100644 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -13,7 +13,7 @@ use crate::{ group::Group, hash::Hash, key_exchange::traits::{FromBytes, KeyExchange, ToBytes, ToBytesWithPointers}, - keypair::{Key, KeyPair, SizedBytesExt}, + keypair::{KeyPair, PrivateKey, PublicKey, SizedBytesExt}, serialization::{serialize, tokenize}, }; use digest::{Digest, FixedOutput}; @@ -78,8 +78,8 @@ impl KeyExchange for TripleDH { serialized_credential_request: Vec, l2_bytes: Vec, ke1_message: Self::KE1Message, - client_s_pk: Key, - server_s_sk: Key, + client_s_pk: PublicKey, + server_s_sk: PrivateKey, id_u: Vec, id_s: Vec, e_info: Vec, @@ -150,8 +150,8 @@ impl KeyExchange for TripleDH { ke2_message: Self::KE2Message, ke1_state: &Self::KE1State, serialized_credential_request: &[u8], - server_s_pk: Key, - client_s_sk: Key, + server_s_pk: PublicKey, + client_s_sk: PrivateKey, id_u: Vec, id_s: Vec, ) -> Result<(Vec, Vec, Self::KE3Message), ProtocolError> { @@ -240,7 +240,7 @@ impl KeyExchange for TripleDH { #[derive(PartialEq, Eq, Zeroize, Clone)] #[zeroize(drop)] pub struct Ke1State { - client_e_sk: Key, + client_e_sk: PrivateKey, client_nonce: GenericArray, } @@ -249,7 +249,7 @@ pub struct Ke1State { pub struct Ke1Message { pub(crate) client_nonce: GenericArray, pub(crate) info: Vec, - pub(crate) client_e_pk: Key, + pub(crate) client_e_pk: PublicKey, } impl FromBytes for Ke1State { @@ -258,7 +258,7 @@ impl FromBytes for Ke1State { let checked_bytes = check_slice_size_atleast(bytes, KEY_LEN + nonce_len, "ke1_state")?; Ok(Self { - client_e_sk: Key::from_bytes(&checked_bytes[..KEY_LEN])?, + client_e_sk: PrivateKey::from_bytes(&checked_bytes[..KEY_LEN])?, client_nonce: GenericArray::clone_from_slice( &checked_bytes[KEY_LEN..KEY_LEN + nonce_len], ), @@ -277,7 +277,7 @@ impl ToBytesWithPointers for Ke1State { vec![ ( self.client_e_sk.as_ptr(), - ::Len::to_usize(), + ::Len::to_usize(), ), (self.client_nonce.as_ptr(), NonceLen::to_usize()), ] @@ -307,7 +307,7 @@ impl FromBytes for Ke1Message { let unchecked_client_e_pk = check_slice_size(&remainder, KEY_LEN, "ke1_message client_e_pk")?; let client_e_pk = - KeyPair::::check_public_key(Key::from_bytes(unchecked_client_e_pk)?)?; + KeyPair::::check_public_key(PublicKey::from_bytes(unchecked_client_e_pk)?)?; Ok(Self { client_nonce: GenericArray::clone_from_slice(&checked_nonce[..nonce_len]), @@ -363,7 +363,7 @@ impl> ToBytesWithPointers for Ke2State { #[derive(Clone)] pub struct Ke2Message> { server_nonce: GenericArray, - server_e_pk: Key, + server_e_pk: PublicKey, e_info: Vec, mac: GenericArray, } @@ -414,7 +414,7 @@ impl> FromBytes for Ke2Message { let checked_mac = check_slice_size(&remainder, HashLen::to_usize(), "ke1_message mac")?; // Check the public key bytes - let server_e_pk = KeyPair::::check_public_key(Key::from_bytes( + let server_e_pk = KeyPair::::check_public_key(PublicKey::from_bytes( &unchecked_server_e_pk[..KEY_LEN], )?)?; @@ -430,12 +430,12 @@ impl> FromBytes for Ke2Message { #[allow(clippy::upper_case_acronyms)] // The triple of public and private components used in the 3DH computation struct TripleDHComponents { - pk1: Key, - sk1: Key, - pk2: Key, - sk2: Key, - pk3: Key, - sk3: Key, + pk1: PublicKey, + sk1: PrivateKey, + pk2: PublicKey, + sk2: PrivateKey, + pk3: PublicKey, + sk3: PrivateKey, } #[allow(clippy::upper_case_acronyms)] diff --git a/src/keypair.rs b/src/keypair.rs index 5940551..d22a983 100644 --- a/src/keypair.rs +++ b/src/keypair.rs @@ -37,8 +37,8 @@ impl SizedBytesExt for T where T: SizedBytes {} /// A Keypair trait with public-private verification #[derive(Clone, Debug, PartialEq, Eq)] pub struct KeyPair { - pk: Key, - sk: Key, + pk: PublicKey, + sk: PrivateKey, _g: PhantomData, } @@ -58,18 +58,18 @@ impl Drop for KeyPair { impl KeyPair { /// The public key component - pub fn public(&self) -> &Key { + pub fn public(&self) -> &PublicKey { &self.pk } /// The private key component - pub fn private(&self) -> &Key { + pub fn private(&self) -> &PrivateKey { &self.sk } /// A constructor that receives public and private key independently as /// bytes - pub fn new(public: Key, private: Key) -> Result { + pub fn new(public: PublicKey, private: PrivateKey) -> Result { Ok(Self { pk: public, sk: private, @@ -83,29 +83,35 @@ impl KeyPair { let sk_bytes = G::scalar_as_bytes(&sk); let pk = G::base_point().mult_by_slice(sk_bytes); Self { - pk: Key(pk.to_arr().to_vec()), - sk: Key(sk_bytes.to_vec()), + pk: PublicKey(Key(pk.to_arr().to_vec())), + sk: PrivateKey(Key(sk_bytes.to_vec())), _g: PhantomData, } } /// Obtaining a public key from secret bytes. At all times, we should have /// &public_from_private(self.private()) == self.public() - pub(crate) fn public_from_private(bytes: &Key) -> Key { + pub(crate) fn public_from_private(bytes: &PrivateKey) -> PublicKey { let bytes_data = GenericArray::::from_slice(&bytes.0[..]); - Key(G::base_point().mult_by_slice(bytes_data).to_arr().to_vec()) + PublicKey(Key(G::base_point() + .mult_by_slice(bytes_data) + .to_arr() + .to_vec())) } /// Check whether a public key is valid. This is meant to be applied on /// material provided through the network which fits the key /// representation (i.e. can be mapped to a curve point), but presents /// some risk - e.g. small subgroup check - pub(crate) fn check_public_key(key: Key) -> Result { + pub(crate) fn check_public_key(key: PublicKey) -> Result { G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key) } /// Computes the diffie hellman function on a public key and private key - pub(crate) fn diffie_hellman(pk: Key, sk: Key) -> Result, InternalPakeError> { + pub(crate) fn diffie_hellman( + pk: PublicKey, + sk: PrivateKey, + ) -> Result, InternalPakeError> { let pk_data = GenericArray::::from_slice(&pk.0[..]); let point = G::from_element_slice(pk_data)?; let secret_data = GenericArray::::from_slice(&sk.0[..]); @@ -114,7 +120,7 @@ impl KeyPair { /// Obtains a KeyPair from a slice representing the private key pub fn from_private_key_slice(input: &[u8]) -> Result { - let sk = Key::from_arr(GenericArray::from_slice(input))?; + let sk = PrivateKey(Key::from_arr(GenericArray::from_slice(input))?); let pk = Self::public_from_private(&sk); Self::new(pk, sk) } @@ -122,8 +128,8 @@ impl KeyPair { #[cfg(test)] pub fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> { vec![ - (self.pk.as_ptr(), ::Len::to_usize()), - (self.sk.as_ptr(), ::Len::to_usize()), + (self.pk.as_ptr(), KeyLen::to_usize()), + (self.sk.as_ptr(), KeyLen::to_usize()), ] } } @@ -145,6 +151,8 @@ impl KeyPair { } } +type KeyLen = U32; + /// A minimalist key type built around a \[u8; 32\] #[derive(Debug, PartialEq, Eq, Clone, Zeroize)] // Ensure Key material is zeroed after use. @@ -160,18 +168,71 @@ impl Deref for Key { } } -impl SizedBytes for Key { - type Len = U32; - - fn to_arr(&self) -> GenericArray { +// Don't make it implement SizedBytes so that it's not constructible outside of this module. +impl Key { + fn to_arr(&self) -> GenericArray { GenericArray::clone_from_slice(&self.0[..]) } - fn from_arr(key_bytes: &GenericArray) -> Result { + fn from_arr(key_bytes: &GenericArray) -> Result { Ok(Key(key_bytes.to_vec())) } } +/// Wrapper around a Key to enforce that it's a private one. +#[derive(Debug, PartialEq, Eq, Clone, Zeroize)] +// Ensure Key material is zeroed after use. +#[zeroize(drop)] +#[repr(transparent)] +pub struct PrivateKey(Key); + +impl Deref for PrivateKey { + type Target = Key; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl SizedBytes for PrivateKey { + type Len = KeyLen; + + fn to_arr(&self) -> GenericArray { + self.0.to_arr() + } + + fn from_arr(key_bytes: &GenericArray) -> Result { + Ok(PrivateKey(Key::from_arr(key_bytes)?)) + } +} + +/// Wrapper around a Key to enforce that it's a public one. +#[derive(Debug, PartialEq, Eq, Clone, Zeroize)] +// Ensure Key material is zeroed after use. +#[zeroize(drop)] +#[repr(transparent)] +pub struct PublicKey(Key); + +impl Deref for PublicKey { + type Target = Key; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl SizedBytes for PublicKey { + type Len = KeyLen; + + fn to_arr(&self) -> GenericArray { + self.0.to_arr() + } + + fn from_arr(key_bytes: &GenericArray) -> Result { + Ok(PublicKey(Key::from_arr(key_bytes)?)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -183,7 +244,7 @@ mod tests { #[test] fn test_zeroize_key() -> Result<(), ProtocolError> { - let key_len = ::Len::to_usize(); + let key_len = KeyLen::to_usize(); let mut key = Key(vec![1u8; key_len]); let ptr = key.as_ptr(); diff --git a/src/messages.rs b/src/messages.rs index 428aa42..dbdfcae 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -14,7 +14,7 @@ use crate::{ }, group::Group, key_exchange::traits::{FromBytes, KeyExchange, ToBytes}, - keypair::{Key, KeyPair, SizedBytesExt}, + keypair::{KeyPair, PublicKey, SizedBytesExt}, }; use generic_array::{typenum::Unsigned, GenericArray}; use generic_bytes::SizedBytes; @@ -61,7 +61,7 @@ pub struct RegistrationResponse { /// The server's oprf output pub(crate) beta: CS::Group, /// Server's static public key - pub(crate) server_s_pk: Vec, + pub(crate) server_s_pk: PublicKey, } // Cannot be derived because it would require for CS to be Clone. @@ -77,13 +77,13 @@ impl Clone for RegistrationResponse { impl RegistrationResponse { /// Serialization into bytes pub fn serialize(&self) -> Vec { - [self.beta.to_arr().to_vec(), self.server_s_pk.clone()].concat() + [self.beta.to_arr().to_vec(), self.server_s_pk.to_vec()].concat() } /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { let elem_len = ::ElemLen::to_usize(); - let key_len = ::Len::to_usize(); + let key_len = ::Len::to_usize(); let checked_slice = check_slice_size(input, elem_len + key_len, "registration_response_bytes")?; @@ -91,9 +91,9 @@ impl RegistrationResponse { // correct subgroup let arr = GenericArray::from_slice(&checked_slice[..elem_len]); let beta = CS::Group::from_element_slice(arr)?; - let server_s_pk = - KeyPair::::check_public_key(Key::from_bytes(&checked_slice[elem_len..])?)? - .to_vec(); + let server_s_pk = KeyPair::::check_public_key(PublicKey::from_bytes( + &checked_slice[elem_len..], + )?)?; Ok(Self { server_s_pk, beta }) } @@ -108,7 +108,7 @@ pub struct RegistrationUpload { /// cryptographic identifiers pub(crate) envelope: Envelope, /// The user's public key - pub(crate) client_s_pk: Key, + pub(crate) client_s_pk: PublicKey, } // Cannot be derived because it would require for CS to be Clone. @@ -133,7 +133,7 @@ impl RegistrationUpload { /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let key_len = ::Len::to_usize(); + let key_len = ::Len::to_usize(); let checked_slice = check_slice_size_atleast(input, key_len, "registration_upload_bytes")?; @@ -145,7 +145,7 @@ impl RegistrationUpload { Ok(Self { envelope, - client_s_pk: KeyPair::::check_public_key(Key::from_bytes( + client_s_pk: KeyPair::::check_public_key(PublicKey::from_bytes( &checked_slice[..key_len], )?)?, }) @@ -204,7 +204,7 @@ impl_serialize_and_deserialize_for!(CredentialRequest); pub struct CredentialResponse { /// the server's oprf output pub(crate) beta: CS::Group, - pub(crate) server_s_pk: Key, + pub(crate) server_s_pk: PublicKey, /// the user's sealed information, pub(crate) envelope: Envelope, pub(crate) ke2_message: >::KE2Message, @@ -234,7 +234,7 @@ impl CredentialResponse { pub(crate) fn serialize_without_ke( beta: &CS::Group, - server_s_pk: &Key, + server_s_pk: &PublicKey, envelope: &Envelope, ) -> Vec { [ @@ -248,7 +248,7 @@ impl CredentialResponse { /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { let elem_len = ::ElemLen::to_usize(); - let key_len = ::Len::to_usize(); + let key_len = ::Len::to_usize(); let checked_slice = check_slice_size_atleast(input, elem_len + key_len, "login_second_message_bytes")?; @@ -258,7 +258,8 @@ impl CredentialResponse { let arr = GenericArray::from_slice(beta_bytes); let beta = CS::Group::from_element_slice(arr)?; - let unchecked_server_s_pk = Key::from_bytes(&checked_slice[elem_len..elem_len + key_len])?; + let unchecked_server_s_pk = + PublicKey::from_bytes(&checked_slice[elem_len..elem_len + key_len])?; let server_s_pk = KeyPair::::check_public_key(unchecked_server_s_pk)?; let (envelope, remainder) = diff --git a/src/opaque.rs b/src/opaque.rs index 822ba57..35caaa0 100644 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -12,7 +12,7 @@ use crate::{ group::Group, hash::Hash, key_exchange::traits::{FromBytes, KeyExchange, ToBytesWithPointers}, - keypair::{Key, KeyPair, SizedBytesExt}, + keypair::{KeyPair, PrivateKey, PublicKey, SizedBytesExt}, map_to_curve::GroupWithMapToCurve, oprf, serialization::{serialize, tokenize}, @@ -275,7 +275,7 @@ impl Clone for ServerRegistrationStartResult { /// The state elements the server holds to record a registration pub struct ServerRegistration { envelope: Option>, - client_s_pk: Option, + client_s_pk: Option, pub(crate) oprf_key: ::Scalar, } @@ -315,7 +315,7 @@ impl ServerRegistration { } // Need to do this check manually because envelope is variable-size - let key_len = ::Len::to_usize(); + let key_len = ::Len::to_usize(); let checked_bytes = check_slice_size_atleast(input, scalar_len + key_len, "server_registration_bytes")?; @@ -323,7 +323,7 @@ impl ServerRegistration { let oprf_key_bytes = GenericArray::from_slice(&checked_bytes[..scalar_len]); let oprf_key = CS::Group::from_scalar_slice(oprf_key_bytes)?; let unchecked_client_s_pk = - Key::from_bytes(&checked_bytes[scalar_len..scalar_len + key_len])?; + PublicKey::from_bytes(&checked_bytes[scalar_len..scalar_len + key_len])?; let client_s_pk = KeyPair::::check_public_key(unchecked_client_s_pk)?; let envelope = Envelope::::from_bytes(&checked_bytes[scalar_len + key_len..])?; @@ -380,7 +380,7 @@ impl ServerRegistration { pub fn start( rng: &mut R, message: RegistrationRequest, - server_s_pk: &Key, + server_s_pk: &PublicKey, ) -> Result, ProtocolError> { // RFC: generate oprf_key (salt) and v_u = g^oprf_key let oprf_key = CS::Group::random_scalar(rng); @@ -391,7 +391,7 @@ impl ServerRegistration { Ok(ServerRegistrationStartResult { message: RegistrationResponse { beta, - server_s_pk: server_s_pk.to_arr().to_vec(), + server_s_pk: server_s_pk.clone(), }, state: Self { envelope: None, @@ -580,7 +580,7 @@ pub struct ClientLoginFinishResult { /// The client-side export key pub export_key: GenericArray::OutputSize>, /// The server's static public key - pub server_s_pk: Key, + pub server_s_pk: PublicKey, /// The confidential info sent by the client pub confidential_info: Vec, /// Instance of the ClientLogin, only used in tests for checking zeroize @@ -707,7 +707,7 @@ impl ClientLogin { err => PakeError::from(err), })?; - let client_s_sk = Key::from_bytes(&opened_envelope.client_s_sk)?; + let client_s_sk = PrivateKey::from_bytes(&opened_envelope.client_s_sk)?; let (id_u, id_s) = match optional_ids { None => ( @@ -875,7 +875,7 @@ impl ServerLogin { pub fn start( rng: &mut R, password_file: ServerRegistration, - server_s_sk: &Key, + server_s_sk: &PrivateKey, l1: CredentialRequest, params: ServerLoginStartParameters, ) -> Result, ProtocolError> { diff --git a/src/tests/full_test.rs b/src/tests/full_test.rs index d8b1c3b..08862e2 100644 --- a/src/tests/full_test.rs +++ b/src/tests/full_test.rs @@ -10,7 +10,7 @@ use crate::{ errors::*, group::Group, key_exchange::tripledh::{NonceLen, TripleDH}, - keypair::{Key, SizedBytesExt}, + keypair::{PrivateKey, PublicKey, SizedBytesExt}, opaque::*, slow_hash::NoOpHash, tests::mock_rng::CycleRng, @@ -494,7 +494,7 @@ fn test_registration_response() -> Result<(), ProtocolError> { ServerRegistration::::start( &mut oprf_key_rng, RegistrationRequest::deserialize(¶meters.registration_request[..])?, - &Key::from_bytes(¶meters.server_s_pk[..])?, + &PublicKey::from_bytes(¶meters.server_s_pk[..])?, )?; assert_eq!( hex::encode(parameters.registration_response), @@ -589,7 +589,7 @@ fn test_credential_response() -> Result<(), ProtocolError> { let server_login_start_result = ServerLogin::::start( &mut server_e_sk_and_nonce_rng, ServerRegistration::deserialize(¶meters.password_file[..])?, - &Key::from_bytes(¶meters.server_s_sk[..])?, + &PrivateKey::from_bytes(¶meters.server_s_sk[..])?, CredentialRequest::::deserialize( ¶meters.credential_request[..], )?, diff --git a/src/tests/opaque_test_vectors.rs b/src/tests/opaque_test_vectors.rs index 466a6a7..68db601 100644 --- a/src/tests/opaque_test_vectors.rs +++ b/src/tests/opaque_test_vectors.rs @@ -7,7 +7,7 @@ use crate::{ ciphersuite::CipherSuite, errors::*, key_exchange::tripledh::TripleDH, - keypair::{Key, SizedBytesExt}, + keypair::{PrivateKey, PublicKey, SizedBytesExt}, opaque::*, slow_hash::NoOpHash, tests::mock_rng::CycleRng, @@ -356,7 +356,7 @@ fn get_password_file_bytes(parameters: &TestVectorParameters) -> Result, ServerRegistration::::start( &mut oprf_key_rng, RegistrationRequest::deserialize(¶meters.registration_request[..]).unwrap(), - &Key::from_bytes(¶meters.server_public_key[..]).unwrap(), + &PublicKey::from_bytes(¶meters.server_public_key[..]).unwrap(), )?; let password_file = server_registration_start_result @@ -391,7 +391,7 @@ fn test_registration_response() -> Result<(), ProtocolError> { ServerRegistration::::start( &mut oprf_key_rng, RegistrationRequest::deserialize(¶meters.registration_request[..]).unwrap(), - &Key::from_bytes(¶meters.server_public_key[..]).unwrap(), + &PublicKey::from_bytes(¶meters.server_public_key[..]).unwrap(), )?; assert_eq!( hex::encode(parameters.registration_response), @@ -473,7 +473,7 @@ fn test_ke2() -> Result<(), ProtocolError> { let server_login_start_result = ServerLogin::::start( &mut server_private_keyshare_and_nonce_rng, ServerRegistration::deserialize(&password_file_bytes[..]).unwrap(), - &Key::from_bytes(¶meters.server_private_key[..]).unwrap(), + &PrivateKey::from_bytes(¶meters.server_private_key[..]).unwrap(), CredentialRequest::::deserialize(¶meters.KE1[..]) .unwrap(), if parameters.envelope_mode == EnvelopeMode::CustomIdentifier { @@ -556,7 +556,7 @@ fn test_server_login_finish() -> Result<(), ProtocolError> { let server_login_start_result = ServerLogin::::start( &mut server_private_keyshare_and_nonce_rng, ServerRegistration::deserialize(&password_file_bytes[..]).unwrap(), - &Key::from_bytes(¶meters.server_private_key[..]).unwrap(), + &PrivateKey::from_bytes(¶meters.server_private_key[..]).unwrap(), CredentialRequest::::deserialize(¶meters.KE1[..]) .unwrap(), if parameters.envelope_mode == EnvelopeMode::CustomIdentifier {