fix(useragent): now using new challenge format
This commit is contained in:
@@ -43,6 +43,14 @@ impl AuthChallenge {
|
|||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_parts(nonce: &[u8], timestamp: i64) -> Result<Self, ()> {
|
||||||
|
let random_nonce = nonce.as_array().ok_or(())?;
|
||||||
|
Ok(AuthChallenge {
|
||||||
|
nonce: *random_nonce,
|
||||||
|
timestamp: DateTime::from_timestamp_nanos(timestamp),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type KeyParams = MlDsa87;
|
pub type KeyParams = MlDsa87;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:arbiter/features/identity/pk_manager.dart';
|
|||||||
import 'package:arbiter/proto/arbiter.pbgrpc.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/auth.pb.dart' as ua_auth;
|
||||||
import 'package:arbiter/proto/user_agent.pb.dart';
|
import 'package:arbiter/proto/user_agent.pb.dart';
|
||||||
|
import 'package:arbiter/src/rust/api.dart';
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
import 'package:mtcore/markettakers.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(
|
talker.info(
|
||||||
'Received auth challenge, signing with key ${base64Encode(pubkey)}',
|
'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);
|
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
|
|
||||||
|
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
import '../shared/client.pb.dart' as $0;
|
import '../shared/client.pb.dart' as $0;
|
||||||
@@ -94,12 +95,12 @@ class AuthChallengeRequest extends $pb.GeneratedMessage {
|
|||||||
|
|
||||||
class AuthChallenge extends $pb.GeneratedMessage {
|
class AuthChallenge extends $pb.GeneratedMessage {
|
||||||
factory AuthChallenge({
|
factory AuthChallenge({
|
||||||
$core.List<$core.int>? pubkey,
|
$fixnum.Int64? timestampNanos,
|
||||||
$core.int? nonce,
|
$core.List<$core.int>? random,
|
||||||
}) {
|
}) {
|
||||||
final result = create();
|
final result = create();
|
||||||
if (pubkey != null) result.pubkey = pubkey;
|
if (timestampNanos != null) result.timestampNanos = timestampNanos;
|
||||||
if (nonce != null) result.nonce = nonce;
|
if (random != null) result.random = random;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,9 +118,11 @@ class AuthChallenge extends $pb.GeneratedMessage {
|
|||||||
package:
|
package:
|
||||||
const $pb.PackageName(_omitMessageNames ? '' : 'arbiter.client.auth'),
|
const $pb.PackageName(_omitMessageNames ? '' : 'arbiter.client.auth'),
|
||||||
createEmptyInstance: create)
|
createEmptyInstance: create)
|
||||||
|
..a<$fixnum.Int64>(
|
||||||
|
1, _omitFieldNames ? '' : 'timestampNanos', $pb.PbFieldType.OU6,
|
||||||
|
defaultOrMaker: $fixnum.Int64.ZERO)
|
||||||
..a<$core.List<$core.int>>(
|
..a<$core.List<$core.int>>(
|
||||||
1, _omitFieldNames ? '' : 'pubkey', $pb.PbFieldType.OY)
|
2, _omitFieldNames ? '' : 'random', $pb.PbFieldType.OY)
|
||||||
..aI(2, _omitFieldNames ? '' : 'nonce')
|
|
||||||
..hasRequiredFields = false;
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
@@ -142,22 +145,22 @@ class AuthChallenge extends $pb.GeneratedMessage {
|
|||||||
static AuthChallenge? _defaultInstance;
|
static AuthChallenge? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.List<$core.int> get pubkey => $_getN(0);
|
$fixnum.Int64 get timestampNanos => $_getI64(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
set pubkey($core.List<$core.int> value) => $_setBytes(0, value);
|
set timestampNanos($fixnum.Int64 value) => $_setInt64(0, value);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.bool hasPubkey() => $_has(0);
|
$core.bool hasTimestampNanos() => $_has(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
void clearPubkey() => $_clearField(1);
|
void clearTimestampNanos() => $_clearField(1);
|
||||||
|
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.int get nonce => $_getIZ(1);
|
$core.List<$core.int> get random => $_getN(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
set nonce($core.int value) => $_setSignedInt32(1, value);
|
set random($core.List<$core.int> value) => $_setBytes(1, value);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.bool hasNonce() => $_has(1);
|
$core.bool hasRandom() => $_has(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
void clearNonce() => $_clearField(2);
|
void clearRandom() => $_clearField(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthChallengeSolution extends $pb.GeneratedMessage {
|
class AuthChallengeSolution extends $pb.GeneratedMessage {
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ final $typed_data.Uint8List authChallengeRequestDescriptor = $convert.base64Deco
|
|||||||
const AuthChallenge$json = {
|
const AuthChallenge$json = {
|
||||||
'1': 'AuthChallenge',
|
'1': 'AuthChallenge',
|
||||||
'2': [
|
'2': [
|
||||||
{'1': 'pubkey', '3': 1, '4': 1, '5': 12, '10': 'pubkey'},
|
{'1': 'timestamp_nanos', '3': 1, '4': 1, '5': 4, '10': 'timestampNanos'},
|
||||||
{'1': 'nonce', '3': 2, '4': 1, '5': 5, '10': 'nonce'},
|
{'1': 'random', '3': 2, '4': 1, '5': 12, '10': 'random'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode(
|
final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode(
|
||||||
'Cg1BdXRoQ2hhbGxlbmdlEhYKBnB1YmtleRgBIAEoDFIGcHVia2V5EhQKBW5vbmNlGAIgASgFUg'
|
'Cg1BdXRoQ2hhbGxlbmdlEicKD3RpbWVzdGFtcF9uYW5vcxgBIAEoBFIOdGltZXN0YW1wTmFub3'
|
||||||
'Vub25jZQ==');
|
'MSFgoGcmFuZG9tGAIgASgMUgZyYW5kb20=');
|
||||||
|
|
||||||
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
|
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
|
||||||
const AuthChallengeSolution$json = {
|
const AuthChallengeSolution$json = {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
|
|
||||||
|
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
import 'auth.pbenum.dart';
|
import 'auth.pbenum.dart';
|
||||||
@@ -90,10 +91,12 @@ class AuthChallengeRequest extends $pb.GeneratedMessage {
|
|||||||
|
|
||||||
class AuthChallenge extends $pb.GeneratedMessage {
|
class AuthChallenge extends $pb.GeneratedMessage {
|
||||||
factory AuthChallenge({
|
factory AuthChallenge({
|
||||||
$core.int? nonce,
|
$fixnum.Int64? timestampNanos,
|
||||||
|
$core.List<$core.int>? random,
|
||||||
}) {
|
}) {
|
||||||
final result = create();
|
final result = create();
|
||||||
if (nonce != null) result.nonce = nonce;
|
if (timestampNanos != null) result.timestampNanos = timestampNanos;
|
||||||
|
if (random != null) result.random = random;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +114,11 @@ class AuthChallenge extends $pb.GeneratedMessage {
|
|||||||
package: const $pb.PackageName(
|
package: const $pb.PackageName(
|
||||||
_omitMessageNames ? '' : 'arbiter.user_agent.auth'),
|
_omitMessageNames ? '' : 'arbiter.user_agent.auth'),
|
||||||
createEmptyInstance: create)
|
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;
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
@@ -134,13 +141,22 @@ class AuthChallenge extends $pb.GeneratedMessage {
|
|||||||
static AuthChallenge? _defaultInstance;
|
static AuthChallenge? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.int get nonce => $_getIZ(0);
|
$fixnum.Int64 get timestampNanos => $_getI64(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
set nonce($core.int value) => $_setSignedInt32(0, value);
|
set timestampNanos($fixnum.Int64 value) => $_setInt64(0, value);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.bool hasNonce() => $_has(0);
|
$core.bool hasTimestampNanos() => $_has(0);
|
||||||
@$pb.TagNumber(1)
|
@$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 {
|
class AuthChallengeSolution extends $pb.GeneratedMessage {
|
||||||
|
|||||||
@@ -67,13 +67,15 @@ final $typed_data.Uint8List authChallengeRequestDescriptor = $convert.base64Deco
|
|||||||
const AuthChallenge$json = {
|
const AuthChallenge$json = {
|
||||||
'1': 'AuthChallenge',
|
'1': 'AuthChallenge',
|
||||||
'2': [
|
'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`.
|
/// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List authChallengeDescriptor = $convert
|
final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode(
|
||||||
.base64Decode('Cg1BdXRoQ2hhbGxlbmdlEhQKBW5vbmNlGAEgASgFUgVub25jZQ==');
|
'Cg1BdXRoQ2hhbGxlbmdlEicKD3RpbWVzdGFtcF9uYW5vcxgBIAEoBFIOdGltZXN0YW1wTmFub3'
|
||||||
|
'MSFgoGcmFuZG9tGAIgASgMUgZyYW5kb20=');
|
||||||
|
|
||||||
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
|
@$core.Deprecated('Use authChallengeSolutionDescriptor instead')
|
||||||
const AuthChallengeSolution$json = {
|
const AuthChallengeSolution$json = {
|
||||||
|
|||||||
@@ -6,6 +6,14 @@
|
|||||||
import 'frb_generated.dart';
|
import 'frb_generated.dart';
|
||||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_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>>
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>
|
||||||
abstract class MldsaKey implements RustOpaqueInterface {
|
abstract class MldsaKey implements RustOpaqueInterface {
|
||||||
static Future<MldsaKey> fromBytes({required List<int> bytes}) =>
|
static Future<MldsaKey> fromBytes({required List<int> bytes}) =>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
|||||||
String get codegenVersion => '2.12.0';
|
String get codegenVersion => '2.12.0';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => -437661335;
|
int get rustContentHash => 1247923898;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig =
|
static const kDefaultExternalLibraryLoaderConfig =
|
||||||
ExternalLibraryLoaderConfig(
|
ExternalLibraryLoaderConfig(
|
||||||
@@ -89,6 +89,11 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
|
|
||||||
Future<Uint8List> crateApiMldsaKeyToBytes({required MldsaKey that});
|
Future<Uint8List> crateApiMldsaKeyToBytes({required MldsaKey that});
|
||||||
|
|
||||||
|
Future<Uint8List> crateApiFormatChallenge({
|
||||||
|
required List<int> random,
|
||||||
|
required PlatformInt64 timestamp,
|
||||||
|
});
|
||||||
|
|
||||||
RustArcIncrementStrongCountFnType
|
RustArcIncrementStrongCountFnType
|
||||||
get rust_arc_increment_strong_count_MldsaKey;
|
get rust_arc_increment_strong_count_MldsaKey;
|
||||||
|
|
||||||
@@ -267,6 +272,40 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
TaskConstMeta get kCrateApiMldsaKeyToBytesConstMeta =>
|
TaskConstMeta get kCrateApiMldsaKeyToBytesConstMeta =>
|
||||||
const TaskConstMeta(debugName: "MldsaKey_to_bytes", argNames: ["that"]);
|
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
|
RustArcIncrementStrongCountFnType
|
||||||
get rust_arc_increment_strong_count_MldsaKey => wire
|
get rust_arc_increment_strong_count_MldsaKey => wire
|
||||||
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey;
|
.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey;
|
||||||
@@ -314,6 +353,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return raw as String;
|
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
|
@protected
|
||||||
List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
|
List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// 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);
|
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
|
@protected
|
||||||
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
|
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// 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);
|
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
|
@protected
|
||||||
void sse_encode_list_prim_u_8_loose(
|
void sse_encode_list_prim_u_8_loose(
|
||||||
List<int> self,
|
List<int> self,
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw);
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
PlatformInt64 dco_decode_i_64(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
|
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
|
||||||
|
|
||||||
@@ -85,6 +88,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer);
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
|
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -136,6 +142,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer);
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
|
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String dco_decode_String(dynamic raw);
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
PlatformInt64 dco_decode_i_64(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
|
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
|
||||||
|
|
||||||
@@ -87,6 +90,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
String sse_decode_String(SseDeserializer deserializer);
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
|
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -138,6 +144,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_String(String self, SseSerializer serializer);
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
|
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
|
||||||
|
|
||||||
|
|||||||
4
useragent/mise.toml
Normal file
4
useragent/mise.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[tasks.codegen]
|
||||||
|
run = '''
|
||||||
|
flutter_rust_bridge_codegen generate
|
||||||
|
'''
|
||||||
46
useragent/rust/Cargo.lock
generated
46
useragent/rust/Cargo.lock
generated
@@ -232,7 +232,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
|||||||
name = "arbiter-crypto"
|
name = "arbiter-crypto"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"chrono",
|
||||||
"memsafe",
|
"memsafe",
|
||||||
"ml-dsa",
|
"ml-dsa",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -487,12 +487,6 @@ dependencies = [
|
|||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.22.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
version = "1.8.3"
|
version = "1.8.3"
|
||||||
@@ -718,6 +712,20 @@ dependencies = [
|
|||||||
"rand_core",
|
"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]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "5.4.1"
|
version = "5.4.1"
|
||||||
@@ -1821,6 +1829,30 @@ dependencies = [
|
|||||||
"zeroize",
|
"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]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use arbiter_crypto::authn::{self, AuthChallenge, USERAGENT_CONTEXT};
|
||||||
use flutter_rust_bridge::frb;
|
use flutter_rust_bridge::frb;
|
||||||
use arbiter_crypto::authn::{self, USERAGENT_CONTEXT};
|
|
||||||
|
|
||||||
#[frb(opaque)]
|
#[frb(opaque)]
|
||||||
pub struct MldsaKey(authn::SigningKey);
|
pub struct MldsaKey(authn::SigningKey);
|
||||||
|
|
||||||
impl MldsaKey {
|
impl MldsaKey {
|
||||||
pub fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
|
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)))
|
Ok(Self(authn::SigningKey::from_seed(bytes)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,3 +29,10 @@ impl MldsaKey {
|
|||||||
self.0.public_key().to_bytes().to_vec()
|
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())
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
|||||||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
|
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
|
// 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
|
// 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> {
|
impl SseDecode for Vec<u8> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
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),
|
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),
|
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),
|
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!(),
|
_ => 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> {
|
impl SseEncode for Vec<u8> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user