fix(useragent): now using new challenge format

This commit is contained in:
Skipper
2026-04-17 18:19:39 +02:00
parent 790026e93b
commit 9ee86afc19
14 changed files with 251 additions and 47 deletions

View File

@@ -232,7 +232,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
name = "arbiter-crypto"
version = "0.1.0"
dependencies = [
"base64",
"chrono",
"memsafe",
"ml-dsa",
"rand",
@@ -487,12 +487,6 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.8.3"
@@ -718,6 +712,20 @@ dependencies = [
"rand_core",
]
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "clipboard-win"
version = "5.4.1"
@@ -1821,6 +1829,30 @@ dependencies = [
"zeroize",
]
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "2.2.0"

View File

@@ -1,13 +1,15 @@
use anyhow::anyhow;
use arbiter_crypto::authn::{self, AuthChallenge, USERAGENT_CONTEXT};
use flutter_rust_bridge::frb;
use arbiter_crypto::authn::{self, USERAGENT_CONTEXT};
#[frb(opaque)]
pub struct MldsaKey(authn::SigningKey);
impl MldsaKey {
pub fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
let bytes: [u8; 32] = bytes.try_into().map_err(|_| anyhow!("Invalid key length"))?;
let bytes: [u8; 32] = bytes
.try_into()
.map_err(|_| anyhow!("Invalid key length"))?;
Ok(Self(authn::SigningKey::from_seed(bytes)))
}
@@ -26,4 +28,11 @@ impl MldsaKey {
pub fn get_public_key(&self) -> Vec<u8> {
self.0.public_key().to_bytes().to_vec()
}
}
}
pub fn format_challenge(random: Vec<u8>, timestamp: i64) -> Result<Vec<u8>, String> {
let challenge = AuthChallenge::from_parts(&random, timestamp)
.map_err(|_| "Invalid nonce length".to_string())?;
Ok(challenge.format())
}

View File

@@ -39,7 +39,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueMoi,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -437661335;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1247923898;
// Section: executor
@@ -267,6 +267,40 @@ fn wire__crate__api__MldsaKey_to_bytes_impl(
},
)
}
fn wire__crate__api__format_challenge_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "format_challenge",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_random = <Vec<u8>>::sse_decode(&mut deserializer);
let api_timestamp = <i64>::sse_decode(&mut deserializer);
deserializer.end();
move |context| {
transform_result_sse::<_, String>((move || {
let output_ok = crate::api::format_challenge(api_random, api_timestamp)?;
Ok(output_ok)
})())
}
},
)
}
// Section: related_funcs
@@ -312,6 +346,13 @@ impl SseDecode for String {
}
}
impl SseDecode for i64 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_i64::<NativeEndian>().unwrap()
}
}
impl SseDecode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -371,6 +412,7 @@ fn pde_ffi_dispatcher_primary_impl(
3 => wire__crate__api__MldsaKey_get_public_key_impl(port, ptr, rust_vec_len, data_len),
4 => wire__crate__api__MldsaKey_sign_impl(port, ptr, rust_vec_len, data_len),
5 => wire__crate__api__MldsaKey_to_bytes_impl(port, ptr, rust_vec_len, data_len),
6 => wire__crate__api__format_challenge_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
}
}
@@ -436,6 +478,13 @@ impl SseEncode for String {
}
}
impl SseEncode for i64 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer.cursor.write_i64::<NativeEndian>(self).unwrap();
}
}
impl SseEncode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {