Skip to content

Commit 07ba952

Browse files
committed
Add support for PEM certs with ECC slot
1 parent e810194 commit 07ba952

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

src/BearSSLClient.cpp

+62
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,15 @@ BearSSLClient::BearSSLClient(Client& client) :
3939

4040
_ecCert.data = NULL;
4141
_ecCert.data_len = 0;
42+
_ecCertDynamic = false;
4243
}
4344

4445
BearSSLClient::~BearSSLClient()
4546
{
47+
if (_ecCertDynamic && _ecCert.data) {
48+
free(_ecCert.data);
49+
_ecCert.data = NULL;
50+
}
4651
}
4752

4853
int BearSSLClient::connect(IPAddress ip, uint16_t port)
@@ -175,6 +180,55 @@ void BearSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLen
175180

176181
_ecCert.data = (unsigned char*)cert;
177182
_ecCert.data_len = certLength;
183+
_ecCertDynamic = false;
184+
}
185+
186+
void BearSSLClient::setEccSlot(int ecc508KeySlot, const char cert[])
187+
{
188+
// try to decode the cert
189+
br_pem_decoder_context pemDecoder;
190+
191+
size_t certLen = strlen(cert);
192+
193+
// free old data
194+
if (_ecCertDynamic && _ecCert.data) {
195+
free(_ecCert.data);
196+
_ecCert.data = NULL;
197+
}
198+
199+
// assume the decoded cert is 3/4 the length of the input
200+
_ecCert.data = (unsigned char*)malloc(((certLen * 3) + 3) / 4);
201+
_ecCert.data_len = 0;
202+
203+
br_pem_decoder_init(&pemDecoder);
204+
205+
while (certLen) {
206+
size_t len = br_pem_decoder_push(&pemDecoder, cert, certLen);
207+
208+
cert += len;
209+
certLen -= len;
210+
211+
switch (br_pem_decoder_event(&pemDecoder)) {
212+
case BR_PEM_BEGIN_OBJ:
213+
br_pem_decoder_setdest(&pemDecoder, BearSSLClient::clientAppendCert, this);
214+
break;
215+
216+
case BR_PEM_END_OBJ:
217+
if (_ecCert.data_len) {
218+
// done
219+
setEccSlot(ecc508KeySlot, _ecCert.data, _ecCert.data_len);
220+
_ecCertDynamic = true;
221+
return;
222+
}
223+
break;
224+
225+
case BR_PEM_ERROR:
226+
// failure
227+
free(_ecCert.data);
228+
setEccSlot(ecc508KeySlot, NULL, 0);
229+
return;
230+
}
231+
}
178232
}
179233

180234
int BearSSLClient::connectSSL(const char* host)
@@ -296,3 +350,11 @@ int BearSSLClient::clientWrite(void *ctx, const unsigned char *buf, size_t len)
296350

297351
return result;
298352
}
353+
354+
void BearSSLClient::clientAppendCert(void *ctx, const void *data, size_t len)
355+
{
356+
BearSSLClient* c = (BearSSLClient*)ctx;
357+
358+
memcpy(&c->_ecCert.data[c->_ecCert.data_len], data, len);
359+
c->_ecCert.data_len += len;
360+
}

src/BearSSLClient.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,19 @@ class BearSSLClient : public Client {
5252
using Print::write;
5353

5454
void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength);
55+
void setEccSlot(int ecc508KeySlot, const char cert[]);
5556

5657
private:
5758
int connectSSL(const char* host);
5859
static int clientRead(void *ctx, unsigned char *buf, size_t len);
5960
static int clientWrite(void *ctx, const unsigned char *buf, size_t len);
61+
static void clientAppendCert(void *ctx, const void *data, size_t len);
6062

6163
private:
62-
Client* _client;
64+
Client* _client;
6365
br_ec_private_key _ecKey;
6466
br_x509_certificate _ecCert;
67+
bool _ecCertDynamic;
6568

6669
br_ssl_client_context _sc;
6770
br_x509_minimal_context _xc;

0 commit comments

Comments
 (0)