mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-21 21:22:31 +03:00
Merge branch 'esp8266' of https://github.com/esp8266/Arduino into doc_modify
This commit is contained in:
@ -193,6 +193,17 @@ File FS::open(const char* path, const char* mode) {
|
|||||||
return File(_impl->open(path, om, am));
|
return File(_impl->open(path, om, am));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FS::exists(const char* path) {
|
||||||
|
if (!_impl) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _impl->exists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FS::exists(const String& path) {
|
||||||
|
return exists(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
Dir FS::openDir(const char* path) {
|
Dir FS::openDir(const char* path) {
|
||||||
if (!_impl) {
|
if (!_impl) {
|
||||||
return Dir();
|
return Dir();
|
||||||
|
@ -97,6 +97,9 @@ public:
|
|||||||
File open(const char* path, const char* mode);
|
File open(const char* path, const char* mode);
|
||||||
File open(const String& path, const char* mode);
|
File open(const String& path, const char* mode);
|
||||||
|
|
||||||
|
bool exists(const char* path);
|
||||||
|
bool exists(const String& path);
|
||||||
|
|
||||||
Dir openDir(const char* path);
|
Dir openDir(const char* path);
|
||||||
Dir openDir(const String& path);
|
Dir openDir(const String& path);
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
virtual bool begin() = 0;
|
virtual bool begin() = 0;
|
||||||
virtual bool format() = 0;
|
virtual bool format() = 0;
|
||||||
virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0;
|
virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0;
|
||||||
|
virtual bool exists(const char* path) = 0;
|
||||||
virtual DirImplPtr openDir(const char* path) = 0;
|
virtual DirImplPtr openDir(const char* path) = 0;
|
||||||
virtual bool rename(const char* pathFrom, const char* pathTo) = 0;
|
virtual bool rename(const char* pathFrom, const char* pathTo) = 0;
|
||||||
virtual bool remove(const char* path) = 0;
|
virtual bool remove(const char* path) = 0;
|
||||||
|
@ -95,7 +95,7 @@ class cbuf {
|
|||||||
size_t bytes_available = room();
|
size_t bytes_available = room();
|
||||||
size_t size_to_write = (size < bytes_available) ? size : bytes_available;
|
size_t size_to_write = (size < bytes_available) ? size : bytes_available;
|
||||||
size_t size_written = size_to_write;
|
size_t size_written = size_to_write;
|
||||||
if(_end > _begin && size_to_write > (size_t)(_bufend - _end)) {
|
if(_end >= _begin && size_to_write > (size_t)(_bufend - _end)) {
|
||||||
size_t top_size = _bufend - _end;
|
size_t top_size = _bufend - _end;
|
||||||
memcpy(_end, src, top_size);
|
memcpy(_end, src, top_size);
|
||||||
_end = _buf;
|
_end = _buf;
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override;
|
FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override;
|
||||||
|
bool exists(const char* path) override;
|
||||||
DirImplPtr openDir(const char* path) override;
|
DirImplPtr openDir(const char* path) override;
|
||||||
|
|
||||||
bool rename(const char* pathFrom, const char* pathTo) override {
|
bool rename(const char* pathFrom, const char* pathTo) override {
|
||||||
@ -404,6 +404,14 @@ FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode acc
|
|||||||
return std::make_shared<SPIFFSFileImpl>(this, fd);
|
return std::make_shared<SPIFFSFileImpl>(this, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SPIFFSImpl::exists(const char* path) {
|
||||||
|
char tmpName[SPIFFS_OBJ_NAME_LEN];
|
||||||
|
strlcpy(tmpName, path, sizeof(tmpName));
|
||||||
|
spiffs_stat stat;
|
||||||
|
int rc = SPIFFS_stat(&_fs, tmpName, &stat);
|
||||||
|
return rc == SPIFFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
DirImplPtr SPIFFSImpl::openDir(const char* path) {
|
DirImplPtr SPIFFSImpl::openDir(const char* path) {
|
||||||
spiffs_DIR dir;
|
spiffs_DIR dir;
|
||||||
char tmpName[SPIFFS_OBJ_NAME_LEN];
|
char tmpName[SPIFFS_OBJ_NAME_LEN];
|
||||||
|
@ -231,6 +231,14 @@ if (!f) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### exists
|
||||||
|
|
||||||
|
```c++
|
||||||
|
SPIFFS.exists(path)
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns *true* if a file with given path exists, *false* otherwise.
|
||||||
|
|
||||||
#### openDir
|
#### openDir
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
|
@ -40,8 +40,7 @@ ESP8266WebServer::ESP8266WebServer(int port)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP8266WebServer::~ESP8266WebServer()
|
ESP8266WebServer::~ESP8266WebServer() {
|
||||||
{
|
|
||||||
if (!_firstHandler)
|
if (!_firstHandler)
|
||||||
return;
|
return;
|
||||||
RequestHandler* handler = _firstHandler;
|
RequestHandler* handler = _firstHandler;
|
||||||
@ -56,14 +55,11 @@ void ESP8266WebServer::begin() {
|
|||||||
_server.begin();
|
_server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction handler) {
|
||||||
void ESP8266WebServer::on(const char* uri, ESP8266WebServer::THandlerFunction handler)
|
|
||||||
{
|
|
||||||
on(uri, HTTP_ANY, handler);
|
on(uri, HTTP_ANY, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn)
|
void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::THandlerFunction fn) {
|
||||||
{
|
|
||||||
_addRequestHandler(new FunctionRequestHandler(fn, uri, method));
|
_addRequestHandler(new FunctionRequestHandler(fn, uri, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +75,10 @@ void ESP8266WebServer::_addRequestHandler(RequestHandler* handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::serveStatic(const char* uri, FS& fs, const char* path) {
|
void ESP8266WebServer::serveStatic(const char* uri, FS& fs, const char* path) {
|
||||||
_addRequestHandler(new StaticRequestHandler(fs, uri));
|
_addRequestHandler(new StaticRequestHandler(fs, path, uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266WebServer::handleClient()
|
void ESP8266WebServer::handleClient() {
|
||||||
{
|
|
||||||
WiFiClient client = _server.available();
|
WiFiClient client = _server.available();
|
||||||
if (!client) {
|
if (!client) {
|
||||||
return;
|
return;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
class RequestHandler {
|
class RequestHandler {
|
||||||
public:
|
public:
|
||||||
RequestHandler(const char* uri, HTTPMethod method)
|
RequestHandler(const char* uri, HTTPMethod method)
|
||||||
: uri(uri)
|
: _uri(uri)
|
||||||
, method(method)
|
, _method(method)
|
||||||
, next(NULL)
|
, next(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -15,8 +15,8 @@ public:
|
|||||||
RequestHandler* next;
|
RequestHandler* next;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String uri;
|
String _uri;
|
||||||
HTTPMethod method;
|
HTTPMethod _method;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -25,47 +25,59 @@ class FunctionRequestHandler : public RequestHandler {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
|
||||||
: fn(fn)
|
: _fn(fn)
|
||||||
, base(uri, method)
|
, base(uri, method)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
||||||
if (method != HTTP_ANY && method != requestMethod)
|
if (_method != HTTP_ANY && _method != requestMethod)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (requestUri != uri)
|
if (requestUri != _uri)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fn();
|
_fn();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ESP8266WebServer::THandlerFunction fn;
|
ESP8266WebServer::THandlerFunction _fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StaticRequestHandler : public RequestHandler {
|
class StaticRequestHandler : public RequestHandler {
|
||||||
typedef RequestHandler base;
|
typedef RequestHandler base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StaticRequestHandler(FS& fs, const char* uri)
|
StaticRequestHandler(FS& fs, const char* path, const char* uri)
|
||||||
: fs(fs)
|
: _fs(fs)
|
||||||
, base(uri, HTTP_GET)
|
, base(uri, HTTP_GET)
|
||||||
|
, _path(path)
|
||||||
{
|
{
|
||||||
|
_isFile = fs.exists(path);
|
||||||
|
DEBUGV("StaticRequestHandler: path=%s uri=%s isFile=%d\r\n", path, uri, _isFile);
|
||||||
|
_baseUriLength = _uri.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
|
||||||
if (requestMethod != method)
|
if (requestMethod != _method)
|
||||||
return false;
|
return false;
|
||||||
DEBUGV("StaticRequestHandler::handle: %s\r\n", requestUri.c_str());
|
DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
|
||||||
if (!requestUri.startsWith(uri))
|
if (!requestUri.startsWith(_uri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto prefixLength = uri.length() - 1;
|
String path(_path);
|
||||||
String path = requestUri.substring(prefixLength);
|
if (!_isFile) {
|
||||||
DEBUGV("StaticRequestHandler::handle: %d %s\r\n", prefixLength, path.c_str());
|
// Base URI doesn't point to a file. Append whatever follows this
|
||||||
File f = fs.open(path, "r");
|
// URI in request to get the file path.
|
||||||
|
path += requestUri.substring(_baseUriLength);
|
||||||
|
}
|
||||||
|
else if (requestUri != _uri) {
|
||||||
|
// Base URI points to a file but request doesn't match this URI exactly
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DEBUGV("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);
|
||||||
|
File f = _fs.open(path, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -90,7 +102,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FS fs;
|
FS _fs;
|
||||||
|
String _path;
|
||||||
|
bool _isFile;
|
||||||
|
size_t _baseUriLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //REQUESTHANDLER_H
|
#endif //REQUESTHANDLER_H
|
||||||
|
88
libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino
Normal file
88
libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* HTTP over TLS (HTTPS) example sketch
|
||||||
|
*
|
||||||
|
* This example demonstrates how to use
|
||||||
|
* WiFiClientSecure class to access HTTPS API.
|
||||||
|
* We fetch and display the status of
|
||||||
|
* esp8266/Arduino project continous integration
|
||||||
|
* build.
|
||||||
|
*
|
||||||
|
* Created by Ivan Grokhotkov, 2015.
|
||||||
|
* This example is in public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
|
||||||
|
const char* ssid = "........";
|
||||||
|
const char* password = "........";
|
||||||
|
|
||||||
|
const char* host = "api.github.com";
|
||||||
|
const int httpsPort = 443;
|
||||||
|
|
||||||
|
// Use web browser to view and copy
|
||||||
|
// SHA1 fingerprint of the certificate
|
||||||
|
const char* fingerprint = "CF 05 98 89 CA FF 8E D8 5E 5C E0 C2 E4 F7 E6 C3 C7 50 DD 5C";
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
Serial.print("connecting to ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected");
|
||||||
|
Serial.println("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// Use WiFiClientSecure class to create TLS connection
|
||||||
|
WiFiClientSecure client;
|
||||||
|
Serial.print("connecting to ");
|
||||||
|
Serial.println(host);
|
||||||
|
if (!client.connect(host, httpsPort)) {
|
||||||
|
Serial.println("connection failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.verify(fingerprint, host)) {
|
||||||
|
Serial.println("certificate matches");
|
||||||
|
} else {
|
||||||
|
Serial.println("certificate doesn't match");
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = "/repos/esp8266/Arduino/commits/esp8266/status";
|
||||||
|
Serial.print("requesting URL: ");
|
||||||
|
Serial.println(url);
|
||||||
|
|
||||||
|
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
|
||||||
|
"Host: " + host + "\r\n" +
|
||||||
|
"User-Agent: BuildFailureDetectorESP8266\r\n" +
|
||||||
|
"Connection: close\r\n\r\n");
|
||||||
|
|
||||||
|
Serial.println("request sent");
|
||||||
|
while (client.connected()) {
|
||||||
|
String line = client.readStringUntil('\n');
|
||||||
|
if (line == "\r") {
|
||||||
|
Serial.println("headers received");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String line = client.readStringUntil('\n');
|
||||||
|
if (line.startsWith("{\"state\":\"success\"")) {
|
||||||
|
Serial.println("esp8266/Arduino CI successfull!");
|
||||||
|
} else {
|
||||||
|
Serial.println("esp8266/Arduino CI has failed");
|
||||||
|
}
|
||||||
|
Serial.println("reply was:");
|
||||||
|
Serial.println("==========");
|
||||||
|
Serial.println(line);
|
||||||
|
Serial.println("==========");
|
||||||
|
Serial.println("closing connection");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
@ -16,6 +16,7 @@ WiFi KEYWORD1
|
|||||||
WiFiClient KEYWORD1
|
WiFiClient KEYWORD1
|
||||||
WiFiServer KEYWORD1
|
WiFiServer KEYWORD1
|
||||||
WiFiUDP KEYWORD1
|
WiFiUDP KEYWORD1
|
||||||
|
WiFiClientSecure KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
@ -64,4 +65,3 @@ scanNetworks KEYWORD2
|
|||||||
WIFI_AP LITERAL1
|
WIFI_AP LITERAL1
|
||||||
WIFI_STA LITERAL1
|
WIFI_STA LITERAL1
|
||||||
WIFI_AP_STA LITERAL1
|
WIFI_AP_STA LITERAL1
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ extern "C"
|
|||||||
}
|
}
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "cbuf.h"
|
||||||
#include "ESP8266WiFi.h"
|
#include "ESP8266WiFi.h"
|
||||||
#include "WiFiClientSecure.h"
|
#include "WiFiClientSecure.h"
|
||||||
#include "WiFiClient.h"
|
#include "WiFiClient.h"
|
||||||
@ -41,15 +42,23 @@ extern "C"
|
|||||||
#include "include/ClientContext.h"
|
#include "include/ClientContext.h"
|
||||||
#include "c_types.h"
|
#include "c_types.h"
|
||||||
|
|
||||||
|
//#define DEBUG_SSL
|
||||||
|
|
||||||
|
#ifdef DEBUG_SSL
|
||||||
|
#define SSL_DEBUG_OPTS SSL_DISPLAY_STATES
|
||||||
|
#else
|
||||||
|
#define SSL_DEBUG_OPTS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
class SSLContext {
|
class SSLContext {
|
||||||
public:
|
public:
|
||||||
SSLContext() {
|
SSLContext() {
|
||||||
if (_ssl_ctx_refcnt == 0) {
|
if (_ssl_ctx_refcnt == 0) {
|
||||||
_ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DISPLAY_STATES, 0);
|
_ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS, 0);
|
||||||
}
|
}
|
||||||
++_ssl_ctx_refcnt;
|
++_ssl_ctx_refcnt;
|
||||||
|
|
||||||
|
_rxbuf = new cbuf(1536);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SSLContext() {
|
~SSLContext() {
|
||||||
@ -62,6 +71,8 @@ public:
|
|||||||
if (_ssl_ctx_refcnt == 0) {
|
if (_ssl_ctx_refcnt == 0) {
|
||||||
ssl_ctx_free(_ssl_ctx);
|
ssl_ctx_free(_ssl_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete _rxbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ref() {
|
void ref() {
|
||||||
@ -78,27 +89,71 @@ public:
|
|||||||
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0);
|
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int read(uint8_t* dst, size_t size) {
|
||||||
|
if (size > _rxbuf->getSize()) {
|
||||||
|
_readAll();
|
||||||
|
}
|
||||||
|
return _rxbuf->read(reinterpret_cast<char*>(dst), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read() {
|
||||||
|
optimistic_yield(100);
|
||||||
|
if (!_rxbuf->getSize()) {
|
||||||
|
_readAll();
|
||||||
|
}
|
||||||
|
return _rxbuf->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
int peek() {
|
||||||
|
if (!_rxbuf->getSize()) {
|
||||||
|
_readAll();
|
||||||
|
}
|
||||||
|
return _rxbuf->peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
int available() {
|
||||||
|
optimistic_yield(100);
|
||||||
|
return _rxbuf->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
operator SSL*() {
|
operator SSL*() {
|
||||||
return _ssl;
|
return _ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
int _readAll() {
|
||||||
|
uint8_t* data;
|
||||||
|
int rc = ssl_read(_ssl, &data);
|
||||||
|
if (rc <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (rc > _rxbuf->room()) {
|
||||||
|
DEBUGV("WiFiClientSecure rx overflow");
|
||||||
|
rc = _rxbuf->room();
|
||||||
|
}
|
||||||
|
int result = 0;
|
||||||
|
size_t sizeBefore = _rxbuf->getSize();
|
||||||
|
if (rc)
|
||||||
|
result = _rxbuf->write(reinterpret_cast<const char*>(data), rc);
|
||||||
|
DEBUGV("*** rb: %d + %d = %d\r\n", sizeBefore, rc, _rxbuf->getSize());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static SSL_CTX* _ssl_ctx;
|
static SSL_CTX* _ssl_ctx;
|
||||||
static int _ssl_ctx_refcnt;
|
static int _ssl_ctx_refcnt;
|
||||||
SSL* _ssl = nullptr;
|
SSL* _ssl = nullptr;
|
||||||
int _refcnt = 0;
|
int _refcnt = 0;
|
||||||
|
cbuf* _rxbuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSL_CTX* SSLContext::_ssl_ctx = nullptr;
|
SSL_CTX* SSLContext::_ssl_ctx = nullptr;
|
||||||
int SSLContext::_ssl_ctx_refcnt = 0;
|
int SSLContext::_ssl_ctx_refcnt = 0;
|
||||||
|
|
||||||
|
|
||||||
WiFiClientSecure::WiFiClientSecure()
|
WiFiClientSecure::WiFiClientSecure() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFiClientSecure::~WiFiClientSecure()
|
WiFiClientSecure::~WiFiClientSecure() {
|
||||||
{
|
|
||||||
if (_ssl) {
|
if (_ssl) {
|
||||||
_ssl->unref();
|
_ssl->unref();
|
||||||
}
|
}
|
||||||
@ -164,14 +219,19 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int WiFiClientSecure::read(uint8_t *buf, size_t size) {
|
int WiFiClientSecure::read(uint8_t *buf, size_t size) {
|
||||||
|
return _ssl->read(buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* data;
|
int WiFiClientSecure::read() {
|
||||||
int rc = ssl_read(*_ssl, &data);
|
return _ssl->read();
|
||||||
if (rc <= 0)
|
}
|
||||||
return 0;
|
|
||||||
|
|
||||||
memcpy(buf, data, rc);
|
int WiFiClientSecure::peek() {
|
||||||
return rc;
|
return _ssl->peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiFiClientSecure::available() {
|
||||||
|
return _ssl->available();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiClientSecure::stop() {
|
void WiFiClientSecure::stop() {
|
||||||
@ -182,6 +242,50 @@ void WiFiClientSecure::stop() {
|
|||||||
return WiFiClient::stop();
|
return WiFiClient::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parseHexNibble(char pb, uint8_t* res) {
|
||||||
|
if (pb >= '0' && pb <= '9') {
|
||||||
|
*res = (uint8_t) (pb - '0'); return true;
|
||||||
|
}
|
||||||
|
else if (pb >= 'a' && pb <= 'f') {
|
||||||
|
*res = (uint8_t) (pb - 'a' + 10); return true;
|
||||||
|
}
|
||||||
|
else if (pb >= 'A' && pb <= 'F') {
|
||||||
|
*res = (uint8_t) (pb - 'A' + 10); return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiClientSecure::verify(const char* fp, const char* url) {
|
||||||
|
uint8_t sha1[20];
|
||||||
|
int len = strlen(fp);
|
||||||
|
int pos = 0;
|
||||||
|
for (int i = 0; i < sizeof(sha1); ++i) {
|
||||||
|
while (pos < len && fp[pos] == ' ') {
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
DEBUGV("pos:%d ", pos);
|
||||||
|
if (pos > len - 2) {
|
||||||
|
DEBUGV("fingerprint too short\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t high, low;
|
||||||
|
if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos+1], &low)) {
|
||||||
|
DEBUGV("invalid hex sequence: %c%c\r\n", fp[pos], fp[pos+1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos += 2;
|
||||||
|
sha1[i] = low | (high << 4);
|
||||||
|
}
|
||||||
|
if (ssl_match_fingerprint(*_ssl, sha1) != 0) {
|
||||||
|
DEBUGV("fingerprint doesn't match\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: check URL against certificate
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
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 = reinterpret_cast<ClientContext*>(fd);
|
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
|
||||||
if (_client->state() != ESTABLISHED && !_client->getSize()) {
|
if (_client->state() != ESTABLISHED && !_client->getSize()) {
|
||||||
@ -217,13 +321,13 @@ extern "C" int ax_get_file(const char *filename, uint8_t **buf) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_TLS_MEM
|
#ifdef DEBUG_TLS_MEM
|
||||||
#define DEBUG_TLS_MEM_PRINT(...) DEBUGV(__VA_ARGS__)
|
#define DEBUG_TLS_MEM_PRINT(...) DEBUGV(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define DEBUG_TLS_MEM_PRINT(...)
|
#define DEBUG_TLS_MEM_PRINT(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C" void* ax_port_malloc(size_t size, const char* file, int line) {
|
extern "C" void* ax_port_malloc(size_t size, const char* file, int line) {
|
||||||
void* result = malloc(size);
|
void* result = malloc(size);
|
||||||
|
|
||||||
@ -254,7 +358,6 @@ extern "C" void* ax_port_realloc(void* ptr, size_t size, const char* file, int l
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void ax_port_free(void* ptr) {
|
extern "C" void ax_port_free(void* ptr) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
uint32_t *p = (uint32_t*) ptr;
|
uint32_t *p = (uint32_t*) ptr;
|
||||||
|
@ -38,8 +38,13 @@ public:
|
|||||||
int connect(IPAddress ip, uint16_t port) override;
|
int connect(IPAddress ip, uint16_t port) override;
|
||||||
int connect(const char* name, uint16_t port) override;
|
int connect(const char* name, uint16_t port) override;
|
||||||
|
|
||||||
|
bool verify(const char* fingerprint, const char* url);
|
||||||
|
|
||||||
size_t write(const uint8_t *buf, size_t size) override;
|
size_t write(const uint8_t *buf, size_t size) override;
|
||||||
int read(uint8_t *buf, size_t size) override;
|
int read(uint8_t *buf, size_t size) override;
|
||||||
|
int available() override;
|
||||||
|
int read() override;
|
||||||
|
int peek() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -375,6 +375,15 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code);
|
|||||||
*/
|
*/
|
||||||
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
|
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if certificate fingerprint (SHA1) matches the one given.
|
||||||
|
*
|
||||||
|
* @param ssl [in] An SSL object reference.
|
||||||
|
* @param fp [in] SHA1 fingerprint to match against
|
||||||
|
* @return SSL_OK if the certificate is verified.
|
||||||
|
*/
|
||||||
|
EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve an X.509 distinguished name component.
|
* @brief Retrieve an X.509 distinguished name component.
|
||||||
*
|
*
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user