diff --git a/src/BearSSLClient.cpp b/src/BearSSLClient.cpp index e8e8d3c..f3bed28 100644 --- a/src/BearSSLClient.cpp +++ b/src/BearSSLClient.cpp @@ -47,8 +47,8 @@ BearSSLClient::BearSSLClient(Client* client, const br_x509_trust_anchor* myTAs, _noSNI(false), _ecChainLen(0) { - _ecVrfy = br_ecdsa_vrfy_asn1_get_default(); - _ecSign = br_ecdsa_sign_asn1_get_default(); + _ecVrfy = eccX08_vrfy_asn1; + _ecSign = eccX08_sign_asn1; _ecKey.curve = 0; _ecKey.x = NULL; @@ -290,6 +290,53 @@ void BearSSLClient::setEccSlot(int ecc508KeySlot, const char cert[]) } } +void BearSSLClient::setEccCertParent(const char cert[]) +{ + // try to decode the cert + br_pem_decoder_context pemDecoder; + + size_t certLen = strlen(cert); + + // free old data + if (_ecCertDynamic && _ecCert[1].data) { + free(_ecCert[1].data); + _ecCert[1].data = NULL; + } + + // assume the decoded cert is 3/4 the length of the input + _ecCert[1].data = (unsigned char*)malloc(((certLen * 3) + 3) / 4); + _ecCert[1].data_len = 0; + _ecChainLen = 2; + + br_pem_decoder_init(&pemDecoder); + + while (certLen) { + size_t len = br_pem_decoder_push(&pemDecoder, cert, certLen); + + cert += len; + certLen -= len; + + switch (br_pem_decoder_event(&pemDecoder)) { + case BR_PEM_BEGIN_OBJ: + br_pem_decoder_setdest(&pemDecoder, BearSSLClient::parentAppendCert, this); + break; + + case BR_PEM_END_OBJ: + if (_ecCert[1].data_len) { + // done + _ecCertDynamic = true; + return; + } + break; + + case BR_PEM_ERROR: + // failure + free(_ecCert[1].data); + return; + } + } +} + int BearSSLClient::errorCode() { return br_ssl_engine_last_error(&_sc.eng); @@ -421,3 +468,12 @@ void BearSSLClient::clientAppendCert(void *ctx, const void *data, size_t len) memcpy(&c->_ecCert[0].data[c->_ecCert[0].data_len], data, len); c->_ecCert[0].data_len += len; } + +void BearSSLClient::parentAppendCert(void *ctx, const void *data, size_t len) +{ + BearSSLClient* c = (BearSSLClient*)ctx; + + memcpy(&c->_ecCert[1].data[c->_ecCert[1].data_len], data, len); + c->_ecCert[1].data_len += len; +} + diff --git a/src/BearSSLClient.h b/src/BearSSLClient.h index b45e30a..93b1779 100644 --- a/src/BearSSLClient.h +++ b/src/BearSSLClient.h @@ -83,6 +83,7 @@ class BearSSLClient : public Client { void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength); void setEccSlot(int ecc508KeySlot, const char cert[]); + void setEccCertParent(const char cert[]); int errorCode(); @@ -91,6 +92,7 @@ class BearSSLClient : public Client { static int clientRead(void *ctx, unsigned char *buf, size_t len); static int clientWrite(void *ctx, const unsigned char *buf, size_t len); static void clientAppendCert(void *ctx, const void *data, size_t len); + static void parentAppendCert(void *ctx, const void *data, size_t len); private: Client* _client;