Skip to content

Commit 526f4fb

Browse files
committed
WiFiClientSecure: add option to allow self-signed certificates
Mainly useful for testing WiFiClientSecure in local environments. If allowSelfSignedCerts is called before verifyCertChain, then the certificate chain will be verified, but the final certificate may be self-signed.
1 parent 84b046f commit 526f4fb

File tree

4 files changed

+63
-37
lines changed

4 files changed

+63
-37
lines changed

libraries/ESP8266WiFi/keywords.txt

+5
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,14 @@ verify KEYWORD2
130130
verifyCertChain KEYWORD2
131131
setCertificate KEYWORD2
132132
setPrivateKey KEYWORD2
133+
setCACert KEYWORD2
134+
setCertificate_P KEYWORD2
135+
setPrivateKey_P KEYWORD2
136+
setCACert_P KEYWORD2
133137
loadCertificate KEYWORD2
134138
loadPrivateKey KEYWORD2
135139
loadCACert KEYWORD2
140+
allowSelfSignedCerts KEYWORD2
136141

137142
#WiFiServer
138143
hasClient KEYWORD2

libraries/ESP8266WiFi/src/WiFiClientSecure.cpp

+42-37
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class SSLContext
110110
uint8_t* data;
111111
int rc = ssl_read(_ssl, &data);
112112
if (rc < SSL_OK) {
113+
ssl_display_error(rc);
113114
break;
114115
}
115116
}
@@ -227,6 +228,25 @@ class SSLContext
227228
return true;
228229
}
229230

231+
bool verifyCert()
232+
{
233+
int rc = ssl_verify_cert(_ssl);
234+
if (_allowSelfSignedCerts && rc == SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED)) {
235+
DEBUGV("Allowing self-signed certificate\n");
236+
return true;
237+
} else if (rc != SSL_OK) {
238+
DEBUGV("ssl_verify_cert returned %d\n", rc);
239+
ssl_display_error(rc);
240+
return false;
241+
}
242+
return true;
243+
}
244+
245+
void allowSelfSignedCerts()
246+
{
247+
_allowSelfSignedCerts = true;
248+
}
249+
230250
operator SSL*()
231251
{
232252
return _ssl;
@@ -268,6 +288,7 @@ class SSLContext
268288
int _refcnt = 0;
269289
const uint8_t* _read_ptr = nullptr;
270290
size_t _available = 0;
291+
bool _allowSelfSignedCerts = false;
271292
static ClientContext* s_io_ctx;
272293
};
273294

@@ -559,96 +580,80 @@ bool WiFiClientSecure::verifyCertChain(const char* domain_name)
559580
if (!_ssl) {
560581
return false;
561582
}
562-
int rc = ssl_verify_cert(*_ssl);
563-
if (rc != SSL_OK) {
564-
DEBUGV("ssl_verify_cert returned %d\n", rc);
583+
if (!_ssl->verifyCert()) {
565584
return false;
566585
}
567-
568586
return _verifyDN(domain_name);
569587
}
570588

571-
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
589+
void WiFiClientSecure::_initSSLContext()
572590
{
573591
if (!_ssl) {
574592
_ssl = new SSLContext;
575593
_ssl->ref();
576594
}
595+
}
596+
597+
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
598+
{
599+
_initSSLContext();
577600
return _ssl->loadObject(SSL_OBJ_X509_CACERT, pk, size);
578601
}
579602

580603
bool WiFiClientSecure::setCertificate(const uint8_t* pk, size_t size)
581604
{
582-
if (!_ssl) {
583-
_ssl = new SSLContext;
584-
_ssl->ref();
585-
}
605+
_initSSLContext();
586606
return _ssl->loadObject(SSL_OBJ_X509_CERT, pk, size);
587607
}
588608

589609
bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size)
590610
{
591-
if (!_ssl) {
592-
_ssl = new SSLContext;
593-
_ssl->ref();
594-
}
611+
_initSSLContext();
595612
return _ssl->loadObject(SSL_OBJ_RSA_KEY, pk, size);
596613
}
597614

