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

@@ -7,6 +7,7 @@ import 'package:arbiter/features/identity/pk_manager.dart';
import 'package:arbiter/proto/arbiter.pbgrpc.dart';
import 'package:arbiter/proto/user_agent/auth.pb.dart' as ua_auth;
import 'package:arbiter/proto/user_agent.pb.dart';
import 'package:arbiter/src/rust/api.dart';
import 'package:grpc/grpc.dart';
import 'package:mtcore/markettakers.dart';
@@ -92,7 +93,10 @@ Future<Connection> connectAndAuthorize(
);
}
final challenge = _formatChallenge(authResponse.challenge, pubkey);
final challenge = await formatChallenge(
random: authResponse.challenge.random,
timestamp: authResponse.challenge.timestampNanos.toInt(),
);
talker.info(
'Received auth challenge, signing with key ${base64Encode(pubkey)}',
);
@@ -164,9 +168,3 @@ Future<Connection> _connect(StoredServerInfo serverInfo) async {
return Connection(channel: channel, tx: tx, rx: rx);
}
List<int> _formatChallenge(ua_auth.AuthChallenge challenge, List<int> pubkey) {
final encodedPubkey = base64Encode(pubkey);
final payload = "${challenge.nonce}:$encodedPubkey";
return utf8.encode(payload);
}

View File

