@@ -48,6 +48,7 @@ BearSSLClient::BearSSLClient(Client* client, const br_x509_trust_anchor* myTAs,
48
48
_TAs(myTAs),
49
49
_numTAs(myNumTAs),
50
50
_noSNI(false ),
51
+ _skeyDecoder(NULL ),
51
52
_ecChainLen(0 )
52
53
{
53
54
#ifndef ARDUINO_DISABLE_ECCX08
@@ -75,6 +76,11 @@ BearSSLClient::~BearSSLClient()
75
76
free (_ecCert[0 ].data );
76
77
_ecCert[0 ].data = NULL ;
77
78
}
79
+
80
+ if (_skeyDecoder) {
81
+ free (_skeyDecoder);
82
+ _skeyDecoder = NULL ;
83
+ }
78
84
}
79
85
80
86
int BearSSLClient::connect (IPAddress ip, uint16_t port)
@@ -303,6 +309,79 @@ void BearSSLClient::setEccSlot(int ecc508KeySlot, const char cert[])
303
309
}
304
310
}
305
311
312
+ void BearSSLClient::setKey (const char key[], const char cert[])
313
+ {
314
+ // try to decode the key and cert
315
+ br_pem_decoder_context pemDecoder;
316
+
317
+ size_t keyLen = strlen (key);
318
+ size_t certLen = strlen (cert);
319
+
320
+ br_pem_decoder_init (&pemDecoder);
321
+
322
+ if (_skeyDecoder == NULL ) {
323
+ _skeyDecoder = (br_skey_decoder_context*)malloc (sizeof (br_skey_decoder_context));
324
+ }
325
+
326
+ br_skey_decoder_init (_skeyDecoder);
327
+
328
+ while (keyLen) {
329
+ size_t len = br_pem_decoder_push (&pemDecoder, key, keyLen);
330
+
331
+ key += len;
332
+ keyLen -= len;
333
+
334
+ switch (br_pem_decoder_event (&pemDecoder)) {
335
+ case BR_PEM_BEGIN_OBJ:
336
+ br_pem_decoder_setdest (&pemDecoder, BearSSLClient::clientAppendKey, this );
337
+ break ;
338
+
339
+ case BR_PEM_END_OBJ:
340
+ if (br_skey_decoder_last_error (_skeyDecoder) != 0 ) {
341
+ return ;
342
+ }
343
+ break ;
344
+
345
+ case BR_PEM_ERROR:
346
+ return ;
347
+ }
348
+ }
349
+
350
+ // assume the decoded cert is 3/4 the length of the input
351
+ _ecCert[0 ].data = (unsigned char *)malloc (((certLen * 3 ) + 3 ) / 4 );
352
+ _ecCert[0 ].data_len = 0 ;
353
+ _ecChainLen = 1 ;
354
+
355
+ br_pem_decoder_init (&pemDecoder);
356
+
357
+ while (certLen) {
358
+ size_t len = br_pem_decoder_push (&pemDecoder, cert, certLen);
359
+
360
+ cert += len;
361
+ certLen -= len;
362
+
363
+ switch (br_pem_decoder_event (&pemDecoder)) {
364
+ case BR_PEM_BEGIN_OBJ:
365
+ br_pem_decoder_setdest (&pemDecoder, BearSSLClient::clientAppendCert, this );
366
+ break ;
367
+
368
+ case BR_PEM_END_OBJ:
369
+ if (_ecCert[0 ].data_len ) {
370
+ // done
371
+ _ecCertDynamic = true ;
372
+ return ;
373
+ }
374
+ break ;
375
+
376
+ case BR_PEM_ERROR:
377
+ // failure
378
+ free (_ecCert[0 ].data );
379
+ _ecCert[0 ].data = NULL ;
380
+ return ;
381
+ }
382
+ }
383
+ }
384
+
306
385
void BearSSLClient::setEccCertParent (const char cert[])
307
386
{
308
387
// try to decode the cert
@@ -383,7 +462,17 @@ int BearSSLClient::connectSSL(const char* host)
383
462
384
463
// enable client auth
385
464
if (_ecCert[0 ].data_len ) {
386
- br_ssl_client_set_single_ec (&_sc, _ecCert, _ecChainLen, &_ecKey, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default (), _ecSign);
465
+ if (_skeyDecoder) {
466
+ int skeyType = br_skey_decoder_key_type (_skeyDecoder);
467
+
468
+ if (skeyType == BR_KEYTYPE_EC) {
469
+ br_ssl_client_set_single_ec (&_sc, _ecCert, _ecChainLen, br_skey_decoder_get_ec (_skeyDecoder), BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default (), br_ecdsa_sign_asn1_get_default ());
470
+ } else if (skeyType == BR_KEYTYPE_RSA) {
471
+ br_ssl_client_set_single_rsa (&_sc, _ecCert, _ecChainLen, br_skey_decoder_get_rsa (_skeyDecoder), br_rsa_pkcs1_sign_get_default ());
472
+ }
473
+ } else {
474
+ br_ssl_client_set_single_ec (&_sc, _ecCert, _ecChainLen, &_ecKey, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default (), _ecSign);
475
+ }
387
476
}
388
477
389
478
// set the hostname used for SNI
@@ -486,6 +575,13 @@ void BearSSLClient::clientAppendCert(void *ctx, const void *data, size_t len)
486
575
c->_ecCert [0 ].data_len += len;
487
576
}
488
577
578
+ void BearSSLClient::clientAppendKey (void *ctx, const void *data, size_t len)
579
+ {
580
+ BearSSLClient* c = (BearSSLClient*)ctx;
581
+
582
+ br_skey_decoder_push (c->_skeyDecoder , data, len);
583
+ }
584
+
489
585
void BearSSLClient::parentAppendCert (void *ctx, const void *data, size_t len)
490
586
{
491
587
BearSSLClient* c = (BearSSLClient*)ctx;
0 commit comments