Topic: gettimeofday undefined error compiling for Arduino Due

Hello, I followed the instructions for compiling for the Arduino Due before posting this.

I have also commented out the line that disables the override for struct timeval tm at wolfcrypt/settings.h

However, I can't get past this error.

I have read that one needs to define a gettimeofday function for the system, I have checked the function arguments of the function prototype, the one with the extern, and I have used the same. For now I just used millis() to define the sec and usec with appropriate multiplication and division.

I have also tried putting this self-defined gettimeofday in different locations in the library itself as well as in my code.

Sorry for the brevity of the post and the lack of code snippet, I shall update this later as I'm posting from my phone. Advanced thanks to anyone who'll reply!

Share

Re: gettimeofday undefined error compiling for Arduino Due

Hi @valcroft,

How was wolfSSL configured? Did you forcefully define WOLFSSL_USER_SETTINGS at the top of wolfssl/wolfcrypt/settings.h and declare the extern gettimeofday prototype in user_settings.h?

Warm Regards,

K

Re: gettimeofday undefined error compiling for Arduino Due

Kaleb J. Himes wrote:

Hi @valcroft,

How was wolfSSL configured? Did you forcefully define WOLFSSL_USER_SETTINGS at the top of wolfssl/wolfcrypt/settings.h and declare the extern gettimeofday prototype in user_settings.h?

Warm Regards,

K

