Topic: No CA signer to verify with error
I'm trying to have wolfSSL working with an Arduino Due. I'm testing it by connecting to google.com
What I did was generate a cert with this command:
openssl s_client -servername google.com -connect google.com:443 \
    </dev/null 2>/dev/null | openssl x509 -textThe end of my error logs are the ff.:
log 1: Certificate Policy extension not supported yet.
log 2: wolfSSL Entering GetAlgoId
log 2: wolfSSL Entering GetObjectId()
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 bufferlog 1: alloc mem success
log 1: h0
log 1: h1
log 1: h2
log 1: h3
log 1: end of GrowOutputBuffer
log 1: end of CheckAvailableSize
log 1: SB0
log 1: SB1
log 1: SB4
log 1: 7
log 1: SBW0
EthernetSend
7
write end
log 1: SBW1
log 1: SBW2
log 1: SBW3
log 1: SB -1
log 1: Shrinking output bufferlog 1: SB end
log 1: Verifying Peer's cert
log 2: wolfSSL Entering GetExplicitVersion
log 2: wolfSSL Entering GetSerialNumber
log 1: Got Cert Header
log 2: wolfSSL Entering GetAlgoId
log 2: wolfSSL Entering GetObjectId()
log 1: Got Algo ID
log 1: Getting Cert Name
log 1: Getting Cert Name
log 1: Got Subject Name
log 2: wolfSSL Entering GetAlgoId
log 2: wolfSSL Entering GetObjectId()
log 1: Got Key
log 1: Parsed Past Key
log 2: wolfSSL Entering DecodeCertExtensions
log 2: wolfSSL Entering GetObjectId()
log 1: DecodeExtKeyUsage
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeAltNames
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeAuthInfo
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeSubjKeyId
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeBasicCaConstraint
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeAuthKeyId
log 2: wolfSSL Entering GetObjectId()
log 1: Certificate Policy extension not supported yet.
log 2: wolfSSL Entering GetObjectId()
log 2: wolfSSL Entering DecodeCrlDist
log 2: wolfSSL Entering GetAlgoId
log 2: wolfSSL Entering GetObjectId()
log 1: About to verify certificate signature
log 1: No CA signer to verify with
log 1: Failed to verify Peer's cert
log 1: No callback override available, fatal
log 3: wolfSSL Leaving ProcessPeerCerts, return -188
log 3: wolfSSL Leaving DoCertificate, return -188
log 3: wolfSSL Leaving DoHandShakeMsgType(), return -188
log 3: wolfSSL Leaving DoHandShakeMsg(), return -188
log 0: wolfSSL error occurred, error = -188
log 0: wolfSSL error occurred, error = -188
Ram used (bytes):
dynamic: 6352
static: 8016
stack: 296
Est. free ram: 83640
aft wolfSSL_conenct err: -1
log 2: wolfSSL Entering SSL_get_error
log 3: wolfSSL Leaving SSL_get_error, return -188
log 2: wolfSSL Entering ERR_error_string
TLS Connect Error: ASN no signer error to confirm failure
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 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
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 = -188
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 -188
log 2: wolfSSL Entering ERR_error_string
TLS Write Error: ASN no signer error to confirm failure
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 1: Shrinking input bufferlog 3: wolfSSL Leaving SSL_free, return 0
Connection complete.
And then the cert I used was this:
byte ROOT_CERTS_PEM[] =
"-----BEGIN CERTIFICATE-----\n"
"MIIHxzCCBq+gAwIBAgIISq/AiE/4Ql0wDQYJKoZIhvcNAQELBQAwVDELMAkGA1UE\n"
"BhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczElMCMGA1UEAxMc\n"
"R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMzAeFw0xOTAxMjkxNDU4MDBaFw0x\n"
"OTA0MjMxNDU4MDBaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh\n"
"MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKDApHb29nbGUgTExDMRUw\n"
"EwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQm\n"
"MtUY17v51azgVGYJUdJAW3uhIdVQPSLnrhFak+s4wxf7kuLiJhnO0wv/jgorpowS\n"
"vTfiyCwobsezvohrOf9co4IFVDCCBVAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYD\n"
"VR0PAQH/BAQDAgeAMIIEGQYDVR0RBIIEEDCCBAyCDCouZ29vZ2xlLmNvbYINKi5h\n"
"bmRyb2lkLmNvbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29n\n"
"bGUuY29tggYqLmcuY2+CDiouZ2NwLmd2dDIuY29tggoqLmdncGh0LmNughYqLmdv\n"
"b2dsZS1hbmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiou\n"
"Z29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyou\n"
"Z29vZ2xlLmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKC\n"
"DyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20u\n"
"dHKCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsq\n"
"Lmdvb2dsZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5u\n"
"bIILKi5nb29nbGUucGyCCyouZ29vZ2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22C\n"
"DyouZ29vZ2xlYXBpcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xl\n"
"dmlkZW8uY29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRp\n"
"Y2NuYXBwcy5jboIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0\n"
"YXRpYy5jb22CDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0\n"
"dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0\n"
"aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyoueXRpbWcuY29t\n"
"ghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2RldmVs\n"
"b3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2ds\n"
"ZS5jboIEZy5jb4IIZ2dwaHQuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5j\n"
"b22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNlLmNvbYIYc291cmNlLmFuZHJv\n"
"aWQuZ29vZ2xlLmNuggp1cmNoaW4uY29tggp3d3cuZ29vLmdsggh5b3V0dS5iZYIL\n"
"eW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29tgg95b3V0dWJla2lkcy5j\n"
"b22CBXl0LmJlMGgGCCsGAQUFBwEBBFwwWjAtBggrBgEFBQcwAoYhaHR0cDovL3Br\n"
"aS5nb29nL2dzcjIvR1RTR0lBRzMuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2Nz\n"
"cC5wa2kuZ29vZy9HVFNHSUFHMzAdBgNVHQ4EFgQU4d6jiJq9XEX/VakZBbvn3GVy\n"
"338wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3wrhQmmd2drEtwobQg6B+pn66\n"
"SzAhBgNVHSAEGjAYMAwGCisGAQQB1nkCBQMwCAYGZ4EMAQICMDEGA1UdHwQqMCgw\n"
"JqAkoCKGIGh0dHA6Ly9jcmwucGtpLmdvb2cvR1RTR0lBRzMuY3JsMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQC7GErM5Cnc5PYfZ+c7S4py1RDd/Irf4TVNOL9VxlYcJkkJo7dG\n"
"VSPiZdEEUV9neMMmSY0mktTkzKYBdYK/y9ZWYCAcpqOZoiYtsbdJ1b5rH+mOI5NG\n"
"+PCGL532Ie6dG/aK+2hDFhMTItimIt1BO7Pxvsj8/zVTlFwjJGT4sTUj3h74rOLM\n"
"UAlPt4ag00tiPxWl4hPmE89StBlX+wGmzHHGjvgCpevS04JluOFFXD30gXxOHGZA\n"
"mZt3a6Y3w1wBae/xZtCl6p0C3+oFX0zzLlmMipq0wtw1pIjrhLnQcaZ5p+3TyR86\n"
"ByLwfJsIKcpYMY05KzEftqBQLaZ5qKFZS3/M\n"
"-----END CERTIFICATE-----\n";My previous progress on this is in this link:
https://www.wolfssl.com/forums/topic132 … o-due.html
Current code is this: 
/* 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";
 */
