import {
getOpaqueConfig,
OpaqueID,
CredentialFile,
OpaqueServer,
KE1
} from '../lib/opaque.mjs'
const cfg = getOpaqueConfig(
OpaqueID.OPAQUE_P256,
'OPAQUE demo'
)
async function auth_init( request, env, context ) {
const requestJSON = await request.json()
const initSerialized = requestJSON[ 'ke1' ]
const client_identity = requestJSON[ 'username' ].trim()
// username is also being used for this demo as server-side credential_identifier
const credential_identifier = client_identity
const credentials_u8array = await env.KV.get( credential_identifier, { type: 'arrayBuffer' } )
if ( credentials_u8array === null ) {
throw new Error( 'client not found in database' )
}
const credential_file = CredentialFile.deserialize( cfg, Array.from( new Uint8Array( credentials_u8array ) ) )
if ( credential_file.credential_identifier !== credential_identifier ) {
throw new Error( 'credential identifier does not match KV key it was retrieved from' )
}
if ( credential_file.client_identity !== client_identity ) {
throw new Error( 'stored credentials file does not seem to match client' )
}
const oprf_seed = JSON.parse( env.oprf_seed )
const server_ake_keypair = JSON.parse( env.server_ake_keypair )
const server_identity = env.server_identity
const server = new OpaqueServer(
cfg,
oprf_seed,
server_ake_keypair,
server_identity
)
const ke1 = KE1.deserialize( cfg, initSerialized )
const initiated = await server.authInit(
ke1,
credential_file.record,
credential_file.credential_identifier,
credential_file.client_identity
)
if ( initiated instanceof Error ) {
throw initiated
}
const { ke2, expected } = initiated
// save expected in Durable Object
const id = env.SESSION.idFromName( client_identity )
const obj = env.SESSION.get( id )
context.waitUntil( obj.fetch( '/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify( { username: client_identity, expected: expected.serialize() } )
} ) )
return new Response( JSON.stringify( {
message: 'intermediate authentication key enclosed',
ke2: ke2.serialize()
} ), {
headers: { 'Content-Type': 'application/json' }
} )
}
export { auth_init }