Hi! Thanks for replying! I tried doing that hours ago (I didn't do it before), and I played around with it to get it working, but I haven't any luck with it yet. This was what I did:

//user_settings.h
// From what I understand, this is already wrapped with extern "C" with the include from settings.h
struct timeval;
int gettimeofday (struct timeval *, void *); 
// wolfssl_client.ino - the example code included with the library
// I'm compiling this for Arduino Due on Arduino 1.8.5 IDE

#include <Arduino.h>

struct timeval {
  long tv_sec;
  long tv_usec;
};

int gettimeofday( struct timeval *tv, void *tzvp)
{
  long mt = millis();
  tv->tv_sec = mt/1000;
  tv->tv_usec = mt*1000;
  return 0;  // return non-zero for error
} // end _gettimeofday()


#include <wolfssl.h>
#include <wolfssl/ssl.h>
#include <Ethernet2.h>

// Insert the rest of sample code for wolfssl_client.ino

Error I'm receiving:

wolfssl_client:30: error: previous declaration of 'int gettimeofday(timeval*, void*)' with 'C++' linkage
int gettimeofday( struct timeval *tv, void *tzvp)
     ^
In file included from /Users/val/Documents/Arduino/libraries/wolfSSL/wolfssl/wolfcrypt/settings.h:190:0,
                 from /Users/val/Documents/Arduino/libraries/wolfSSL/wolfssl.h:2,
                 from /Users/val/Documents/SCAN-NDSG/basic-probe/V3DUE/others/ssl/wolfssl_client/wolfssl_client.ino:42:
/Users/val/Documents/Arduino/libraries/wolfSSL/wolfssl/wolfcrypt/user_settings.h:8:43: error: conflicts with new declaration with 'C' linkage
int gettimeofday (struct timeval *, void *);
                                           ^
Using library wolfSSL in folder: /Users/val/Documents/Arduino/libraries/wolfSSL (legacy)
Using library Ethernet2 at version 1.0.4 in folder: /Users/val/Documents/Arduino/libraries/Ethernet2
Using library SPI at version 1.0 in folder: /Users/val/Library/Arduino15/packages/arduino/hardware/sam/1.6.11/libraries/SPI
exit status 1
previous declaration of 'int gettimeofday(timeval*, void*)' with 'C++' linkage

Share

Re: gettimeofday undefined error compiling for Arduino Due

@Kaleb Ok I got it compiling! What I did was move the wolfssl headers to the top of my ino file, and also changing the gettimeofday to _gettimeofday in both user_settings.h and the ino file.

Was wondering though, would WolfSSL with the Arduino allow me to communicate via HTTPS with other websites configured with SSL/TLS certificates? I'm using Let's Encrypt as the Certificate Authority, and I'm not sure if I should be configuring my server to use WolfSSL as well? The server is an AWS EC2 instance running Ubuntu.

Share

Re: gettimeofday undefined error compiling for Arduino Due

I'm currently still trying out wolfssl_client.ino, and I've been trying to make an HTTP GET request with google.com.
Where I set the host to "google.com", and the port number to 443.

I get the error of "Unable to allocate to SSL object.", but do get a connection to google.com.

    
    if (client.connect(host, port)) {

      Serial.print("Connected to ");
      Serial.println(host);

      ssl = wolfSSL_new(ctx);
      if (ssl == NULL) {
        Serial.println("Unable to allocate SSL object");
        return;
      }

Share

Re: gettimeofday undefined error compiling for Arduino Due

Hi @valcroft,

You have made good progress. Failure to allocate the SSL object usually indicates insufficient memory. What is your heap and stack available on the device?

- K

7 (edited by valcroft 2019-02-11 13:08:53)

Re: gettimeofday undefined error compiling for Arduino Due

Hi! I really appreciate your help. I'm really lost about what to do about this really haha. I've been reading through the WolfSSL docs for the past hours.

I'm not sure what to make of this actually as I don't think it's a memory error(?). I got the following results from inserting these lines of code "freeRam()" as seen below in the "wolfssl_client.ino" code:

// inside void setup()
   // initialize wolfSSL using callback functions
   wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
   wolfSSL_SetIOSend(ctx, EthernetSend);
   wolfSSL_SetIORecv(ctx, EthernetReceive);
   

   Serial.println("Setup success!");
   freeRam();
   return;
 } 


// inside the void loop()
   if (reconnect) {
     reconnect--;
    
     if (client.connect(host, port)) {
 
       Serial.print("Connected to ");
       Serial.println(host);
        freeRam();

       ssl = wolfSSL_new(ctx);
       freeRam();
       if (ssl == NULL) {
         Serial.println("Unable to allocate SSL object");
         freeRam();
         return;
       }

And here are the results from each of those freeRam():

Sketch uses 141148 bytes (26%) of program storage space. Maximum is 524288 bytes.


Setup success!
Ram used (bytes): 
dynamic: 368
static: 5192
stack: 72
Est. free ram: 92672

Connected to google.com

Ram used (bytes): 
dynamic: 368
static: 5192
stack: 288
Est. free ram: 92456

Unable to allocate SSL object
Ram used (bytes): 
dynamic: 368
static: 5192
stack: 288
Est. free ram: 92456

Here's the code of freeRam() from the freeRam.h I'm importing:

#include <Arduino.h>
#include <malloc.h>

extern char _end;
extern "C" char *sbrk(int i);

void freeRam()
{
    char *ramstart = (char *) 0x20070000;
    char *ramend = (char *) 0x20088000;
    char *heapend = sbrk(0);
    register char * stack_ptr asm( "sp" );
    struct mallinfo mi = mallinfo();

    Serial.println(F("Ram used (bytes): "));
    Serial.print(F("dynamic: ")); Serial.println(mi.uordblks);
    Serial.print(F("static: ")); Serial.println(&_end - ramstart);
    Serial.print(F("stack: ")); Serial.println(ramend - stack_ptr);
    Serial.print(F("Est. free ram: ")); Serial.println(stack_ptr - heapend + mi.fordblks);
}

And here's the complete sample code btw with the modifications I made while trying to make it work:

/* wolfssl_client.ino
 *
 * Copyright (C) 2006-2018 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */
 #include <Arduino.h>
 //#include <sys/time.h>
 
 #include <wolfssl.h>
 #include <wolfssl/ssl.h>
 
 struct timeval {
   long tv_sec;
   long tv_usec;
 };
 
 int _gettimeofday( struct timeval *tv, void *tzvp)
 {
   //uint64_t t = __your_system_time_function_here__();  // get uptime in nanoseconds
   //tv->tv_sec = t / 1000000000;  // convert to seconds
   //tv->tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
   long mt = millis();
   tv->tv_sec = mt/1000;
   tv->tv_usec = mt*1000;
   return 0;  // return non-zero for error
 } // end _gettimeofday()
 
 
 
 #include <Ethernet2.h>

#include <freeRam.h>
 /*
 struct timeval {
   long      tv_sec;
   long tv_usec;
 };
 */
 
 /*
 int _gettimeofday( struct timeval *tv, void *tzvp )
 {
     //uint64_t t = __your_system_time_function_here__();  // get uptime in nanoseconds
     //tv->tv_sec = t / 1000000000;  // convert to seconds
     //tv->tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
     long mt = millis();
     tv->tv_sec = mt/1000;
     tv->tv_usec = mt*1000;
     return 0;  // return non-zero for error
 } // end _gettimeofday()
 */
 
 
 
 
 //const char host[] = "192.168.1.148"; // server to connect to
 //const int port = 11111; // port on server to connect to
 const char host[] = "google.com";
 const char req[]= "GET / HTTP/1.0\r\n\r\n"; // Get the root page
 const int port = 443;
 
 int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
 int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
 int reconnect = 10;
 
 EthernetClient client;
 
 WOLFSSL_CTX* ctx = NULL;
 WOLFSSL* ssl = NULL;
 
 void setup() {

   WOLFSSL_METHOD* method;
 
   Serial.begin(9600);
   freeRam();

   method = wolfTLSv1_2_client_method();
   if (method == NULL) {
     Serial.println("unable to get method");
     return;
   }
   ctx = wolfSSL_CTX_new(method);
   if (ctx == NULL) {
     Serial.println("unable to get ctx");
     return;
   }
   // initialize wolfSSL using callback functions
   wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
   wolfSSL_SetIOSend(ctx, EthernetSend);
   wolfSSL_SetIORecv(ctx, EthernetReceive);
   

   Serial.println("Setup success!");
   freeRam();
   return;
 }
 
 int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx) {
   int sent = 0;
 
   sent = client.write((byte*)msg, sz);
 
   return sent;
 }
 
 int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
   int ret = 0;
 
   while (client.available() > 0 && ret < sz) {
     reply[ret++] = client.read();
   }
 
   return ret;
 }
 
 void loop() {
   int err            = 0;
   int input          = 0;
   int total_input    = 0;
   char msg[32]       = "hello wolfssl!";
   int msgSz          = (int)strlen(msg);
   char errBuf[80];
   char reply[80];
   const char* cipherName;
     
   if (reconnect) {
     reconnect--;
    
     if (client.connect(host, port)) {
 
       Serial.print("Connected to ");
       Serial.println(host);
        freeRam();

       ssl = wolfSSL_new(ctx);
       freeRam();
       if (ssl == NULL) {
         Serial.println("Unable to allocate SSL object");
         freeRam();
         return;
       }
 
       err = wolfSSL_connect(ssl);
       if (err != WOLFSSL_SUCCESS) {
         err = wolfSSL_get_error(ssl, 0);
         wolfSSL_ERR_error_string(err, errBuf);
         Serial.print("TLS Connect Error: ");
         Serial.println(errBuf);
       }
 
       Serial.print("SSL version is ");
       Serial.println(wolfSSL_get_version(ssl));
       
       cipherName = wolfSSL_get_cipher(ssl);
       Serial.print("SSL cipher suite is ");
       Serial.println(cipherName);
 
       if ((wolfSSL_write(ssl, msg, msgSz)) == msgSz) {
         
         Serial.print("Server response: ");
         while (client.available() || wolfSSL_pending(ssl)) {
           input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
           total_input += input;
           if (input < 0) {
             err = wolfSSL_get_error(ssl, 0);
             wolfSSL_ERR_error_string(err, errBuf);
             Serial.print("TLS Read Error: ");
             Serial.println(errBuf);
             break;
           } else if (input > 0) {
             reply[input] = '\0';
             Serial.print(reply);
           } else {
             Serial.println();
           }
         } 
       } else {
         err = wolfSSL_get_error(ssl, 0);
         wolfSSL_ERR_error_string(err, errBuf);
         Serial.print("TLS Write Error: ");
         Serial.println(errBuf);
       }
       
       wolfSSL_shutdown(ssl);
       wolfSSL_free(ssl);
 
       client.stop();
       Serial.println("Connection complete.");
       reconnect = 0;
     } else {
       Serial.println("Trying to reconnect...");
     }
   }
   delay(1000);
 }
 

Share

8 (edited by valcroft 2019-02-11 20:41:58)

Re: gettimeofday undefined error compiling for Arduino Due

Update to this, I inserted the following to get the error message:

       ssl = wolfSSL_new(ctx);
       freeRam();
       if (ssl == NULL) {
         Serial.println("Unable to allocate SSL object");
         freeRam();

         err = wolfSSL_get_error(ssl, 0);
         wolfSSL_ERR_error_string_n(err, errBuf, 80);
         Serial.print("wolfSSL_new: ");
         Serial.println(errBuf);
         return;
       }

And am getting this:

wolfSSL_new: Bad function argument

So now I'm looking for where in the world that went wrong haha.

Edit: Ok that was done in a moment of frustration lol, it's bad function argument since ssl is null in the first place and hasn't been allocated for. Damn haha.

Share

9 (edited by valcroft 2019-02-11 21:20:47)

Re: gettimeofday undefined error compiling for Arduino Due

Upon enabling logging, I got the ff.:

(Sorry for the error spam! Would be posting my debug problems here and what I'm doing about it, as I don't really know where else to get help from smile) Trying to get this working is really out of my comfort zone right now. Although, it does make for a nice learning experience.)

