Skip to content

Add ALPN support to WiFiClientSecure #5633

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

Merged
merged 3 commits into from
Oct 25, 2021
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
15 changes: 15 additions & 0 deletions libraries/WiFiClientSecure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,18 @@ To use PSK:
encryption for the connection

Please see the WiFiClientPSK example.

Specifying the ALPN Protocol
----------------------------

Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension that allows
the application layer to negotiate which protocol should be performed over a secure connection in a manner
that avoids additional round trips and which is independent of the application-layer protocols.

For example, this is used with AWS IoT Custom Authorizers where an MQTT client must set the ALPN protocol to ```mqtt```:

```
const char *aws_protos[] = {"mqtt", NULL};
...
wiFiClient.setAlpnProtocols(aws_protos);
```
1 change: 1 addition & 0 deletions libraries/WiFiClientSecure/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ connected KEYWORD2
setCACert KEYWORD2
setCertificate KEYWORD2
setPrivateKey KEYWORD2
setAlpnProtocols KEYWORD2

#######################################
# Constants (LITERAL1)
Expand Down
11 changes: 9 additions & 2 deletions libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ WiFiClientSecure::WiFiClientSecure()
_pskIdent = NULL;
_psKey = NULL;
next = NULL;
_alpn_protos = NULL;
}


Expand All @@ -66,6 +67,7 @@ WiFiClientSecure::WiFiClientSecure(int sock)
_pskIdent = NULL;
_psKey = NULL;
next = NULL;
_alpn_protos = NULL;
}

WiFiClientSecure::~WiFiClientSecure()
Expand Down Expand Up @@ -127,7 +129,7 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_ce
if(_timeout > 0){
sslclient->handshake_timeout = _timeout;
}
int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure);
int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos);
_lastError = ret;
if (ret < 0) {
log_e("start_ssl_client: %d", ret);
Expand All @@ -147,7 +149,7 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskId
if(_timeout > 0){
sslclient->handshake_timeout = _timeout;
}
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure);
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos);
_lastError = ret;
if (ret < 0) {
log_e("start_ssl_client: %d", ret);
Expand Down Expand Up @@ -341,3 +343,8 @@ void WiFiClientSecure::setHandshakeTimeout(unsigned long handshake_timeout)
{
sslclient->handshake_timeout = handshake_timeout * 1000;
}

void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos)
{
_alpn_protos = alpn_protos;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_alpn_protos must be set to NULL in the class constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, have added that here: 00da95f

}
2 changes: 2 additions & 0 deletions libraries/WiFiClientSecure/src/WiFiClientSecure.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class WiFiClientSecure : public WiFiClient
const char *_private_key;
const char *_pskIdent; // identity for PSK cipher suites
const char *_psKey; // key in hex for PSK cipher suites
const char **_alpn_protos;

public:
WiFiClientSecure *next;
Expand Down Expand Up @@ -73,6 +74,7 @@ class WiFiClientSecure : public WiFiClient
bool loadPrivateKey(Stream& stream, size_t size);
bool verify(const char* fingerprint, const char* domain_name);
void setHandshakeTimeout(unsigned long handshake_timeout);
void setAlpnProtocols(const char **alpn_protos);
const mbedtls_x509_crt* getPeerCertificate() { return mbedtls_ssl_get_peer_cert(&sslclient->ssl_ctx); };
bool getFingerprintSHA256(uint8_t sha256_result[32]) { return get_peer_fingerprint(sslclient, sha256_result); };
int setTimeout(uint32_t seconds){ return 0; }
Expand Down
9 changes: 8 additions & 1 deletion libraries/WiFiClientSecure/src/ssl_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void ssl_init(sslclient_context *ssl_client)
}


int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure)
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos)
{
char buf[512];
int ret, flags;
Expand Down Expand Up @@ -156,6 +156,13 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
return handle_error(ret);
}

if (alpn_protos != NULL) {
log_v("Setting ALPN protocols");
if ((ret = mbedtls_ssl_conf_alpn_protocols(&ssl_client->ssl_conf, alpn_protos) ) != 0) {
return handle_error(ret);
}
}

// MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
// MBEDTLS_SSL_VERIFY_NONE if not.

Expand Down
2 changes: 1 addition & 1 deletion libraries/WiFiClientSecure/src/ssl_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ typedef struct sslclient_context {


void ssl_init(sslclient_context *ssl_client);
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure);
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos);
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
int data_to_read(sslclient_context *ssl_client);
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len);
Expand Down