1 (edited by mariorossi 2021-12-30 14:45:46)

Topic: Connection between Arduino client and Python server

Hello everyone, we are having some troubles with secure communication between Arduino client and Python server. The client is stuck and waits for the connection and nothing happens, this happens precisely when the function

wolfSSL_connect(ssl)

is called. The following is the code:

Client:

#include <WiFi.h>
#include "wolfssl.h"
#include "wolfssl/ssl.h"

#define LIGHT_PIN 34
#define TEMP_PIN 35

const char* ssid = "myssid";
const char* password= "mypassword";
const uint16_t port = 8090;
const char* host = "myip";

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

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

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

  /* Initialize WiFi */
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("...");
  }
  Serial.print("WiFi connected with IP: ");
  Serial.println(WiFi.localIP());
  
  /* Initialize WolfSSL */
  WOLFSSL_METHOD* method;
  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;
  }
  //wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
  wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
  wolfSSL_SetIOSend(ctx, EthernetSend);
  wolfSSL_SetIORecv(ctx, EthernetReceive);
}

void loop() {
  int err = 0;
  int input = 0;
  int total_input = 0;
  char msg[16];
  int msgSz = (int) strlen(msg);
  char errBuf[80];
  char reply[80];
  const char* cipherName;
  
  int lightLevel = analogRead(LIGHT_PIN);
  itoa(lightLevel, msg, 10);

  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;
    }

    Serial.println("Before connect");
    err = wolfSSL_connect(ssl);
    Serial.println("A");
    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: ");
      /* wait for data */
      while (!client.available()) {}
      
      /* read data */
      while (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.");
    } else {
      Serial.println("Trying to reconnect...");
    }
  delay(1000);
}

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;
}

Server:

import sys
import socket
import argparse
import wolfssl


def get_method(index):
    return (
        wolfssl.PROTOCOL_SSLv3,
        wolfssl.PROTOCOL_TLSv1,
        wolfssl.PROTOCOL_TLSv1_1,
        wolfssl.PROTOCOL_TLSv1_2,
        wolfssl.PROTOCOL_SSLv23
    )[index]


def main():
    bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    bind_socket.bind(('0.0.0.0', 8090))
    bind_socket.listen(0)

    print("Server listening on port", bind_socket.getsockname()[1])

    # enable debug, if native wolfSSL has been compiled with '--enable-debug'
    wolfssl.WolfSSL.enable_debug()
    context = wolfssl.SSLContext(get_method(3), server_side=True)
    context.load_cert_chain("./certs/server-cert.pem", "./certs/server-key.pem")
    context.set_ciphers("")


    context.verify_mode = wolfssl.CERT_NONE


    while True:
        try:
            secure_socket = None
            new_socket, from_addr = bind_socket.accept()
            secure_socket = context.wrap_socket(new_socket)

            print("Connection received from", from_addr)
            print("\n", secure_socket.read(), "\n")
            secure_socket.write(b"I hear you fa shizzle!")

        except KeyboardInterrupt:
            print()
            break

        finally:
            if secure_socket:
                secure_socket.close()

    break

    bind_socket.close()


if __name__ == '__main__':
    main()

Share

Re: Connection between Arduino client and Python server

Hi Mario,

Are you confident the python wolfSSL server is working correctly? You might try using our built-in C

./examples/server/server -b -p 8090

. I tried to setup the wolfssl-py here and looks like it is a bit outdated.

For the client side the call to wolfSSL_connect will trigger the EthernetSend with a client_hello TLS packet and the server should respond with a server_hello. You might consider enabling the client side debugging by building with

DEBUG_WOLFSSL

and calling

wolfSSL_Debugging_ON();

to see what is happening. You might also consider adding some debug statements in your ethernet send / recv functions. I did compare the client to our IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino.

Thanks,
David Garske, wolfSSL
Happy New Year!

Share