@@ -11,6 +11,8 @@ INCBIN(x509_crt_bundle, PATH_CERT_BUNDLE);
11
11
#endif
12
12
13
13
#include " at_handler.h"
14
+ #include " mbedtls/pem.h"
15
+ #include " SSE.h"
14
16
15
17
#ifndef WIFI_CLIENT_DEF_CONN_TIMEOUT_MS
16
18
#define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000 )
@@ -110,6 +112,105 @@ void CAtHandler::add_cmds_wifi_SSL() {
110
112
return chAT::CommandStatus::ERROR;
111
113
}
112
114
};
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
+
113
214
/* ....................................................................... */
114
215
command_table[_SSLCLIENTSTATE] = [this ](auto & srv, auto & parser) {
115
216
/* ....................................................................... */
0 commit comments