public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate
@ 2025-09-04 10:09 Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/1] fix: android: add network config to support custom certificates Shan Shaji
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Shan Shaji @ 2025-09-04 10:09 UTC (permalink / raw)
  To: pve-devel

The app was not honoring the user installed certificate and was still
throwing `HandShakeException` when using `IOClient`. Inorder to fix the
issue used the `cronet_http` package. This patch series only includes
the changes specific to android.  

changes since v1: https://lore.proxmox.com/pve-devel/DCJ4ONVHUS1B.2PR9TS3ZF3OE4@proxmox.com/T/#t
- Update the commit message with more details and links
- fixed package name not correct in the commit message. 

pve_flutter_frontend:

Shan Shaji (1):
  fix: android: add network config to support custom certificates

 android/app/src/main/AndroidManifest.xml                 | 3 ++-
 android/app/src/main/res/xml/network_security_config.xml | 9 +++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 android/app/src/main/res/xml/network_security_config.xml


proxmox_dart_api_client:

Shan Shaji (2):
  fix: android: use `cronet_http` package to honor custom certificates
  fix: add explicit throw of `HandShakeException`

 lib/src/authenticate.dart | 31 ++++++++++----
 lib/src/utils_native.dart | 12 ++++++
 pubspec.lock              | 89 ++++++++++++++++++++++++++++++++++++---
 pubspec.yaml              |  1 +
 4 files changed, 117 insertions(+), 16 deletions(-)


Summary over all repositories:
  6 files changed, 128 insertions(+), 17 deletions(-)

-- 
Generated by git-murpp 0.8.1


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH pve_flutter_frontend v2 1/1] fix: android: add network config to support custom certificates
  2025-09-04 10:09 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Shan Shaji
@ 2025-09-04 10:09 ` Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/2] fix: android: use `cronet_http` package to honor " Shan Shaji
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Shan Shaji @ 2025-09-04 10:09 UTC (permalink / raw)
  To: pve-devel

Apps targeting Android 6 (API level 23) and lower trust the user added
CA store by default. However, apps targeting > API level 23 need to
explicity mention trust anchor in the security configuration [0] to
trust user installed certificates.

[0] - https://developer.android.com/privacy-and-security/security-config#manifest

References:
- https://developer.android.com/privacy-and-security/security-config#CustomTrust
- https://developer.android.com/privacy-and-security/security-config#ConfigInheritance
- https://developer.android.com/privacy-and-security/security-config#trust-anchors
- https://developer.android.com/privacy-and-security/security-config#certificates

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 android/app/src/main/AndroidManifest.xml                 | 3 ++-
 android/app/src/main/res/xml/network_security_config.xml | 9 +++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 android/app/src/main/res/xml/network_security_config.xml

diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b699752..66135eb 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -5,7 +5,8 @@
 
     <application
         android:label="Proxmox Virtual Environment"
-        android:icon="@mipmap/ic_launcher">
+        android:icon="@mipmap/ic_launcher"
+        android:networkSecurityConfig="@xml/network_security_config">
 
         <activity
             android:name="com.proxmox.app.pve_flutter_frontend.MainActivity"
diff --git a/android/app/src/main/res/xml/network_security_config.xml b/android/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..37a8e3f
--- /dev/null
+++ b/android/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config>
+        <trust-anchors>
+            <certificates src="system"/>
+            <certificates src="user"/>
+        </trust-anchors>
+    </base-config>
+</network-security-config>
\ No newline at end of file
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH proxmox_dart_api_client v2 1/2] fix: android: use `cronet_http` package to honor custom certificates
  2025-09-04 10:09 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/1] fix: android: add network config to support custom certificates Shan Shaji
@ 2025-09-04 10:09 ` Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 2/2] fix: add explicit throw of `HandShakeException` Shan Shaji
  2025-09-05  8:43 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Michael Köppl
  3 siblings, 0 replies; 5+ messages in thread
From: Shan Shaji @ 2025-09-04 10:09 UTC (permalink / raw)
  To: pve-devel

In android when a user installs a custom certificate the app was not
honoring the installed certificate and was still throwing
`HandShakeException`.

The issue is because the `IOClient` doesn't by default honor user
installed certificate [0].

To fix the issue, used the `cronet_http` [1] package which will honor
the user installed certificates. Used the standalone embedded
library [2] of cronet inorder to avoid the dependency on
Google Play Services.

[0] - https://github.com/dart-lang/sdk/issues/50435
[1] - https://pub.dev/packages/cronet_http
[2] - https://pub.dev/packages/cronet_http#use-embedded-cronet

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
changes since v1:
- Update commit message with more details and links. 
- Fixed wrong package name in the commit message. 
 
lib/src/utils_native.dart | 12 ++++++
 pubspec.lock              | 89 ++++++++++++++++++++++++++++++++++++---
 pubspec.yaml              |  1 +
 3 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/lib/src/utils_native.dart b/lib/src/utils_native.dart