Am currently trying to trace the point of error. It seems to me that it's somewhere with _InitRng but still looking into it.

Ram used (bytes):
dynamic: 0
static: 5256
stack: 80
Est. free ram: 92968

log 2: wolfSSL Entering TLSv1_2_client_method_ex
log 2: wolfSSL Entering wolfSSL_CTX_new_ex
log 2: wolfSSL Entering wolfSSL_Init
log 2: wolfSSL Entering wolfCrypt_Init
log 2: wolfSSL Entering wolfSSL_CertManagerNew
log 3: wolfSSL Leaving WOLFSSL_CTX_new, return 0
log 2: wolfSSL Entering wolfSSL_CTX_set_verify

Setup success!

Ram used (bytes):
dynamic: 368
static: 5256
stack: 72
Est. free ram: 92608

Connected to google.com

log 2: wolfSSL Entering SSL_new
log 1: RNG Init error
log 1: CTX ref count not 0 yet, no free
log 3: wolfSSL Leaving SSL_new, return -209

Ram used (bytes):
dynamic: 368
static: 5256
stack: 304
Est. free ram: 92376

Unable to allocate SSL object

log 2: wolfSSL Entering SSL_get_error
log 2: wolfSSL Entering wolfSSL_ERR_error_string_n
log 2: wolfSSL Entering ERR_error_string
wolfSSL_new: Bad function argument

