Skip to content
Open
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
35 changes: 34 additions & 1 deletion libraries/WiFiS3/src/WiFiSSLClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ int WiFiSSLClient::connect(const char* host, uint16_t port) {
if(!modem.passthrough((uint8_t *)_ecc_cert, _ecc_cert_len)) {
return 0;
}
} else if(_client_cert != nullptr && _private_key != nullptr) { // TODO make sure if set certificate is called to not use the above code
size_t size = strlen(_client_cert);
modem.write_nowait(string(PROMPT(_SSLCLIENTSETCERT)),res, "%s%d,%d\r\n" , CMD_WRITE(_SSLCLIENTSETCERT), _sock, size);
if(!modem.passthrough((uint8_t *)_client_cert, size)) {
return 0;
}

size = strlen(_private_key);
modem.write_nowait(string(PROMPT(_SSLCLIENTSETPKEY)),res, "%s%d,%d\r\n" , CMD_WRITE(_SSLCLIENTSETPKEY), _sock, size);
if(!modem.passthrough((uint8_t *)_private_key, size)) {
return 0;
}
}

if (_connectionTimeout) {
Expand All @@ -88,6 +100,9 @@ void WiFiSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLen
_ecc_slot = ecc508KeySlot;
_ecc_cert = cert;
_ecc_cert_len = certLength;

_client_cert = nullptr;
_private_key = nullptr;
}

/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -282,4 +297,22 @@ uint16_t WiFiSSLClient::remotePort(){
}
}
return rv;
}
}

/* -------------------------------------------------------------------------- */
void WiFiSSLClient::setCertificate(const char* clientCert){
/* -------------------------------------------------------------------------- */
_client_cert = clientCert;
_ecc_slot = -1;
_ecc_cert = nullptr;
_ecc_cert_len = 0;
}

/* -------------------------------------------------------------------------- */
void WiFiSSLClient::setPrivateKey(const char* privateKey){
/* -------------------------------------------------------------------------- */
_private_key = privateKey;
_ecc_slot = -1;
_ecc_cert = nullptr;
_ecc_cert_len = 0;
}
102 changes: 65 additions & 37 deletions libraries/WiFiS3/src/WiFiSSLClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

/**
* @brief A specialized client class for secure SSL/TLS connections.
*
*
* The WiFiSSLClient class extends the functionality of the WiFiClient class to provide secure
* communication over SSL/TLS protocols. It ensures encrypted and authenticated communication
* between the client and a remote server.
Expand All @@ -43,50 +43,53 @@ class WiFiSSLClient : public WiFiClient {

/**
* @brief Establishes a secure SSL connection to a specified IP address and port.
*
*
* @param It takes an `IPAddress` object representing the IP address of the server
* and a `uint16_t` port number as parameters.
*
* @return Returns a status code indicating the success or failure of the
* @return Returns a status code indicating the success or failure of the
* connection.
*/
virtual int connect(IPAddress ip, uint16_t port);

/**
* @brief Establishes a secure SSL connection to a specified host and port.
*
*
* @param `host` is the hostname or IP address of the server to connect to.
* `port` is the port number to connect to.
*
*
* @return Returns `1` if the connection is successfully established, `0` otherwise.
*/
virtual int connect(const char* host, uint16_t port);

/**
* @brief Sets the Certificate Authority (CA) for SSL/TLS verification.
*
* @param `root_ca` is a pointer to a null-terminated string containing the root
* CA certificate in PEM format. If set to `nullptr`, the default root
* @param `root_ca` is a pointer to a null-terminated string containing the root
* CA certificate in PEM format. If set to `nullptr`, the default root
* CA bundle will be used.
*/
void setCACert(const char* root_ca);

/**
* @brief Sets the ECC (Elliptic Curve Cryptography) key slot and
* @brief Sets the ECC (Elliptic Curve Cryptography) key slot and
* certificate for establishing secure SSL connections.
*
*
* Note that this function will disable custom certificates and private keys set with
* setCertificate() and setPrivateKey()
*
* @param `int ecc508KeySlot` specifies the ECC key slot to be used for the SSL connection.
* @param `const byte cert[]` is a pointer to the certificate data in the form of an array of bytes.
* @param `int certLength` specifies the length of the certificate data array.
*/
void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength);

