@@ -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
void CAtHandler::add_cmds_wifi_SSL () {
16
18
/* ....................................................................... */
@@ -106,6 +108,105 @@ void CAtHandler::add_cmds_wifi_SSL() {
106
108
return chAT::CommandStatus::ERROR;
107
109
}
108
110
};
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
+
109
210
/* ....................................................................... */
110
211
command_table[_SSLCLIENTSTATE] = [this ](auto & srv, auto & parser) {
111
212
/* ....................................................................... */
0 commit comments