My code is connecting to AWS-END-POINT properly but when I tried connecting to Greengrass core using local network ip. I get this error.
E/flutter (12349): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: HandshakeException: Handshake error in client (OS Error:
E/flutter (12349): CERTIFICATE_VERIFY_FAILED: Hostname mismatch(handshake.cc:352))
I have already checked the greengrass core. it's working fine. It is connecting to web client very well. I think there might be some issue of using ip address instead of URL address. but i am not sure. Can anyone help please?
The Code I am running is:
import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'dart:convert' show utf8;
import 'dart:convert';
Future<int> main() async {
const String url =
'192.168.8.106';
const int port = 8883;
const String clientId =
'MY CLIENT ID';
MqttClient client = MqttClient(url,clientId);
client.port = port;
client.secure = true;
final SecurityContext context = new SecurityContext(withTrustedRoots: true);
context.setTrustedCertificatesBytes(utf8.encode(' CERT '));
context.useCertificateChainBytes(utf8.encode(' CERT '));
context.usePrivateKeyBytes(utf8.encode(' PRIVEATE KEY '));
client.securityContext = context;
client.setProtocolV311();
// logging if you wish
client.logging(on: false);
print('Before Connecting');
try{
await client.connect();
}catch(e){
print('CATCH IS : ');
print (e);
}
print('After Connecting');
if (client.connectionStatus.state == MqttConnectionState.connected) {
print('iotcore client connected');
} else {
client.disconnect();
}
print('Sleeping....');
for (int i=1; i>0; i++)
{
const String topic = '\$aws/things/Pi_tmfacility_0_1/shadow/update';
Map<dynamic, dynamic> payload =
{'state': {
'desired': {
'number' : i
}
}
};
final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
builder.addString(json.encode(payload));
print('into the publish to get single device shadow ');
client.publishMessage(topic, MqttQos.atMostOnce, builder.payload);
print('Ready to Sleep');
await MqttUtilities.asyncSleep(10);
print('Loop no = $i');
}
print('Disconnecting');
client.disconnect();
return 0;
}
The problem is that the CN (or SANs) in the certificate presented by the local machine do not include 192.168.8.106
.
You can verify this by using the openssl s_client
command:
openssl s_client -connect 192.168.8.106:8883 -CAfile /path/to/ca/cert
This means that the SSL/TLS library in flutter will complain that certificate doesn't reliably represent that machine.
This is important as this is what stops Man-in-the-Middle attacks.
You have 2 options to solve this.
You have to be very careful if you go with option 2 to ensure that you do not open up too big a hole for Man-in-the-middle attacks.