hirotakaster / TlsTcpClient

Other
32 stars 9 forks source link

Can't connect to an AWS-hosted server #3

Open ghost opened 6 years ago

ghost commented 6 years ago

Hello Hirotaka! Great work with this library!!!

I would like to connect my Particle Photon directly to my database (InfluxDb instance on AWS cloud). The database is behind the AWS load balancer using default security policy. My idea is to post a value directly from the Photon via an HTTPS post.

Unfortunately, I can't make it working: there is no "invalid certificate" or other errors. I was able to pin-point that the issue could be non compatibility of the ciphers used. The ciphers supported by AWS are the following: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-ssl-security-policy.html#ssl-ciphers

Could you please address this issue?

Thanks in advance, Alex Masolin

hirotakaster commented 6 years ago

Hi @alexmasolin , Okay, I will update cipher suite and test on the elb. Thank you.

hirotakaster commented 6 years ago

Hi @alexmasolin

I update 0.2.8 version(CBC to GCM mode). And I checked this version on my AWS ELB and Let's Encrypt my web server, it's works fine.

Test environment is ELB(443:aws.hirotakaster.com) forward to the two EC2 Web Server(Apache:80), here is test source code on the Photon firmware. my aws. hirotakaster.com domain/elb/servers already expire.

#include "application.h"

#include "TlsTcpClient.h"

#define AWS_ROOT_CA_PEM                                              \
"-----BEGIN CERTIFICATE----- \r\n"                                      \
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\r\n"  \
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\r\n"  \
"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\r\n"  \
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\r\n"  \
"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\r\n"  \
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\r\n"  \
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\r\n"  \
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\r\n"  \
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\r\n"  \
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\r\n"  \
"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\r\n"  \
"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\r\n"  \
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\r\n"  \
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\r\n"  \
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\r\n"  \
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\r\n"  \
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\r\n"  \
"rqXRfboQnoZsG4q5WTP468SQvvG5\r\n"  \
"-----END CERTIFICATE----- "

const char awsRootCaPem[] = AWS_ROOT_CA_PEM;

#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();

void setup() {
    Serial.begin(9600);

    // need a Particle time sync for X509 certificates verify.
    if (millis() - lastSync > ONE_DAY_MILLIS) {
        Particle.syncTime();
        lastSync = millis();
    }
    Serial.print(Time.timeStr());
}

void loop() {
    unsigned char buff[256];

    TlsTcpClient client;

    // setup Root CA pem.
    client.init(awsRootCaPem, sizeof(awsRootCaPem));

    // connect HTTPS server.
    client.connect("aws.hirotakaster.com", 443);

    // check server certificate. if verify failed, TLS connection is alive.
    if (!client.verify()) {
      Serial.println("Server Certificates is in-valid.");
    }

    // Send request to HTTPS web server.
    int len = sprintf((char *)buff, "GET / HTTP/1.0\r\nHost: aws.hirotakaster.com\r\nContent-Length: 0\r\n\r\n");
    client.write(buff, len );

    // GET HTTPS response.
    memset(buff, 0, sizeof(buff));
    while(1) {
        // read renponse.
        memset(buff, 0, sizeof(buff));
        int ret = client.read(buff, sizeof(buff) - 1);
        if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
            delay(100);
        } else if (ret <= 0) {
            break;
        } else {
            Serial.println((char *)buff);
        }
    }
    delay(10000);
}

here is WebIDE build. screenshot1

Photon with ELB TLS negotiation WireShark packet capture. screenshot2

Thank you, hirotakaster

ghost commented 6 years ago

Hello Hirotaka!

Thank you for the super-quick support. Indeed now there is a different behavior and I get "invalid certificate" error.

What I know is that my server (the domain where the server is allocated) is using "Comodo EssentialSSL SHA-2 certificate" and you can find the root and intermediate certificates here: https://support.comodo.com/index.php?/comodo/Knowledgebase/Article/View/620/0/

