Skip to content

Commit d2a8e8a

Browse files
Add debug messages on BSSL errors (#5723)
Add debugging output when DEBUG_ESP_SSL is defined. Add dump of actual error when connect fails
1 parent e74b1e5 commit d2a8e8a

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

+62-4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ extern "C" {
5858

5959
#endif
6060

61+
#ifdef DEBUG_ESP_SSL
62+
#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
63+
#else
64+
#define DEBUG_BSSL(...)
65+
#endif
66+
6167
namespace BearSSL {
6268

6369
void WiFiClientSecure::_clear() {
@@ -214,9 +220,11 @@ int WiFiClientSecure::connect(CONST IPAddress& ip, uint16_t port) {
214220
int WiFiClientSecure::connect(const char* name, uint16_t port) {
215221
IPAddress remote_addr;
216222
if (!WiFi.hostByName(name, remote_addr)) {
223+
DEBUG_BSSL("connect: Name loopup failure\n");
217224
return 0;
218225
}
219226
if (!WiFiClient::connect(remote_addr, port)) {
227+
DEBUG_BSSL("connect: Unable to connect TCP socket\n");
220228
return 0;
221229
}
222230
return _connectSSL(name);
@@ -309,6 +317,7 @@ size_t WiFiClientSecure::write(Stream& stream) {
309317
size_t countSent;
310318

311319
if (!connected() || !_handshake_done) {
320+
DEBUG_BSSL("write: Connect/handshake not completed yet\n");
312321
return 0;
313322
}
314323

@@ -336,6 +345,7 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size) {
336345
return 0; // We're still connected, but nothing to read
337346
}
338347
if (!avail && !conn) {
348+
DEBUG_BSSL("read: Not connected, none left available\n");
339349
return -1;
340350
}
341351

@@ -349,14 +359,19 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size) {
349359
return to_copy;
350360
}
351361

352-
return conn ? 0 : -1; // If we're connected, no error but no read. OTW error
362+
if (!conn) {
363+
DEBUG_BSSL("read: Not connected\n");
364+
return -1;
365+
}
366+
return 0; // If we're connected, no error but no read.
353367
}
354368

355369
int WiFiClientSecure::read() {
356370
uint8_t c;
357371
if (1 == read(&c, 1)) {
358372
return c;
359373
}
374+
DEBUG_BSSL("read: failed\n");
360375
return -1;
361376
}
362377

@@ -383,17 +398,20 @@ int WiFiClientSecure::available() {
383398

384399
int WiFiClientSecure::peek() {
385400
if (!ctx_present() || !available()) {
401+
DEBUG_BSSL("peek: Not connected, none left available\n");
386402
return -1;
387403
}
388404
if (_recvapp_buf && _recvapp_len) {
389405
return _recvapp_buf[0];
390406
}
407+
DEBUG_BSSL("peek: No data left\n");
391408
return -1;
392409
}
393410

394411
size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
395412
size_t to_copy = 0;
396413
if (!ctx_present()) {
414+
DEBUG_BSSL("peekBytes: Not connected\n");
397415
return 0;
398416
}
399417

@@ -415,6 +433,7 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
415433
*/
416434
int WiFiClientSecure::_run_until(unsigned target, bool blocking) {
417435
if (!ctx_present()) {
436+
DEBUG_BSSL("_run_until: Not connected\n");
418437
return -1;
419438
}
420439
for (int no_work = 0; blocking || no_work < 2;) {
@@ -477,6 +496,7 @@ int WiFiClientSecure::_run_until(unsigned target, bool blocking) {
477496
This is unrecoverable here, so we report an error.
478497
*/
479498
if (state & BR_SSL_RECVAPP) {
499+
DEBUG_BSSL("_run_until: Fatal protocol state\n");
480500
return -1;
481501
}
482502

@@ -524,6 +544,7 @@ bool WiFiClientSecure::_wait_for_handshake() {
524544
while (!_handshake_done && _clientConnected()) {
525545
int ret = _run_until(BR_SSL_SENDAPP);
526546
if (ret < 0) {
547+
DEBUG_BSSL("_wait_for_handshake: failed\n");
527548
break;
528549
}
529550
if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) {
@@ -552,10 +573,14 @@ bool WiFiClientSecure::setFingerprint(const char *fpStr) {
552573
c = pgm_read_byte(fpStr++);
553574
if (!c) break; // String ended, done processing
554575
d = pgm_read_byte(fpStr++);
555-
if (!d) return false; // Only half of the last hex digit, error
576+
if (!d) {
577+
DEBUG_BSSL("setFingerprint: FP too short\n");
578+
return false; // Only half of the last hex digit, error
579+
}
556580
c = htoi(c);
557581
d = htoi(d);
558582
if ((c>15) || (d>15)) {
583+
DEBUG_BSSL("setFingerprint: Invalid char\n");
559584
return false; // Error in one of the hex characters
560585
}
561586
fp[idx++] = (c<<4)|d;
@@ -566,6 +591,7 @@ bool WiFiClientSecure::setFingerprint(const char *fpStr) {
566591
}
567592
}
568593
if ((idx != 20) || pgm_read_byte(fpStr)) {
594+
DEBUG_BSSL("setFingerprint: Garbage at end of fp\n");
569595
return false; // Garbage at EOL or we didn't have enough hex digits
570596
}
571597
return setFingerprint(fp);
@@ -641,13 +667,15 @@ extern "C" {
641667
static unsigned insecure_end_chain(const br_x509_class **ctx) {
642668
const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx;
643669
if (!xc->done_cert) {
670+
DEBUG_BSSL("insecure_end_chain: No cert seen\n");
644671
return 1; // error
645672
}
646673

647674
// Handle SHA1 fingerprint matching
648675
char res[20];
649676
br_sha1_out(&xc->sha1_cert, res);
650677
if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) {
678+
DEBUG_BSSL("insecure_end_chain: Received cert FP doesn't match\n");
651679
return BR_ERR_X509_NOT_TRUSTED;
652680
}
653681

@@ -657,6 +685,7 @@ extern "C" {
657685
br_sha256_out(&xc->sha256_issuer, res_issuer);
658686
br_sha256_out(&xc->sha256_subject, res_subject);
659687
if (xc->allow_self_signed && memcmp(res_subject, res_issuer, sizeof(res_issuer))) {
688+
DEBUG_BSSL("insecure_end_chain: Didn't get self-signed cert\n");
660689
return BR_ERR_X509_NOT_TRUSTED;
661690
}
662691

@@ -816,6 +845,7 @@ bool WiFiClientSecure::setCiphers(const uint16_t *cipherAry, int cipherCount) {
816845
_cipher_list = nullptr;
817846
_cipher_list = std::shared_ptr<uint16_t>(new uint16_t[cipherCount], std::default_delete<uint16_t[]>());
818847
if (!_cipher_list.get()) {
848+
DEBUG_BSSL("setCiphers: list empty\n");
819849
return false;
820850
}
821851
memcpy_P(_cipher_list.get(), cipherAry, cipherCount * sizeof(uint16_t));
@@ -837,6 +867,7 @@ bool WiFiClientSecure::_installClientX509Validator() {
837867
// Use common insecure x509 authenticator
838868
_x509_insecure = std::make_shared<struct br_x509_insecure_context>();
839869
if (!_x509_insecure) {
870+
DEBUG_BSSL("_installClientX509Validator: OOM for _x509_insecure\n");
840871
return false;
841872
}
842873
br_x509_insecure_init(_x509_insecure.get(), _use_fingerprint, _fingerprint, _use_self_signed);
@@ -845,6 +876,7 @@ bool WiFiClientSecure::_installClientX509Validator() {
845876
// Simple, pre-known public key authenticator, ignores cert completely.
846877
_x509_knownkey = std::make_shared<br_x509_knownkey_context>();
847878
if (!_x509_knownkey) {
879+
DEBUG_BSSL("_installClientX509Validator: OOM for _x509_knownkey\n");
848880
return false;
849881
}
850882
if (_knownkey->isRSA()) {
@@ -857,6 +889,7 @@ bool WiFiClientSecure::_installClientX509Validator() {
857889
// X509 minimal validator. Checks dates, cert chain for trusted CA, etc.
858890
_x509_minimal = std::make_shared<br_x509_minimal_context>();
859891
if (!_x509_minimal) {
892+
DEBUG_BSSL("_installClientX509Validator: OOM for _x509_minimal\n");
860893
return false;
861894
}
862895
br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _ta ? _ta->getTrustAnchors() : nullptr, _ta ? _ta->getCount() : 0);
@@ -878,13 +911,14 @@ bool WiFiClientSecure::_installClientX509Validator() {
878911
// Called by connect() to do the actual SSL setup and handshake.
879912
// Returns if the SSL handshake succeeded.
880913
bool WiFiClientSecure::_connectSSL(const char* hostName) {
914+
DEBUG_BSSL("_connectSSL: start connection\n");
881915
_freeSSL();
882916
_oom_err = false;
883917

884918
#ifdef DEBUG_ESP_SSL
885919
// BearSSL will reject all connections unless an authentication option is set, warn in DEBUG builds
886920
if (!_use_insecure && !_use_fingerprint && !_use_self_signed && !_knownkey && !_certStore && !_ta) {
887-
DEBUGV("BSSL: Connection *will* fail, no authentication method is setup");
921+
DEBUG_BSSL("Connection *will* fail, no authentication method is setup\n");
888922
}
889923
#endif
890924

@@ -896,6 +930,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
896930
if (!_sc || !_iobuf_in || !_iobuf_out) {
897931
_freeSSL(); // Frees _sc, _iobuf*
898932
_oom_err = true;
933+
DEBUG_BSSL("_connectSSL: OOM error\n");
899934
return false;
900935
}
901936

@@ -909,6 +944,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
909944
if (!_installClientX509Validator()) {
910945
_freeSSL();
911946
_oom_err = true;
947+
DEBUG_BSSL("_connectSSL: Can't install x509 validator\n");
912948
return false;
913949
}
914950
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
@@ -929,10 +965,21 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
929965

930966
if (!br_ssl_client_reset(_sc.get(), hostName, _session?1:0)) {
931967
_freeSSL();
968+
DEBUG_BSSL("_connectSSL: Can't reset client\n");
932969
return false;
933970
}
934971

935-
return _wait_for_handshake();
972+
auto ret = _wait_for_handshake();
973+
#ifdef DEBUG_ESP_SSL
974+
if (!ret) {
975+
char err[256];
976+
getLastSSLError(err, sizeof(err));
977+
DEBUG_BSSL("Couldn't connect. Error = '%s'\n", err);
978+
} else {
979+
DEBUG_BSSL("Connected!\n");
980+
}
981+
#endif
982+
return ret;
936983
}
937984

938985
// Slightly different X509 setup for servers who want to validate client
@@ -945,6 +992,7 @@ bool WiFiClientSecure::_installServerX509Validator(const X509List *client_CA_ta)
945992
if (!_x509_minimal) {
946993
_freeSSL();
947994
_oom_err = true;
995+
DEBUG_BSSL("_installServerX509Validator: OOM for _x509_minimal\n");
948996
return false;
949997
}
950998
br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _ta->getTrustAnchors(), _ta->getCount());
@@ -977,16 +1025,19 @@ bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain,
9771025
if (!_sc_svr || !_iobuf_in || !_iobuf_out) {
9781026
_freeSSL();
9791027
_oom_err = true;
1028+
DEBUG_BSSL("_connectSSLServerRSA: OOM error\n");
9801029
return false;
9811030
}
9821031

9831032
br_ssl_server_init_full_rsa(_sc_svr.get(), chain ? chain->getX509Certs() : nullptr, chain ? chain->getCount() : 0, sk ? sk->getRSA() : nullptr);
9841033
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
9851034
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
1035+
DEBUG_BSSL("_connectSSLServerRSA: Can't install serverX509check\n");
9861036
return false;
9871037
}
9881038
if (!br_ssl_server_reset(_sc_svr.get())) {
9891039
_freeSSL();
1040+
DEBUG_BSSL("_connectSSLServerRSA: Can't reset server ctx\n");
9901041
return false;
9911042
}
9921043

@@ -1007,17 +1058,20 @@ bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain,
10071058
if (!_sc_svr || !_iobuf_in || !_iobuf_out) {
10081059
_freeSSL();
10091060
_oom_err = true;
1061+
DEBUG_BSSL("_connectSSLServerEC: OOM error\n");
10101062
return false;
10111063
}
10121064

10131065
br_ssl_server_init_full_ec(_sc_svr.get(), chain ? chain->getX509Certs() : nullptr, chain ? chain->getCount() : 0,
10141066
cert_issuer_key_type, sk ? sk->getEC() : nullptr);
10151067
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
10161068
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
1069+
DEBUG_BSSL("_connectSSLServerEC: Can't install serverX509check\n");
10171070
return false;
10181071
}
10191072
if (!br_ssl_server_reset(_sc_svr.get())) {
10201073
_freeSSL();
1074+
DEBUG_BSSL("_connectSSLServerEC: Can't reset server ctx\n");
10211075
return false;
10221076
}
10231077

@@ -1107,6 +1161,7 @@ int WiFiClientSecure::getLastSSLError(char *dest, size_t len) {
11071161
bool WiFiClientSecure::probeMaxFragmentLength(const char* name, uint16_t port, uint16_t len) {
11081162
IPAddress remote_addr;
11091163
if (!WiFi.hostByName(name, remote_addr)) {
1164+
DEBUG_BSSL("probeMaxFragmentLength: Can't resolve host\n");
11101165
return false;
11111166
}
11121167
return WiFiClientSecure::probeMaxFragmentLength(remote_addr, port, len);
@@ -1184,6 +1239,7 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1
11841239
int ttlLen = sizeof(clientHelloHead_P) + (2 + sizeof(suites_P)) + (sizeof(clientHelloTail_P) + 1);
11851240
uint8_t *clientHello = new uint8_t[ttlLen];
11861241
if (!clientHello) {
1242+
DEBUG_BSSL("probeMaxFragmentLength: OOM\n");
11871243
return false;
11881244
}
11891245
memcpy_P(clientHello, clientHelloHead_P, sizeof(clientHelloHead_P));
@@ -1209,12 +1265,14 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1
12091265
probe.connect(ip, port);
12101266
if (!probe.connected()) {
12111267
delete[] clientHello;
1268+
DEBUG_BSSL("probeMaxFragmentLength: Can't connect\n");
12121269
return false;
12131270
}
12141271

12151272
int ret = probe.write(clientHello, ttlLen);
12161273
delete[] clientHello; // We're done w/the hello message
12171274
if (!probe.connected() || (ret != ttlLen)) {
1275+
DEBUG_BSSL("probeMaxFragmentLength: Protocol error\n");
12181276
return false;
12191277
}
12201278

0 commit comments

Comments
 (0)