Hi everyone,
I have been trying for some time now to realize the following via the NativeEthernet-Libary and a Teensy 4.1 with the Ethernet-Kit:
The Teensy 4.1 regularly pings a web server via https GET request and receives a control command back. However, our computing center has given us the requirement to store an x.509 certificate on the Teensy so that the proxy server in the network forwards the request outside. Alternatively, if the whole thing is without a certificate, then an SSH connection is ok with them, but this would mean rewriting or creating a translate layer for the backend.
Now to my question:
Has anyone already gotten the NativeEthernet-Libary and a x.509 certificate to work? I last tried it with ArduinoBearSSL in the small demo below, but the Teensy fails when calling the connection (sslClient.connect()) and reboots.
If I can help with more information, feel free to ask!
Many thanks in advance!
Hardware:
I have been trying for some time now to realize the following via the NativeEthernet-Libary and a Teensy 4.1 with the Ethernet-Kit:
The Teensy 4.1 regularly pings a web server via https GET request and receives a control command back. However, our computing center has given us the requirement to store an x.509 certificate on the Teensy so that the proxy server in the network forwards the request outside. Alternatively, if the whole thing is without a certificate, then an SSH connection is ok with them, but this would mean rewriting or creating a translate layer for the backend.
Now to my question:
Has anyone already gotten the NativeEthernet-Libary and a x.509 certificate to work? I last tried it with ArduinoBearSSL in the small demo below, but the Teensy fails when calling the connection (sslClient.connect()) and reboots.
If I can help with more information, feel free to ask!
Many thanks in advance!
Hardware:
- Teensy 4.1
- Ethernet-Kit (soldered and connected according to explanation; works without SSL)
- Arduino 2.3.3
- Windows 11
C++:
#include <NativeEthernet.h>
#include <ArduinoBearSSL.h>
// Define the server and port
const char *server = "api.domain.com"; // Replace with your server's address
const int server_port = 443; // HTTPS port
IPAddress ip(192, 168, 0, 100);
IPAddress myDns(192, 168, 0, 1);
const uint8_t root_ca_der[] = {
0x30, 0x82, 0x06, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01,
....
0xb9, 0x5f, 0x49, 0xba, 0x56, 0xb0, 0x9b
};
const size_t root_ca_der_len = 1543;
EthernetClient ethClient;
BearSSLClient sslClient(ethClient);
byte mac[] = {};
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
bool printWebData = true;
void teensyMAC(uint8_t *mac) {
for (uint8_t by = 0; by < 2; by++) mac[by] = (HW_OCOTP_MAC1 >> ((1 - by) * 8)) & 0xFF;
for (uint8_t by = 0; by < 4; by++) mac[by + 2] = (HW_OCOTP_MAC0 >> ((3 - by) * 8)) & 0xFF;
Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
teensyMAC(mac);
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip, myDns);
} else {
Serial.print(" DHCP assigned IP ");
Serial.println(Ethernet.localIP());
}
// give a second to initialize:
delay(1000);
Serial.print("connecting to ");
Serial.print(server);
Serial.println("...");
// CreateBearSSL certificate object
br_x509_certificate root_ca_cert;
memset(&root_ca_cert, 0, sizeof(root_ca_cert));
root_ca_cert.data = (unsigned char *)root_ca_der;
root_ca_cert.data_len = root_ca_der_len;
sslClient.setEccCert(root_ca_cert);
// Send an HTTPS GET request
if (sslClient.connect(server, server_port)) {
sslClient.println("GET /status HTTP/1.1");
sslClient.print("Host: ");
sslClient.println(server);
sslClient.println("Connection: close");
sslClient.println();
} else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
beginMicros = micros();
}
void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
int len = sslClient.available();
if (len > 0) {
byte buffer[80];
if (len > 80) len = 80;
sslClient.read(buffer, len);
if (printWebData) {
Serial.write(buffer, len); // show in the serial monitor (slows some boards)
}
byteCount = byteCount + len;
}
// if the server's disconnected, stop the client:
if (!sslClient.connected()) {
endMicros = micros();
Serial.println();
Serial.println("disconnecting.");
sslClient.stop();
Serial.print("Received ");
Serial.print(byteCount);
Serial.print(" bytes in ");
float seconds = (float)(endMicros - beginMicros) / 1000000.0;
Serial.print(seconds, 4);
float rate = (float)byteCount / seconds / 1000.0;
Serial.print(", rate = ");
Serial.print(rate);
Serial.print(" kbytes/second");
Serial.println();
// do nothing forevermore:
while (true) {
delay(1);
}
}
}