update ActStage to derive nex_key on its own

This commit is contained in:
red binder 2026-06-23 11:43:21 +02:00
commit 772f1c4b28
4 changed files with 35 additions and 8 deletions

2
Cargo.lock generated
View file

@ -918,7 +918,7 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]] [[package]]
name = "nex-account" name = "nex-account"
version = "0.2.0" version = "0.2.1"
dependencies = [ dependencies = [
"hmac", "hmac",
"log", "log",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "nex-account" name = "nex-account"
version = "0.2.0" version = "0.2.1"
edition = "2024" edition = "2024"
publish = ["spbr"] publish = ["spbr"]

View file

@ -10,7 +10,12 @@ message ActCreateInfo {
} }
message ActStageInfo { message ActStageInfo {
bytes password = 1;
}
message ActStageReturn {
bytes nex_key = 1; bytes nex_key = 1;
int32 pid = 2;
} }
message PID { message PID {
@ -24,5 +29,5 @@ message NexKey {
service NexAccountService { service NexAccountService {
rpc CreateNewSequentialOrUpdateAndGetAccount(ActCreateInfo) returns (NexKey); rpc CreateNewSequentialOrUpdateAndGetAccount(ActCreateInfo) returns (NexKey);
rpc GetNexKeyByPid(PID) returns (NexKey); rpc GetNexKeyByPid(PID) returns (NexKey);
rpc StageNewAccount(ActStageInfo) returns (PID); rpc StageNewAccount(ActStageInfo) returns (ActStageReturn);
} }

View file

@ -8,9 +8,10 @@ use simplelog::{Config, TerminalMode};
use sqlx::{PgPool, query}; use sqlx::{PgPool, query};
use tonic::{Response, transport::Server}; use tonic::{Response, transport::Server};
use crate::grpc::{ use crate::grpc::{
ActCreateInfo, NexKey, Pid, ActStageInfo, ActCreateInfo, NexKey, Pid, ActStageInfo, ActStageReturn,
nex_account_service_server::{NexAccountService, NexAccountServiceServer}, nex_account_service_server::{NexAccountService, NexAccountServiceServer},
}; };
use md5::{Digest, Md5};
pub mod grpc; pub mod grpc;
@ -50,6 +51,25 @@ fn db_neverfail(sql_err: sqlx::Error) -> tonic::Status {
tonic::Status::aborted("error in database") tonic::Status::aborted("error in database")
} }
pub fn derive_key(pid: i32, password: &[u8]) -> [u8; 16] {
let iteration_count = 65000 + pid % 1024;
// we do one iteration out here to ensure the key is always 16 bytes
let mut key: [u8; 16] = {
let mut md5 = Md5::new();
md5.update(password);
md5.finalize().try_into().unwrap()
};
for _ in 1..iteration_count {
let mut md5 = Md5::new();
md5.update(key);
key = md5.finalize().try_into().unwrap();
}
key
}
#[tonic::async_trait] #[tonic::async_trait]
impl NexAccountService for NexAccountServer { impl NexAccountService for NexAccountServer {
async fn create_new_sequential_or_update_and_get_account( async fn create_new_sequential_or_update_and_get_account(
@ -139,12 +159,14 @@ impl NexAccountService for NexAccountServer {
async fn stage_new_account( async fn stage_new_account(
&self, &self,
request: tonic::Request<ActStageInfo>, request: tonic::Request<ActStageInfo>,
) -> Result<tonic::Response<Pid>, tonic::Status> { ) -> Result<tonic::Response<ActStageReturn>, tonic::Status> {
let request = request.into_inner(); let request = request.into_inner();
let next_pid = next_pid(&self.pool).await; let next_pid = next_pid(&self.pool).await;
if request.nex_key.len() != 16 { let nex_key = derive_key(next_pid, &request.password);
if nex_key.len() != 16 {
return Err(tonic::Status::invalid_argument("invalid key length")); return Err(tonic::Status::invalid_argument("invalid key length"));
} }
@ -155,13 +177,13 @@ impl NexAccountService for NexAccountServer {
$1, $2 $1, $2
)", )",
next_pid, next_pid,
request.nex_key &nex_key
) )
.execute(&self.pool) .execute(&self.pool)
.await .await
.map_err(db_neverfail)?; .map_err(db_neverfail)?;
Ok(Response::new(Pid { pid: next_pid})) Ok(Response::new(ActStageReturn{ pid: next_pid, nex_key: nex_key.into() }))
} }
} }