<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[wolfSSL - Embedded SSL Library — Getting stuck at lg 2: wolfSSL Entering SSL_CTX_free at some point]]></title>
		<link>https://www.wolfssl.com/forums/topic1437-getting-stuck-at-lg-2-wolfssl-entering-sslctxfree-at-some-point.html</link>
		<atom:link href="https://www.wolfssl.com/forums/feed-rss-topic1437.xml" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Getting stuck at lg 2: wolfSSL Entering SSL_CTX_free at some point.]]></description>
		<lastBuildDate>Fri, 13 Sep 2019 18:58:25 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Getting stuck at lg 2: wolfSSL Entering SSL_CTX_free at some point]]></title>
			<link>https://www.wolfssl.com/forums/post4857.html#p4857</link>
			<description><![CDATA[<p>Hi valcroft,</p><p>Rather than freeing the context (which will also free the context handlers) could you try only freeing and re-creating the SSL object? </p><p>If you do need to free the context factory you should try calling wolfSSL_Cleanu()p and wolfSSL_Init() also before proceeding but it isn&#039;t ideal.</p><p>- KH</p>]]></description>
			<author><![CDATA[null@example.com (Kaleb J. Himes)]]></author>
			<pubDate>Fri, 13 Sep 2019 18:58:25 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post4857.html#p4857</guid>
		</item>
		<item>
			<title><![CDATA[Getting stuck at lg 2: wolfSSL Entering SSL_CTX_free at some point]]></title>
			<link>https://www.wolfssl.com/forums/post4847.html#p4847</link>
			<description><![CDATA[<p>Hi! I&#039;ve tried using WolfSSL with the Arduino Due. And I thought it was going on well at some point, but then I now have these consistent errors where the entire thing hangs at &quot;lg 2: wolfSSL Entering SSL_CTX_free&quot;. I use a W5500 with the Ethernet2 library btw.</p><p>This happens because what I do is everytime I get a LAN connection or connection &quot;error&quot;, I reinitialize the ethernet connection with &quot;Ethernet.begin()&quot;, and then reinitialize the wolfSSLSetup. But to accomodate for potential memory leak, I put this on top of the whole process: <br /></p><div class="codebox"><pre><code>    if (ctx != NULL) {
        Serial.println(F(&quot;[wolfSSLSetup]: ctx not null, so freed&quot;));

        wolfSSL_CTX_free(ctx); ctx = NULL;
    }</code></pre></div><p>I think it gets stuck right at that line above and I&#039;m not sure why.</p><p>The errors that happen actually that by logic makes my code reinitialize the Ethernet connection and the wolfSSL setup is either an error -308 or -150.</p><p>Right now, I&#039;m thinking that perhaps this error would get fixed if I don&#039;t do the setup for reloading wolfSSL instead, but only do the &quot;Ethernet.begin()&quot; thing when there&#039;s a LAN disconnect. Idea is I would like the node to be able to reconnect on its own without human interference.</p><p>Below is the wrapper code I use to make use of WolfSSL with the Arduino Due:</p><div class="codebox"><pre><code>#include &lt;Arduino.h&gt;


// Type definitions
typedef unsigned int   word32;

struct timeval {
  long tv_sec;
  long tv_usec;
};

// Custom RNG Function
int  myRngFunc(byte* output, unsigned int sz)
{
    unsigned int i;
    randomSeed(analogRead(0));

    for (i = 0; i &lt; sz; i++) {
        output[i] = random(0, 254);
    }

    return 0;
}


// Get Unix timestmap via NTP


// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
unsigned int localPort = 8888;       // local port to listen for UDP packets

//long int CURRENT_TIMESTAMP = 2208988800UL;


long int getUnixNTP()
{

    int repeat = 20;
    int res = 0;

    unsigned long epoch =  2208988800U;
    char timeServer[] = &quot;time.nist.gov&quot;; // time.nist.gov NTP server
    const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
    byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets


    for (int i = 0; i &lt; repeat; i++) {
        res = 0;

        res = Udp.begin(localPort);
        if (res == 0) {
            Serial.println(&quot;UDPE0&quot;);
            Udp.stop();
            return -1;
        }
    
    
    
    
    
        // Send an NTP Packet to the given address
    
        // set all bytes in the buffer to 0
        memset(packetBuffer, 0, NTP_PACKET_SIZE);
        // Initialize values needed to form NTP request
        // (see URL above for details on the packets)
        packetBuffer[0] = 0b11100011;   // LI, Version, Mode
        packetBuffer[1] = 0;     // Stratum, or type of clock
        packetBuffer[2] = 6;     // Polling Interval
        packetBuffer[3] = 0xEC;  // Peer Clock Precision
        // 8 bytes of zero for Root Delay &amp; Root Dispersion
        packetBuffer[12]  = 49;
        packetBuffer[13]  = 0x4E;
        packetBuffer[14]  = 49;
        packetBuffer[15]  = 52;
    
        // all NTP fields have been given values, now
        // you can send a packet requesting a timestamp:
        Serial.println(F(&quot;before udp begin packet&quot;));
        res = Udp.beginPacket(timeServer, 123); //NTP requests are to port 123
        if (res == 0) {
            Serial.println(&quot;UDPE1&quot;);
            Udp.stop();
            return -1;
        }
        Udp.write(packetBuffer, NTP_PACKET_SIZE);
        res = Udp.endPacket();
        if (res == 0) {
            Serial.println(&quot;UDPE2&quot;);
            Udp.stop();
            return -1;
        }
        Serial.println(F(&quot;afterx udp end&quot;));
    
        // wait to see if a reply is available
        delay(1000);
    
        if ( Udp.parsePacket() ) {
            Serial.println(F(&quot;UDP1&quot;));
    
            // We&#039;ve received a packet, read the data from it
            Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
            Serial.println(F(&quot;UDP2&quot;));
    
            //the timestamp starts at byte 40 of the received packet and is four bytes,
            // or two words, long. First, esxtract the two words:
    
            unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
            unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
            Serial.println(F(&quot;UDP3&quot;));
    
            // combine the four bytes (two words) into a long integer
            // this is NTP time (seconds since Jan 1 1900):
            unsigned long secsSince1900 = highWord &lt;&lt; 16 | lowWord;
            Serial.print(F(&quot;Seconds since Jan 1 1900 = &quot;));
            Serial.println(secsSince1900);
    
            // now convert NTP time into everyday time:
            Serial.print(F(&quot;Unix time = &quot;));
            // Unix time starts on Jan 1 1970. In seconds, that&#039;s 2208988800:
            const unsigned long seventyYears = 2208988800UL;
            // subtract seventy years:
            epoch = secsSince1900 - seventyYears;
            // print Unix time:
            Serial.println(epoch);
    
            /*
                // print the hour, minute and second:
                Serial.print(F(&quot;The UTC time is &quot;));       // UTC is the time at Greenwich Meridian (GMT)
                Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
                Serial.print(&#039;:&#039;);
                if ( ((epoch % 3600) / 60) &lt; 10 ) {
                // In the first 10 minutes of each hour, we&#039;ll want a leading &#039;0&#039;
                Serial.print(&#039;0&#039;);
                }
                Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
                Serial.print(&#039;:&#039;);
                if ( (epoch % 60) &lt; 10 ) {
                // In the first 10 seconds of each minute, we&#039;ll want a leading &#039;0&#039;
                Serial.print(&#039;0&#039;);
                }
                Serial.println(epoch % 60); // print the second
            */
           Udp.stop();
           break;
        }
        Udp.stop();
        if (i == repeat - 1) {
            Serial.println(&quot;[ntp]: reached 20 err&quot;);
            return -1;
        }
    }

    return epoch;
}

int _gettimeofday( struct timeval *tv, void *tzvp)
{
  //uint64_t t = __your_system_time_function_here__();  // get uptime in nanoseconds
  //tv-&gt;tv_sec = t / 1000000000;  // convert to seconds
  //tv-&gt;tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
  /*
  long mt = millis();
  tv-&gt;tv_sec = mt/1000;
  tv-&gt;tv_usec = mt*1000;
  */
  //long int mt = 1550041049;

  //long int mt = 1550633024 ;

    long int CURRENT_TIMESTAMP = 2208988800UL;

    CURRENT_TIMESTAMP = getUnixNTP();

    if (CURRENT_TIMESTAMP == -1) {
        return -1;
    }

    Serial.print(&quot;[_gettimeofday]: &quot;); Serial.println(CURRENT_TIMESTAMP);
    tv-&gt;tv_sec = CURRENT_TIMESTAMP;
    tv-&gt;tv_usec = 0;
    return 0;  // return non-zero for error
} // end _gettimeofday()



// Custom logger
void wolfssl_custom_logging_cb(const int logLevel, const char *const logMessage) {
    Serial.print(F(&quot;lg &quot;)); Serial.print(logLevel); Serial.print(F(&quot;: &quot;)); Serial.println(logMessage);
 }


// Connection variables and functions

WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;

int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
EthernetClient client;


int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx) {
    Serial.println(F(&quot;[EthernetSend]&quot;));
    int sent = 0;
    Serial.print(F(&quot;[EthernetSend] msg &quot;));
    Serial.println(msg);
    Serial.print(F(&quot;[EthernetSend] sz &quot;));
    Serial.println(sz);
    sent = client.write((byte*)msg, sz);


    // size_t EthernetClient::write(uint8_t b) {
    //     return write(&amp;b, 1);
    //   }
    //   size_t EthernetClient::write(const uint8_t *buf, size_t size) {
    //     if (_sock == MAX_SOCK_NUM) {
    //       setWriteError();
    //       return 0;
    //     }
    //     if (!send(_sock, buf, size)) {
    //       setWriteError();
    //       return 0;
    //     }
    //     return size;
    //   }

    // Error handling
    // Max Sock Num
    // Error in writing
    if (sent == 0) {
        sent = -1;
    }

    return sent;
}

int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
    Serial.println(F(&quot;[EthernetReceive]&quot;));
    int ret = 0;

    if (client.available() &gt; 0) {
        Serial.println(F(&quot;ETR0&quot;));
    }

    if (ret &lt; sz) {
        Serial.println(F(&quot;ETR1&quot;));
    }
    Serial.print(&quot;ret: &quot;);
    Serial.println(ret);
    Serial.print(&quot;sz: &quot;);
    Serial.println(sz);
    Serial.println(&quot;ETRLOOP&quot;);
    while (client.available() &gt; 0 &amp;&amp; ret &lt; sz) {

        reply[ret++] = client.read();
        

    }
    Serial.println(ret);

    //Serial.println(reply);
    Serial.println(&quot;ETR2&quot;);
    if (ret != sz) {
        Serial.println(&quot;ETR3&quot;);
        Serial.println(ret);
        Serial.println(sz);
        return -1; //  return SOCKET_ERROR_E;

    }
    return ret;
}



int8_t wolfSSLSetup(byte * ROOT_CERTS_PEM, unsigned int size_cert, const char * host) {
    WOLFSSL_METHOD* method;

    freeRam();

    // If not init, then ctx is not null
    if (ctx != NULL) {
        Serial.println(F(&quot;[wolfSSLSetup]: ctx not null, so freed&quot;));

        wolfSSL_CTX_free(ctx); ctx = NULL;
    }

    // Enable logging

    wolfSSL_Debugging_ON();

    wolfSSL_SetLoggingCb(&amp;wolfssl_custom_logging_cb);

    // WOLFSSL_ECC_X25519
    //wolfSSL_CTX_UseSupportedCurve(ssl, WOLFSSL_ECC_X25519);
    wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP160K1);
    method = wolfTLSv1_2_client_method();
    //method =  wolfSSLv23_client_method();
    //method = wolfTLSv1_3_client_method();
    if (method == NULL) {
        Serial.println(F(&quot;[wolfTLSv1_2_client_method] unable to get method&quot;));
        return -1;
    }

    //wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);




    ctx = wolfSSL_CTX_new(method);
    if (ctx == NULL) {
        Serial.println(F(&quot;[wolfSSL_CTX_new] unable to get ctx&quot;));
        return -1;
    }
    /*
    Serial.println((char *)ROOT_CERTS_PEM);
    Serial.println(sizeof((&amp;ROOT_CERTS_PEM)[0]));
    Serial.println(sizeof (&amp;ROOT_CERTS_PEM)[0]);
    Serial.println((char *)ROOT_CERTS_PEM_0);
    Serial.println(sizeof(ROOT_CERTS_PEM_0));
    Serial.println(sizeof ROOT_CERTS_PEM_0);
    */
    /* Add cert to ctx */
    int x =     wolfSSL_CTX_load_verify_buffer(ctx, ROOT_CERTS_PEM,size_cert, WOLFSSL_FILETYPE_PEM);
    int err            = 0;
    char errBuf[81];

    if (x != WOLFSSL_SUCCESS) {
        Serial.println(F(&quot;WolfSSL not success with ctx load&quot;));
        err = wolfSSL_get_error(ssl, 0);
        wolfSSL_ERR_error_string_n(err, errBuf, 80);
        Serial.print(F(&quot;ERR wolfSSL_CTX_Load_verify_buffer: &quot;));
        Serial.println(errBuf);
        return -1;
    }

    if (wolfSSL_CTX_UseSNI(ctx, 0, host, (word16) XSTRLEN(host)) != WOLFSSL_SUCCESS) {
        Serial.println(F(&quot;WolfSSL failed UseSNI&quot;));

        wolfSSL_CTX_free(ctx); ctx = NULL;
        Serial.println(F(&quot;UseSNI failed&quot;));
        //err_sys(&quot;UseSNI failed&quot;));
        return -1;
    }
    // initialize wolfSSL using callback functions
    //wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);

    wolfSSL_SetIOSend(ctx, EthernetSend);
    wolfSSL_SetIORecv(ctx, EthernetReceive);

    Serial.println(F(&quot;Setup success!&quot;));
    freeRam();

    return 0;
}

