Search code examples
fluttercertificatemqtt

Flutter won't load certificate from assets


I've been trying to get this resolved for the past 3 hours to no avail. I have written a code on flutter that is supposed to connect with a MQTT server, but unfortunately I am stuck at loading the certificate. Below is my code for loading the ceritficates using rootBundle.load(). But unfortunately no matter what i've tried I get an error. (Error at bottom of page)

  _MyHomePageState() {

Future<SecurityContext> loadSecurityContext() async {
  // Load the CA certificate
  final ByteData caByteData = await rootBundle.load('certs/ca.crt');
  final caCrt = String.fromCharCodes(caByteData.buffer.asUint8List());

  // Load the client certificate
  final ByteData clientByteData = await rootBundle.load('certs/mosquitto.crt');
  final clientCrt = String.fromCharCodes(clientByteData.buffer.asUint8List());

  // Load the client private key
  final ByteData keyByteData = await rootBundle.load('certs/mosquitto.key');
  final keyBytes = keyByteData.buffer.asUint8List();


  // Create the security context
  final context = SecurityContext.defaultContext;
  context.setTrustedCertificatesBytes(caCrt.codeUnits);
  context.useCertificateChainBytes(clientCrt.codeUnits);
  context.usePrivateKeyBytes(keyBytes, password: keyPassword);

  // Set the security context for the MQTT client
  return context;
}

loadSecurityContext().then((securityContext) {
  final mqttServer = "REDACTED";
  client = MqttServerClient.withPort(mqttServer, "flutter_client", mqttPort);
  client.secure = true;
  client.securityContext = securityContext;
  client.onConnected = onConnected;
  client.onDisconnected = onDisconnected;
  client.onSubscribed = onSubscribed;
  client.logging(on: true);

  subscription = client.updates!.listen((List<MqttReceivedMessage<MqttMessage>> messages) {
    final MqttPublishMessage receivedMessage = messages[0].payload as MqttPublishMessage;
    final String message = MqttPublishPayload.bytesToStringAsString(receivedMessage.payload.message);

    setState(() {
      _receivedMessage = message;
    });
  });

  client.connect();
});

}

Syncing files to device Android SDK built for x86...
E/flutter ( 6814): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Unable to load asset: certs/ca.crt
E/flutter ( 6814): #0      PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:224:7)
E/flutter ( 6814): <asynchronous suspension>
E/flutter ( 6814): #1      new _MyHomePageState.loadSecurityContext (package:mars2/main.dart:54:35)
E/flutter ( 6814): <asynchronous suspension>
E/flutter ( 6814): 

I do not know what to do. This is my pubspec yaml.

assets:
  - assets/certificates/
  - certs/

My certificates are in the root folder of the project in a 'certs' folder. They were previously in an assets folder but i moved them around trying to see if that solves the issue. enter image description here

YAML : https://goonlinetools.com/snapshot/code/#wdd6ag2rklawf6gwp8kyy enter image description here


Solution

  • Your assets section is in the wrong place. Please review the instructions.

    You need to be under the flutter: section, correctly indented:

    flutter:
      assets:
        - assets/certificates/
        - certs/
    

    Also, simplify (and correct) you code by removing all the codeUnits stuff. You should find this works:

      final ByteData caByteData = await rootBundle.load('certs/ca.crt');
      final caCrt = caByteData.buffer.asUint8List();
      context.setTrustedCertificatesBytes(caCrt);