I've run into a bit of a quandary. I'm writing a client/server application. The frontend is in Flutter and uses the Dio http package, the backend is Java. The backend REST API is secured via TLS certificate.
As many other questions have pointed out, Flutter doesn't seem to have access to the system CA Certificate store on all platforms. This is problematic because I intend to allow for self hosting of the server application, meaning certificates from all different CAs could be utilized server-side, so my HTTP client will need to support all of the CAs that a typical web browser supports.
Dio apparently allows you to set a trusted cert chain, but I'm wondering how best to leverage that.
Has anyone encountered this problem before. What solution did you implement to fix this?
These are the solutions I've thought of so far:
The other issue I came here about is that Dio appears to be ignoring my onBadCertificate method. I declared this inside a ConnectionManager, should I not do that?
Here is the code that is being ignored:
var dio = Dio()
  ..options.baseUrl = server
  ..interceptors.add(LogInterceptor())
  ..interceptors.add(CookieManager(cookieJar))
  ..httpClientAdapter = Http2Adapter(
    ConnectionManager(
      idleTimeout: 10000,
      // Ignore bad certificate
      onClientCreate: (_, config) => {
        //config.context?.setTrustedCertificatesBytes(File("/assets/certs/wildcard.pem").readAsBytesSync()),
        config.onBadCertificate = (_) => true, // <-- ignored, should bypass check
      }
    ),
  );
EDIT:
As mentioned in the comments, Flutter was in fact capable of using the system CA Certificate store. As I test other platforms, I'll update if I run into any problems with certificates. But this one is solved!
Actual on March 2024:
 callback is deprecated. Now you should use onHttpClientCreatecreateHttpClient and return your own HttpClient instance:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
Dio createDio({required String baseUrl, bool trustSelfSigned = false}) {
  // initialize dio
  final dio = Dio()
    ..options.baseUrl = baseUrl;
  // allow self-signed certificate
  (dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () {
    final client = HttpClient();
    client.badCertificateCallback = (cert, host, port) => trustSelfSigned;
    return client;
  };
  
  return dio;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With