mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-06 05:21:22 +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:
parent
84b046f98c
commit
526f4fbb6c
@ -130,9 +130,14 @@ verify KEYWORD2
|
|||||||
verifyCertChain KEYWORD2
|
verifyCertChain KEYWORD2
|
||||||
setCertificate KEYWORD2
|
setCertificate KEYWORD2
|
||||||
setPrivateKey KEYWORD2
|
setPrivateKey KEYWORD2
|
||||||
|
setCACert KEYWORD2
|
||||||
|
setCertificate_P KEYWORD2
|
||||||
|
setPrivateKey_P KEYWORD2
|
||||||
|
setCACert_P KEYWORD2
|
||||||
loadCertificate KEYWORD2
|
loadCertificate KEYWORD2
|
||||||
loadPrivateKey KEYWORD2
|
loadPrivateKey KEYWORD2
|
||||||
loadCACert KEYWORD2
|
loadCACert KEYWORD2
|
||||||
|
allowSelfSignedCerts KEYWORD2
|
||||||
|
|
||||||
#WiFiServer
|
#WiFiServer
|
||||||
hasClient KEYWORD2
|
hasClient KEYWORD2
|
||||||
|
@ -110,6 +110,7 @@ public:
|
|||||||
uint8_t* data;
|
uint8_t* data;
|
||||||
int rc = ssl_read(_ssl, &data);
|
int rc = ssl_read(_ssl, &data);
|
||||||
if (rc < SSL_OK) {
|
if (rc < SSL_OK) {
|
||||||
|
ssl_display_error(rc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,6 +228,25 @@ public:
|
|||||||
return true;
|
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*()
|
operator SSL*()
|
||||||
{
|
{
|
||||||
return _ssl;
|
return _ssl;
|
||||||
@ -268,6 +288,7 @@ protected:
|
|||||||
int _refcnt = 0;
|
int _refcnt = 0;
|
||||||
const uint8_t* _read_ptr = nullptr;
|
const uint8_t* _read_ptr = nullptr;
|
||||||
size_t _available = 0;
|
size_t _available = 0;
|
||||||
|
bool _allowSelfSignedCerts = false;
|
||||||
static ClientContext* s_io_ctx;
|
static ClientContext* s_io_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -559,96 +580,80 @@ bool WiFiClientSecure::verifyCertChain(const char* domain_name)
|
|||||||
if (!_ssl) {
|
if (!_ssl) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int rc = ssl_verify_cert(*_ssl);
|
if (!_ssl->verifyCert()) {
|
||||||
if (rc != SSL_OK) {
|
|
||||||
DEBUGV("ssl_verify_cert returned %d\n", rc);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _verifyDN(domain_name);
|
return _verifyDN(domain_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
|
void WiFiClientSecure::_initSSLContext()
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
if (!_ssl) {
|
||||||
_ssl = new SSLContext;
|
_ssl = new SSLContext;
|
||||||
_ssl->ref();
|
_ssl->ref();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size)
|
||||||
|
{
|
||||||
|
_initSSLContext();
|
||||||
return _ssl->loadObject(SSL_OBJ_X509_CACERT, pk, size);
|
return _ssl->loadObject(SSL_OBJ_X509_CACERT, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setCertificate(const uint8_t* pk, size_t size)
|
bool WiFiClientSecure::setCertificate(const uint8_t* pk, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject(SSL_OBJ_X509_CERT, pk, size);
|
return _ssl->loadObject(SSL_OBJ_X509_CERT, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size)
|
bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject(SSL_OBJ_RSA_KEY, pk, size);
|
return _ssl->loadObject(SSL_OBJ_RSA_KEY, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setCACert_P(PGM_VOID_P pk, size_t size)
|
bool WiFiClientSecure::setCACert_P(PGM_VOID_P pk, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject_P(SSL_OBJ_X509_CACERT, pk, size);
|
return _ssl->loadObject_P(SSL_OBJ_X509_CACERT, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setCertificate_P(PGM_VOID_P pk, size_t size)
|
bool WiFiClientSecure::setCertificate_P(PGM_VOID_P pk, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject_P(SSL_OBJ_X509_CERT, pk, size);
|
return _ssl->loadObject_P(SSL_OBJ_X509_CERT, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::setPrivateKey_P(PGM_VOID_P pk, size_t size)
|
bool WiFiClientSecure::setPrivateKey_P(PGM_VOID_P pk, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject_P(SSL_OBJ_RSA_KEY, pk, size);
|
return _ssl->loadObject_P(SSL_OBJ_RSA_KEY, pk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::loadCACert(Stream& stream, size_t size)
|
bool WiFiClientSecure::loadCACert(Stream& stream, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject(SSL_OBJ_X509_CACERT, stream, size);
|
return _ssl->loadObject(SSL_OBJ_X509_CACERT, stream, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size)
|
bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject(SSL_OBJ_X509_CERT, stream, size);
|
return _ssl->loadObject(SSL_OBJ_X509_CERT, stream, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size)
|
bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size)
|
||||||
{
|
{
|
||||||
if (!_ssl) {
|
_initSSLContext();
|
||||||
_ssl = new SSLContext;
|
|
||||||
_ssl->ref();
|
|
||||||
}
|
|
||||||
return _ssl->loadObject(SSL_OBJ_RSA_KEY, stream, size);
|
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)
|
extern "C" int __ax_port_read(int fd, uint8_t* buffer, size_t count)
|
||||||
{
|
{
|
||||||
ClientContext* _client = SSLContext::getIOContext(fd);
|
ClientContext* _client = SSLContext::getIOContext(fd);
|
||||||
|
@ -62,6 +62,8 @@ public:
|
|||||||
bool loadCertificate(Stream& stream, size_t size);
|
bool loadCertificate(Stream& stream, size_t size);
|
||||||
bool loadPrivateKey(Stream& stream, size_t size);
|
bool loadPrivateKey(Stream& stream, size_t size);
|
||||||
|
|
||||||
|
void allowSelfSignedCerts();
|
||||||
|
|
||||||
template<typename TFile>
|
template<typename TFile>
|
||||||
bool loadCertificate(TFile& file) {
|
bool loadCertificate(TFile& file) {
|
||||||
return loadCertificate(file, file.size());
|
return loadCertificate(file, file.size());
|
||||||
@ -79,6 +81,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _initSSLContext();
|
||||||
int _connectSSL(const char* hostName);
|
int _connectSSL(const char* hostName);
|
||||||
bool _verifyDN(const char* name);
|
bool _verifyDN(const char* name);
|
||||||
|
|
||||||
|
@ -113,6 +113,19 @@ typedef struct SSL_EXTENSIONS_ SSL_EXTENSIONS;
|
|||||||
#define SSL_X509_OFFSET -512
|
#define SSL_X509_OFFSET -512
|
||||||
#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
|
#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 */
|
/* alert types that are recognized */
|
||||||
#define SSL_ALERT_TYPE_WARNING 1
|
#define SSL_ALERT_TYPE_WARNING 1
|
||||||
#define SLL_ALERT_TYPE_FATAL 2
|
#define SLL_ALERT_TYPE_FATAL 2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user