vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.91k stars 708 forks source link

SIM7600 SSL support 🤯 #767

Open ghost opened 5 months ago

ghost commented 5 months ago

What

Native SSL support for the SIM7600. Use in the same way you would for 7080:

#define TINY_GSM_MODEM_SIM7600
TinyGsm modem(SerialAT);
TinyGsmClientSecure client(modem, 0);  // be sure to only use mux 0 or 1, it's all the chip allows!
HttpClient http(client, SERVER, PORT);

In your runtime code, before making any requests, you may need to add

        client.setCertificate(AWS_CERT_CA);  // e.g. static const char AWS_CERT_CA[] PROGMEM = R"EOF(BEGIN CERTIFICATE-----...

You DO NOT! need any additional SSL libraries for this code to work!

Tested On

Known/Suspected Bugs

Lextan276 commented 5 months ago

Hello @Matt-Stedman-HardStuff, @Matt-Stedman It's a great job. Can you share your custom code for OTA AWS S3?

Matt-Stedman commented 5 months ago

@Lextan276 I've drafted an example here: https://github.com/Hard-Stuff/EXAMPLES-SIMCOM_OTA Hopefully it's clear enough for ya, let me know if you have any questions

floBik commented 5 months ago

Hi @Matt-Stedman

I was also working on implementing ssl support for the SIM7600. Are you aware that your added certificates have no effect on the connection? You need to enable authentication with the following AT command AT+CSSLCFG="authmode",0,1 otherwise the server will not be verified. Unfortunately this causes some problems with the connection, at the moment I have not been able to solve them, I am working on it.

ghost commented 5 months ago

@floBik you're absolutely right! I actually got it working on HTTPS but without the certs, or something, but yeah it needed authmode to connect to certain servers including AWS.

There's another branch I've got where I was trying to get MQTTS working over UDP as in the unsecure mode, but I'm still struggling to get that part working. But, in that branch I DO have the authmode and I think that addresses your thought.

I've switched this MR to a draft and when I'm back from travelling I'll test the MQTTS functionality again, and either way I'll adjust the MR accordingly. If you want to use my MQTTS branch as a base and figure out why it's not working then it saves us from having to implement the SIMCOM MQTTS AT functions.

floBik commented 4 months ago

Hello @Matt-Stedman-HardStuff ,

After some time I got the authentication working. I tested the CA authentication and also the client authentication successfully. For me it also works for MQTT with SSL while using the PubSubClient library.

I have opened a pull request in your branch for my solution. If you have any questions or so feel free to message me.

floBik commented 4 months ago

An additional note: some servers require a Server Name Indication (SNI), which is not currently supported by my Solution. This is because the SIM7600 only supports this feature from firmware version 2.0 ? earlier versions do not seem to be able to provide the SNI. If you want to use it and your firmware is able to do so, you need to enable it with the following AT command: AT+CSSLCFG=”enableSNI”,<ssl_ctx_index>,1

ghost commented 4 months ago

@floBik Just confirmed your code works for both MQTTS and HTTPS. Currently works with AWS, doesn't work with Airtable HTTP (but I've consistently had issues with this even on WiFi), so I'm giving it a 👍 on my end!

Thanks for the help, and nice work!

live-alchemy commented 2 months ago

@vshymanskyy @SRGDamia1 kindly requesting you to take a look at this PR if you've a moment! would unblock our team :D

for others coming here, I was able to get a working HTTP client with SSL over LTE and Wifi by using this SSLClient library

Matt-Stedman commented 2 months ago

Hi all,

I'm Matt (Ghost, above! Just been combining my GitHub accounts).

I can confirm I've been using this PR for a few months now and @floBik you did an excellent job, works perfectly! Yes, I think @vshymanskyy and @SRGDamia1 should look to test and if they're happy merge this, as it's now also a forked dependency on a few internal and public libraries I manage, which is a bit of a blocker!

@live-alchemy, if you're using platformio or similar you can temporarily make your dependency git@github.com:Hard-Stuff/TinyGSM.git. My very rudimentary testing suggests that using the SIMCOM built-in SSL is about twice as fast as trying to do SSL encryption on the ESP32/MCU first!

BenUniqcode commented 2 months ago

Thanks for this PR, it looks useful. However I've run into an issue which I think is a bug in this change:

   bool modemGetConnected(uint8_t mux) {
     // Read the status of all sockets at once
-    sendAT(GF("+CIPCLOSE?"));
-    if (waitResponse(GF("+CIPCLOSE:")) != 1) {
+    sendAT(GF("+CIPOPEN?"));
+    if (waitResponse(GF("+CIPOPEN:")) != 1) {
       // return false;  // TODO:  Why does this not read correctly?
     }
     for (int muxNo = 0; muxNo < TINY_GSM_MUX_COUNT; muxNo++) {
-      // +CIPCLOSE:<link0_state>,<link1_state>,...,<link9_state>
-      bool muxState = stream.parseInt();
-      if (sockets[muxNo]) { sockets[muxNo]->sock_connected = muxState; }
+      // +CIPOPEN:<mux>,<State or blank...>
+      String state = stream.readStringUntil('\n');
+      if (state.indexOf(',') > 0) { sockets[muxNo]->sock_connected = true; }
+      waitResponse(GF("+CIPOPEN:"));
     }
     waitResponse();  // Should be an OK at the end
     if (!sockets[mux]) return false;

Anyway, what happens is that you are doing one too many waitResponses for "+CIPOPEN". So the last one will always timeout, and it will also capture the "OK", so the following waitResponse() that is looking for that will also time out. This creates a significant delay every time modemGetConnected() is called - which is a lot. Before I added your PR, my connection and sending a few (non-SSL) MQTT messages would take about 7 seconds; with this bug it takes more like 60 seconds!

Why did you change it from CIPCLOSE? That presents all the information that modemGetConnected() requires in a more compact form, and seems to work fine.