/**
* @brief Writes a single byte of data to the SSL connection.
*
*
* @param `b` is the byte to be sent.
*
* @return The number of bytes successfully written. Returns `1` if the byte
*
* @return The number of bytes successfully written. Returns `1` if the byte
* was sent successfully, or `0` if an error occurred.
*/
virtual size_t write(uint8_t);
Expand All @@ -97,22 +100,22 @@ class WiFiSSLClient : public WiFiClient {
* @param `buf` is a pointer to the buffer containing the data to be sent.
* @param `size` is the number of bytes to send from the buffer.
*
* @return Returns `size` if the data is successfully sent,
* @return Returns `size` if the data is successfully sent,
* or `0` if the transmission fails or the socket is invalid.
*/
virtual size_t write(const uint8_t *buf, size_t size);

/**
* @brief Checks the number of bytes available for reading from the SSL connection.
*
*
* @return Returns the number of bytes available to read from the SSL connection without blocking.
*/
virtual int available();

/**
* @brief Reads data from the SSL connection into the receive buffer.
*
* @return Returns the number of bytes successfully read into the buffer. Returns
* @return Returns the number of bytes successfully read into the buffer. Returns
* `0` if no data is received, or `-1` if the socket is invalid or an error occurs.
*/
virtual int read();
Expand All @@ -123,26 +126,26 @@ class WiFiSSLClient : public WiFiClient {
* @param `buf` is a pointer to the buffer where the read data will be stored.
* `size` is the maximum number of bytes to read into the buffer.
*
* @return The number of bytes successfully read. Returns `0` if no data is
* @return The number of bytes successfully read. Returns `0` if no data is
* available or an error occurs.
*/
virtual int read(uint8_t *buf, size_t size);

/**
* @brief Peeks at the next byte available from the SSL connection without removing it.
*
* This function queries the modem to retrieve the next byte available in the
* This function queries the modem to retrieve the next byte available in the
* SSL/TLS connection, allowing the byte to remain in the buffer for future reads.
*
* @return The next byte available as an integer value (0–255), or `-1` if
* @return The next byte available as an integer value (0–255), or `-1` if
* the socket is invalid or no data is available.
*/
virtual int peek();

/**
* @brief Flushes the write buffer of the SSL connection.
*
* This function clears the write buffer, ensuring that any pending data is sent
*
* This function clears the write buffer, ensuring that any pending data is sent
* over the SSL/TLS connection. It uses the modem to handle the flush operation.
*/
virtual void flush();
Expand All @@ -155,8 +158,8 @@ class WiFiSSLClient : public WiFiClient {
/**
* @brief Checks if the SSL/TLS connection is active.
*
* This function determines if the SSL/TLS client is still connected by querying
* the modem for the connection status. It checks the validity of the socket
* This function determines if the SSL/TLS client is still connected by querying
* the modem for the connection status. It checks the validity of the socket
* before proceeding with the query.
*
* @return Returns `1` if the client is connected, `0` otherwise.
Expand All @@ -165,7 +168,7 @@ class WiFiSSLClient : public WiFiClient {

/**
* @brief Implicit conversion operator to check if the SSL client is connected.
*
*
* @return `true` if the socket is valid (i.e., connected), `false` otherwise.
*/
virtual operator bool() {
Expand All @@ -174,20 +177,20 @@ class WiFiSSLClient : public WiFiClient {

/**
* @brief Comparison operator to check equality between two `WiFiSSLClient` objects.
*
*
* @param `WiFiSSLClient` object to compare.
*
*
* @return `true` if both WiFiSSLClient objects are equivalent (i.e., they have the same socket),
* `false` otherwise.
*/
virtual bool operator==(const WiFiSSLClient&);

/**
* @brief Inequality operator to compare two `WiFiSSLClient` objects.
*
*
* This operator compares the current `WiFiSSLClient` object with another `WiFiSSLClient` object
* to determine if they are not equal, based on their underlying socket or connection.
*
*
* @param `whs` The WiFiSSLClient object to compare with.
* @return `true` if the two WiFiSSLClient objects do not represent the same connection (i.e., have different sockets),
* `false` otherwise.
Expand All @@ -200,38 +203,61 @@ class WiFiSSLClient : public WiFiClient {
/**
* @brief Retrieves the remote IP address of the WiFi SSL client.
*
* This function queries the modem for the remote IP address associated with
* This function queries the modem for the remote IP address associated with
* the current connection.
*
* @return The remote IP address of the client. Returns `0.0.0.0` if the
* @return The remote IP address of the client. Returns `0.0.0.0` if the
* socket is not valid or the query fails.
*/
virtual IPAddress remoteIP();

/**
* @brief Retrieves the remote port number of the WiFi SSL client.
*
* This function queries the modem to obtain the remote port number associated
* This function queries the modem to obtain the remote port number associated
* with the current connection.
*
* @return Returns the remote port number of the client. Returns `0` if the socket
* @return Returns the remote port number of the client. Returns `0` if the socket
* is not valid or the query fails.
*/
virtual uint16_t remotePort();

/**
* @brief Set the public certificate for this ssl client communication
*
* This function explicitly sets the certificate to use for this client in tls
* communication. Note that if setEccSlot was used it will be disabled for this client.
* This function should be called in conjunction with setPrivateKey()
*
* @param `clientCert` client certificate in PEM format
*
*/
void setCertificate(const char* clientCert);

/**
* @brief Set the private key for this ssl client communication
*
* This function explicitly sets the private key to use for this client in tls
* communication. Note that if setEccSlot was used it will be disabled for this client.
* This function should be called in conjunction with setCertificate()
*
* @param `privateKey` client private key in PEM format
*
*/
void setPrivateKey(const char* privateKey);

/**
* @brief Declares WiFiServer as a friend class.
*
* This allows the WiFiServer class to access private and protected members
*
* This allows the WiFiServer class to access private and protected members
* of the WiFiSSLClient class.
*/
friend class WiFiServer;

/**
* @brief Inherits the `write` method from the Print class.
*
* This allows the WiFiSSLClient class to use the `write` method defined in the
*
* This allows the WiFiSSLClient class to use the `write` method defined in the
* Print class.
*/
using Print::write;
Expand All @@ -241,6 +267,8 @@ class WiFiSSLClient : public WiFiClient {
int _read();
void read_if_needed(size_t s);
const char* _root_ca = nullptr;
const char* _client_cert = nullptr;
const char* _private_key = nullptr;
int _ecc_slot = -1;
const byte* _ecc_cert = nullptr;
int _ecc_cert_len = 0;
Expand Down
Loading