@@ -12,6 +12,7 @@
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import '../shared/client.pb.dart' as $0;
@@ -94,12 +95,12 @@ class AuthChallengeRequest extends $pb.GeneratedMessage {
class AuthChallenge extends $pb.GeneratedMessage {
factory AuthChallenge({
$core.List<$core.int>? pubkey,
$core.int? nonce,
$fixnum.Int64? timestampNanos,
$core.List<$core.int>? random,
}) {
final result = create();
if (pubkey != null) result.pubkey = pubkey;
if (nonce != null) result.nonce = nonce;
if (timestampNanos != null) result.timestampNanos = timestampNanos;
if (random != null) result.random = random;
return result;
}
@@ -117,9 +118,11 @@ class AuthChallenge extends $pb.GeneratedMessage {
package:
const $pb.PackageName(_omitMessageNames ? '' : 'arbiter.client.auth'),
createEmptyInstance: create)
..a<$fixnum.Int64>(
1, _omitFieldNames ? '' : 'timestampNanos', $pb.PbFieldType.OU6,
defaultOrMaker: $fixnum.Int64.ZERO)
..a<$core.List<$core.int>>(
1, _omitFieldNames ? '' : 'pubkey', $pb.PbFieldType.OY)
..aI(2, _omitFieldNames ? '' : 'nonce')
2, _omitFieldNames ? '' : 'random', $pb.PbFieldType.OY)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@@ -142,22 +145,22 @@ class AuthChallenge extends $pb.GeneratedMessage {
static AuthChallenge? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get pubkey => $_getN(0);
$fixnum.Int64 get timestampNanos => $_getI64(0);
@$pb.TagNumber(1)
set pubkey($core.List<$core.int> value) => $_setBytes(0, value);
set timestampNanos($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasPubkey() => $_has(0);
$core.bool hasTimestampNanos() => $_has(0);
@$pb.TagNumber(1)
void clearPubkey() => $_clearField(1);
void clearTimestampNanos() => $_clearField(1);
@$pb.TagNumber(2)
$core.int get nonce => $_getIZ(1);
$core.List<$core.int> get random => $_getN(1);
@$pb.TagNumber(2)
set nonce($core.int value) => $_setSignedInt32(1, value);
set random($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasNonce() => $_has(1);
$core.bool hasRandom() => $_has(1);
@$pb.TagNumber(2)
void clearNonce() => $_clearField(2);
void clearRandom() => $_clearField(2);
}
class AuthChallengeSolution extends $pb.GeneratedMessage {

View File

@@ -62,15 +62,15 @@ final $typed_data.Uint8List authChallengeRequestDescriptor = $convert.base64Deco
const AuthChallenge$json = {
'1': 'AuthChallenge',
'2': [
{'1': 'pubkey', '3': 1, '4': 1, '5': 12, '10': 'pubkey'},
{'1': 'nonce', '3': 2, '4': 1, '5': 5, '10': 'nonce'},
{'1': 'timestamp_nanos', '3': 1, '4': 1, '5': 4, '10': 'timestampNanos'},
{'1': 'random', '3': 2, '4': 1, '5': 12, '10': 'random'},
],
};
/// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode(
'Cg1BdXRoQ2hhbGxlbmdlEhYKBnB1YmtleRgBIAEoDFIGcHVia2V5EhQKBW5vbmNlGAIgASgFUg'
'Vub25jZQ==');
'Cg1BdXRoQ2hhbGxlbmdlEicKD3RpbWVzdGFtcF9uYW5vcxgBIAEoBFIOdGltZXN0YW1wTmFub3'
'MSFgoGcmFuZG9tGAIgASgMUgZyYW5kb20=');
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
const AuthChallengeSolution$json = {

View File

@@ -12,6 +12,7 @@
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'auth.pbenum.dart';
@@ -90,10 +91,12 @@ class AuthChallengeRequest extends $pb.GeneratedMessage {
class AuthChallenge extends $pb.GeneratedMessage {
factory AuthChallenge({
$core.int? nonce,
$fixnum.Int64? timestampNanos,
$core.List<$core.int>? random,
}) {
final result = create();
if (nonce != null) result.nonce = nonce;
if (timestampNanos != null) result.timestampNanos = timestampNanos;
if (random != null) result.random = random;
return result;
}
@@ -111,7 +114,11 @@ class AuthChallenge extends $pb.GeneratedMessage {
package: const $pb.PackageName(
_omitMessageNames ? '' : 'arbiter.user_agent.auth'),
createEmptyInstance: create)
..aI(1, _omitFieldNames ? '' : 'nonce')
..a<$fixnum.Int64>(
1, _omitFieldNames ? '' : 'timestampNanos', $pb.PbFieldType.OU6,
defaultOrMaker: $fixnum.Int64.ZERO)
..a<$core.List<$core.int>>(
2, _omitFieldNames ? '' : 'random', $pb.PbFieldType.OY)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@@ -134,13 +141,22 @@ class AuthChallenge extends $pb.GeneratedMessage {
static AuthChallenge? _defaultInstance;
@$pb.TagNumber(1)
$core.int get nonce => $_getIZ(0);
$fixnum.Int64 get timestampNanos => $_getI64(0);
@$pb.TagNumber(1)
set nonce($core.int value) => $_setSignedInt32(0, value);
set timestampNanos($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasNonce() => $_has(0);
$core.bool hasTimestampNanos() => $_has(0);
@$pb.TagNumber(1)
void clearNonce() => $_clearField(1);
void clearTimestampNanos() => $_clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get random => $_getN(1);
@$pb.TagNumber(2)
set random($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasRandom() => $_has(1);
@$pb.TagNumber(2)
void clearRandom() => $_clearField(2);
}
class AuthChallengeSolution extends $pb.GeneratedMessage {

View File

@@ -67,13 +67,15 @@ final $typed_data.Uint8List authChallengeRequestDescriptor = $convert.base64Deco
const AuthChallenge$json = {
'1': 'AuthChallenge',
'2': [
{'1': 'nonce', '3': 1, '4': 1, '5': 5, '10': 'nonce'},
{'1': 'timestamp_nanos', '3': 1, '4': 1, '5': 4, '10': 'timestampNanos'},
{'1': 'random', '3': 2, '4': 1, '5': 12, '10': 'random'},
],
};
/// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authChallengeDescriptor = $convert
.base64Decode('Cg1BdXRoQ2hhbGxlbmdlEhQKBW5vbmNlGAEgASgFUgVub25jZQ==');
final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode(
'Cg1BdXRoQ2hhbGxlbmdlEicKD3RpbWVzdGFtcF9uYW5vcxgBIAEoBFIOdGltZXN0YW1wTmFub3'
'MSFgoGcmFuZG9tGAIgASgMUgZyYW5kb20=');
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
const AuthChallengeSolution$json = {

View File

@@ -6,6 +6,14 @@
import 'frb_generated.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
Future<Uint8List> formatChallenge({
required List<int> random,
required PlatformInt64 timestamp,
}) => RustLib.instance.api.crateApiFormatChallenge(
random: random,
timestamp: timestamp,
);
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>
abstract class MldsaKey implements RustOpaqueInterface {
static Future<MldsaKey> fromBytes({required List<int> bytes}) =>

View File

@@ -64,7 +64,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.12.0';
@override
int get rustContentHash => -437661335;
int get rustContentHash => 1247923898;
static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
@@ -89,6 +89,11 @@ abstract class RustLibApi extends BaseApi {
Future<Uint8List> crateApiMldsaKeyToBytes({required MldsaKey that});
Future<Uint8List> crateApiFormatChallenge({
required List<int> random,
required PlatformInt64 timestamp,
});
RustArcIncrementStrongCountFnType
get rust_arc_increment_strong_count_MldsaKey;
@@ -267,6 +272,40 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
TaskConstMeta get kCrateApiMldsaKeyToBytesConstMeta =>
const TaskConstMeta(debugName: "MldsaKey_to_bytes", argNames: ["that"]);
@override
Future<Uint8List> crateApiFormatChallenge({
required List<int> random,
required PlatformInt64 timestamp,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_list_prim_u_8_loose(random, serializer);
sse_encode_i_64(timestamp, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 6,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_list_prim_u_8_strict,
decodeErrorData: sse_decode_String,
),
constMeta: kCrateApiFormatChallengeConstMeta,
argValues: [random, timestamp],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiFormatChallengeConstMeta => const TaskConstMeta(
debugName: "format_challenge",
argNames: ["random", "timestamp"],
);
RustArcIncrementStrongCountFnType
get rust_arc_increment_strong_count_MldsaKey => wire
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey;
@@ -314,6 +353,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw as String;
}
@protected
PlatformInt64 dco_decode_i_64(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dcoDecodeI64(raw);
}
@protected
List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -394,6 +439,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return utf8.decoder.convert(inner);
}
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return deserializer.buffer.getPlatformInt64();
}
@protected
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -491,6 +542,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
}
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
serializer.buffer.putPlatformInt64(self);
}
@protected
void sse_encode_list_prim_u_8_loose(
List<int> self,

View File

@@ -46,6 +46,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String dco_decode_String(dynamic raw);
@protected
PlatformInt64 dco_decode_i_64(dynamic raw);
@protected
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
@@ -85,6 +88,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String sse_decode_String(SseDeserializer deserializer);
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
@protected
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
@@ -136,6 +142,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_String(String self, SseSerializer serializer);
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
@protected
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);

View File

@@ -48,6 +48,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String dco_decode_String(dynamic raw);
@protected
PlatformInt64 dco_decode_i_64(dynamic raw);
@protected
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
@@ -87,6 +90,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String sse_decode_String(SseDeserializer deserializer);
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
@protected
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
@@ -138,6 +144,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_String(String self, SseSerializer serializer);
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
@protected
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);