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()