@@ -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
1517void 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 /* ....................................................................... */
0 commit comments