Changeset View
Changeset View
Standalone View
Standalone View
shared/comm-opaque2/src/client/login.rs
use opaque_ke::{ | use opaque_ke::{ | ||||
errors::ProtocolError, ClientLogin, ClientLoginFinishParameters, | errors::ProtocolError, ClientLogin, ClientLoginFinishParameters, | ||||
CredentialResponse, | CredentialResponse, | ||||
}; | }; | ||||
use rand::rngs::OsRng; | use rand::rngs::OsRng; | ||||
use wasm_bindgen::prelude::wasm_bindgen; | |||||
use crate::Cipher; | use crate::{error::OpaqueError, Cipher}; | ||||
#[wasm_bindgen] | |||||
pub struct Login { | pub struct Login { | ||||
state: Option<ClientLogin<Cipher>>, | state: Option<ClientLogin<Cipher>>, | ||||
password: Option<String>, | password: Option<String>, | ||||
rng: OsRng, | rng: OsRng, | ||||
export_key: Option<Vec<u8>>, | export_key: Option<Vec<u8>>, | ||||
pub session_key: Option<Vec<u8>>, | session_key: Option<Vec<u8>>, | ||||
} | } | ||||
#[wasm_bindgen] | |||||
impl Login { | impl Login { | ||||
#[wasm_bindgen(constructor)] | |||||
pub fn new() -> Login { | pub fn new() -> Login { | ||||
Login { | Login { | ||||
state: None, | state: None, | ||||
password: None, | password: None, | ||||
rng: OsRng, | rng: OsRng, | ||||
session_key: None, | session_key: None, | ||||
export_key: None, | export_key: None, | ||||
} | } | ||||
} | } | ||||
pub fn start(&mut self, password: &str) -> Result<Vec<u8>, ProtocolError> { | #[wasm_bindgen] | ||||
varun: why do we need the wasm_bindgen attribute on every function? other examples i looked at only… | |||||
jonAuthorUnsubmitted Done Inline Actionsyou're right, we don't. Was just following wasm-opaque. jon: you're right, we don't. Was just following `wasm-opaque`. | |||||
pub fn start(&mut self, password: &str) -> Result<Vec<u8>, OpaqueError> { | |||||
let client_start_result = | let client_start_result = | ||||
ClientLogin::<Cipher>::start(&mut self.rng, password.as_bytes())?; | ClientLogin::<Cipher>::start(&mut self.rng, password.as_bytes())?; | ||||
self.state = Some(client_start_result.state); | self.state = Some(client_start_result.state); | ||||
self.password = Some(password.to_string()); | self.password = Some(password.to_string()); | ||||
Ok(client_start_result.message.serialize().to_vec()) | Ok(client_start_result.message.serialize().to_vec()) | ||||
} | } | ||||
#[wasm_bindgen] | |||||
pub fn finish( | pub fn finish( | ||||
&mut self, | &mut self, | ||||
response_payload: &[u8], | response_payload: &[u8], | ||||
) -> Result<Vec<u8>, ProtocolError> { | ) -> Result<Vec<u8>, OpaqueError> { | ||||
let response = CredentialResponse::deserialize(response_payload)?; | let response = CredentialResponse::deserialize(response_payload)?; | ||||
let password = self | let password = self | ||||
.password | .password | ||||
.take() | .take() | ||||
.ok_or_else(|| ProtocolError::InvalidLoginError)?; | .ok_or_else(|| ProtocolError::InvalidLoginError)?; | ||||
let state = self | let state = self | ||||
.state | .state | ||||
.take() | .take() | ||||
.ok_or_else(|| ProtocolError::InvalidLoginError)?; | .ok_or_else(|| ProtocolError::InvalidLoginError)?; | ||||
let result = state.finish( | let result = state.finish( | ||||
password.as_bytes(), | password.as_bytes(), | ||||
response, | response, | ||||
ClientLoginFinishParameters::default(), | ClientLoginFinishParameters::default(), | ||||
)?; | )?; | ||||
self.session_key = Some(result.session_key.to_vec()); | self.session_key = Some(result.session_key.to_vec()); | ||||
self.export_key = Some(result.export_key.to_vec()); | self.export_key = Some(result.export_key.to_vec()); | ||||
Ok(result.message.serialize().to_vec()) | Ok(result.message.serialize().to_vec()) | ||||
} | } | ||||
#[wasm_bindgen(getter)] | |||||
pub fn session_key(&self) -> Result<Vec<u8>, OpaqueError> { | |||||
match &self.session_key { | |||||
Some(v) => Ok(v.clone()), | |||||
None => Err(ProtocolError::InvalidLoginError.into()), | |||||
} | |||||
} | |||||
} | } |
why do we need the wasm_bindgen attribute on every function? other examples i looked at only had it above the impl block