Skip to content

Commit db368e0

Browse files
committed
Add WiFi command to configure ECC slot
- This is used to configure client certificate and client key in the ssl client The certificate is sent as buffer via AT command and the key is read from secure element nvs namespace
1 parent aada6f2 commit db368e0

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

UNOR4USBBridge/at_handler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
#include "cmds_wifi_station.h"
99
#include "cmds_wifi_softAP.h"
1010
#include "cmds_wifi_netif.h"
11+
#include "cmds_preferences.h"
1112
#include "cmds_wifi_SSL.h"
1213
#include "cmds_wifi_udp.h"
1314
#include "cmds_ble_bridge.h"
1415
#include "cmds_ota.h"
15-
#include "cmds_preferences.h"
1616
#include "cmds_se.h"
1717

1818
using namespace SudoMaker;

UNOR4USBBridge/at_handler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class CAtHandler {
8787
public:
8888
std::vector<std::uint8_t> cert_buf;
8989
std::vector<std::uint8_t> se_buf;
90+
std::vector<std::uint8_t> client_cert_pem;
91+
std::vector<std::uint8_t> client_key_pem;
9092
CAtHandler(HardwareSerial *s);
9193
CAtHandler() = delete ;
9294
static void onWiFiEvent(WiFiEvent_t event);

UNOR4USBBridge/cmds_wifi_SSL.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ INCBIN(x509_crt_bundle, PATH_CERT_BUNDLE);
1111
#endif
1212

1313
#include "at_handler.h"
14+
#include "mbedtls/pem.h"
15+
#include "SSE.h"
1416

1517
#ifndef WIFI_CLIENT_DEF_CONN_TIMEOUT_MS
1618
#define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000)
@@ -110,6 +112,105 @@ void CAtHandler::add_cmds_wifi_SSL() {
110112
return chAT::CommandStatus::ERROR;
111113
}
112114
};
115+
116+
/* ....................................................................... */
117+
command_table[_SETECCSLOT] = [this](auto & srv, auto & parser) {
118+
/* ....................................................................... */
119+
switch (parser.cmd_mode) {
120+
case chAT::CommandMode::Write: {
121+
if (parser.args.size() != 3) {
122+
return chAT::CommandStatus::ERROR;
123+
}
124+
125+
auto &sock_num = parser.args[0];
126+
auto &slot_num = parser.args[1];
127+
auto &cert_len = parser.args[2];
128+
if (sock_num.empty() || slot_num.empty() || cert_len.empty()) {
129+
return chAT::CommandStatus::ERROR;
130+
}
131+
132+
int sock = atoi(sock_num.c_str());
133+
int size = atoi(cert_len.c_str());
134+
135+
CClientWrapper the_client = getClient(sock);
136+
if (the_client.sslclient == nullptr) {
137+
return chAT::CommandStatus::ERROR;
138+
}
139+
140+
std::vector<unsigned char> client_cert_der;
141+
client_cert_der = srv.inhibit_read(size);
142+
size_t offset = client_cert_der.size();
143+
144+
if(offset < size) {
145+
client_cert_der.resize(size);
146+
do {
147+
offset += serial->read(client_cert_der.data() + offset, size - offset);
148+
} while (offset < size);
149+
}
150+
srv.continue_read();
151+
152+
#if ECC_DEBUG_ENABLED
153+
log_v("_SETECCSLOT: input cert");
154+
log_buf_v((const uint8_t *)client_cert_der.data(), size);
155+
#endif
156+
157+
/* Convert client certificate DER buffer into PEM */
158+
client_cert_pem.resize(1024);
159+
size_t olen;
160+
mbedtls_pem_write_buffer("-----BEGIN CERTIFICATE-----\n",
161+
"-----END CERTIFICATE-----\n",
162+
client_cert_der.data(), size,
163+
client_cert_pem.data(), 1024,
164+
&olen);
165+
client_cert_pem.resize(olen);
166+
167+
#if ECC_DEBUG_ENABLED
168+
log_v("_SETECCSLOT: output cert");
169+
log_v("\n%s", client_cert_pem.data());
170+
#endif
171+
172+
/* Set client certificate */
173+
the_client.sslclient->setCertificate((const char *)client_cert_pem.data());
174+
175+
/* Read private key from non volatile storage in DER format */
176+
std::vector<unsigned char> client_key_der;
177+
int len = sse.getBytesLength(slot_num.c_str());
178+
int ret = -1;
179+
client_key_der.resize(len);
180+
if ((ret = sse.getBytes(slot_num.c_str(), client_key_der.data(), len)) < len) {
181+
log_e(" failed\n ! sse.getBytes returned -0x%04x", (unsigned int) -ret);
182+
return chAT::CommandStatus::ERROR;
183+
}
184+
185+
#if ECC_DEBUG_ENABLED
186+
log_v("_SETECCSLOT: input key");
187+
log_buf_v((const uint8_t *)client_key_der.data(), ret);
188+
#endif
189+
190+
/* Convert private key in PEM format */
191+
client_key_pem.resize(1024);
192+
mbedtls_pem_write_buffer("-----BEGIN EC PRIVATE KEY-----\n",
193+
"-----END EC PRIVATE KEY-----\n",
194+
client_key_der.data(), len,
195+
client_key_pem.data(), 1024,
196+
&olen);
197+
client_key_pem.resize(olen);
198+
199+
#if ECC_DEBUG_ENABLED
200+
log_v("_SETECCSLOT: output key");
201+
log_v("\n%s", client_key_pem.data());
202+
#endif
203+
204+
/* Set client key */
205+
the_client.sslclient->setPrivateKey((const char *)client_key_pem.data());
206+
207+
return chAT::CommandStatus::OK;
208+
}
209+
default:
210+
return chAT::CommandStatus::ERROR;
211+
}
212+
};
213+
113214
/* ....................................................................... */
114215
command_table[_SSLCLIENTSTATE] = [this](auto & srv, auto & parser) {
115216
/* ....................................................................... */

UNOR4USBBridge/commands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ enum file_op {
5858
#define _CLIENTCONNECTED "+CLIENTCONNECTED"
5959
#define _SSLBEGINCLIENT "+SSLBEGINCLIENT"
6060
#define _SETCAROOT "+SETCAROOT"
61+
#define _SETECCSLOT "+SETECCSLOT"
6162
#define _SSLCLIENTSTATE "+SSLCLIENTSTATE"
6263
#define _SSLCLIENTCONNECTNAME "+SSLCLIENTCONNECTNAME"
6364
#define _SSLCLIENTCONNECT "+SSLCLIENTCONNECT"

0 commit comments

Comments
 (0)