byte ROOT_CERTS_PEM[] =
"-----BEGIN CERTIFICATE-----\n"
"MIIHxzCCBq+gAwIBAgIISq/AiE/4Ql0wDQYJKoZIhvcNAQELBQAwVDELMAkGA1UE\n"
"BhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczElMCMGA1UEAxMc\n"
"R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMzAeFw0xOTAxMjkxNDU4MDBaFw0x\n"
"OTA0MjMxNDU4MDBaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh\n"
"MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKDApHb29nbGUgTExDMRUw\n"
"EwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQm\n"
"MtUY17v51azgVGYJUdJAW3uhIdVQPSLnrhFak+s4wxf7kuLiJhnO0wv/jgorpowS\n"
"vTfiyCwobsezvohrOf9co4IFVDCCBVAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYD\n"
"VR0PAQH/BAQDAgeAMIIEGQYDVR0RBIIEEDCCBAyCDCouZ29vZ2xlLmNvbYINKi5h\n"
"bmRyb2lkLmNvbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29n\n"
"bGUuY29tggYqLmcuY2+CDiouZ2NwLmd2dDIuY29tggoqLmdncGh0LmNughYqLmdv\n"
"b2dsZS1hbmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiou\n"
"Z29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyou\n"
"Z29vZ2xlLmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKC\n"
"DyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20u\n"
"dHKCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsq\n"
"Lmdvb2dsZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5u\n"
"bIILKi5nb29nbGUucGyCCyouZ29vZ2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22C\n"
"DyouZ29vZ2xlYXBpcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xl\n"
"dmlkZW8uY29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRp\n"
"Y2NuYXBwcy5jboIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0\n"
"YXRpYy5jb22CDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0\n"
"dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0\n"
"aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyoueXRpbWcuY29t\n"
"ghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2RldmVs\n"
"b3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2ds\n"
"ZS5jboIEZy5jb4IIZ2dwaHQuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5j\n"
"b22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNlLmNvbYIYc291cmNlLmFuZHJv\n"
"aWQuZ29vZ2xlLmNuggp1cmNoaW4uY29tggp3d3cuZ29vLmdsggh5b3V0dS5iZYIL\n"
"eW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29tgg95b3V0dWJla2lkcy5j\n"
"b22CBXl0LmJlMGgGCCsGAQUFBwEBBFwwWjAtBggrBgEFBQcwAoYhaHR0cDovL3Br\n"
"aS5nb29nL2dzcjIvR1RTR0lBRzMuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2Nz\n"
"cC5wa2kuZ29vZy9HVFNHSUFHMzAdBgNVHQ4EFgQU4d6jiJq9XEX/VakZBbvn3GVy\n"
"338wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3wrhQmmd2drEtwobQg6B+pn66\n"
"SzAhBgNVHSAEGjAYMAwGCisGAQQB1nkCBQMwCAYGZ4EMAQICMDEGA1UdHwQqMCgw\n"
"JqAkoCKGIGh0dHA6Ly9jcmwucGtpLmdvb2cvR1RTR0lBRzMuY3JsMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQC7GErM5Cnc5PYfZ+c7S4py1RDd/Irf4TVNOL9VxlYcJkkJo7dG\n"
"VSPiZdEEUV9neMMmSY0mktTkzKYBdYK/y9ZWYCAcpqOZoiYtsbdJ1b5rH+mOI5NG\n"
"+PCGL532Ie6dG/aK+2hDFhMTItimIt1BO7Pxvsj8/zVTlFwjJGT4sTUj3h74rOLM\n"
"UAlPt4ag00tiPxWl4hPmE89StBlX+wGmzHHGjvgCpevS04JluOFFXD30gXxOHGZA\n"
"mZt3a6Y3w1wBae/xZtCl6p0C3+oFX0zzLlmMipq0wtw1pIjrhLnQcaZ5p+3TyR86\n"
"ByLwfJsIKcpYMY05KzEftqBQLaZ5qKFZS3/M\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("ERR 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);
}