Skip to content

Commit a334932

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 45bc131 commit a334932

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

UNOR4USBBridge/commands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum {
5757
#define _CLIENTCONNECTED "+CLIENTCONNECTED"
5858
#define _SSLBEGINCLIENT "+SSLBEGINCLIENT"
5959
#define _SETCAROOT "+SETCAROOT"
60+
#define _SETECCSLOT "+SETECCSLOT"
6061
#define _SSLCLIENTSTATE "+SSLCLIENTSTATE"
6162
#define _SSLCLIENTCONNECTNAME "+SSLCLIENTCONNECTNAME"
6263
#define _SETIP "+SETIP"

0 commit comments

Comments
 (0)