Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand SSLSessionId structure to manage allocated memory. #1614

Merged
merged 5 commits into from
Feb 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sming/SmingCore/Network/Http/HttpRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ String HttpRequest::toString()
F("> SSL Cert Fingerprint Length: ") + String((sslFingerprint.certSha1 == nullptr) ? 0 : SHA1_SIZE) + '\n';
content +=
F("> SSL PK Fingerprint Length: ") + String((sslFingerprint.pkSha256 == nullptr) ? 0 : SHA256_SIZE) + '\n';
content += F("> SSL ClientCert Length: ") + String(sslKeyCertPair.certificateLength) + '\n';
content += F("> SSL ClientCert PK Length: ") + String(sslKeyCertPair.keyLength) + '\n';
content += F("> SSL ClientCert Length: ") + String(sslKeyCertPair.getCertificateLength()) + '\n';
content += F("> SSL ClientCert PK Length: ") + String(sslKeyCertPair.getKeyLength()) + '\n';
content += '\n';
#endif

Expand Down
10 changes: 5 additions & 5 deletions Sming/SmingCore/Network/Http/HttpRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ class HttpRequest
/**
* @brief Requires(pins) the remote SSL certificate to match certain fingerprints
* Check if SHA256 hash of Subject Public Key Info matches the one given.
* @param SSLFingerprints - passes the certificate fingerprints by reference.
* @param fingerprints - passes the certificate fingerprints by reference.
*
* @return bool true of success, false or failure
*/
HttpRequest* pinCertificate(const SSLFingerprints& fingerprints)
HttpRequest* pinCertificate(const SslFingerprints& fingerprints)
{
sslFingerprint = fingerprints;
return this;
Expand All @@ -245,7 +245,7 @@ class HttpRequest
*
* @return HttpRequest pointer
*/
HttpRequest* setSslKeyCert(const SSLKeyCertPair& keyCertPair)
HttpRequest* setSslKeyCert(const SslKeyCertPair& keyCertPair)
{
sslKeyCertPair = keyCertPair;
return this;
Expand Down Expand Up @@ -284,8 +284,8 @@ class HttpRequest

#ifdef ENABLE_SSL
uint32_t sslOptions = 0;
SSLFingerprints sslFingerprint;
SSLKeyCertPair sslKeyCertPair;
SslFingerprints sslFingerprint;
SslKeyCertPair sslKeyCertPair;
#endif

private:
Expand Down
12 changes: 4 additions & 8 deletions Sming/SmingCore/Network/HttpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ bool HttpClient::send(HttpRequest* request)
// Based on the URL decide if we should reuse the SSL and TCP pool
if(useSsl) {
if(!sslSessionIdPool.contains(cacheKey)) {
sslSessionIdPool[cacheKey] = (SSLSessionId*)malloc(sizeof(SSLSessionId));
sslSessionIdPool[cacheKey]->value = NULL;
sslSessionIdPool[cacheKey]->length = 0;
sslSessionIdPool[cacheKey] = new SslSessionId;
}
httpConnectionPool[cacheKey]->addSslOptions(request->getSslOptions());
httpConnectionPool[cacheKey]->pinCertificate(request->sslFingerprint);
Expand Down Expand Up @@ -101,15 +99,13 @@ HashMap<String, HttpConnection*> HttpClient::httpConnectionPool;
HashMap<String, RequestQueue*> HttpClient::queue;

#ifdef ENABLE_SSL
HashMap<String, SSLSessionId*> HttpClient::sslSessionIdPool;
HashMap<String, SslSessionId*> HttpClient::sslSessionIdPool;

void HttpClient::freeSslSessionPool()
{
for(int i = 0; i < sslSessionIdPool.count(); i++) {
for(unsigned i = 0; i < sslSessionIdPool.count(); i++) {
String key = sslSessionIdPool.keyAt(i);
free(sslSessionIdPool[key]->value);
sslSessionIdPool[key]->value = NULL;
free(sslSessionIdPool[key]);
delete sslSessionIdPool[key];
sslSessionIdPool[key] = NULL;
}
sslSessionIdPool.clear();
Expand Down
4 changes: 2 additions & 2 deletions Sming/SmingCore/Network/HttpClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ class HttpClient
static HashMap<String, RequestQueue*> queue;

#ifdef ENABLE_SSL
static HashMap<String, SSLSessionId*> sslSessionIdPool;
static HashMap<String, SslSessionId*> sslSessionIdPool;
#endif
};

/** @} */
#endif /* _SMING_CORE_NETWORK_HTTPCLIENT_H_ */
#endif /* _SMING_CORE_NETWORK_HTTPCLIENT_H_ */
28 changes: 28 additions & 0 deletions Sming/SmingCore/Network/Ssl/SslFingerprints.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/

#include "ssl/ssl.h"

enum SslFingerprintType {
eSFT_CertSha1 = 0, // << Fingerprint based on the SHA1 value of the certificate.
// Every time a certificate is renewed this value will change.
eSFT_PkSha256, // << Fingerprint based on the SHA256 value of the public key subject in the certificate.
// Only when the private key used to generate the certificate is used then that fingerprint
};

typedef struct {
uint8_t* certSha1 = nullptr; // << certificate SHA1 fingerprint
uint8_t* pkSha256 = nullptr; // << public key SHA256 fingerprint

void free()
{
delete certSha1;
certSha1 = nullptr;
delete pkSha256;
pkSha256 = nullptr;
}
} SslFingerprints;
112 changes: 112 additions & 0 deletions Sming/SmingCore/Network/Ssl/SslKeyCertPair.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/

#ifndef SMINGCORE_NETWORK_SSLKEYCERTPAIR_H_
#define SMINGCORE_NETWORK_SSLKEYCERTPAIR_H_

#include "ssl/ssl.h"
#include "WString.h"

/** @brief Class to manage an SSL key certificate with optional password
*/
class SslKeyCertPair
{
public:
bool isValid()
{
return key && certificate;
}

/** @brief Create certificate using provided values
* @param newKey
* @param newKeyLength
* @param newCertificate
* @param newCertificateLength
* @param newKeyPassword
* @retval bool false on memory allocation failure
* @note We take a new copy of the certificate
*/
bool assign(const uint8_t* newKey, unsigned newKeyLength, const uint8_t* newCertificate,
unsigned newCertificateLength, const char* newKeyPassword = nullptr)
{
free();

if(newKeyLength != 0 && newKey != nullptr) {
if(!key.setLength(newKeyLength)) {
return false;
}
memcpy(key.begin(), newKey, newKeyLength);
}

if(newCertificateLength != 0 && newCertificate != nullptr) {
if(!certificate.setLength(newCertificateLength)) {
return false;
}
memcpy(certificate.begin(), newCertificate, newCertificateLength);
}

unsigned passwordLength = (newKeyPassword == nullptr) ? 0 : strlen(newKeyPassword);
if(passwordLength != 0) {
keyPassword.setString(newKeyPassword, passwordLength);
if(!keyPassword) {
return false;
}
}

return true;
}

/** @brief Assign another certificate to this structure
* @param keyCert
* @retval bool false on memory allocation failure
* @note We take a new copy of the certificate
*/
bool assign(const SslKeyCertPair& keyCert)
{
*this = keyCert;
return (key == keyCert.key) && (keyPassword == keyCert.keyPassword) && (certificate == keyCert.certificate);
}

void free()
{
key = nullptr;
keyPassword = nullptr;
certificate = nullptr;
}

const uint8_t* getKey()
{
return reinterpret_cast<const uint8_t*>(key.c_str());
}

unsigned getKeyLength()
{
return key.length();
}

const char* getKeyPassword()
{
return keyPassword.c_str();
}

const uint8_t* getCertificate()
{
return reinterpret_cast<const uint8_t*>(certificate.c_str());
}

unsigned getCertificateLength()
{
return certificate.length();
}

private:
String key;
String keyPassword;
String certificate;
};

#endif /* SMINGCORE_NETWORK_SSLKEYCERTPAIR_H_ */
49 changes: 49 additions & 0 deletions Sming/SmingCore/Network/Ssl/SslSessionId.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/

#ifndef SMINGCORE_NETWORK_SSLSESSIONID_H_
#define SMINGCORE_NETWORK_SSLSESSIONID_H_

#include "ssl/ssl.h"
#include "WString.h"

/** @brief Manages buffer to store SSL Session ID
*/
class SslSessionId
{
public:
/** @brief May be called even when object is null */
const uint8_t* getValue()
{
return this ? reinterpret_cast<const uint8_t*>(value.c_str()) : nullptr;
}

/** @brief May be called even when object is null */
unsigned getLength()
{
return this ? value.length() : 0;
}

bool isValid()
{
return getLength() != 0;
}

bool assign(const uint8_t* newValue, unsigned newLength)
{
if(!value.setLength(newLength)) {
return false;
}
memcpy(value.begin(), newValue, newLength);
return true;
}

private:
String value;
};

#endif /* SMINGCORE_NETWORK_SSLSESSIONID_H_ */
22 changes: 22 additions & 0 deletions Sming/SmingCore/Network/Ssl/SslStructs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/

#ifndef SMINGCORE_NETWORK_SSL_SSLSTRUCTS_H_
#define SMINGCORE_NETWORK_SSL_SSLSTRUCTS_H_

#include "SslFingerprints.h"
#include "SslKeyCertPair.h"
#include "SslSessionId.h"

/*
* These structures have been renamed, please use the revised convention SslXXX
*/
typedef SslKeyCertPair SSLKeyCertPair __attribute__((deprecated));
typedef SslSessionId SSLSessionId __attribute__((deprecated));
typedef SslFingerprints SSLFingerprints __attribute__((deprecated));

#endif /* SMINGCORE_NETWORK_SSL_SSLSTRUCTS_H_ */
2 changes: 1 addition & 1 deletion Sming/SmingCore/Network/TcpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ bool TcpClient::pinCertificate(const uint8_t* fingerprint, SslFingerprintType ty
return true;
}

bool TcpClient::pinCertificate(const SSLFingerprints& fingerprints)
bool TcpClient::pinCertificate(const SslFingerprints& fingerprints)
{
bool success = false;
if(fingerprints.certSha1 != nullptr) {
Expand Down
12 changes: 6 additions & 6 deletions Sming/SmingCore/Network/TcpClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "Delegate.h"

#ifdef ENABLE_SSL
#include "SslValidator.h"
#include "Ssl/SslValidator.h"
#endif

class TcpClient;
Expand Down Expand Up @@ -154,15 +154,15 @@ class TcpClient : public TcpConnection
bool pinCertificate(const uint8_t* fingerprint, SslFingerprintType type);

/**
* @brief Requires(pins) the remote SSL certificate to match certain fingerprints
* @brief Requires(pins) the remote SSL certificate to match certain fingerprints
*
* @note The data inside the fingerprints parameter is passed by reference
* @note The data inside the fingerprints parameter is passed by reference
*
* @param SSLFingerprints - passes the certificate fingerprints by reference.
* @param fingerprints - passes the certificate fingerprints by reference.
*
* @return bool true of success, false or failure
* @retval bool true of success, false or failure
*/
bool pinCertificate(const SSLFingerprints& fingerprints);
bool pinCertificate(const SslFingerprints& fingerprints);
#endif

protected:
Expand Down
Loading