int8_t SSLRequest(const char * host, const int port, char * msg, char * errBuf, char * reply)
{
    int err            = 0;
    int input          = 0;
    int total_input    = 0;

    int msgSz = (int)strlen(msg);

    const char* cipherName;

    int bwritten = 0;
    int8_t ifSuccess = 0;

    int reconnect = 10;

    int8_t res = 0;

    while (1) {

        if (reconnect &gt; 0) {
            reconnect--;

            res = client.connect(host, port);
            Serial.print(&quot;[client.connect ret]: &quot;); Serial.println(res);
            if (res &gt; 0) {
                Serial.print(F(&quot;[SSLRequest] Connected to &quot;));
                Serial.println(host);
                // freeRam();

                if (ctx == NULL) {
                    Serial.println(F(&quot;[SSLRequest] null ctx&quot;));
                } 

                ssl = wolfSSL_new(ctx);
                Serial.println(F(&quot;SSLRequest&quot;));
                freeRam();
                if (ssl == NULL) {
                    Serial.println(F(&quot;[SSLRequest] Unable to allocate SSL object&quot;));
                    //freeRam();

                    err = wolfSSL_get_error(ssl, 0);
                    wolfSSL_ERR_error_string_n(err, errBuf, 80);
                    Serial.print(F(&quot;[SSLRequest] wolfSSL_new: &quot;));
                    Serial.println(errBuf);
                    client.stop();
                    return -1;
                }

                err = wolfSSL_connect(ssl);
                freeRam();

                Serial.print(F(&quot;[SSLRequest] aft wolfSSL_connect err: &quot;)); Serial.println(err);
                if (err != WOLFSSL_SUCCESS) {
                    err = wolfSSL_get_error(ssl, 0);
                    wolfSSL_ERR_error_string(err, errBuf);
                    Serial.print(F(&quot;[SSLRequest] TLS Connect Error: &quot;));
                    Serial.println(errBuf);
                    wolfSSL_shutdown(ssl);
                    wolfSSL_free(ssl);
                    client.stop();

                    return -1;
                }

                Serial.print(F(&quot;[SSLRequest] SSL version is &quot;));
                Serial.println(wolfSSL_get_version(ssl));

                cipherName = wolfSSL_get_cipher(ssl);
                Serial.print(F(&quot;[SSLRequest] SSL cipher suite is &quot;));
                Serial.println(cipherName);
                Serial.println(F(&quot;[msg to send]:&quot;));
                Serial.println(msg);
                Serial.println(strlen(msg));

                bwritten = wolfSSL_write(ssl, (char *) msg, strlen(msg));
                Serial.print(F(&quot;[SSLRequest] [Bytes written= ]&quot;));
                Serial.println(bwritten);
                freeRam();

                if (bwritten &gt; 0) {
                    Serial.println(F(&quot;[SSLRequest] [Server response]: &quot;));
                    while ( client.available() || wolfSSL_pending(ssl) ) {
                        input = wolfSSL_read(ssl, reply, 1000-1);
                        total_input += input;
                        Serial.println(F(&quot;[SSLRequest]: Input&quot;));
                        if ( input &gt; 0 ) {
                            reply[input] = &#039;\0&#039;;
                            Serial.print(reply);
                        } else {
                            Serial.println();
                            Serial.println(F(&quot;Read error&quot;));
                            //return -1;
                        }
                    }

                    Serial.print(F(&quot;[SSLRequest] Bytes read= &quot;));
                    Serial.println(total_input);
                } else {
                    err = wolfSSL_get_error(ssl, 0);
                    wolfSSL_ERR_error_string(err, errBuf);
                    Serial.print(F(&quot;[SSLRequest] LS Write Error: &quot;));
                    Serial.println(errBuf);
                    //return -1;
                }
                freeRam();

                Serial.println(F(&quot;[SSLRequest] [before shutdown]&quot;));
                wolfSSL_shutdown(ssl);
                wolfSSL_free(ssl);

                client.stop();
                Serial.println(F(&quot;[SSLRequest] Connection complete.&quot;));
                reconnect = 0;
                freeRam();
                ifSuccess = 1;

            } else {
                Serial.println(F(&quot;[SSLRequest] Trying to reconnect...&quot;));
            }
        } else {
            if (ifSuccess == 1) {
                return 0; // Transaction completed succssfully
            } else {
                client.stop();

                return -2; // Transaction completed, but did not send properly
            }
        }
        Serial.println(F(&quot;[SSLRequest]: before delay 5000&quot;));
        delay(2000);

    }
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (valcroft)]]></author>
			<pubDate>Mon, 09 Sep 2019 03:08:37 +0000</pubDate>
			<guid>https://www.wolfssl.com/forums/post4847.html#p4847</guid>
		</item>
	</channel>
</rss>