Share

10 (edited by valcroft 2019-02-12 14:42:40)

Re: gettimeofday undefined error compiling for Arduino Due

Ok got past the above error by adding WOLFSSL_ARDUINO to this list:

#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \
      defined(WOLFSSL_IAR_ARM)  || defined(WOLFSSL_MDK_ARM) || \
      defined(WOLFSSL_uITRON4)  || defined(WOLFSSL_uTKERNEL2) || \
      defined(WOLFSSL_LPC43xx)  || defined(WOLFSSL_STM32F2xx) || \
      defined(MBED)             || defined(WOLFSSL_EMBOS) || \
      defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \
      defined(WOLFSSL_CONTIKI) || defined(WOLFSSL_ARDUINO)
        // @custom added WOLFSSL_ARDUINO
    /* these platforms do not have a default random seed and
       you'll need to implement your own wc_GenerateSeed or define via
       CUSTOM_RAND_GENERATE_BLOCK */

    #define USE_TEST_GENSEED

#elif defined(NO_DEV_RANDOM)

Haven't looked into it yet, but how does one generate a custom random seed for that? Would filling the array with random values based on voltage values from an analog pin suffice?

Anyway, another error I encountered right after that is getting stuck in the ff.:

// from wolfssl_client.ino
 err = wolfSSL_connect(ssl);
