Skip to content

Commit 15bbd0a

Browse files
authoredOct 25, 2021
Add ALPN support to WiFiClientSecure (#5633)
This adds a function to WiFiClientSecure to set the ALPN protocol. This is required for an MQTT client to connect to AWS IoT when using an AWS Custom Authorizer, as described here. Example code snippet: ... WiFiClientSecure wiFiClient; // ALPN protocol, needed with AWS custom authorizer const char *aws_protos[] = {"mqtt", NULL}; void setup() { wiFiClient.setCACert(AWSCAPEM); wiFiClient.setAlpnProtocols(aws_protos); } ...
1 parent 02c3ec0 commit 15bbd0a

File tree

6 files changed

+36
-4
lines changed

6 files changed

+36
-4
lines changed
 

‎libraries/WiFiClientSecure/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,18 @@ To use PSK:
6666
encryption for the connection
6767

6868
Please see the WiFiClientPSK example.
69+
70+
Specifying the ALPN Protocol
71+
----------------------------
72+
73+
Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension that allows
74+
the application layer to negotiate which protocol should be performed over a secure connection in a manner
75+
that avoids additional round trips and which is independent of the application-layer protocols.
76+
77+
For example, this is used with AWS IoT Custom Authorizers where an MQTT client must set the ALPN protocol to ```mqtt```:
78+
79+
```
80+
const char *aws_protos[] = {"mqtt", NULL};
81+
...
82+
wiFiClient.setAlpnProtocols(aws_protos);
83+
```

‎libraries/WiFiClientSecure/keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ connected KEYWORD2
2929
setCACert KEYWORD2
3030
setCertificate KEYWORD2
3131
setPrivateKey KEYWORD2
32+
setAlpnProtocols KEYWORD2
3233

3334
#######################################
3435
# Constants (LITERAL1)

‎libraries/WiFiClientSecure/src/WiFiClientSecure.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ WiFiClientSecure::WiFiClientSecure()
4343
_pskIdent = NULL;
4444
_psKey = NULL;
4545
next = NULL;
46+
_alpn_protos = NULL;
4647
}
4748

4849

@@ -66,6 +67,7 @@ WiFiClientSecure::WiFiClientSecure(int sock)
6667
_pskIdent = NULL;
6768
_psKey = NULL;
6869
next = NULL;
70+
_alpn_protos = NULL;
6971
}
7072

7173
WiFiClientSecure::~WiFiClientSecure()
@@ -127,7 +129,7 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_ce
127129
if(_timeout > 0){
128130
sslclient->handshake_timeout = _timeout;
129131
}
130-
int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure);
132+
int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos);
131133
_lastError = ret;
132134
if (ret < 0) {
133135
log_e("start_ssl_client: %d", ret);
@@ -147,7 +149,7 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskId
147149
if(_timeout > 0){
148150
sslclient->handshake_timeout = _timeout;
149151
}
150-
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure);
152+
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos);
151153
_lastError = ret;
152154
if (ret < 0) {
153155
log_e("start_ssl_client: %d", ret);
@@ -341,3 +343,8 @@ void WiFiClientSecure::setHandshakeTimeout(unsigned long handshake_timeout)
341343
{
342344
sslclient->handshake_timeout = handshake_timeout * 1000;
343345
}
346+
347+
void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos)
348+
{
349+
_alpn_protos = alpn_protos;
350+
}

‎libraries/WiFiClientSecure/src/WiFiClientSecure.h

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class WiFiClientSecure : public WiFiClient
3939
const char *_private_key;
4040
const char *_pskIdent; // identity for PSK cipher suites
4141
const char *_psKey; // key in hex for PSK cipher suites
42+
const char **_alpn_protos;
4243

4344
public:
4445
WiFiClientSecure *next;
@@ -73,6 +74,7 @@ class WiFiClientSecure : public WiFiClient
7374
bool loadPrivateKey(Stream& stream, size_t size);
7475
bool verify(const char* fingerprint, const char* domain_name);
7576
void setHandshakeTimeout(unsigned long handshake_timeout);
77+
void setAlpnProtocols(const char **alpn_protos);
7678
const mbedtls_x509_crt* getPeerCertificate() { return mbedtls_ssl_get_peer_cert(&sslclient->ssl_ctx); };
7779
bool getFingerprintSHA256(uint8_t sha256_result[32]) { return get_peer_fingerprint(sslclient, sha256_result); };
7880
int setTimeout(uint32_t seconds){ return 0; }

‎libraries/WiFiClientSecure/src/ssl_client.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void ssl_init(sslclient_context *ssl_client)
5151
}
5252

5353

54-
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)
54+
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)
5555
{
5656
char buf[512];
5757
int ret, flags;
@@ -156,6 +156,13 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
156156
return handle_error(ret);
157157
}
158158

159+
if (alpn_protos != NULL) {
160+
log_v("Setting ALPN protocols");
161+
if ((ret = mbedtls_ssl_conf_alpn_protocols(&ssl_client->ssl_conf, alpn_protos) ) != 0) {
162+
return handle_error(ret);
163+
}
164+
}
165+
159166
// MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
160167
// MBEDTLS_SSL_VERIFY_NONE if not.
161168

‎libraries/WiFiClientSecure/src/ssl_client.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ typedef struct sslclient_context {
2929

3030

3131
void ssl_init(sslclient_context *ssl_client);
32-
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);
32+
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);
3333
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
3434
int data_to_read(sslclient_context *ssl_client);
3535
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len);

0 commit comments

Comments
 (0)
Please sign in to comment.