From this page you can download several files like: comodo-rsa-domain-validation-sha-2-intermediates.ca-bundle (4.07 KB) comodo-rsa-domain-validation-sha-2-w-root.ca-bundle (5.58 KB) comodorsaaddtrustca.crt (1.91 KB) addtrustexternalcaroot.crt (1.49 KB) comodorsadomainvalidationsecureserverca.crt (2.13 KB)

but, due to my lack of knowledge, I wasn't able to know which one is needed in the script.

Can you help me?

If I browse from Chrome of course I get a 204 reply from the server. You can try your self with the following GET: https:// earthangel -28c4556f .influxcloud.net: 8086/ping [remove the spaces] untitled

Many thanks in advance Cheers Alex

hirotakaster commented 6 years ago

Hi @alexmasolin ,

Maybe your Photon firmware is not 0.6.3? "invalid certificate" error occur on the prerelease version 0.7.x or 0.8.x firmware.

Please use 0.6.3(default) firmware.

ghost commented 6 years ago

Hello @hirotakaster

I was aware about the problems with 0.7.x and 0.8.x so I sticked with 0.6.3 firmware.

Cheers, Alex

hirotakaster commented 6 years ago

Hi @alexmasolin ,

Okay!! I got a same error on your server. I would test with COMODO root ca with your server okay?

ghost commented 6 years ago

Hey @hirotakaster well, at least the error is reproducible. That's fine for me. Go ahead with your test.

Cheers, Alex

hirotakaster commented 6 years ago

Hi @alexmasolin ,

All problem is clear but not resolved(sorry...). The point of the problems is Photon memory limitation.

here is my test.

I try to clear this problem but it need a time. I would like to propose about this problem, how about changing the certificate? I tested certificate with Let's Encrypt, GlobalSign, Amazon Root CA(AWS), there certificate are signed SHA-256 and safety.

Thank you

ghost commented 6 years ago

Hi @hirotakaster Can I help to solve this issue? Unfortunately my knowledge of the SSL stack is not quite advance :(

Changing certificate would be a nice -to-have... unfortunately we use influx cloud services so the server is managed directly by them.... I will try to ask them to change certificate but I'm not really positive.

I suppose that you are already aware of this document: https://tls.mbed.org/kb/how-to/reduce-mbedtls-memory-and-storage-footprint Is it possible to offload RAM by using EEPROM and Backup RAM (SRAM) space for the certificate? https://docs.particle.io/reference/firmware/photon/#backup-ram-sram-

Keep me posted.

Cheers, Alex

hirotakaster commented 6 years ago

Hi @alexmasolin ,

I can success to your COMODO certificate AWS, the previous post was my mistake. You can use TlsTcpClient 0.2.9 version on Photon WebIDE or Desktop Particle Dev IDE. source code is here.(domain name is masked)

#include "application.h"

#include "TlsTcpClient.h"
#define COMODO_ROOT_CA_PEM                                              \
"-----BEGIN CERTIFICATE----- \r\n"                                      \
"MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB\r\n"   \
"hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\r\n"   \
"A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\r\n"   \
"BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy\r\n"   \
"MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\r\n"   \
"EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\r\n"   \
"Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh\r\n"   \
"bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\r\n"   \
"ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh\r\n"   \
"bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0\r\n"   \
"Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6\r\n"   \
"ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51\r\n"   \
"UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n\r\n"   \
"c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY\r\n"   \
"MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz\r\n"   \
"30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV\r\n"   \
"HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG\r\n"   \
"BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv\r\n"   \
"bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB\r\n"   \
"AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E\r\n"   \
"T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v\r\n"   \
"ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p\r\n"   \
"mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/\r\n"   \
"e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps\r\n"   \
"P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY\r\n"   \
"dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc\r\n"   \
"2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG\r\n"   \
"V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4\r\n"   \
"HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX\r\n"   \
"j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII\r\n"   \
"0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap\r\n"   \
"lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf\r\n"   \
"+AZxAeKCINT+b72x\r\n"   \
"-----END CERTIFICATE----- "
const char comodoRootCaPem[] = COMODO_ROOT_CA_PEM;

#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();

void setup() {
    Serial.begin(9600);

    // need a Particle time sync for X509 certificates verify.
    if (millis() - lastSync > ONE_DAY_MILLIS) {
        Particle.syncTime();
        lastSync = millis();
    }
    Serial.println(Time.timeStr());
}

void loop() {
    unsigned char buff[256];

    TlsTcpClient client;

    // setup Root CA pem.
    client.init(comodoRootCaPem, sizeof(comodoRootCaPem));

    // connect HTTPS server.
    client.connect("xxxx-28c4556f.xxxx.net", 8086);
    if (!client.isConnected() || !client.verify()) {
      Serial.println("Server Certificates is in-valid.");
      client.close();
      delay(10000);
      return;
    }

    // Send request to HTTPS web server.
    int len = sprintf((char *)buff, "GET / HTTP/1.0\r\nHost: xxxx-28c4556f.xxxx.net\r\nContent-Length: 0\r\n\r\n");
    client.write(buff, len );

    // GET HTTPS response.
    memset(buff, 0, sizeof(buff));
    while(1) {
        // read renponse.
        memset(buff, 0, sizeof(buff));
        int ret = client.read(buff, sizeof(buff) - 1);
        if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
            delay(100);
            continue;
        } else if (ret <= 0) {
            // no more read.
            break;
        } else if (ret > 0){
            Serial.println((char *)buff);
        }
    }
    delay(10000);
}

here is access log. access_log

Regards

ghost commented 6 years ago

Dear @hirotakaster

well... it works!!! You made my day :)

I was able to get a positive response (a 204 not a 404) from the server by changing the buffer to int len = sprintf((char *)buff, "GET /ping HTTP/1.1\r\nHost: xxxxx-28c4556f.xxxxx.net:8086\r\n\r\n");

Now I have to find a way to send the payload. I hope that, when I will integrate your library into my original script, I won't hit memory boundaries.

Did you follow some advice about memory footprint reduction? See https://github.com/hirotakaster/TlsTcpClient/issues/3#issuecomment-362198176 Or maybe you implemented them already...

Once again, thank you very very much!

Lot of luck Alex

hirotakaster commented 6 years ago

Hi @alexmasolin ,

okay, that's good.

Did you follow some advice about memory footprint reduction? See #3 (comment)

Thank you, I tried to use mbedTLS memory Reduce and Footprint with EEPROM and SRAM in the past but I get a two problem.

  1. SRAM(3068bytes) and EEPROM(2047bytes) are used for the memory backup for application, so I think it would good for not use in the library.
  2. EEPROM have a fixed number of writes and very slow. I tried to use certification save to the EEPROM(not include into the application and reduce the flash/memory) in sample application, it works well. But if the big certification file, this try would be not works.

Now application could use about 16Kbyte free memory area with this library and sample source. I think Particle function "System.freeMemory()" call after the TlsTcpClient.verify() would be works well.

Thank you, Hirotaka

ghost commented 6 years ago

Hello @hirotakaster

Few thoughts about memory reduction: 1) while usually sram and eeprom could be used by the application, this is anyway something that the programmer should decide. Even in the reference or Particle Photon is mentioned the use of SRAM as "extra ram", i.e. not for backup. https://docs.particle.io/reference/firmware/photon/#backup-ram-sram- 2) EEPROM has limited numbers of writes but only if you change the content! If you write the same thing you won't experience degradation. Am I wrong or the certificate is always the same?

Using System.freeMemory() gives me 5400bytes available... not much... if I increase the buff size to 512 I get an SOS with 1 blink (Hard fault).

Finally - most important - I'm struggling to send a body with my post request. I've tried so many ways.... could you please give me a working example? Using Postman, the http request looks like this

POST /write?db=mydb&u=user&p=password HTTP/1.1 Host: earthangel-REDACTED.influxcloud.net:8086

power,system=one value=1234

