-
-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Outdated Basic_AWS example #2511
Comments
@Asanga-Viraj Isn't this sample working for you? In it you can see how to attach SSL certificates: https://github.com/SmingHub/Sming/blob/develop/samples/Basic_AWS/app/application.cpp#L21-L24 In addition if you want to syncrhonise the local clock you can use the NTP sample as a starting point. |
@slaff I couldn't manage to work Basic_AWS example with the current MQTT AWS IoT Core. To connect to AWS, we need to assign a device certificate, private key, and Root CA1 certificate. But there is no entry to assign the Root CA1 certificate. Refer this Arduino example. it is working with AWS. I forgot to tell you that the message "please start sntp first !" only appears on ESP8266. Not in ESP32. I will test with NTP sample. Thank you for that. |
Short StoryThe Amazon Root CA1 certificate is not used in the sample because we skip SERVER CERTIFICATE verification. We should probably update it to include full SERVER CERTIFICATE verification. Long StoryOk, even with over-simplifications, this is probably going to be a long answer but once you read this you should know better
How TLS/SSL communication worksHere we are focusing only on the communication from our device, the client, to the remote AWS cloud, the server. When a client connects to a remote server using TLS it does many things. Some of the important ones are:
Let's start with A). What happens here is the following:
Let's focus on the B). In order to trust the remote side the client could/should verify the SERVER CERTIFICATE. The fact that the communication is encrypted does not prevent the client from talking to a malicious server pretending to be a valid AWS server. The SERVER CERTIFICATE verification does. A full verification is expensive, especially for embedded devices like ESP8266. A full verification requires the expiration date of the SERVER CERTIFICATE to be checked. For this your device will need a VALID TIME. Getting the current time will require another network call to an NTP server which additionally increases the time and resource needed. If your device is not time critical and not running on a battery then fine. If you want to go this route then make sure to replace the code below: mqtt.setSslInitHandler([](Ssl::Session& session) {
session.options.verifyLater = true;
session.keyCert.assign(privateKeyData, certificateData);
}); with mqtt.setSslInitHandler([](Ssl::Session& session) {
session.options.verifyLater = false; // Do expensive certificate validation!
session.keyCert.assign(privateKeyData, certificateData);
}); Now in order to fully verify a certificate a lot of steps need to be done. Not only the expiration date, hostname in the certificate matching the one one used BUT also its signature. My bold guess is that the SERVER CERTIFICATE is signed using the Amazon Root CA1 certificate. This way the client can verify with high certainty if the SERVER CERTIFICATE is the one that is expected. And thus trust the remote server to be the one that it pretends to be. A slightly less secure but much faster way is to verify the provided SERVER CERTIFICATE against its SHA1 or SHA256 finger-prints. Basically the content of the certificate is used to feed a SHA1/SHA256 hash function and compared against expected finger-print. Of course even small changes in the SERVER CERTIFICATE will cause our fingerprinting check to fail. Slightly less error-prone and a bit slower is to extract the public key from the SERVER CERTIFICATE and compare its SHA1/SHA256 hash against expected ones. Our Basic_SSL example explains how to set such fingerprint checks: Sming/samples/Basic_Ssl/app/application.cpp Lines 78 to 100 in da1ff08
In our Basic_AWS example we DON'T do full SERVER CERTIFICATE verification this is why you don't see it used.
Basic_AWS is not using any server certificate validators and this is the reason why you see this message. You can either set finger-print validators or even set a callback validator where the received SERVER CERTIFICATE is provided to the validator and in your application you can do all needed manual validations. In the example the client provides its CLIENT CERTIFICATE and private key. mqtt.setSslInitHandler([](Ssl::Session& session) {
session.options.verifyLater = true;
session.keyCert.assign(privateKeyData, certificateData);
}); The CLIENT CERTIFICATE is sent to AWS and used by the remote server to check if it was issued by them. This way our client is ALLOWED to communicate further with the AWS servers. The private key is used from our client to encrypt the communication. AWS generates the private key, then the CLIENT CERTIFICATE and allows you to download the private key. (We assume that) AWS itself does not keep your private key. The CLIENT CERTIFICATE helps the remote server to verify if our client is valid and also to communicate in a secure manner. How to debug network communication in SmingIf you are using Windows or Linux the fastest way to debug the network communication is to compile the example using the Host architecture. For example you go to the root folder of the Basic_AWS sample and type:
In addition to this since the sample application will be running on your local machine you should be able to sniff the network communication using Wireshark.
As I wrote before, connecting will require A1) and A2). A successful A1) looks like this:
If error is 0 you are connected via TCP. A successful A2) looks like this:
There is communication with the remote server, data is sent and all looks good. This is all you need to know. Now try to compile your application with DEBUG_VERBOSE_LEVEL=3 and paste the output here. |
Thank you for the full detail information. Extremely sorry for my lack of knowledge about TSL/SSL communication. Now I have the idea about how root certificate authority (RootCA1) file works. So, nothing wrong about setSslInitHandler(). I tried to work with Basic_AWS example on ESP32. Then I got this with DEBUG_VERBOSE_LEVEL=3
At the end, TCP connection is disconnected. The I commented mqtt subscribes and publishes.
After, I tried this on ESP32 and got this.
Connection is stablished and didn't disconnect. We can see ping data packet after each 10 seconds. Then, I put a timer to call publish message after 10 seconds. ESP published messages successfully. Debug output is below.
It keeps publishing data into AWS without disconnecting. After 10 seconds I tried this
Things I saw
These are the things I found. |
@slaff
I am working on connecting ESP into MQTT AWS IoT Core. I couldn't' connect it because it shows a debug message "please start sntp first !". I went deep and I saw "sntp_init()" included in "configTime" is not called any where.
Then, I called below lines on gotIP function.
sntp_stop();
sntp_setservername(0, (char*)"pool.ntp.org");
sntp_setservername(1, (char*)"0.au.pool.ntp.org");
sntp_set_timezone(10); // GTM+10
sntp_init();
Now, message "please start sntp first !" is gone and got "SSL Validator: list empty, allow connection". Can you help me with this?
Thanks.
The text was updated successfully, but these errors were encountered: