mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-18 23:03:34 +03:00
Merge branch 'master' into feature/issue-2246-multi-wifi-hidden
This commit is contained in:
@ -526,6 +526,10 @@ namespace brssl {
|
||||
case BR_KEYTYPE_EC:
|
||||
ek = br_skey_decoder_get_ec(dc.get());
|
||||
sk = (private_key*)malloc(sizeof * sk);
|
||||
if (!sk)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
sk->key_type = BR_KEYTYPE_EC;
|
||||
sk->key.ec.curve = ek->curve;
|
||||
sk->key.ec.x = (uint8_t*)malloc(ek->xlen);
|
||||
@ -626,6 +630,17 @@ namespace brssl {
|
||||
return pk;
|
||||
}
|
||||
|
||||
static uint8_t *loadStream(Stream& stream, size_t size) {
|
||||
uint8_t *dest = (uint8_t *)malloc(size);
|
||||
if (!dest) {
|
||||
return nullptr; // OOM error
|
||||
}
|
||||
if (size != stream.readBytes(dest, size)) {
|
||||
free(dest); // Error during read
|
||||
return nullptr;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -648,6 +663,15 @@ PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) {
|
||||
parse(derKey, derLen);
|
||||
}
|
||||
|
||||
PublicKey::PublicKey(Stream &stream, size_t size) {
|
||||
_key = nullptr;
|
||||
auto buff = brssl::loadStream(stream, size);
|
||||
if (buff) {
|
||||
parse(buff, size);
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
|
||||
PublicKey::~PublicKey() {
|
||||
if (_key) {
|
||||
brssl::free_public_key(_key);
|
||||
@ -711,6 +735,15 @@ PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) {
|
||||
parse(derKey, derLen);
|
||||
}
|
||||
|
||||
PrivateKey::PrivateKey(Stream &stream, size_t size) {
|
||||
_key = nullptr;
|
||||
auto buff = brssl::loadStream(stream, size);
|
||||
if (buff) {
|
||||
parse(buff, size);
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
|
||||
PrivateKey::~PrivateKey() {
|
||||
if (_key) {
|
||||
brssl::free_private_key(_key);
|
||||
@ -781,6 +814,17 @@ X509List::X509List(const uint8_t *derCert, size_t derLen) {
|
||||
append(derCert, derLen);
|
||||
}
|
||||
|
||||
X509List::X509List(Stream &stream, size_t size) {
|
||||
_count = 0;
|
||||
_cert = nullptr;
|
||||
_ta = nullptr;
|
||||
auto buff = brssl::loadStream(stream, size);
|
||||
if (buff) {
|
||||
append(buff, size);
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
|
||||
X509List::~X509List() {
|
||||
brssl::free_certificates(_cert, _count); // also frees cert
|
||||
for (size_t i = 0; i < _count; i++) {
|
||||
@ -832,6 +876,22 @@ bool X509List::append(const uint8_t *derCert, size_t derLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerSessions::~ServerSessions() {
|
||||
if (_isDynamic && _store != nullptr)
|
||||
delete _store;
|
||||
}
|
||||
|
||||
ServerSessions::ServerSessions(ServerSession *sessions, uint32_t size, bool isDynamic) :
|
||||
_size(sessions != nullptr ? size : 0),
|
||||
_store(sessions), _isDynamic(isDynamic) {
|
||||
if (_size > 0)
|
||||
br_ssl_session_cache_lru_init(&_cache, (uint8_t*)_store, size * sizeof(ServerSession));
|
||||
}
|
||||
|
||||
const br_ssl_session_cache_class **ServerSessions::getCache() {
|
||||
return _size > 0 ? &_cache.vtable : nullptr;
|
||||
}
|
||||
|
||||
// SHA256 hash for updater
|
||||
void HashSHA256::begin() {
|
||||
br_sha256_init( &_cc );
|
||||
|
@ -43,6 +43,8 @@ class PublicKey {
|
||||
PublicKey();
|
||||
PublicKey(const char *pemKey);
|
||||
PublicKey(const uint8_t *derKey, size_t derLen);
|
||||
PublicKey(Stream& stream, size_t size);
|
||||
PublicKey(Stream& stream) : PublicKey(stream, stream.available()) { };
|
||||
~PublicKey();
|
||||
|
||||
bool parse(const char *pemKey);
|
||||
@ -69,6 +71,8 @@ class PrivateKey {
|
||||
PrivateKey();
|
||||
PrivateKey(const char *pemKey);
|
||||
PrivateKey(const uint8_t *derKey, size_t derLen);
|
||||
PrivateKey(Stream& stream, size_t size);
|
||||
PrivateKey(Stream& stream) : PrivateKey(stream, stream.available()) { };
|
||||
~PrivateKey();
|
||||
|
||||
bool parse(const char *pemKey);
|
||||
@ -98,6 +102,8 @@ class X509List {
|
||||
X509List();
|
||||
X509List(const char *pemCert);
|
||||
X509List(const uint8_t *derCert, size_t derLen);
|
||||
X509List(Stream& stream, size_t size);
|
||||
X509List(Stream& stream) : X509List(stream, stream.available()) { };
|
||||
~X509List();
|
||||
|
||||
bool append(const char *pemCert);
|
||||
@ -127,17 +133,61 @@ class X509List {
|
||||
// significantly faster. Completely optional.
|
||||
class WiFiClientSecure;
|
||||
|
||||
// Cache for a TLS session with a server
|
||||
// Use with BearSSL::WiFiClientSecure::setSession
|
||||
// to accelerate the TLS handshake
|
||||
class Session {
|
||||
friend class WiFiClientSecure;
|
||||
friend class WiFiClientSecureCtx;
|
||||
|
||||
public:
|
||||
Session() { memset(&_session, 0, sizeof(_session)); }
|
||||
private:
|
||||
br_ssl_session_parameters *getSession() { return &_session; }
|
||||
// The actual BearSSL ession information
|
||||
// The actual BearSSL session information
|
||||
br_ssl_session_parameters _session;
|
||||
};
|
||||
|
||||
// Represents a single server session.
|
||||
// Use with BearSSL::ServerSessions.
|
||||
typedef uint8_t ServerSession[100];
|
||||
|
||||
// Cache for the TLS sessions of multiple clients.
|
||||
// Use with BearSSL::WiFiServerSecure::setCache
|
||||
class ServerSessions {
|
||||
friend class WiFiClientSecureCtx;
|
||||
|
||||
public:
|
||||
// Uses the given buffer to cache the given number of sessions and initializes it.
|
||||
ServerSessions(ServerSession *sessions, uint32_t size) : ServerSessions(sessions, size, false) {}
|
||||
|
||||
// Dynamically allocates a cache for the given number of sessions and initializes it.
|
||||
// If the allocation of the buffer wasn't successfull, the value
|
||||
// returned by size() will be 0.
|
||||
ServerSessions(uint32_t size) : ServerSessions(size > 0 ? new ServerSession[size] : nullptr, size, true) {}
|
||||
|
||||
~ServerSessions();
|
||||
|
||||
// Returns the number of sessions the cache can hold.
|
||||
uint32_t size() { return _size; }
|
||||
|
||||
private:
|
||||
ServerSessions(ServerSession *sessions, uint32_t size, bool isDynamic);
|
||||
|
||||
// Returns the cache's vtable or null if the cache has no capacity.
|
||||
const br_ssl_session_cache_class **getCache();
|
||||
|
||||
// Size of the store in sessions.
|
||||
uint32_t _size;
|
||||
// Store where the informations for the sessions are stored.
|
||||
ServerSession *_store;
|
||||
// Whether the store is dynamically allocated.
|
||||
// If this is true, the store needs to be freed in the destructor.
|
||||
bool _isDynamic;
|
||||
|
||||
// Cache of the server using the _store.
|
||||
br_ssl_session_cache_lru _cache;
|
||||
};
|
||||
|
||||
// Updater SHA256 hash and signature verification
|
||||
class HashSHA256 : public UpdaterHashClass {
|
||||
public:
|
||||
@ -164,7 +214,7 @@ class SigningVerifier : public UpdaterVerifyClass {
|
||||
private:
|
||||
PublicKey *_pubKey;
|
||||
};
|
||||
|
||||
|
||||
// Stack thunked versions of calls
|
||||
extern "C" {
|
||||
extern unsigned char *thunk_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len);
|
||||
|
@ -80,7 +80,7 @@ CertStore::CertInfo CertStore::_preprocessCert(uint32_t length, uint32_t offset,
|
||||
|
||||
// The certs.ar file is a UNIX ar format file, concatenating all the
|
||||
// individual certificates into a single blob in a space-efficient way.
|
||||
int CertStore::initCertStore(FS &fs, const char *indexFileName, const char *dataFileName) {
|
||||
int CertStore::initCertStore(fs::FS &fs, const char *indexFileName, const char *dataFileName) {
|
||||
int count = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
@ -101,12 +101,12 @@ int CertStore::initCertStore(FS &fs, const char *indexFileName, const char *data
|
||||
memcpy_P(_indexName, indexFileName, strlen_P(indexFileName) + 1);
|
||||
memcpy_P(_dataName, dataFileName, strlen_P(dataFileName) + 1);
|
||||
|
||||
File index = _fs->open(_indexName, "w");
|
||||
fs::File index = _fs->open(_indexName, "w");
|
||||
if (!index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
File data = _fs->open(_dataName, "r");
|
||||
fs::File data = _fs->open(_dataName, "r");
|
||||
if (!data) {
|
||||
index.close();
|
||||
return 0;
|
||||
@ -179,7 +179,7 @@ const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
File index = cs->_fs->open(cs->_indexName, "r");
|
||||
fs::File index = cs->_fs->open(cs->_indexName, "r");
|
||||
if (!index) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -191,12 +191,12 @@ const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn,
|
||||
if (!der) {
|
||||
return nullptr;
|
||||
}
|
||||
File data = cs->_fs->open(cs->_dataName, "r");
|
||||
fs::File data = cs->_fs->open(cs->_dataName, "r");
|
||||
if (!data) {
|
||||
free(der);
|
||||
return nullptr;
|
||||
}
|
||||
if (!data.seek(ci.offset, SeekSet)) {
|
||||
if (!data.seek(ci.offset, fs::SeekSet)) {
|
||||
data.close();
|
||||
free(der);
|
||||
return nullptr;
|
||||
|
@ -31,7 +31,15 @@
|
||||
|
||||
namespace BearSSL {
|
||||
|
||||
class CertStore {
|
||||
class CertStoreBase {
|
||||
public:
|
||||
virtual ~CertStoreBase() {}
|
||||
|
||||
// Installs the cert store into the X509 decoder (normally via static function callbacks)
|
||||
virtual void installCertStore(br_x509_minimal_context *ctx) = 0;
|
||||
};
|
||||
|
||||
class CertStore: public CertStoreBase {
|
||||
public:
|
||||
CertStore() { };
|
||||
~CertStore();
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
#include "include/wl_definitions.h"
|
||||
#include <wl_definitions.h>
|
||||
}
|
||||
|
||||
#include "IPAddress.h"
|
||||
|
@ -33,11 +33,11 @@ extern "C" {
|
||||
#include "osapi.h"
|
||||
#include "mem.h"
|
||||
#include "user_interface.h"
|
||||
#include <lwip/init.h> // LWIP_VERSION_*
|
||||
}
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#include "LwipDhcpServer.h"
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------------------- Private functions ------------------------------------------------
|
||||
@ -156,13 +156,7 @@ bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int ch
|
||||
DEBUG_WIFI("[AP] softap config unchanged\n");
|
||||
}
|
||||
|
||||
if(wifi_softap_dhcps_status() != DHCP_STARTED) {
|
||||
DEBUG_WIFI("[AP] DHCP not started, starting...\n");
|
||||
if(!wifi_softap_dhcps_start()) {
|
||||
DEBUG_WIFI("[AP] wifi_softap_dhcps_start failed!\n");
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
dhcpSoftAP.end();
|
||||
|
||||
// check IP config
|
||||
struct ip_info ip;
|
||||
@ -182,6 +176,8 @@ bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int ch
|
||||
ret = false;
|
||||
}
|
||||
|
||||
dhcpSoftAP.begin(&ip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -237,19 +233,22 @@ bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPA
|
||||
dhcp_lease.end_ip.addr = ip.v4();
|
||||
DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str());
|
||||
|
||||
if(!wifi_softap_set_dhcps_lease(&dhcp_lease)) {
|
||||
if(!dhcpSoftAP.set_dhcps_lease(&dhcp_lease))
|
||||
{
|
||||
DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
// set lease time to 720min --> 12h
|
||||
if(!wifi_softap_set_dhcps_lease_time(720)) {
|
||||
if(!dhcpSoftAP.set_dhcps_lease_time(720))
|
||||
{
|
||||
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_lease_time failed!\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
uint8 mode = info.gw.addr ? 1 : 0;
|
||||
if(!wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode)) {
|
||||
if(!dhcpSoftAP.set_dhcps_offer_option(OFFER_ROUTER, &mode))
|
||||
{
|
||||
DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_offer_option failed!\n");
|
||||
ret = false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
ESP8266WiFiGeneric.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Based on WiFi.h from Arduino WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ESP8266WiFiGeneric.h"
|
||||
#include "ESP8266WiFiSTA.h"
|
||||
#include "PolledTimeout.h"
|
||||
#include "LwipIntf.h"
|
||||
|
||||
#include "c_types.h"
|
||||
#include "ets_sys.h"
|
||||
@ -281,28 +282,9 @@ bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress a
|
||||
return true;
|
||||
}
|
||||
|
||||
//To allow compatibility, check first octet of 3rd arg. If 255, interpret as ESP order, otherwise Arduino order.
|
||||
IPAddress gateway = arg1;
|
||||
IPAddress subnet = arg2;
|
||||
IPAddress dns1 = arg3;
|
||||
|
||||
if(subnet[0] != 255)
|
||||
{
|
||||
//octet is not 255 => interpret as Arduino order
|
||||
gateway = arg2;
|
||||
subnet = arg3[0] == 0 ? IPAddress(255,255,255,0) : arg3; //arg order is arduino and 4th arg not given => assign it arduino default
|
||||
dns1 = arg1;
|
||||
}
|
||||
|
||||
// check whether all is IPv4 (or gateway not set)
|
||||
if (!(local_ip.isV4() && subnet.isV4() && (!gateway.isSet() || gateway.isV4()))) {
|
||||
IPAddress gateway, subnet, dns1;
|
||||
if (!ipAddressReorder(local_ip, arg1, arg2, arg3, gateway, subnet, dns1))
|
||||
return false;
|
||||
}
|
||||
|
||||
//ip and gateway must be in the same subnet
|
||||
if((local_ip.v4() & subnet.v4()) != (gateway.v4() & subnet.v4())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !CORE_MOCK
|
||||
// get current->previous IP address
|
||||
@ -522,94 +504,6 @@ IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) {
|
||||
return IPAddress(dns_getserver(dns_no));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get ESP8266 station DHCP hostname
|
||||
* @return hostname
|
||||
*/
|
||||
String ESP8266WiFiSTAClass::hostname(void) {
|
||||
return wifi_station_get_hostname();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ESP8266 station DHCP hostname
|
||||
* @param aHostname max length:24
|
||||
* @return ok
|
||||
*/
|
||||
bool ESP8266WiFiSTAClass::hostname(const char* aHostname) {
|
||||
/*
|
||||
vvvv RFC952 vvvv
|
||||
ASSUMPTIONS
|
||||
1. A "name" (Net, Host, Gateway, or Domain name) is a text string up
|
||||
to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
|
||||
sign (-), and period (.). Note that periods are only allowed when
|
||||
they serve to delimit components of "domain style names". (See
|
||||
RFC-921, "Domain Name System Implementation Schedule", for
|
||||
background). No blank or space characters are permitted as part of a
|
||||
name. No distinction is made between upper and lower case. The first
|
||||
character must be an alpha character. The last character must not be
|
||||
a minus sign or period. A host which serves as a GATEWAY should have
|
||||
"-GATEWAY" or "-GW" as part of its name. Hosts which do not serve as
|
||||
Internet gateways should not use "-GATEWAY" and "-GW" as part of
|
||||
their names. A host which is a TAC should have "-TAC" as the last
|
||||
part of its host name, if it is a DoD host. Single character names
|
||||
or nicknames are not allowed.
|
||||
^^^^ RFC952 ^^^^
|
||||
|
||||
- 24 chars max
|
||||
- only a..z A..Z 0..9 '-'
|
||||
- no '-' as last char
|
||||
*/
|
||||
|
||||
size_t len = strlen(aHostname);
|
||||
|
||||
if (len == 0 || len > 32) {
|
||||
// nonos-sdk limit is 32
|
||||
// (dhcp hostname option minimum size is ~60)
|
||||
DEBUG_WIFI_GENERIC("WiFi.(set)hostname(): empty or large(>32) name\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check RFC compliance
|
||||
bool compliant = (len <= 24);
|
||||
for (size_t i = 0; compliant && i < len; i++)
|
||||
if (!isalnum(aHostname[i]) && aHostname[i] != '-')
|
||||
compliant = false;
|
||||
if (aHostname[len - 1] == '-')
|
||||
compliant = false;
|
||||
|
||||
if (!compliant) {
|
||||
DEBUG_WIFI_GENERIC("hostname '%s' is not compliant with RFC952\n", aHostname);
|
||||
}
|
||||
|
||||
bool ret = wifi_station_set_hostname(aHostname);
|
||||
if (!ret) {
|
||||
DEBUG_WIFI_GENERIC("WiFi.hostname(%s): wifi_station_set_hostname() failed\n", aHostname);
|
||||
return false;
|
||||
}
|
||||
|
||||
// now we should inform dhcp server for this change, using lwip_renew()
|
||||
// looping through all existing interface
|
||||
// harmless for AP, also compatible with ethernet adapters (to come)
|
||||
for (netif* intf = netif_list; intf; intf = intf->next) {
|
||||
|
||||
// unconditionally update all known interfaces
|
||||
intf->hostname = wifi_station_get_hostname();
|
||||
|
||||
if (netif_dhcp_data(intf) != nullptr) {
|
||||
// renew already started DHCP leases
|
||||
err_t lwipret = dhcp_renew(intf);
|
||||
if (lwipret != ERR_OK) {
|
||||
DEBUG_WIFI_GENERIC("WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n",
|
||||
intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num);
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret && compliant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Connection status.
|
||||
* @return one of the value defined in wl_status_t
|
||||
|
@ -27,9 +27,10 @@
|
||||
#include "ESP8266WiFiType.h"
|
||||
#include "ESP8266WiFiGeneric.h"
|
||||
#include "user_interface.h"
|
||||
#include "LwipIntf.h"
|
||||
|
||||
|
||||
class ESP8266WiFiSTAClass {
|
||||
class ESP8266WiFiSTAClass: public LwipIntf {
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------- STA function ----------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
@ -69,10 +70,6 @@ class ESP8266WiFiSTAClass {
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsIP(uint8_t dns_no = 0);
|
||||
|
||||
String hostname();
|
||||
bool hostname(const String& aHostname) { return hostname(aHostname.c_str()); }
|
||||
bool hostname(const char* aHostname);
|
||||
|
||||
// STA WiFi info
|
||||
wl_status_t status();
|
||||
String SSID() const;
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "include/wl_definitions.h"
|
||||
#include "wl_definitions.h"
|
||||
#include "osapi.h"
|
||||
#include "ets_sys.h"
|
||||
}
|
||||
@ -195,7 +195,7 @@ bool WiFiClient::getSync() const
|
||||
return _client->getSync();
|
||||
}
|
||||
|
||||
size_t WiFiClient::availableForWrite ()
|
||||
int WiFiClient::availableForWrite ()
|
||||
{
|
||||
return _client? _client->availableForWrite(): 0;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
WiFiClient(const WiFiClient&);
|
||||
WiFiClient& operator=(const WiFiClient&);
|
||||
|
||||
uint8_t status();
|
||||
virtual uint8_t status();
|
||||
virtual int connect(IPAddress ip, uint16_t port) override;
|
||||
virtual int connect(const char *host, uint16_t port) override;
|
||||
virtual int connect(const String& host, uint16_t port);
|
||||
@ -86,7 +86,7 @@ public:
|
||||
|
||||
static void setLocalPortStart(uint16_t port) { _localPort = port; }
|
||||
|
||||
size_t availableForWrite();
|
||||
int availableForWrite() override;
|
||||
|
||||
friend class WiFiServer;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <list>
|
||||
#include <errno.h>
|
||||
#include <algorithm>
|
||||
#include <Esp.h>
|
||||
|
||||
extern "C" {
|
||||
#include "osapi.h"
|
||||
@ -44,6 +45,9 @@ extern "C" {
|
||||
#include <include/ClientContext.h>
|
||||
#include "c_types.h"
|
||||
#include "coredecls.h"
|
||||
#include <mmu_iram.h>
|
||||
#include <umm_malloc/umm_malloc.h>
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
|
||||
#if !CORE_MOCK
|
||||
|
||||
@ -67,7 +71,7 @@ extern "C" {
|
||||
|
||||
namespace BearSSL {
|
||||
|
||||
void WiFiClientSecure::_clear() {
|
||||
void WiFiClientSecureCtx::_clear() {
|
||||
// TLS handshake may take more than the 5 second default timeout
|
||||
_timeout = 15000;
|
||||
|
||||
@ -91,7 +95,7 @@ void WiFiClientSecure::_clear() {
|
||||
_cipher_cnt = 0;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::_clearAuthenticationSettings() {
|
||||
void WiFiClientSecureCtx::_clearAuthenticationSettings() {
|
||||
_use_insecure = false;
|
||||
_use_fingerprint = false;
|
||||
_use_self_signed = false;
|
||||
@ -100,7 +104,7 @@ void WiFiClientSecure::_clearAuthenticationSettings() {
|
||||
}
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure() : WiFiClient() {
|
||||
WiFiClientSecureCtx::WiFiClientSecureCtx() : WiFiClient() {
|
||||
_clear();
|
||||
_clearAuthenticationSettings();
|
||||
_certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived
|
||||
@ -108,12 +112,7 @@ WiFiClientSecure::WiFiClientSecure() : WiFiClient() {
|
||||
stack_thunk_add_ref();
|
||||
}
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure &rhs) : WiFiClient(rhs) {
|
||||
*this = rhs;
|
||||
stack_thunk_add_ref();
|
||||
}
|
||||
|
||||
WiFiClientSecure::~WiFiClientSecure() {
|
||||
WiFiClientSecureCtx::~WiFiClientSecureCtx() {
|
||||
if (_client) {
|
||||
_client->unref();
|
||||
_client = nullptr;
|
||||
@ -123,9 +122,10 @@ WiFiClientSecure::~WiFiClientSecure() {
|
||||
stack_thunk_del_ref();
|
||||
}
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(ClientContext* client,
|
||||
WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext* client,
|
||||
const X509List *chain, const PrivateKey *sk,
|
||||
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) {
|
||||
int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta) {
|
||||
_clear();
|
||||
_clearAuthenticationSettings();
|
||||
stack_thunk_add_ref();
|
||||
@ -133,17 +133,18 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client,
|
||||
_iobuf_out_size = iobuf_out_size;
|
||||
_client = client;
|
||||
_client->ref();
|
||||
if (!_connectSSLServerRSA(chain, sk, client_CA_ta)) {
|
||||
if (!_connectSSLServerRSA(chain, sk, cache, client_CA_ta)) {
|
||||
_client->unref();
|
||||
_client = nullptr;
|
||||
_clear();
|
||||
}
|
||||
}
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(ClientContext *client,
|
||||
WiFiClientSecureCtx::WiFiClientSecureCtx(ClientContext *client,
|
||||
const X509List *chain,
|
||||
unsigned cert_issuer_key_type, const PrivateKey *sk,
|
||||
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) {
|
||||
int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta) {
|
||||
_clear();
|
||||
_clearAuthenticationSettings();
|
||||
stack_thunk_add_ref();
|
||||
@ -151,19 +152,19 @@ WiFiClientSecure::WiFiClientSecure(ClientContext *client,
|
||||
_iobuf_out_size = iobuf_out_size;
|
||||
_client = client;
|
||||
_client->ref();
|
||||
if (!_connectSSLServerEC(chain, cert_issuer_key_type, sk, client_CA_ta)) {
|
||||
if (!_connectSSLServerEC(chain, cert_issuer_key_type, sk, cache, client_CA_ta)) {
|
||||
_client->unref();
|
||||
_client = nullptr;
|
||||
_clear();
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setClientRSACert(const X509List *chain, const PrivateKey *sk) {
|
||||
void WiFiClientSecureCtx::setClientRSACert(const X509List *chain, const PrivateKey *sk) {
|
||||
_chain = chain;
|
||||
_sk = sk;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setClientECCert(const X509List *chain,
|
||||
void WiFiClientSecureCtx::setClientECCert(const X509List *chain,
|
||||
const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) {
|
||||
_chain = chain;
|
||||
_sk = sk;
|
||||
@ -171,7 +172,7 @@ void WiFiClientSecure::setClientECCert(const X509List *chain,
|
||||
_cert_issuer_key_type = cert_issuer_key_type;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setBufferSizes(int recv, int xmit) {
|
||||
void WiFiClientSecureCtx::setBufferSizes(int recv, int xmit) {
|
||||
// Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately)
|
||||
const int MAX_OUT_OVERHEAD = 85;
|
||||
const int MAX_IN_OVERHEAD = 325;
|
||||
@ -187,7 +188,7 @@ void WiFiClientSecure::setBufferSizes(int recv, int xmit) {
|
||||
_iobuf_out_size = xmit;
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::stop(unsigned int maxWaitMs) {
|
||||
bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) {
|
||||
bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush()
|
||||
// Only if we've already connected, store session params and clear the connection options
|
||||
if (_handshake_done) {
|
||||
@ -199,19 +200,19 @@ bool WiFiClientSecure::stop(unsigned int maxWaitMs) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::flush(unsigned int maxWaitMs) {
|
||||
bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) {
|
||||
(void) _run_until(BR_SSL_SENDAPP);
|
||||
return WiFiClient::flush(maxWaitMs);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port) {
|
||||
int WiFiClientSecureCtx::connect(IPAddress ip, uint16_t port) {
|
||||
if (!WiFiClient::connect(ip, port)) {
|
||||
return 0;
|
||||
}
|
||||
return _connectSSL(nullptr);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char* name, uint16_t port) {
|
||||
int WiFiClientSecureCtx::connect(const char* name, uint16_t port) {
|
||||
IPAddress remote_addr;
|
||||
if (!WiFi.hostByName(name, remote_addr)) {
|
||||
DEBUG_BSSL("connect: Name lookup failure\n");
|
||||
@ -224,11 +225,11 @@ int WiFiClientSecure::connect(const char* name, uint16_t port) {
|
||||
return _connectSSL(name);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const String& host, uint16_t port) {
|
||||
int WiFiClientSecureCtx::connect(const String& host, uint16_t port) {
|
||||
return connect(host.c_str(), port);
|
||||
}
|
||||
|
||||
void WiFiClientSecure::_freeSSL() {
|
||||
void WiFiClientSecureCtx::_freeSSL() {
|
||||
// These are smart pointers and will free if refcnt==0
|
||||
_sc = nullptr;
|
||||
_sc_svr = nullptr;
|
||||
@ -245,18 +246,18 @@ void WiFiClientSecure::_freeSSL() {
|
||||
_timeout = 15000;
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::_clientConnected() {
|
||||
bool WiFiClientSecureCtx::_clientConnected() {
|
||||
return (_client && _client->state() == ESTABLISHED);
|
||||
}
|
||||
|
||||
uint8_t WiFiClientSecure::connected() {
|
||||
uint8_t WiFiClientSecureCtx::connected() {
|
||||
if (available() || (_clientConnected() && _handshake_done && (br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::_write(const uint8_t *buf, size_t size, bool pmem) {
|
||||
size_t WiFiClientSecureCtx::_write(const uint8_t *buf, size_t size, bool pmem) {
|
||||
size_t sent_bytes = 0;
|
||||
|
||||
if (!connected() || !size || !_handshake_done) {
|
||||
@ -297,16 +298,16 @@ size_t WiFiClientSecure::_write(const uint8_t *buf, size_t size, bool pmem) {
|
||||
return sent_bytes;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) {
|
||||
size_t WiFiClientSecureCtx::write(const uint8_t *buf, size_t size) {
|
||||
return _write(buf, size, false);
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write_P(PGM_P buf, size_t size) {
|
||||
size_t WiFiClientSecureCtx::write_P(PGM_P buf, size_t size) {
|
||||
return _write((const uint8_t *)buf, size, true);
|
||||
}
|
||||
|
||||
// We have to manually read and send individual chunks.
|
||||
size_t WiFiClientSecure::write(Stream& stream) {
|
||||
size_t WiFiClientSecureCtx::write(Stream& stream) {
|
||||
size_t totalSent = 0;
|
||||
size_t countRead;
|
||||
size_t countSent;
|
||||
@ -329,7 +330,7 @@ size_t WiFiClientSecure::write(Stream& stream) {
|
||||
return totalSent;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read(uint8_t *buf, size_t size) {
|
||||
int WiFiClientSecureCtx::read(uint8_t *buf, size_t size) {
|
||||
if (!ctx_present() || !_handshake_done) {
|
||||
return -1;
|
||||
}
|
||||
@ -361,7 +362,7 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size) {
|
||||
return 0; // If we're connected, no error but no read.
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read() {
|
||||
int WiFiClientSecureCtx::read() {
|
||||
uint8_t c;
|
||||
if (1 == read(&c, 1)) {
|
||||
return c;
|
||||
@ -370,7 +371,7 @@ int WiFiClientSecure::read() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::available() {
|
||||
int WiFiClientSecureCtx::available() {
|
||||
if (_recvapp_buf) {
|
||||
return _recvapp_len; // Anything from last call?
|
||||
}
|
||||
@ -391,7 +392,7 @@ int WiFiClientSecure::available() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::peek() {
|
||||
int WiFiClientSecureCtx::peek() {
|
||||
if (!ctx_present() || !available()) {
|
||||
DEBUG_BSSL("peek: Not connected, none left available\n");
|
||||
return -1;
|
||||
@ -403,7 +404,7 @@ int WiFiClientSecure::peek() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
|
||||
size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) {
|
||||
size_t to_copy = 0;
|
||||
if (!ctx_present()) {
|
||||
DEBUG_BSSL("peekBytes: Not connected\n");
|
||||
@ -426,22 +427,22 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
|
||||
combination of both (the combination matches either). When a match is
|
||||
achieved, this function returns 0. On error, it returns -1.
|
||||
*/
|
||||
int WiFiClientSecure::_run_until(unsigned target, bool blocking) {
|
||||
int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) {
|
||||
if (!ctx_present()) {
|
||||
DEBUG_BSSL("_run_until: Not connected\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
esp8266::polledTimeout::oneShotMs loopTimeout(_timeout);
|
||||
|
||||
for (int no_work = 0; blocking || no_work < 2;) {
|
||||
|
||||
for (int no_work = 0; blocking || no_work < 2;) {
|
||||
optimistic_yield(100);
|
||||
|
||||
|
||||
if (loopTimeout) {
|
||||
DEBUG_BSSL("_run_until: Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int state;
|
||||
state = br_ssl_engine_current_state(_eng);
|
||||
if (state & BR_SSL_CLOSED) {
|
||||
@ -464,15 +465,15 @@ int WiFiClientSecure::_run_until(unsigned target, bool blocking) {
|
||||
|
||||
buf = br_ssl_engine_sendrec_buf(_eng, &len);
|
||||
availForWrite = WiFiClient::availableForWrite();
|
||||
|
||||
|
||||
if (!blocking && len > availForWrite) {
|
||||
/*
|
||||
/*
|
||||
writes on WiFiClient will block if len > availableForWrite()
|
||||
this is needed to prevent available() calls from blocking
|
||||
on dropped connections
|
||||
on dropped connections
|
||||
*/
|
||||
len = availForWrite;
|
||||
}
|
||||
}
|
||||
wlen = WiFiClient::write(buf, len);
|
||||
if (wlen <= 0) {
|
||||
/*
|
||||
@ -550,7 +551,7 @@ int WiFiClientSecure::_run_until(unsigned target, bool blocking) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::_wait_for_handshake() {
|
||||
bool WiFiClientSecureCtx::_wait_for_handshake() {
|
||||
_handshake_done = false;
|
||||
while (!_handshake_done && _clientConnected()) {
|
||||
int ret = _run_until(BR_SSL_SENDAPP);
|
||||
@ -575,7 +576,7 @@ static uint8_t htoi (unsigned char c)
|
||||
}
|
||||
|
||||
// Set a fingerprint by parsing an ASCII string
|
||||
bool WiFiClientSecure::setFingerprint(const char *fpStr) {
|
||||
bool WiFiClientSecureCtx::setFingerprint(const char *fpStr) {
|
||||
int idx = 0;
|
||||
uint8_t c, d;
|
||||
uint8_t fp[20];
|
||||
@ -968,7 +969,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
// Set custom list of ciphers
|
||||
bool WiFiClientSecure::setCiphers(const uint16_t *cipherAry, int cipherCount) {
|
||||
bool WiFiClientSecureCtx::setCiphers(const uint16_t *cipherAry, int cipherCount) {
|
||||
_cipher_list = nullptr;
|
||||
_cipher_list = std::shared_ptr<uint16_t>(new (std::nothrow) uint16_t[cipherCount], std::default_delete<uint16_t[]>());
|
||||
if (!_cipher_list.get()) {
|
||||
@ -980,16 +981,16 @@ bool WiFiClientSecure::setCiphers(const uint16_t *cipherAry, int cipherCount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::setCiphersLessSecure() {
|
||||
bool WiFiClientSecureCtx::setCiphersLessSecure() {
|
||||
return setCiphers(faster_suites_P, sizeof(faster_suites_P)/sizeof(faster_suites_P[0]));
|
||||
}
|
||||
|
||||
bool WiFiClientSecure::setCiphers(std::vector<uint16_t> list) {
|
||||
bool WiFiClientSecureCtx::setCiphers(const std::vector<uint16_t>& list) {
|
||||
return setCiphers(&list[0], list.size());
|
||||
}
|
||||
|
||||
// Installs the appropriate X509 cert validation method for a client connection
|
||||
bool WiFiClientSecure::_installClientX509Validator() {
|
||||
bool WiFiClientSecureCtx::_installClientX509Validator() {
|
||||
if (_use_insecure || _use_fingerprint || _use_self_signed) {
|
||||
// Use common insecure x509 authenticator
|
||||
_x509_insecure = std::make_shared<struct br_x509_insecure_context>();
|
||||
@ -1046,7 +1047,7 @@ bool WiFiClientSecure::_installClientX509Validator() {
|
||||
|
||||
// Called by connect() to do the actual SSL setup and handshake.
|
||||
// Returns if the SSL handshake succeeded.
|
||||
bool WiFiClientSecure::_connectSSL(const char* hostName) {
|
||||
bool WiFiClientSecureCtx::_connectSSL(const char* hostName) {
|
||||
DEBUG_BSSL("_connectSSL: start connection\n");
|
||||
_freeSSL();
|
||||
_oom_err = false;
|
||||
@ -1060,8 +1061,17 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
|
||||
|
||||
_sc = std::make_shared<br_ssl_client_context>();
|
||||
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
//C This was borrowed from @earlephilhower PoC, to exemplify the use of IRAM.
|
||||
//C Is this something we want to keep in the final release?
|
||||
{ // ESP.setIramHeap(); would be an alternative to using a class to set a scope for IRAM usage.
|
||||
HeapSelectIram ephemeral;
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
DBG_MMU_PRINTF("\n_iobuf_in: %p\n", _iobuf_in.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_out: %p\n", _iobuf_out.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_in_size: %u\n", _iobuf_in_size);
|
||||
DBG_MMU_PRINTF( "_iobuf_out_size: %u\n", _iobuf_out_size);
|
||||
} // ESP.resetHeap();
|
||||
|
||||
if (!_sc || !_iobuf_in || !_iobuf_out) {
|
||||
_freeSSL(); // Frees _sc, _iobuf*
|
||||
@ -1136,7 +1146,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
|
||||
|
||||
// Slightly different X509 setup for servers who want to validate client
|
||||
// certificates, so factor it out as it's used in RSA and EC servers.
|
||||
bool WiFiClientSecure::_installServerX509Validator(const X509List *client_CA_ta) {
|
||||
bool WiFiClientSecureCtx::_installServerX509Validator(const X509List *client_CA_ta) {
|
||||
if (client_CA_ta) {
|
||||
_ta = client_CA_ta;
|
||||
// X509 minimal validator. Checks dates, cert chain for trusted CA, etc.
|
||||
@ -1169,15 +1179,22 @@ bool WiFiClientSecure::_installServerX509Validator(const X509List *client_CA_ta)
|
||||
|
||||
|
||||
// Called by WiFiServerBearSSL when an RSA cert/key is specified.
|
||||
bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain,
|
||||
const PrivateKey *sk,
|
||||
bool WiFiClientSecureCtx::_connectSSLServerRSA(const X509List *chain,
|
||||
const PrivateKey *sk, ServerSessions *cache,
|
||||
const X509List *client_CA_ta) {
|
||||
_freeSSL();
|
||||
_oom_err = false;
|
||||
_sc_svr = std::make_shared<br_ssl_server_context>();
|
||||
_eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
{ // ESP.setIramHeap();
|
||||
HeapSelectIram ephemeral;
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
DBG_MMU_PRINTF("\n_iobuf_in: %p\n", _iobuf_in.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_out: %p\n", _iobuf_out.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_in_size: %u\n", _iobuf_in_size);
|
||||
DBG_MMU_PRINTF( "_iobuf_out_size: %u\n", _iobuf_out_size);
|
||||
} // ESP.resetHeap();
|
||||
|
||||
if (!_sc_svr || !_iobuf_in || !_iobuf_out) {
|
||||
_freeSSL();
|
||||
@ -1189,8 +1206,10 @@ bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain,
|
||||
br_ssl_server_base_init(_sc_svr.get(), suites_server_rsa_P, sizeof(suites_server_rsa_P) / sizeof(suites_server_rsa_P[0]));
|
||||
br_ssl_server_set_single_rsa(_sc_svr.get(), chain ? chain->getX509Certs() : nullptr, chain ? chain->getCount() : 0,
|
||||
sk ? sk->getRSA() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
|
||||
br_rsa_private_get_default(), br_rsa_pkcs1_sign_get_default());
|
||||
br_rsa_private_get_default(), br_rsa_pkcs1_sign_get_default());
|
||||
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
|
||||
if (cache != nullptr)
|
||||
br_ssl_server_set_cache(_sc_svr.get(), cache->getCache());
|
||||
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
|
||||
DEBUG_BSSL("_connectSSLServerRSA: Can't install serverX509check\n");
|
||||
return false;
|
||||
@ -1205,16 +1224,23 @@ bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain,
|
||||
}
|
||||
|
||||
// Called by WiFiServerBearSSL when an elliptic curve cert/key is specified.
|
||||
bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain,
|
||||
bool WiFiClientSecureCtx::_connectSSLServerEC(const X509List *chain,
|
||||
unsigned cert_issuer_key_type, const PrivateKey *sk,
|
||||
const X509List *client_CA_ta) {
|
||||
ServerSessions *cache, const X509List *client_CA_ta) {
|
||||
#ifndef BEARSSL_SSL_BASIC
|
||||
_freeSSL();
|
||||
_oom_err = false;
|
||||
_sc_svr = std::make_shared<br_ssl_server_context>();
|
||||
_eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
{ // ESP.setIramHeap();
|
||||
HeapSelectIram ephemeral;
|
||||
_iobuf_in = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete<unsigned char[]>());
|
||||
_iobuf_out = std::shared_ptr<unsigned char>(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete<unsigned char[]>());
|
||||
DBG_MMU_PRINTF("\n_iobuf_in: %p\n", _iobuf_in.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_out: %p\n", _iobuf_out.get());
|
||||
DBG_MMU_PRINTF( "_iobuf_in_size: %u\n", _iobuf_in_size);
|
||||
DBG_MMU_PRINTF( "_iobuf_out_size: %u\n", _iobuf_out_size);
|
||||
} // ESP.resetHeap();
|
||||
|
||||
if (!_sc_svr || !_iobuf_in || !_iobuf_out) {
|
||||
_freeSSL();
|
||||
@ -1228,6 +1254,8 @@ bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain,
|
||||
sk ? sk->getEC() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
|
||||
cert_issuer_key_type, br_ssl_engine_get_ec(_eng), br_ecdsa_i15_sign_asn1);
|
||||
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
|
||||
if (cache != nullptr)
|
||||
br_ssl_server_set_cache(_sc_svr.get(), cache->getCache());
|
||||
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
|
||||
DEBUG_BSSL("_connectSSLServerEC: Can't install serverX509check\n");
|
||||
return false;
|
||||
@ -1251,14 +1279,25 @@ bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain,
|
||||
|
||||
// Returns an error ID and possibly a string (if dest != null) of the last
|
||||
// BearSSL reported error.
|
||||
int WiFiClientSecure::getLastSSLError(char *dest, size_t len) {
|
||||
int WiFiClientSecureCtx::getLastSSLError(char *dest, size_t len) {
|
||||
int err = 0;
|
||||
const char *t = PSTR("OK");
|
||||
const char *recv_fatal = "";
|
||||
const char *send_fatal = "";
|
||||
if (_sc || _sc_svr) {
|
||||
err = br_ssl_engine_last_error(_eng);
|
||||
}
|
||||
if (_oom_err) {
|
||||
err = -1000;
|
||||
} else {
|
||||
if (err & BR_ERR_RECV_FATAL_ALERT) {
|
||||
recv_fatal = PSTR("SSL received fatal alert - ");
|
||||
err &= ~BR_ERR_RECV_FATAL_ALERT;
|
||||
}
|
||||
if (err & BR_ERR_SEND_FATAL_ALERT) {
|
||||
send_fatal = PSTR("SSL sent fatal alert - ");
|
||||
err &= ~BR_ERR_SEND_FATAL_ALERT;
|
||||
}
|
||||
}
|
||||
switch (err) {
|
||||
case -1000: t = PSTR("Unable to allocate memory for SSL structures and buffers."); break;
|
||||
@ -1323,8 +1362,8 @@ int WiFiClientSecure::getLastSSLError(char *dest, size_t len) {
|
||||
default: t = PSTR("Unknown error code."); break;
|
||||
}
|
||||
if (dest) {
|
||||
strncpy_P(dest, t, len);
|
||||
dest[len - 1] = 0;
|
||||
// snprintf is PSTR safe and guaranteed to 0-terminate
|
||||
snprintf(dest, len, "%s%s%s", recv_fatal, send_fatal, t);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -1395,7 +1434,7 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1
|
||||
0x00, 26 + 14 + 6 + 5, // Extension length
|
||||
0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x04, 0x03, 0x03, 0x03, 0x05, 0x03,
|
||||
0x06, 0x03, 0x02, 0x03, 0x04, 0x01, 0x03, 0x01, 0x05, 0x01, 0x06,
|
||||
0x01, 0x02, 0x01, // Supported signature algorithms
|
||||
0x01, 0x02, 0x01, // Supported signature algorithms
|
||||
0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19,
|
||||
0x00, 0x1d, // Supported groups
|
||||
0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, // Supported EC formats
|
||||
|
@ -31,13 +31,13 @@
|
||||
|
||||
namespace BearSSL {
|
||||
|
||||
class WiFiClientSecure : public WiFiClient {
|
||||
class WiFiClientSecureCtx : public WiFiClient {
|
||||
public:
|
||||
WiFiClientSecure();
|
||||
WiFiClientSecure(const WiFiClientSecure &rhs);
|
||||
~WiFiClientSecure() override;
|
||||
WiFiClientSecureCtx();
|
||||
WiFiClientSecureCtx(const WiFiClientSecure &rhs) = delete;
|
||||
~WiFiClientSecureCtx() override;
|
||||
|
||||
WiFiClientSecure& operator=(const WiFiClientSecure&) = default; // The shared-ptrs handle themselves automatically
|
||||
WiFiClientSecureCtx& operator=(const WiFiClientSecureCtx&) = delete;
|
||||
|
||||
int connect(IPAddress ip, uint16_t port) override;
|
||||
int connect(const String& host, uint16_t port) override;
|
||||
@ -46,12 +46,6 @@ class WiFiClientSecure : public WiFiClient {
|
||||
uint8_t connected() override;
|
||||
size_t write(const uint8_t *buf, size_t size) override;
|
||||
size_t write_P(PGM_P buf, size_t size) override;
|
||||
size_t write(const char *buf) {
|
||||
return write((const uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
size_t write_P(const char *buf) {
|
||||
return write_P((PGM_P)buf, strlen_P(buf));
|
||||
}
|
||||
size_t write(Stream& stream); // Note this is not virtual
|
||||
int read(uint8_t *buf, size_t size) override;
|
||||
int available() override;
|
||||
@ -116,21 +110,16 @@ class WiFiClientSecure : public WiFiClient {
|
||||
int getLastSSLError(char *dest = NULL, size_t len = 0);
|
||||
|
||||
// Attach a preconfigured certificate store
|
||||
void setCertStore(CertStore *certStore) {
|
||||
void setCertStore(CertStoreBase *certStore) {
|
||||
_certStore = certStore;
|
||||
}
|
||||
|
||||
// Select specific ciphers (i.e. optimize for speed over security)
|
||||
// These may be in PROGMEM or RAM, either will run properly
|
||||
bool setCiphers(const uint16_t *cipherAry, int cipherCount);
|
||||
bool setCiphers(std::vector<uint16_t> list);
|
||||
bool setCiphers(const std::vector<uint16_t>& list);
|
||||
bool setCiphersLessSecure(); // Only use the limited set of RSA ciphers without EC
|
||||
|
||||
// Check for Maximum Fragment Length support for given len before connection (possibly insecure)
|
||||
static bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len);
|
||||
static bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len);
|
||||
static bool probeMaxFragmentLength(const String& host, uint16_t port, uint16_t len);
|
||||
|
||||
protected:
|
||||
bool _connectSSL(const char *hostName); // Do initial SSL handshake
|
||||
|
||||
@ -151,7 +140,7 @@ class WiFiClientSecure : public WiFiClient {
|
||||
std::shared_ptr<unsigned char> _iobuf_out;
|
||||
time_t _now;
|
||||
const X509List *_ta;
|
||||
CertStore *_certStore;
|
||||
CertStoreBase *_certStore;
|
||||
int _iobuf_in_size;
|
||||
int _iobuf_out_size;
|
||||
bool _handshake_done;
|
||||
@ -188,25 +177,135 @@ class WiFiClientSecure : public WiFiClient {
|
||||
unsigned _cert_issuer_key_type;
|
||||
|
||||
// Methods for handling server.available() call which returns a client connection.
|
||||
friend class WiFiServerSecure; // Server needs to access these constructors
|
||||
WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type,
|
||||
const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
|
||||
WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk,
|
||||
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta);
|
||||
friend class WiFiClientSecure; // access to private context constructors
|
||||
WiFiClientSecureCtx(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type,
|
||||
const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta);
|
||||
WiFiClientSecureCtx(ClientContext* client, const X509List *chain, const PrivateKey *sk,
|
||||
int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta);
|
||||
|
||||
// RSA keyed server
|
||||
bool _connectSSLServerRSA(const X509List *chain, const PrivateKey *sk, const X509List *client_CA_ta);
|
||||
bool _connectSSLServerRSA(const X509List *chain, const PrivateKey *sk,
|
||||
ServerSessions *cache, const X509List *client_CA_ta);
|
||||
// EC keyed server
|
||||
bool _connectSSLServerEC(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk,
|
||||
const X509List *client_CA_ta);
|
||||
ServerSessions *cache, const X509List *client_CA_ta);
|
||||
|
||||
// X.509 validators differ from server to client
|
||||
bool _installClientX509Validator(); // Set up X509 validator for a client conn.
|
||||
bool _installServerX509Validator(const X509List *client_CA_ta); // Setup X509 client cert validation, if supplied
|
||||
|
||||
uint8_t *_streamLoad(Stream& stream, size_t size);
|
||||
};
|
||||
}; // class WiFiClientSecureCtx
|
||||
|
||||
};
|
||||
|
||||
class WiFiClientSecure : public WiFiClient {
|
||||
|
||||
// WiFiClient's "ClientContext* _client" is always nullptr in this class.
|
||||
// Instead, all virtual functions call their counterpart in "WiFiClientecureCtx* _ctx"
|
||||
// which also derives from WiFiClient (this parent is the one which is eventually used)
|
||||
|
||||
public:
|
||||
|
||||
WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { }
|
||||
WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { }
|
||||
~WiFiClientSecure() override { _ctx = nullptr; }
|
||||
|
||||
WiFiClientSecure& operator=(const WiFiClientSecure&) = default; // The shared-ptrs handle themselves automatically
|
||||
|
||||
uint8_t status() override { return _ctx->status(); }
|
||||
int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); }
|
||||
int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); }
|
||||
int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); }
|
||||
|
||||
uint8_t connected() override { return _ctx->connected(); }
|
||||
size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); }
|
||||
size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); }
|
||||
size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); }
|
||||
size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); }
|
||||
size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); }
|
||||
int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); }
|
||||
int available() override { return _ctx->available(); }
|
||||
int read() override { return _ctx->read(); }
|
||||
int peek() override { return _ctx->peek(); }
|
||||
size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); }
|
||||
bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); }
|
||||
bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); }
|
||||
void flush() override { (void)flush(0); }
|
||||
void stop() override { (void)stop(0); }
|
||||
|
||||
// Allow sessions to be saved/restored automatically to a memory area
|
||||
void setSession(Session *session) { _ctx->setSession(session); }
|
||||
|
||||
// Don't validate the chain, just accept whatever is given. VERY INSECURE!
|
||||
void setInsecure() { _ctx->setInsecure(); }
|
||||
|
||||
// Assume a given public key, don't validate or use cert info at all
|
||||
void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN) {
|
||||
_ctx->setKnownKey(pk, usages);
|
||||
}
|
||||
// Only check SHA1 fingerprint of certificate
|
||||
bool setFingerprint(const uint8_t fingerprint[20]) {
|
||||
return _ctx->setFingerprint(fingerprint);
|
||||
}
|
||||
bool setFingerprint(const char *fpStr) { return _ctx->setFingerprint(fpStr); }
|
||||
// Accept any certificate that's self-signed
|
||||
void allowSelfSignedCerts() { _ctx->allowSelfSignedCerts(); }
|
||||
|
||||
// Install certificates of trusted CAs or specific site
|
||||
void setTrustAnchors(const X509List *ta) { _ctx->setTrustAnchors(ta); }
|
||||
// In cases when NTP is not used, app must set a time manually to check cert validity
|
||||
void setX509Time(time_t now) { _ctx->setX509Time(now); }
|
||||
// Install a client certificate for this connection, in case the server requires it (i.e. MQTT)
|
||||
void setClientRSACert(const X509List *cert, const PrivateKey *sk) { _ctx->setClientRSACert(cert, sk); }
|
||||
void setClientECCert(const X509List *cert, const PrivateKey *sk,
|
||||
unsigned allowed_usages, unsigned cert_issuer_key_type) {
|
||||
_ctx->setClientECCert(cert, sk, allowed_usages, cert_issuer_key_type);
|
||||
}
|
||||
|
||||
// Sets the requested buffer size for transmit and receive
|
||||
void setBufferSizes(int recv, int xmit) { _ctx->setBufferSizes(recv, xmit); }
|
||||
|
||||
// Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection)
|
||||
int getMFLNStatus() { return _ctx->getMFLNStatus(); }
|
||||
|
||||
// Return an error code and possibly a text string in a passed-in buffer with last SSL failure
|
||||
int getLastSSLError(char *dest = NULL, size_t len = 0) { return _ctx->getLastSSLError(dest, len); }
|
||||
|
||||
// Attach a preconfigured certificate store
|
||||
void setCertStore(CertStoreBase *certStore) { _ctx->setCertStore(certStore); }
|
||||
|
||||
// Select specific ciphers (i.e. optimize for speed over security)
|
||||
// These may be in PROGMEM or RAM, either will run properly
|
||||
bool setCiphers(const uint16_t *cipherAry, int cipherCount) { return _ctx->setCiphers(cipherAry, cipherCount); }
|
||||
bool setCiphers(const std::vector<uint16_t> list) { return _ctx->setCiphers(list); }
|
||||
bool setCiphersLessSecure() { return _ctx->setCiphersLessSecure(); } // Only use the limited set of RSA ciphers without EC
|
||||
|
||||
// Check for Maximum Fragment Length support for given len before connection (possibly insecure)
|
||||
static bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len);
|
||||
static bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len);
|
||||
static bool probeMaxFragmentLength(const String& host, uint16_t port, uint16_t len);
|
||||
|
||||
private:
|
||||
std::shared_ptr<WiFiClientSecureCtx> _ctx;
|
||||
|
||||
// Methods for handling server.available() call which returns a client connection.
|
||||
friend class WiFiServerSecure; // Server needs to access these constructors
|
||||
WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type,
|
||||
const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta):
|
||||
_ctx(new WiFiClientSecureCtx(client, chain, cert_issuer_key_type, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta)) {
|
||||
}
|
||||
|
||||
WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk,
|
||||
int iobuf_in_size, int iobuf_out_size, ServerSessions *cache,
|
||||
const X509List *client_CA_ta):
|
||||
_ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta)) {
|
||||
}
|
||||
|
||||
}; // class WiFiClientSecure
|
||||
|
||||
}; // namespace BearSSL
|
||||
|
||||
#endif
|
||||
|
@ -115,9 +115,10 @@ WiFiClient WiFiServer::available(byte* status) {
|
||||
WiFiClient result(_unclaimed);
|
||||
|
||||
// pcb can be null when peer has already closed the connection
|
||||
if (_unclaimed->getPCB())
|
||||
if (_unclaimed->getPCB()) {
|
||||
// give permission to lwIP to accept one more peer
|
||||
tcp_backlog_accepted(_unclaimed->getPCB());
|
||||
}
|
||||
|
||||
_unclaimed = _unclaimed->next();
|
||||
result.setNoDelay(getNoDelay());
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define wifiserver_h
|
||||
|
||||
extern "C" {
|
||||
#include "include/wl_definitions.h"
|
||||
#include "wl_definitions.h"
|
||||
|
||||
struct tcp_pcb;
|
||||
}
|
||||
|
@ -79,13 +79,13 @@ WiFiClientSecure WiFiServerSecure::available(uint8_t* status) {
|
||||
(void) status; // Unused
|
||||
if (_unclaimed) {
|
||||
if (_sk && _sk->isRSA()) {
|
||||
WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
|
||||
WiFiClientSecure result(_unclaimed, _chain, _sk, _iobuf_in_size, _iobuf_out_size, _cache, _client_CA_ta);
|
||||
_unclaimed = _unclaimed->next();
|
||||
result.setNoDelay(_noDelay);
|
||||
DEBUGV("WS:av\r\n");
|
||||
return result;
|
||||
} else if (_sk && _sk->isEC()) {
|
||||
WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _client_CA_ta);
|
||||
WiFiClientSecure result(_unclaimed, _chain, _cert_issuer_key_type, _sk, _iobuf_in_size, _iobuf_out_size, _cache, _client_CA_ta);
|
||||
_unclaimed = _unclaimed->next();
|
||||
result.setNoDelay(_noDelay);
|
||||
DEBUGV("WS:av\r\n");
|
||||
|
@ -42,6 +42,11 @@ class WiFiServerSecure : public WiFiServer {
|
||||
_iobuf_out_size = xmit;
|
||||
}
|
||||
|
||||
// Sets the server's cache to the given one.
|
||||
void setCache(ServerSessions *cache) {
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
// Set the server's RSA key and x509 certificate (required, pick one).
|
||||
// Caller needs to preserve the chain and key throughout the life of the server.
|
||||
void setRSACert(const X509List *chain, const PrivateKey *sk);
|
||||
@ -69,6 +74,7 @@ class WiFiServerSecure : public WiFiServer {
|
||||
int _iobuf_in_size = BR_SSL_BUFSIZE_INPUT;
|
||||
int _iobuf_out_size = 837;
|
||||
const X509List *_client_CA_ta = nullptr;
|
||||
ServerSessions *_cache = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "include/wl_definitions.h"
|
||||
#include "wl_definitions.h"
|
||||
#include "osapi.h"
|
||||
#include "ets_sys.h"
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
wl_definitions.h - Library for Arduino Wifi shield.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*
|
||||
* wl_definitions.h
|
||||
*
|
||||
* Created on: Mar 6, 2011
|
||||
* Author: dlafauci
|
||||
*/
|
||||
|
||||
#ifndef WL_DEFINITIONS_H_
|
||||
#define WL_DEFINITIONS_H_
|
||||
|
||||
// Maximum size of a SSID
|
||||
#define WL_SSID_MAX_LENGTH 32
|
||||
// Length of passphrase. Valid lengths are 8-63.
|
||||
#define WL_WPA_KEY_MAX_LENGTH 63
|
||||
// Length of key in bytes. Valid values are 5 and 13.
|
||||
#define WL_WEP_KEY_MAX_LENGTH 13
|
||||
// Size of a MAC-address or BSSID
|
||||
#define WL_MAC_ADDR_LENGTH 6
|
||||
// Size of a MAC-address or BSSID
|
||||
#define WL_IPV4_LENGTH 4
|
||||
// Maximum size of a SSID list
|
||||
#define WL_NETWORKS_LIST_MAXNUM 10
|
||||
// Maxmium number of socket
|
||||
#define MAX_SOCK_NUM 4
|
||||
// Socket not available constant
|
||||
#define SOCK_NOT_AVAIL 255
|
||||
// Default state value for Wifi state field
|
||||
#define NA_STATE -1
|
||||
//Maximum number of attempts to establish wifi connection
|
||||
#define WL_MAX_ATTEMPT_CONNECTION 10
|
||||
|
||||
typedef enum {
|
||||
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
|
||||
WL_IDLE_STATUS = 0,
|
||||
WL_NO_SSID_AVAIL = 1,
|
||||
WL_SCAN_COMPLETED = 2,
|
||||
WL_CONNECTED = 3,
|
||||
WL_CONNECT_FAILED = 4,
|
||||
WL_CONNECTION_LOST = 5,
|
||||
WL_WRONG_PASSWORD = 6,
|
||||
WL_DISCONNECTED = 7
|
||||
} wl_status_t;
|
||||
|
||||
/* Encryption modes */
|
||||
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
|
||||
ENC_TYPE_WEP = 5,
|
||||
ENC_TYPE_TKIP = 2,
|
||||
ENC_TYPE_CCMP = 4,
|
||||
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
|
||||
ENC_TYPE_NONE = 7,
|
||||
ENC_TYPE_AUTO = 8
|
||||
};
|
||||
|
||||
#if !defined(LWIP_INTERNAL) && !defined(__LWIP_TCP_H__)
|
||||
enum wl_tcp_state {
|
||||
CLOSED = 0,
|
||||
LISTEN = 1,
|
||||
SYN_SENT = 2,
|
||||
SYN_RCVD = 3,
|
||||
ESTABLISHED = 4,
|
||||
FIN_WAIT_1 = 5,
|
||||
FIN_WAIT_2 = 6,
|
||||
CLOSE_WAIT = 7,
|
||||
CLOSING = 8,
|
||||
LAST_ACK = 9,
|
||||
TIME_WAIT = 10
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WL_DEFINITIONS_H_ */
|
Reference in New Issue
Block a user