I've tried to use this line in your application int len = sprintf((char *)buff, "POST /write?db=mydb&amp;u=user&amp;p=password HTTP/1.1\r\nHost: %s:%i\r\n\r\npower,system=one value=1234\r\n\r\n", SERVER_NAME, SERVER_PORT); But the body is simply ignored from the server (first a 204 - No content and after a while a 408 - Timeout error). Replacing the space (betwen "one" and "value" with %20 or adding Content-Type as header doesn't change the result. Could you help me?

Many thanks, Alex

hirotakaster commented 6 years ago

Hi, @alexmasolin ,

here is sample with my webbserver.

#include "application.h"

#include "TlsTcpClient.h"

#define LET_ENCRYPT_CA_PEM                                              \
"-----BEGIN CERTIFICATE----- \r\n"                                      \
"MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw\r\n"  \
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\r\n"  \
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1\r\n"  \
"WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\r\n"  \
"RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi\r\n"  \
"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX\r\n"  \
"NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf\r\n"  \
"89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl\r\n"  \
"Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc\r\n"  \
"Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz\r\n"  \
"uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB\r\n"  \
"AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU\r\n"  \
"BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB\r\n"  \
"FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo\r\n"  \
"SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js\r\n"  \
"LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF\r\n"  \
"BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG\r\n"  \
"AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD\r\n"  \
"VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB\r\n"  \
"ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx\r\n"  \
"A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM\r\n"  \
"UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2\r\n"  \
"DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1\r\n"  \
"eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu\r\n"  \
"OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw\r\n"  \
"p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY\r\n"  \
"2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0\r\n"  \
"ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR\r\n"  \
"PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b\r\n"  \
"rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt\r\n"  \
"-----END CERTIFICATE----- "
const char letencryptCaPem[] = LET_ENCRYPT_CA_PEM;

#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();

void setup() {
    Serial.begin(9600);

    // need a Particle time sync for X509 certificates verify.
    if (millis() - lastSync > ONE_DAY_MILLIS) {
        Particle.syncTime();
        lastSync = millis();
    }
    Serial.println(Time.timeStr());
}

void loop() {
    TlsTcpClient client;
    unsigned char buff[256];

    // setup Root CA pem.
    client.init(letencryptCaPem, sizeof(letencryptCaPem));

    // connect HTTPS server.
    client.connect("www.hirotakaster.com", 443);

    if (!client.verify()) {
      Serial.println("Server Certificates is in-valid.");
    }

    // Send request to HTTPS web server.
    char *postVal = "key1=value1&key2=value2";
    char *postUrl = "/download/samplepost.php?db=mydb&amp;u=user&amp;p=password";
    char *httpHeader = "Host: www.hirotakaster.com\r\nConnection: Keep-Alive\r\nContent-Type:application/x-www-form-urlencoded\r\n";

    int len = sprintf((char *)buff, "POST %s HTTP/1.0\r\n", postUrl);
    client.write(buff, len);

    len = sprintf((char *)buff, "%s", httpHeader);
    client.write(buff, len);

    len = sprintf((char *)buff, "Content-Length: %d\r\n\r\n", strlen(postVal));
    client.write(buff, len);

    len = sprintf((char *)buff, "%s", postVal);
    client.write(buff, len);

    // GET HTTPS response.
    memset(buff, 0, sizeof(buff));
    while(1) {
        // read renponse.
        memset(buff, 0, sizeof(buff));
        int ret = client.read(buff, sizeof(buff) - 1);
        if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
            delay(100);
            continue;
        } else if (ret <= 0) {
            // no more read.
            break;
        } else if (ret > 0){
            Serial.println((char *)buff);
        }
    }

    delay(10000);
}

server side PHP is very simple.

<html><head><title>sample post</title></head> <body>
<?php
print(http_build_query($_POST));
?>
</body></html>

In the Particle community site developer reported how to manage the memory, but I don't sure this option is correct or not(I think maybe some case would be good but others don't). https://community.particle.io/t/mqtt-tls-on-photon-am-i-running-out-of-memory/39430

And please use version 0.2.10. This version is light the memory about 2kbyte compare to 0.2.9.

Thank you

ghost commented 6 years ago

Awesome! Everything is fixed!