Skip to content

Commit

Permalink
Add Initial Certificate Override Support
Browse files Browse the repository at this point in the history
Backend work to provide certificate override functionality added. User Interface to manage history and provide context should be added. Clarification of when new certs for a domain (if not valid) are added versus never having been approved should be noted to the user. Allow them to reject if the remote end has changed (or is behind a load-balancer with multiple certs/ports...)

Signed-off-by: Odin Vex <44311901+OdinVex@users.noreply.github.com>
  • Loading branch information
OdinVex committed Oct 22, 2023
1 parent 56942bc commit 3aaad80
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1 deletion.
15 changes: 15 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';

Expand Down Expand Up @@ -50,7 +51,21 @@ import 'services/music_player_background_task.dart';
import 'models/jellyfin_models.dart';
import 'models/finamp_models.dart';

// https://stackoverflow.com/questions/68450768/flutter-chopper-allow-self-signed-certificate-for-use
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback = isCertificateOverridden;
}

bool isCertificateOverridden(X509Certificate cert, String host, int port) {
return FinampSettingsHelper.hasCertificateOverride(host, port, cert.sha1);
}
}

void main() async {
HttpOverrides.global = MyHttpOverrides();
// If the app has failed, this is set to true. If true, we don't attempt to run the main app since the error app has started.
bool hasFailed = false;
try {
Expand Down
7 changes: 7 additions & 0 deletions lib/models/finamp_models.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:collection';
import 'dart:io';

import 'package:flutter/material.dart';
Expand Down Expand Up @@ -88,6 +89,7 @@ class FinampSettings {
this.tabOrder = _tabOrder,
this.hasCompletedBlurhashImageMigration = true,
this.hasCompletedBlurhashImageMigrationIdFix = true,
required this.overriddenCertificates,
});

@HiveField(0)
Expand Down Expand Up @@ -180,6 +182,9 @@ class FinampSettings {
@HiveField(24, defaultValue: false)
bool hasCompletedBlurhashImageMigrationIdFix;

@HiveField(25, defaultValue: {})
Map<String, Set<String>> overriddenCertificates;

static Future<FinampSettings> create() async {
final internalSongDir = await getInternalSongDir();
final downloadLocation = DownloadLocation.create(
Expand All @@ -188,6 +193,7 @@ class FinampSettings {
useHumanReadableNames: false,
deletable: false,
);
final overriddenCertificates = {};
return FinampSettings(
downloadLocations: [],
// Create a map of TabContentType from TabContentType's values.
Expand All @@ -199,6 +205,7 @@ class FinampSettings {
downloadLocationsMap: {downloadLocation.id: downloadLocation},
tabSortBy: {},
tabSortOrder: {},
overriddenCertificates: {},
);
}

Expand Down
7 changes: 6 additions & 1 deletion lib/models/finamp_models.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions lib/services/finamp_settings_helper.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import 'dart:collection';
import 'dart:convert';

import 'package:convert/convert.dart';
import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';

Expand Down Expand Up @@ -224,4 +228,50 @@ class FinampSettingsHelper {
),
);
}

static void addCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
if (!finampSettingsTemp.overriddenCertificates.containsKey("$host:$port")) {
finampSettingsTemp.overriddenCertificates.addAll({
"$host:$port": {thumbprintHex}
});
} else {
finampSettingsTemp.overriddenCertificates["$host:$port"]
?.add(thumbprintHex);
}
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}

static void deleteCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
finampSettingsTemp.overriddenCertificates["$host:$port"]
?.remove(thumbprintHex);
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}

static bool hasCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
if (!finampSettingsTemp.overriddenCertificates.containsKey("$host:port")) {
return false;
} else if (!finampSettingsTemp.overriddenCertificates["$host:port"]!
.contains(thumbprintHex)) {
return false;
}
return true;
}

static void resetCertificateOverrides() {
FinampSettings finampSettingsTemp = finampSettings;
finampSettingsTemp.overriddenCertificates.clear();
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}
}

0 comments on commit 3aaad80

Please sign in to comment.