1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-04 18:03:20 +03:00

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.
This commit is contained in:
Ivan Grokhotkov 2017-10-08 07:08:51 +08:00
parent 84b046f98c
commit 526f4fbb6c
4 changed files with 63 additions and 37 deletions

View File

@ -130,9 +130,14 @@ verify KEYWORD2
verifyCertChain KEYWORD2
setCertificate KEYWORD2
setPrivateKey KEYWORD2
setCACert KEYWORD2
setCertificate_P KEYWORD2
setPrivateKey_P KEYWORD2
setCACert_P KEYWORD2
loadCertificate KEYWORD2
loadPrivateKey KEYWORD2
loadCACert KEYWORD2
allowSelfSignedCerts KEYWORD2
#WiFiServer
hasClient KEYWORD2

View File

@ -110,6 +110,7 @@ public:
uint8_t* data;
int rc = ssl_read(_ssl, &data);
if (rc < SSL_OK) {
ssl_display_error(rc);
break;
}
}
@ -227,6 +228,25 @@ public:
return true;
}
bool verifyCert()
{
int rc = ssl_verify_cert(_ssl);
if (_allowSelfSignedCerts && rc == SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED)) {
DEBUGV("Allowing self-signed certificate\n");
return true;
} else if (rc != SSL_OK) {
DEBUGV("ssl_verify_cert returned %d\n", rc);
ssl_display_error(rc);
return false;
}
return true;
}
void allowSelfSignedCerts()
{
_allowSelfSignedCerts = true;
}
operator SSL*()
{
return _ssl;
@ -268,6 +288,7 @@ protected:
int _refcnt = 0;
const uint8_t* _read_ptr = nullptr;
size_t _available = 0;
bool _allowSelfSignedCerts = false;
static ClientContext* s_io_ctx;
};
@ -559,96 +580,80 @@ bool WiFiClientSecure::verifyCertChain(const char* domain_name)
if (!_ssl) {
return false;
}
int rc = ssl_verify_cert(*_ssl);
if (rc != SSL_OK) {
DEBUGV("ssl_verify_cert returned %d\n", rc);
if (!_ssl->verifyCert()) {
return false;
}
return _verifyDN(domain_name);
}
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
void WiFiClientSecure::_initSSLContext()
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
}
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
{
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_X509_CACERT, pk, size);
}
bool WiFiClientSecure::setCertificate(const uint8_t* pk, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_X509_CERT, pk, size);
}
bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_RSA_KEY, pk, size);
}
bool WiFiClientSecure::setCACert_P(PGM_VOID_P pk, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject_P(SSL_OBJ_X509_CACERT, pk, size);
}
bool WiFiClientSecure::setCertificate_P(PGM_VOID_P pk, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject_P(SSL_OBJ_X509_CERT, pk, size);
}
bool WiFiClientSecure::setPrivateKey_P(PGM_VOID_P pk, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject_P(SSL_OBJ_RSA_KEY, pk, size);
}
bool WiFiClientSecure::loadCACert(Stream& stream, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_X509_CACERT, stream, size);
}
bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_X509_CERT, stream, size);
}
bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size)
{
if (!_ssl) {
_ssl = new SSLContext;
_ssl->ref();
}
_initSSLContext();
return _ssl->loadObject(SSL_OBJ_RSA_KEY, stream, size);
}
void WiFiClientSecure::allowSelfSignedCerts()
{
_initSSLContext();
_ssl->allowSelfSignedCerts();
}
extern "C" int __ax_port_read(int fd, uint8_t* buffer, size_t count)
{
ClientContext* _client = SSLContext::getIOContext(fd);

View File

@ -62,6 +62,8 @@ public:
bool loadCertificate(Stream& stream, size_t size);
bool loadPrivateKey(Stream& stream, size_t size);
void allowSelfSignedCerts();
template<typename TFile>
bool loadCertificate(TFile& file) {
return loadCertificate(file, file.size());
@ -79,6 +81,7 @@ public:
protected:
void _initSSLContext();
int _connectSSL(const char* hostName);
bool _verifyDN(const char* name);

View File

@ -113,6 +113,19 @@ typedef struct SSL_EXTENSIONS_ SSL_EXTENSIONS;
#define SSL_X509_OFFSET -512
#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
#define X509_OK 0
#define X509_NOT_OK -1
#define X509_VFY_ERROR_NO_TRUSTED_CERT -2
#define X509_VFY_ERROR_BAD_SIGNATURE -3
#define X509_VFY_ERROR_NOT_YET_VALID -4
#define X509_VFY_ERROR_EXPIRED -5
#define X509_VFY_ERROR_SELF_SIGNED -6
#define X509_VFY_ERROR_INVALID_CHAIN -7
#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8
#define X509_INVALID_PRIV_KEY -9
#define X509_MAX_CERTS -10
#define X509_VFY_ERROR_BASIC_CONSTRAINT -11
/* alert types that are recognized */
#define SSL_ALERT_TYPE_WARNING 1
#define SLL_ALERT_TYPE_FATAL 2