index 2ece3a3..a4b7397 100644
--- a/lib/src/utils_native.dart
+++ b/lib/src/utils_native.dart
@@ -1,3 +1,4 @@
+import 'package:cronet_http/cronet_http.dart';
 import 'package:http/http.dart' as http;
 import 'package:http/io_client.dart' as http_io;
 import 'dart:io';
@@ -5,6 +6,17 @@ import 'dart:io';
 http.Client getCustomIOHttpClient({bool validateSSL = true}) {
   var ioClient = HttpClient();
 
+  if (Platform.isAndroid && validateSSL) {
+    final engine = CronetEngine.build(
+      cacheMaxSize: 1024 * 1024,
+      cacheMode: CacheMode.memory,
+    );
+    return CronetClient.fromCronetEngine(
+      engine,
+      closeEngine: true,
+    );
+  }
+
   if (!validateSSL) {
     ioClient.badCertificateCallback =
         ((X509Certificate cert, String host, int port) {
diff --git a/pubspec.lock b/pubspec.lock
index 857f2bc..6496e27 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -113,6 +113,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "8.9.2"
+  characters:
+    dependency: transitive
+    description:
+      name: characters
+      sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.4.0"
   checked_yaml:
     dependency: transitive
     description:
@@ -133,10 +141,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+      sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
       url: "https://pub.dev"
     source: hosted
-    version: "1.18.0"
+    version: "1.19.1"
   convert:
     dependency: transitive
     description:
@@ -153,6 +161,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.7.2"
+  cronet_http:
+    dependency: "direct main"
+    description:
+      name: cronet_http
+      sha256: "1b99ad5ae81aa9d2f12900e5f17d3681f3828629bb7f7fe7ad88076a34209840"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.5.0"
   crypto:
     dependency: transitive
     description:
@@ -169,6 +185,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.3.6"
+  ffi:
+    dependency: transitive
+    description:
+      name: ffi
+      sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.4"
   file:
     dependency: transitive
     description:
@@ -185,6 +209,11 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.1.0"
+  flutter:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
   frontend_server_client:
     dependency: transitive
     description:
@@ -213,10 +242,10 @@ packages:
     dependency: "direct main"
     description:
       name: http
-      sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+      sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.1"
+    version: "1.5.0"
   http_multi_server:
     dependency: transitive
     description:
@@ -233,6 +262,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "4.0.2"
+  http_profile:
+    dependency: transitive
+    description:
+      name: http_profile
+      sha256: "7e679e355b09aaee2ab5010915c932cce3f2d1c11c3b2dc177891687014ffa78"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.1.0"
   io:
     dependency: transitive
     description:
@@ -241,6 +278,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.4"
+  jni:
+    dependency: transitive
+    description:
+      name: jni
+      sha256: d2c361082d554d4593c3012e26f6b188f902acd291330f13d6427641a92b3da1
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.14.2"
   js:
     dependency: transitive
     description:
@@ -281,14 +326,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.12.16+1"
+  material_color_utilities:
+    dependency: transitive
+    description:
+      name: material_color_utilities
+      sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.11.1"
   meta:
     dependency: transitive
     description:
       name: meta
-      sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b"
+      sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
       url: "https://pub.dev"
     source: hosted
-    version: "1.14.0"
+    version: "1.16.0"
   mime:
     dependency: transitive
     description:
@@ -321,6 +374,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.9.0"
+  plugin_platform_interface:
+    dependency: transitive
+    description:
+      name: plugin_platform_interface
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.8"
   pool:
     dependency: transitive
     description:
@@ -385,6 +446,11 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.4"
+  sky_engine:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
   source_gen:
     dependency: transitive
     description:
@@ -497,6 +563,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.2"
+  vector_math:
+    dependency: transitive
+    description:
+      name: vector_math
+      sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.4"
   vm_service:
     dependency: transitive
     description:
@@ -546,4 +620,5 @@ packages:
     source: hosted
     version: "3.1.2"
 sdks:
-  dart: ">=3.3.0 <4.0.0"
+  dart: ">=3.7.0 <4.0.0"
+  flutter: ">=3.22.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 7b61edc..3aa881b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,6 +10,7 @@ dependencies:
   built_value: ^8.4.2
   built_collection: ^5.1.1
   retry: ^3.1.0
+  cronet_http: ^1.5.0
 
 dev_dependencies:
   lints: ^3.0.0
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pve-devel] [PATCH proxmox_dart_api_client v2 2/2] fix: add explicit throw of `HandShakeException`
  2025-09-04 10:09 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/1] fix: android: add network config to support custom certificates Shan Shaji
  2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/2] fix: android: use `cronet_http` package to honor " Shan Shaji
@ 2025-09-04 10:09 ` Shan Shaji
  2025-09-05  8:43 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Michael Köppl
  3 siblings, 0 replies; 5+ messages in thread
From: Shan Shaji @ 2025-09-04 10:09 UTC (permalink / raw)
  To: pve-devel

The `cronet_http` is throwing `ClientException` [0] instead of
`HandShakeException` when the certificate is not valid.

Due to this the exception was directly shown in the UI. Inorder to make
the error more user friendly catch the `ClientException` and rethrow
`HandShakeException` if the certificate is not valid.

[0] - https://github.com/dart-lang/http/blob/ef05b3744424885d93f88a6a50664fb5b7d5cbdb/pkgs/cronet_http/lib/src/cronet_client.dart#L327

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 lib/src/authenticate.dart | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/lib/src/authenticate.dart b/lib/src/authenticate.dart
index 118408f..a142a4c 100644
--- a/lib/src/authenticate.dart
+++ b/lib/src/authenticate.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'dart:convert';
+import 'dart:io';
 
 import 'package:http/http.dart' as http;
 import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart';
@@ -56,6 +57,11 @@ Future<ProxmoxApiClient> authenticate(
   } on TimeoutException catch (_) {
     throw ProxmoxApiException(
         'Authentication takes unusually long, check network connection', 408);
+  } on http.ClientException catch (e) {
+    if (e.message.contains('net::ERR_CERT_AUTHORITY_INVALID')) {
+      throw HandshakeException(e.message);
+    }
+    rethrow;
   }
 }
 
@@ -64,14 +70,21 @@ Future<List<PveAccessDomainModel?>> accessDomains(
   bool validateSSL, {
   http.Client? httpClient,
 }) async {
-  httpClient ??= getCustomIOHttpClient(validateSSL: validateSSL);
+  try {
+    httpClient ??= getCustomIOHttpClient(validateSSL: validateSSL);
 
-  final path = '/api2/json/access/domains';
-  final response = await httpClient
-      .get(apiBaseUrl.replace(path: path))
-      .timeout(Duration(seconds: 25));
-  var data = (json.decode(response.body)['data'] as List).map((f) {
-    return serializers.deserializeWith(PveAccessDomainModel.serializer, f);
-  });
-  return data.toList();
+    final path = '/api2/json/access/domains';
+    final response = await httpClient
+        .get(apiBaseUrl.replace(path: path))
+        .timeout(Duration(seconds: 25));
+    var data = (json.decode(response.body)['data'] as List).map((f) {
+      return serializers.deserializeWith(PveAccessDomainModel.serializer, f);
+    });
+    return data.toList();
+  } on http.ClientException catch (e) {
+    if (e.message.contains('net::ERR_CERT_AUTHORITY_INVALID')) {
+      throw HandshakeException(e.message);
+    }
+    rethrow;
+  }
 }
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate
  2025-09-04 10:09 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Shan Shaji
                   ` (2 preceding siblings ...)
  2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 2/2] fix: add explicit throw of `HandShakeException` Shan Shaji