598615
bool WiFiClientSecure::setCACert_P(PGM_VOID_P pk, size_t size)
599616
{
600-
if (!_ssl) {
601-
_ssl = new SSLContext;
602-
_ssl->ref();
603-
}
617+
_initSSLContext();
604618
return _ssl->loadObject_P(SSL_OBJ_X509_CACERT, pk, size);
605619
}
606620

607621
bool WiFiClientSecure::setCertificate_P(PGM_VOID_P pk, size_t size)
608622
{
609-
if (!_ssl) {
610-
_ssl = new SSLContext;
611-
_ssl->ref();
612-
}
623+
_initSSLContext();
613624
return _ssl->loadObject_P(SSL_OBJ_X509_CERT, pk, size);
614625
}
615626

616627
bool WiFiClientSecure::setPrivateKey_P(PGM_VOID_P pk, size_t size)
617628
{
618-
if (!_ssl) {
619-
_ssl = new SSLContext;
620-
_ssl->ref();
621-
}
629+
_initSSLContext();
622630
return _ssl->loadObject_P(SSL_OBJ_RSA_KEY, pk, size);
623631
}
624632

625633
bool WiFiClientSecure::loadCACert(Stream& stream, size_t size)
626634
{
627-
if (!_ssl) {
628-
_ssl = new SSLContext;
629-
_ssl->ref();
630-
}
635+
_initSSLContext();
631636
return _ssl->loadObject(SSL_OBJ_X509_CACERT, stream, size);
632637
}
633638

634639
bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size)
635640
{
636-
if (!_ssl) {
637-
_ssl = new SSLContext;
638-
_ssl->ref();
639-
}
641+
_initSSLContext();
640642
return _ssl->loadObject(SSL_OBJ_X509_CERT, stream, size);
641643
}
642644

643645
bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size)
644646
{
645-
if (!_ssl) {
646-
_ssl = new SSLContext;
647-
_ssl->ref();
648-
}
647+
_initSSLContext();
649648
return _ssl->loadObject(SSL_OBJ_RSA_KEY, stream, size);
650649
}
651650

651+
void WiFiClientSecure::allowSelfSignedCerts()
652+
{
653+
_initSSLContext();
654+
_ssl->allowSelfSignedCerts();
655+
}
656+
652657
extern "C" int __ax_port_read(int fd, uint8_t* buffer, size_t count)
653658
{
654659
ClientContext* _client = SSLContext::getIOContext(fd);

libraries/ESP8266WiFi/src/WiFiClientSecure.h

+3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class WiFiClientSecure : public WiFiClient {
6262
bool loadCertificate(Stream& stream, size_t size);
6363
bool loadPrivateKey(Stream& stream, size_t size);
6464

65+
void allowSelfSignedCerts();
66+
6567
template<typename TFile>
6668
bool loadCertificate(TFile& file) {
6769
return loadCertificate(file, file.size());
@@ -79,6 +81,7 @@ class WiFiClientSecure : public WiFiClient {
7981

8082

8183
protected:
84+
void _initSSLContext();
8285
int _connectSSL(const char* hostName);
8386
bool _verifyDN(const char* name);
8487

libraries/ESP8266WiFi/src/include/ssl.h

+13
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ typedef struct SSL_EXTENSIONS_ SSL_EXTENSIONS;
113113
#define SSL_X509_OFFSET -512
114114
#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
115115

116+
#define X509_OK 0
117+
#define X509_NOT_OK -1
118+
#define X509_VFY_ERROR_NO_TRUSTED_CERT -2
119+
#define X509_VFY_ERROR_BAD_SIGNATURE -3
120+
#define X509_VFY_ERROR_NOT_YET_VALID -4
121+
#define X509_VFY_ERROR_EXPIRED -5
122+
#define X509_VFY_ERROR_SELF_SIGNED -6
123+
#define X509_VFY_ERROR_INVALID_CHAIN -7
124+
#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8
125+
#define X509_INVALID_PRIV_KEY -9
126+
#define X509_MAX_CERTS -10
127+
#define X509_VFY_ERROR_BASIC_CONSTRAINT -11
128+
116129
/* alert types that are recognized */
117130
#define SSL_ALERT_TYPE_WARNING 1
118131
#define SLL_ALERT_TYPE_FATAL 2

0 commit comments

Comments
 (0)