// from internal.c

    tmp = (byte*)XMALLOC(size + ssl->buffers.outputBuffer.length + align,
                             ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
    WOLFSSL_MSG("growing output buffer\n");
    // @custom
        /*
    if (tmp == NULL)
        return MEMORY_E;
        */

    if (tmp == NULL) {
        WOLFSSL_MSG("GrowOutputBuffer: tmp=null err");
        return MEMORY_E;
    } else {
        WOLFSSL_MSG("alloc mem success");
    }

log 2: wolfSSL Entering SSL_connect()
log 2: wolfSSL Entering SendClientHello
log 1: growing output buffer

log 1: alloc mem success

Update: Seems like it blocks inside the while loop of int SendBuffered(WOLFSSL* ssl). I ended up printing debug msgs throughout the code to trace the problem.

Share

11 (edited by valcroft 2019-02-12 15:25:53)

Re: gettimeofday undefined error compiling for Arduino Due

Ok I got past the above problem, turns out the sample code for Arduino with wolfssl_client.ino doesn't have an "Ethernet.begin()" anywhere and I didn't notice that. Once putting it in, the CBIO error got solved since it can now send and receive data.

However these are the new error messages:
*I'm trying to connect to google.com here with port set to 443

log 1: SB end
log 1: SCH21
log 3: wolfSSL Leaving SendClientHello, return 0
log 1: SC end
log 1: aft SendClientHello
log 1: connect state: CLIENT_HELLO_SENT
log 1: received record layer msg
log 1: got ALERT!
log 1: Got alert
log 0: wolfSSL error occurred, error = 40
log 0: wolfSSL error occurred, error = -313
aft wolfSSL_conenct err: -1
log 2: wolfSSL Entering SSL_get_error
log 3: wolfSSL Leaving SSL_get_error, return -313
log 2: wolfSSL Entering ERR_error_string
TLS Connect Error: revcd alert fatal error
SSL version is log 2: wolfSSL Entering SSL_get_version
TLSv1.2
log 2: wolfSSL Entering wolfSSL_get_cipher
log 2: wolfSSL Entering SSL_get_current_cipher
log 2: wolfSSL Entering SSL_CIPHER_get_name
SSL cipher suite is NONE
log 2: wolfSSL Entering SSL_write()
log 1: handshake not complete, trying to finish
log 2: wolfSSL Entering wolfSSL_negotiate
log 2: wolfSSL Entering SSL_connect()
log 1: ProcessReply retry in error state, not allowed
log 0: wolfSSL error occurred, error = -313
log 3: wolfSSL Leaving wolfSSL_negotiate, return -1
log 3: wolfSSL Leaving SSL_write(), return -1
log 2: wolfSSL Entering SSL_get_error
log 3: wolfSSL Leaving SSL_get_error, return -313
log 2: wolfSSL Entering ERR_error_string
TLS Write Error: revcd alert fatal error
log 2: wolfSSL Entering SSL_shutdown()
log 3: wolfSSL Leaving SSL_shutdown(), return -1
log 2: wolfSSL Entering SSL_free
log 1: CTX ref count not 0 yet, no free
log 3: wolfSSL Leaving SSL_free, return 0
Connection complete.

Share

12 (edited by valcroft 2019-02-13 00:59:33)

Re: gettimeofday undefined error compiling for Arduino Due

So now I have a CA error.

log 1: About to verify certificate signature
log 1: No CA signer to verify with
log 1: Failed to verify CA from chain
log 1: growing output buffer

I have enabled the ff. at user_settings.h

#define WOLFSSL_STATIC_RSA 
#define HAVE_SUPPORTED_CURVES
#define HAVE_TLS_EXTENSIONS

#define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA

And this is how my code looks like now, with updates to setting a hardcoded pem file and setting a supported curve (i'm not sure how to know which is correct, so I randomly picked one)

/* wolfssl_client.ino
 *
 * Copyright (C) 2006-2018 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */
 #include <Arduino.h>
 //#include <sys/time.h>
 
 #include <wolfssl.h>
 #include <wolfssl/ssl.h>
 //#include <wolfssl/wolflogging.h>
 
 struct timeval {
   long tv_sec;
   long tv_usec;
 };
 
 int _gettimeofday( struct timeval *tv, void *tzvp)
 {
   //uint64_t t = __your_system_time_function_here__();  // get uptime in nanoseconds
   //tv->tv_sec = t / 1000000000;  // convert to seconds
   //tv->tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
   /*
   long mt = millis();
   tv->tv_sec = mt/1000;
   tv->tv_usec = mt*1000;
   */
   long int mt = 1550041049;
   tv->tv_sec = mt;
   tv->tv_usec = 0;
   return 0;  // return non-zero for error
 } // end _gettimeofday()
 
 byte ROOT_CERTS_PEM[] = 
 "-----BEGIN CERTIFICATE-----\n"
"MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG\n"
"A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n"
"cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2\n"
"MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV\n"
"BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt\n"
"YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n"
"ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE\n"
"BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is\n"
"I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G\n"
"CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do\n"
"lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc\n"
"AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k\n"
"-----END CERTIFICATE-----\n";
 
 #include <Ethernet2.h>

#include <freeRam.h>
 /*
 struct timeval {
   long      tv_sec;
   long tv_usec;
 };
 */
 
 /*
 int _gettimeofday( struct timeval *tv, void *tzvp )
 {
     //uint64_t t = __your_system_time_function_here__();  // get uptime in nanoseconds
     //tv->tv_sec = t / 1000000000;  // convert to seconds
     //tv->tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
     long mt = millis();
     tv->tv_sec = mt/1000;
     tv->tv_usec = mt*1000;
     return 0;  // return non-zero for error
 } // end _gettimeofday()
 */
 
 
 
 
 //const char host[] = "192.168.1.148"; // server to connect to
 //const int port = 11111; // port on server to connect to
 const char host[] = "google.com";
 const int port = 443;
 
 int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
 int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
 int reconnect = 10;
 
 EthernetClient client;
 
 WOLFSSL_CTX* ctx = NULL;
 WOLFSSL* ssl = NULL;
 
 byte MAC_ADDR[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };


// void wolfSSL_Logging_cb(const int logLevel, const char *const logMessage);

void wolfssl_custom_logging_cb(const int logLevel, const char *const logMessage) {
    Serial.print("log "); Serial.print(logLevel); Serial.print(": "); Serial.println(logMessage);
}


void setup() {


    Serial.begin(9600);


    if (Ethernet.begin(MAC_ADDR) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        return;
    }
    Serial.println(Ethernet.localIP());


    WOLFSSL_METHOD* method;

    freeRam();

    // Enable logging

    wolfSSL_Debugging_ON();


    wolfSSL_SetLoggingCb(&wolfssl_custom_logging_cb);


    wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP160K1);
    method = wolfTLSv1_2_client_method();
    //method = wolfTLSv1_3_client_method();
    if (method == NULL) {
        Serial.println("unable to get method");
        return;
    }

    //wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    ctx = wolfSSL_CTX_new(method);
    if (ctx == NULL) {
    Serial.println("unable to get ctx");
    return;
    }

    /* Add cert to ctx */
    int x =     wolfSSL_CTX_load_verify_buffer(ctx, ROOT_CERTS_PEM,sizeof ROOT_CERTS_PEM, WOLFSSL_FILETYPE_PEM);
    int err            = 0;
    char errBuf[81];

    if (x != WOLFSSL_SUCCESS)
    {
        err = wolfSSL_get_error(ssl, 0);
        wolfSSL_ERR_error_string_n(err, errBuf, 80);
        Serial.print(F("wolfSSL_CTX_Load_verify_buffer: "));
        Serial.println(errBuf);
        return;
    }
    
    // initialize wolfSSL using callback functions
    //wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    wolfSSL_SetIOSend(ctx, EthernetSend);
    wolfSSL_SetIORecv(ctx, EthernetReceive);



    Serial.println("Setup success!");
    freeRam();
    return;
}
 
int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx) {
    Serial.println("EthernetSend");
    int sent = 0;
    Serial.println(msg);
    Serial.println(sz);
    sent = client.write((byte*)msg, sz);

    return sent;
}
 
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
    int ret = 0;

    while (client.available() > 0 && ret < sz) {
        reply[ret++] = client.read();
    }

    return ret;
}
 
 void loop() {
    int err            = 0;
    int input          = 0;
    int total_input    = 0;
    char msg[]= "GET / HTTP/1.0\r\n\r\n"; // Get the root page
    int msgSz = (int)strlen(msg);
   //char msg[32]       = "hello wolfssl!";
   //int msgSz          = (int)strlen(msg);
    char errBuf[81];
    char reply[81];
    const char* cipherName;

    if (reconnect) {
        reconnect--;

        if (client.connect(host, port)) {

        Serial.print("Connected to ");
        Serial.println(host);
        // freeRam();

        if (ctx == NULL) {
            Serial.println("null ctx");
        }

        ssl = wolfSSL_new(ctx);
        freeRam();
        if (ssl == NULL) {
            Serial.println("Unable to allocate SSL object");
            //freeRam();

            err = wolfSSL_get_error(ssl, 0);
            wolfSSL_ERR_error_string_n(err, errBuf, 80);
            Serial.print("wolfSSL_new: ");
            Serial.println(errBuf);
            return;
        }

        err = wolfSSL_connect(ssl);
        freeRam();

        Serial.print(F("aft wolfSSL_conenct err: ")); Serial.println(err);
        if (err != WOLFSSL_SUCCESS) {
            err = wolfSSL_get_error(ssl, 0);
            wolfSSL_ERR_error_string(err, errBuf);
            Serial.print("TLS Connect Error: ");
            Serial.println(errBuf);
        }

        Serial.print("SSL version is ");
        Serial.println(wolfSSL_get_version(ssl));
        
        cipherName = wolfSSL_get_cipher(ssl);
        Serial.print("SSL cipher suite is ");
        Serial.println(cipherName);
        if ((wolfSSL_write(ssl, msg, msgSz)) == msgSz) {
        //if ((wolfSSL_write(ssl, msg, msgSz)) == msgSz) {
            
            Serial.print("Server response: ");
            while (client.available() || wolfSSL_pending(ssl)) {
            input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
            total_input += input;
            if (input < 0) {
                err = wolfSSL_get_error(ssl, 0);
                wolfSSL_ERR_error_string(err, errBuf);
                Serial.print("TLS Read Error: ");
                Serial.println(errBuf);
                break;
            } else if (input > 0) {
                reply[input] = '\0';
                Serial.print(reply);
            } else {
                Serial.println();
            }
            } 
        } else {
            err = wolfSSL_get_error(ssl, 0);
            wolfSSL_ERR_error_string(err, errBuf);
            Serial.print("TLS Write Error: ");
            Serial.println(errBuf);
        }
        
        wolfSSL_shutdown(ssl);
        wolfSSL_free(ssl);

        client.stop();
        Serial.println("Connection complete.");
        reconnect = 0;
        } else {
        Serial.println("Trying to reconnect...");
        }
    }
    delay(1000);
}
 

Share