Compare commits
1 Commits
28f84d03ab
...
check-uac-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e1ab51398 |
@@ -4,7 +4,7 @@
|
||||
"cargo:cargo-vet" = "0.10.2"
|
||||
flutter = "3.38.9-stable"
|
||||
protoc = "29.6"
|
||||
"rust" = {version = "1.93.0", components = "clippy,rust-analyzer"}
|
||||
"rust" = {version = "1.93.0", components = "clippy"}
|
||||
"cargo:cargo-features-manager" = "0.11.1"
|
||||
"cargo:cargo-nextest" = "0.9.126"
|
||||
"cargo:cargo-shear" = "latest"
|
||||
|
||||
776
server/Cargo.lock
generated
776
server/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -16,22 +16,22 @@ tonic = { version = "0.14.5", features = [
|
||||
"zstd",
|
||||
] }
|
||||
tracing = "0.1.44"
|
||||
tokio = { version = "1.51.1", features = ["full"] }
|
||||
tokio = { version = "1.50.0", features = ["full"] }
|
||||
ed25519-dalek = { version = "3.0.0-pre.6", features = ["rand_core"] }
|
||||
chrono = { version = "0.4.44", features = ["serde"] }
|
||||
rand = "0.10.1"
|
||||
rustls = { version = "0.23.38", features = ["aws-lc-rs", "logging", "prefer-post-quantum", "std"], default-features = false }
|
||||
rand = "0.10.0"
|
||||
rustls = { version = "0.23.37", features = ["aws-lc-rs", "logging", "prefer-post-quantum", "std"], default-features = false }
|
||||
smlang = "0.8.0"
|
||||
thiserror = "2.0.18"
|
||||
async-trait = "0.1.89"
|
||||
futures = "0.3.32"
|
||||
tokio-stream = { version = "0.1.18", features = ["full"] }
|
||||
kameo = "0.20.0"
|
||||
kameo = "0.19.2"
|
||||
prost-types = { version = "0.14.3", features = ["chrono"] }
|
||||
x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
|
||||
rstest = "0.26.1"
|
||||
rustls-pki-types = "1.14.0"
|
||||
alloy = "2.0.0"
|
||||
alloy = "1.7.3"
|
||||
rcgen = { version = "0.14.7", features = [
|
||||
"aws_lc_rs",
|
||||
"pem",
|
||||
@@ -40,11 +40,11 @@ rcgen = { version = "0.14.7", features = [
|
||||
], default-features = false }
|
||||
k256 = { version = "0.13.4", features = ["ecdsa", "pkcs8"] }
|
||||
rsa = { version = "0.9", features = ["sha2"] }
|
||||
sha2 = "0.11"
|
||||
spki = "0.8"
|
||||
sha2 = "0.10"
|
||||
spki = "0.7"
|
||||
prost = "0.14.3"
|
||||
miette = { version = "7.6.0", features = ["fancy", "serde"] }
|
||||
mutants = "0.0.4"
|
||||
ml-dsa = { version = "0.1.0-rc.8", features = ["zeroize"] }
|
||||
base64 = "0.22.1"
|
||||
hmac = "0.13.0"
|
||||
hmac = "0.12.1"
|
||||
|
||||
@@ -21,6 +21,6 @@ tokio.workspace = true
|
||||
tokio-stream.workspace = true
|
||||
thiserror.workspace = true
|
||||
http = "1.4.0"
|
||||
rustls-webpki = { version = "0.103.12", features = ["aws-lc-rs"] }
|
||||
rustls-webpki = { version = "0.103.10", features = ["aws-lc-rs"] }
|
||||
async-trait.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
@@ -61,7 +61,7 @@ x25519-dalek.workspace = true
|
||||
k256.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.47.2"
|
||||
insta = "1.46.3"
|
||||
proptest = "1.11.0"
|
||||
rstest.workspace = true
|
||||
test-log = { version = "0.2", default-features = false, features = ["trace"] }
|
||||
|
||||
@@ -4,7 +4,7 @@ use diesel::{
|
||||
dsl::{insert_into, update},
|
||||
};
|
||||
use diesel_async::{AsyncConnection, RunQueryDsl};
|
||||
use hmac::{KeyInit as _, Mac as _};
|
||||
use hmac::Mac as _;
|
||||
use kameo::{Actor, Reply, messages};
|
||||
use strum::{EnumDiscriminants, IntoDiscriminant};
|
||||
use tracing::{error, info};
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:convert';
|
||||
import 'package:arbiter/features/connection/connection.dart';
|
||||
import 'package:arbiter/features/connection/server_info_storage.dart';
|
||||
import 'package:arbiter/features/identity/pk_manager.dart';
|
||||
import 'package:crypto/crypto.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';
|
||||
@@ -45,6 +46,18 @@ class ConnectionException implements Exception {
|
||||
String toString() => message;
|
||||
}
|
||||
|
||||
String certificateFingerprintHex(List<int> derBytes) {
|
||||
return sha256.convert(derBytes).toString();
|
||||
}
|
||||
|
||||
bool isPinnedServerCertificate({
|
||||
required String expectedFingerprint,
|
||||
required List<int> certificateDer,
|
||||
}) {
|
||||
return certificateFingerprintHex(certificateDer) ==
|
||||
expectedFingerprint.toLowerCase();
|
||||
}
|
||||
|
||||
Future<Connection> connectAndAuthorize(
|
||||
StoredServerInfo serverInfo,
|
||||
KeyHandle key, {
|
||||
@@ -155,7 +168,12 @@ Future<Connection> _connect(StoredServerInfo serverInfo) async {
|
||||
connectTimeout: const Duration(seconds: 10),
|
||||
credentials: ChannelCredentials.secure(
|
||||
onBadCertificate: (cert, host) {
|
||||
return true;
|
||||
final isExpectedHost = host == serverInfo.address;
|
||||
final isPinnedCert = isPinnedServerCertificate(
|
||||
expectedFingerprint: serverInfo.caCertFingerprint,
|
||||
certificateDer: cert.der,
|
||||
);
|
||||
return isExpectedHost && isPinnedCert;
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:arbiter/features/connection/auth.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('certificate pinning helpers', () {
|
||||
test('certificateFingerprintHex returns SHA-256 in hex', () {
|
||||
final fingerprint = certificateFingerprintHex('abc'.codeUnits);
|
||||
|
||||
expect(
|
||||
fingerprint,
|
||||
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
|
||||
);
|
||||
});
|
||||
|
||||
test('isPinnedServerCertificate matches expected fingerprint', () {
|
||||
final matches = isPinnedServerCertificate(
|
||||
expectedFingerprint:
|
||||
'BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD',
|
||||
certificateDer: 'abc'.codeUnits,
|
||||
);
|
||||
|
||||
expect(matches, isTrue);
|
||||
});
|
||||
|
||||
test('isPinnedServerCertificate rejects mismatched fingerprint', () {
|
||||
final matches = isPinnedServerCertificate(
|
||||
expectedFingerprint:
|
||||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||
certificateDer: 'abc'.codeUnits,
|
||||
);
|
||||
|
||||
expect(matches, isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user