@ 2025-09-05  8:43 ` Michael Köppl
  3 siblings, 0 replies; 5+ messages in thread
From: Michael Köppl @ 2025-09-05  8:43 UTC (permalink / raw)
  To: Proxmox VE development discussion; +Cc: pve-devel

Since the v2 of this series features only minor changes to the commit
messages that I suggested in my review of v1, please consider this:

Reviewed-by: Michael Köppl <m.koeppl@proxmox.com>
Tested-by: Michael Köppl <m.koeppl@proxmox.com>

On Thu Sep 4, 2025 at 12:09 PM CEST, Shan Shaji wrote:
> The app was not honoring the user installed certificate and was still
> throwing `HandShakeException` when using `IOClient`. Inorder to fix the
> issue used the `cronet_http` package. This patch series only includes
> the changes specific to android.  
>
> changes since v1: https://lore.proxmox.com/pve-devel/DCJ4ONVHUS1B.2PR9TS3ZF3OE4@proxmox.com/T/#t
> - Update the commit message with more details and links
> - fixed package name not correct in the commit message. 
>
> pve_flutter_frontend:
>
> Shan Shaji (1):
>   fix: android: add network config to support custom certificates
>
>  android/app/src/main/AndroidManifest.xml                 | 3 ++-
>  android/app/src/main/res/xml/network_security_config.xml | 9 +++++++++
>  2 files changed, 11 insertions(+), 1 deletion(-)
>  create mode 100644 android/app/src/main/res/xml/network_security_config.xml
>
>
> proxmox_dart_api_client:
>
> Shan Shaji (2):
>   fix: android: use `cronet_http` package to honor custom certificates
>   fix: add explicit throw of `HandShakeException`
>
>  lib/src/authenticate.dart | 31 ++++++++++----
>  lib/src/utils_native.dart | 12 ++++++
>  pubspec.lock              | 89 ++++++++++++++++++++++++++++++++++++---
>  pubspec.yaml              |  1 +
>  4 files changed, 117 insertions(+), 16 deletions(-)
>
>
> Summary over all repositories:
>   6 files changed, 128 insertions(+), 17 deletions(-)



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-09-05  8:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-04 10:09 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Shan Shaji
2025-09-04 10:09 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/1] fix: android: add network config to support custom certificates Shan Shaji
2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/2] fix: android: use `cronet_http` package to honor " Shan Shaji
2025-09-04 10:09 ` [pve-devel] [PATCH proxmox_dart_api_client v2 2/2] fix: add explicit throw of `HandShakeException` Shan Shaji
2025-09-05  8:43 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: android: add support to honor user installed certificate Michael Köppl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal