Jump to content
Marc

CC3200 & SSL

Recommended Posts

Hi there,

 

Really excited to see the new release of Energia supporting the CC3200 launchpad! I just ordered some for myself.

 

Does anyone know if there are plans to include the SSL demo for the CC3200 in Energia?

 

Thank you!

Share this post


Link to post
Share on other sites

I got basic outbound SSL sockets working.  Wasn't that hard, although the File Writing process for uploading a root CA certificate doesn't seem to work so I axed it...

 

Replace your energia-0101E0013/hardware/cc3200/libraries/WiFi/WiFiClient.cpp and WiFiClient.h files with these:

https://raw.githubusercontent.com/energia/Energia/issue_472/hardware/cc3200/libraries/WiFi/WiFiClient.cpp

and

https://raw.githubusercontent.com/energia/Energia/issue_472/hardware/cc3200/libraries/WiFi/WiFiClient.h

 

Syntax is just .sslConnect(hostname, port) or .sslConnect(IPAddress, port).

 

Example sketch:

#include <WiFiUdp.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>

const char ssid[] = "myWifiSSID";
const char wifipw[] = "blahblahblah";

void setup()
{
  uint32_t msave;
  
  Serial.begin(115200);
  
  delay(2000);
  Serial.println("WiFi:");

  WiFi.begin((char *)ssid, (char *)wifipw);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(150);
  }
  Serial.println();
  
  Serial.println("Connected- waiting for IP");
  msave = millis();
  while (WiFi.localIP() == INADDR_NONE) {
    Serial.print('.');
    delay(150);
    if (millis()-msave > 5000) {
      Serial.println("Timeout waiting for IP; disconnecting & reconnecting.");
      WiFi.disconnect();
      WiFi.begin((char*)ssid);
      msave = millis();
    }
  }
  Serial.print(" done; IP=");
  IPAddress my_ip = WiFi.localIP();
  Serial.println(my_ip);
}

void loop()
{
  char buf[1025];
  int i;
  size_t total = 0;
  WiFiClient http;

  Serial.println("Attempting HTTPS request-");
  if (http.sslConnect("www.ti.com", 443)) {
    Serial.println("Connected to www.ti.com- submitting GET / HTTP/1.0 request");
    http.print("GET / HTTP/1.0\r\nHost: www.ti.com\r\n\r\n");
    Serial.println("Waiting for response...");
    while (http.connected()) {
      while (!http.available()) delay(50);
      i = http.read((uint8_t *)buf, 1024);
      buf[i] = '\0';
      
      total += i;
      //Serial.print(buf);
    }
    Serial.println("Disconnected by remote host.");
    Serial.print(total); Serial.println(" bytes read in total.");
    delay(100000000);
  } else {
    Serial.println("Error connecting to www.ti.com");
  }
}

Output from serial monitor:

WiFi:
..
Connected- waiting for IP
............... done; IP=192.168.0.195
Attempting HTTPS request-
Connected to www.ti.com- submitting GET / HTTP/1.0 request
Waiting for response...
Disconnected by remote host.
87527 bytes read in total.

Share this post


Link to post
Share on other sites

Ok, the links up above now have a new commit - SSL root CA support.

 

TBH, I have not got it to work 100% kosher yet.  I keep trying www.ti.com with various root certs (chrome says they use GeoTrust, the closest I can get is GeoTrust Global CA - but it gives a "date error", possibly b/c that needs an Intermediate CA yet there's no way to specify one in the CC3100/CC3200 that I can find).

 

I may test it with my own private root CA + self-generated certificate just to prove that it works.

 

The functions for managing that-

.sslRootCA(uint8_t *derfile, size_t length) - requires binary DER format

.useRootCA() - Looks for /cert/rootCA.der, if it exists, use it (so you don't have to keep re-uploading the root CA each time you load a sketch)

.sslStrict(true/false) - Insist that only a perfectly executed SSL connection be passable.

.sslGetReason() - returns a const char * string indicating the last known error from sl_Connect(), good way to figure out WTF went wrong with your SSL connection attempt.

.sslIsVerified - a public variable, test this after making a connection to see if it's truly a verified connection or not.

 

If .sslRootCA() is called with either derfile = NULL or length = 0, the /cert/rootCA.der is deleted and the library won't attempt root CA verification anymore.

Share this post


Link to post
Share on other sites

I'm really grateful for your SSL update!

I've been trying to figure out how to send an email directly from my MSP430F5529/CC3100 boosterpack using a gmail SMTP server, and had come to the conclusion that it's not possible without an SSL connection. I was about to give up until I saw your post here.

 

Having seen it, I updated my library (/msp430 instead of /cc3200) with the latest WiFiClient (cpp and h) from github and was able to write some code that successfully connected securely to the gmail server. Woohoo! Whatever may still be missing from your update doesn't appear to prevent my scenario from working, and I can now send an email directly from the CC3100 with a secure smtp connection authenticated against my gmail account. Outstanding, and thanks again!!

In case it useful, here's my code:

#include <WiFi.h>#include <SPI.h>#include <WiFiClient.h>#include <WiFiServer.h>const char ssid[] = "ssid";const char wifipw[] = "wifipswd";const char smpt_server[] = "smtp.gmail.com";const int smpt_port = 465;const char userid[] = "myuserid"; // gmail userid const char pswd[] = "mypassword";// gmail password const char mailTo[] = "<myuserid@gmail.com>";const char mailFrom[] = "<myuserid@gmail.com>";char base64_userid[64]; char base64_pswd[64];void setup(){  uint32_t msave;  int i;    Serial.begin(115200);    delay(2000);  Serial.println("WiFi:");  WiFi.begin((char *)ssid, (char *)wifipw);  while (WiFi.status() != WL_CONNECTED) {    Serial.print('.');    delay(150);  }  Serial.println();    Serial.println("Connected- waiting for IP");  msave = millis();  while (WiFi.localIP() == INADDR_NONE) {    Serial.print('.');    delay(150);    if (millis()-msave > 5000) {      Serial.println("Timeout waiting for IP; disconnecting & reconnecting.");      WiFi.disconnect();      WiFi.begin((char *)ssid, (char *)wifipw);      msave = millis();    }  }  Serial.print(" done; IP=");  IPAddress my_ip = WiFi.localIP();  Serial.println(my_ip);    // encode the userid and password  i = base64_encode(userid, (sizeof userid)-1, base64_userid, sizeof base64_userid);  base64_userid[i] = '\0';  i = base64_encode(pswd, (sizeof pswd)-1, base64_pswd, sizeof base64_pswd);  base64_pswd[i] = '\0';  Serial.print("userid ");  Serial.print(userid);  Serial.print(", base64: ");  Serial.println(base64_userid);  //Serial.print("password ");  //Serial.print(pswd);  //Serial.print(", base64: ");  //Serial.println(base64_pswd);}void loop(){  char buf[1025];  int i;  size_t total = 0;  WiFiClient smtp;  Serial.println("Attempting SSL connection to smtp server");  if (smtp.sslConnect(smpt_server, smpt_port)) {    Serial.println("Connected");    getResponse(&smtp);    Serial.println("Sending EHLO");    smtp.println("EHLO");    getResponse(&smtp);    Serial.println("Sending AUTH LOGIN");    smtp.println("AUTH LOGIN");    getResponse(&smtp);    Serial.println("Sending userid");    smtp.println(base64_userid);    getResponse(&smtp);    Serial.println("Sending pswd");    smtp.println(base64_pswd);    getResponse(&smtp);    Serial.println("Sending MAIL FROM");    smtp.print("MAIL FROM:"); // must be first    smtp.println(mailFrom);    getResponse(&smtp);    Serial.println("Sending RCPT TO");    smtp.print("RCPT TO:");    smtp.println(mailTo);    getResponse(&smtp);    Serial.println("Sending DATA");    smtp.println("DATA");    getResponse(&smtp);    Serial.println("Sending actual data...");    smtp.print("From: CC3100");    smtp.println(mailFrom);    smtp.println("Subject: Wow!!");    smtp.print("To:");    smtp.println(mailTo);    smtp.println(" ");    smtp.println("Is this cool or what!");    smtp.println(" ");    smtp.println("(Email sent directly from the TI CC3100 WiFi device)");    smtp.println(".");    delay(1000);    getResponse(&smtp);    Serial.println("Sending QUIT");    smtp.println("QUIT");    getResponse(&smtp);        Serial.println("Done");    delay(100000000); // dont really want to do it again!  } else {    Serial.println("Error connecting to smtp server");  }}/** * Read response * If not available immediately then wait a bit. If still not available, return */void getResponse(WiFiClient* client) {  const int TIME_INCR = 10;  const int TIME_MAX = 10000;  char buf[1025];  int i;  int time_elapsed = 0;  WiFiClient smtp = *client;    if (smtp.connected()) {    while (!smtp.available() && time_elapsed < TIME_MAX) {      delay(TIME_INCR);      time_elapsed += TIME_INCR;    }    if (!smtp.available()) {      Serial.print("No response (");      Serial.print(TIME_MAX);      Serial.println("ms)");      return;    } else {      Serial.print("Server response (");      Serial.print(time_elapsed);      Serial.println("ms):");      while (smtp.available()) {        i = smtp.read((uint8_t *)buf, 1024);        buf[i] = '\0';        Serial.print(buf);        delay(100);      }    }  } else {    Serial.println("Server is not connected");  }}/* * The following is based largely on original code courtesy of Ren

Share this post


Link to post
Share on other sites

Good stuff @@silverado ! Fyi Energia 14 is poised to be released soon and will incorporate this code, client SSL only, no root CA verification. Be aware that the CC3100/CC3200 only supports standalone SSL connections- there is no way to start a normal socket and "switch" it over to SSL mode a la STARTTLS.

Share this post


Link to post
Share on other sites

My intention in developing the code for sending an email was to transfer it from F5529 to G2xxx (not that I yet know how to drive the CC3100 from a G2xxx!) so that ultimately I could build a circuit on stripboard with the G2xxx and a breakout CC3100. For this to be possible for home assembly the G2xxx has to be in a dip package, and I've discovered that the largest memory variant of G2xxx that comes in this format is the G2553, with a memory of just 16K. I find that this isn't enough to do even a bare minimum WiFi.begin() - the compiler reports the ram already overflows by 2294 bytes.

So, am I wasting my time here? Is there any possibility of reducing the binary size, or some other approach a noob has a chance of achieving? The attraction of the G2 launchpad for me is that you can burn removable MCUs to be used elsewhere. The F5529 solution is tied to the launchpad.

The info from TI is that the MSP430G2 launchpad can be used to drive the CC3100, so it must be possible (I did read this although I can't find it now, but I did contact them originally to check and they confirmed it). Perhaps they were referring to CCS and it generates smaller code? Having used it (CCS) originally I'd hate to have to go back to that after using Energia.

Comment, suggestions and encouragement most welcome. If I've not posted this is the right place, apologies, and I'm happy for it to be moved.

Share this post


Link to post
Share on other sites

PS- The magic behind the CC3100 and CC3200 WiFi APIs is in the utility/ subdirectory within the WiFi library directory. That contains a standalone (non-RTOS) implementation of the SimpleLink WiFi API, which is used throughout the WiFi C++ library code that you reference in your sketches.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

It is probably possible but it would require retuning & testing of the Energia library code, probably only allow 1 socket, reduce buffer sizes per socket, etc. Probably doable.

 

Sent from my Galaxy Note II with Tapatalk 4

 

Retuning of the library code is probably beyond me. I did reduce the number of sockets to 1 which buys back 2K, but is still short and that's without 99% of my code in place. I see that the compiler already has size opt switched on (-Os) and the linker is already throwing away unused code (--gc-sections) so I think I have to admit defeat and just go for a CC3200 instead. Simpler anyway. But thanks for the advice.

Share this post


Link to post
Share on other sites

Retuning of the library code is probably beyond me. I did reduce the number of sockets to 1 which buys back 2K, but is still short and that's without 99% of my code in place. I see that the compiler already has size opt switched on (-Os) and the linker is already throwing away unused code (--gc-sections) so I think I have to admit defeat and just go for a CC3200 instead. Simpler anyway. But thanks for the advice.

I think that's a fair bet, or use a Tiva or MSP430F5529 launchpad with the CC3100. The G2553's RAM restrictions are a big liability for this kind of stuff.

 

To illustrate further, I worked on supporting the WizNet W5500 with G2553 and was successful with a bufferless stack (leaning on the transceiver as much as possible for buffering), however implementing DHCP and DNS in firmware resulted in programs that often did overflow their stack or heap a lot. 512 bytes of RAM is just brutal.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

Hi Guys,

 

Great topic!

 

I've been trying to do a basic SSL connection to google.co.uk / google.com and these are not working - do I need to copy over any certificated to the CC3200? Is there any debug I can configure to see whats going wrong?

 

If I need to upload a certificate, is this done using UniFlash?

 

Thanks!

Share this post


Link to post
Share on other sites

No cert necessary, however you can validate the cert if you upload the site's root cert via uniflash or whatever. I found that method a pain but I can see where it would work for specific IoT style setups.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

Thanks.. even trying the above examples to any https site just keeps cycling. I just get "error connecting to www.google.co.uk"..

 

Going by what you say, it should be connect without cert validation.

 

I will give UniFlash a try..

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...