-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add ser/de for HandleLogin state
This is necessary to keep a stateless server across the two request handlers needed to implement login. This state should be persisted to an ephemeral key/value store, keyed on the user identifier, and with a short TTL, to ensure the complete handshake is completed within a reasonable time. It should also be stored encrypted for additional security, but this is out of the scope of this feature. - Add Rust tests - Reflect change in JS test - Use OPAQUE latest RFC naming conventions in JS test
- Loading branch information
Showing
4 changed files
with
158 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,78 @@ | ||
import { Registration, Login, HandleRegistration, HandleLogin, ServerSetup } from 'opaque-wasm'; | ||
import { | ||
HandleLogin, | ||
HandleRegistration, | ||
Login, | ||
Registration, | ||
ServerSetup, | ||
set_panic_hook, | ||
} from 'opaque-wasm' | ||
|
||
const password = 'test123' | ||
const email = '[email protected]' | ||
|
||
async function run() { | ||
console.log('--- STARTING ---') | ||
set_panic_hook() | ||
|
||
// Server configuration; this must be saved. | ||
let server_setup = new ServerSetup() | ||
|
||
// Save and reload the ServerSetup for demonstration | ||
const server_setup_export = server_setup.serialize(); | ||
server_setup = ServerSetup.deserialize(server_setup_export); | ||
const server_setup_export = server_setup.serialize() | ||
server_setup = ServerSetup.deserialize(server_setup_export) | ||
|
||
// User registration | ||
const registration = new Registration() | ||
const registration_tx = registration.start(password) | ||
const client_registration = new Registration() | ||
const registration_request = client_registration.start(password) | ||
|
||
console.log('--- begin ---', registration_tx) | ||
console.log('--- registration request ---', registration_request) | ||
|
||
const serverRegistration = new HandleRegistration(server_setup) | ||
const registration_response = serverRegistration.start(email, registration_tx) | ||
console.log('-- server response --', registration_response) | ||
|
||
|
||
const registration_final = registration.finish(password, registration_response) | ||
console.log('-- client finish --', registration_final) | ||
|
||
const password_file = serverRegistration.finish(registration_final) | ||
const registration_response = serverRegistration.start( | ||
email, | ||
registration_request | ||
) | ||
console.log('-- registration response --', registration_response) | ||
|
||
const registration_record = client_registration.finish( | ||
password, | ||
registration_response | ||
) | ||
console.log('-- registration upload --', registration_record) | ||
|
||
const password_file = serverRegistration.finish(registration_record) | ||
console.log('-- password_file --', password_file) | ||
const registration_export_key = client_registration.getExportKey() | ||
|
||
// User Login | ||
|
||
const login = new Login() | ||
const login_tx = login.start(password) | ||
console.log('login_tx', login_tx) | ||
|
||
console.log(login) | ||
|
||
const serverLogin = new HandleLogin(server_setup) | ||
const login_response = serverLogin.start(password_file, email, login_tx) | ||
const client_login = new Login() | ||
const login_request = client_login.start(password) | ||
console.log('login_request', login_request) | ||
|
||
const server_login1 = new HandleLogin(server_setup) | ||
const login_response = server_login1.start( | ||
password_file, | ||
email, | ||
login_request | ||
) | ||
console.log('login_response', login_response) | ||
// Serialize login handler state and persist it outside of the server | ||
// to preserve statlessness across request handlers | ||
const login_state = server_login1.serialize() | ||
server_login1.free() | ||
console.log('login_state', login_state) | ||
|
||
const login_final = login.finish(password, login_response) | ||
const login_final = client_login.finish(password, login_response) | ||
console.log('client login final', login_final) | ||
console.log('client session key', client_login.getSessionKey()) | ||
|
||
console.log(login) | ||
|
||
console.log('client session key', login.getSessionKey()) | ||
|
||
const server_finish = serverLogin.finish(login_final) | ||
const server_login2 = HandleLogin.deserialize(login_state, server_setup) | ||
const server_finish = server_login2.finish(login_final) | ||
console.log('server session key', server_finish) | ||
|
||
console.log('registration export key', registration_export_key) | ||
console.log('login export key', client_login.getExportKey()) | ||
} | ||
|
||
run() | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,71 @@ pub use client_registration::Registration; | |
pub use handle_login::HandleLogin; | ||
pub use handle_registration::HandleRegistration; | ||
pub use server_setup::ServerSetup; | ||
|
||
// ----------------------------------------------------------------------------- | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn complete_exchange() { | ||
// Server configuration | ||
let server_setup = ServerSetup::new(); | ||
|
||
// Client configuration | ||
let username = "[email protected]"; | ||
let password = "correct horse battery staple"; | ||
|
||
// Registration | ||
let [password_file, registration_export_key] = { | ||
let mut client_registration = Registration::new(); | ||
let registration_request = client_registration.start(&password).unwrap(); | ||
let server_registration = HandleRegistration::new(&server_setup); | ||
let registration_response = server_registration | ||
.start(username.into(), registration_request) | ||
.unwrap(); | ||
let registration_record = client_registration | ||
.finish(&password, registration_response.clone()) | ||
.unwrap(); | ||
let password_file = server_registration | ||
.finish(registration_record.clone()) | ||
.unwrap(); | ||
assert_eq!(password_file, registration_record); | ||
let export_key = client_registration.get_export_key().unwrap(); | ||
assert_ne!(export_key, registration_response); | ||
[password_file, export_key] | ||
}; | ||
|
||
// Login | ||
let login_export_key = { | ||
let mut client_login = Login::new(); | ||
let login_request = client_login.start(&password).unwrap(); | ||
|
||
// Client -> Server - First request handler | ||
let mut server_login1 = HandleLogin::new(&server_setup); | ||
let login_response = server_login1 | ||
.start(Some(password_file), username.into(), login_request) | ||
.unwrap(); | ||
let serialized_state = server_login1.serialize().unwrap(); | ||
// Client <- Server - end of first request handler | ||
|
||
let login_record = client_login.finish(&password, login_response).unwrap(); | ||
let export_key = client_login.get_export_key().unwrap(); | ||
let client_session_key = client_login.get_session_key().unwrap(); | ||
assert_ne!(export_key, client_session_key); | ||
|
||
// Client -> Server - Second request handler | ||
let server_login2 = HandleLogin::deserialize(serialized_state, &server_setup).unwrap(); | ||
let server_session_key = server_login2.finish(login_record).unwrap(); | ||
assert_eq!(client_session_key, server_session_key); | ||
|
||
export_key | ||
}; | ||
|
||
assert_eq!( | ||
registration_export_key, login_export_key, | ||
"Export keys differ" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters