|
| 1 | +NetworkClientSecure |
| 2 | +================ |
| 3 | + |
| 4 | +The NetworkClientSecure class implements support for secure connections using TLS (SSL). |
| 5 | +It inherits from NetworkClient and thus implements a superset of that class' interface. |
| 6 | +There are three ways to establish a secure connection using the NetworkClientSecure class: |
| 7 | +using a root certificate authority (CA) cert, using a root CA cert plus a client cert and key, |
| 8 | +and using a pre-shared key (PSK). |
| 9 | + |
| 10 | +Using a root certificate authority cert |
| 11 | +--------------------------------------- |
| 12 | +This method authenticates the server and negotiates an encrypted connection. |
| 13 | +It is the same functionality as implemented in your web browser when you connect to HTTPS sites. |
| 14 | + |
| 15 | +If you are accessing your own server: |
| 16 | +- Generate a root certificate for your own certificate authority |
| 17 | +- Generate a cert & private key using your root certificate ("self-signed cert") for your server |
| 18 | + |
| 19 | +If you are accessing a public server: |
| 20 | +- Obtain the cert of the public CA that signed that server's cert |
| 21 | +Then: |
| 22 | +- In NetworkClientSecure use setCACert (or the appropriate connect method) to set the root cert of your |
| 23 | + CA or of the public CA |
| 24 | +- When NetworkClientSecure connects to the target server it uses the CA cert to verify the certificate |
| 25 | + presented by the server, and then negotiates encryption for the connection |
| 26 | + |
| 27 | +Please see the NetworkClientSecure example. |
| 28 | + |
| 29 | +Using a bundle of root certificate authority certificates |
| 30 | +--------------------------------------------------------- |
| 31 | +This method is similar to the single root certificate verfication above, but it uses a standard set of |
| 32 | +root certificates from Mozilla to authenticate against, while the previous method only accepts a single |
| 33 | +certificate for a given server. This allows the client to connect to all public SSL servers. |
| 34 | + |
| 35 | +To use this feature in PlatformIO: |
| 36 | +1. create a certificate bundle as described in the document below, or obtain a pre-built one you trust: |
| 37 | +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_crt_bundle.html |
| 38 | +(gen_crt_bundle.py can be found in the /tools folder) |
| 39 | + a. note: the full bundle will take up around 64k of flash space, but has minimal RAM usage, as only |
| 40 | + the index of the certificates is kept in RAM |
| 41 | +2. Place the bundle under the file name "data/cert/x509_crt_bundle.bin" in your platformio project |
| 42 | +3. add "board_build.embed_files = data/cert/x509_crt_bundle.bin" in your platformio.ini |
| 43 | +4. add the following global declaration in your project: |
| 44 | + extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start"); |
| 45 | +5. before initiating the first SSL connection, call |
| 46 | + my_client.setCACertBundle(rootca_crt_bundle_start); |
| 47 | + |
| 48 | +To use this feature in Arduino IDE: |
| 49 | +If the Arduino IDE added support for embedding files in the meantime, then follow the instructions above. |
| 50 | +If not, you have three choices: |
| 51 | +1. convert your project to PlatformIO |
| 52 | +2. create a makefile where you can add the idf_component_register() declaration to include the certificate bundle |
| 53 | +3. Store the bundle as a SPIFFS file, but then you have to load it into RAM in runtime and waste 64k of precious memory |
| 54 | + |
| 55 | +Using a root CA cert and client cert/keys |
| 56 | +----------------------------------------- |
| 57 | +This method authenticates the server and additionally also authenticates |
| 58 | +the client to the server, then negotiates an encrypted connection. |
| 59 | + |
| 60 | +- Follow steps above |
| 61 | +- Using your root CA generate cert/key for your client |
| 62 | +- Register the keys with the server you will be accessing so the server can authenticate your client |
| 63 | +- In NetworkClientSecure use setCACert (or the appropriate connect method) to set the root cert of your |
| 64 | + CA or of the public CA, this is used to authenticate the server |
| 65 | +- In NetworkClientSecure use setCertificate, and setPrivateKey (or the appropriate connect method) to |
| 66 | + set your client's cert & key, this will be used to authenticate your client to the server |
| 67 | +- When NetworkClientSecure connects to the target server it uses the CA cert to verify the certificate |
| 68 | + presented by the server, it will use the cert/key to authenticate your client to the server, and |
| 69 | + it will then negotiate encryption for the connection |
| 70 | + |
| 71 | +Using Pre-Shared Keys (PSK) |
| 72 | +--------------------------- |
| 73 | + |
| 74 | +TLS supports authentication and encryption using a pre-shared key (i.e. a key that both client and |
| 75 | +server know) as an alternative to the public key cryptography commonly used on the web for HTTPS. |
| 76 | +PSK is starting to be used for MQTT, e.g. in mosquitto, to simplify the set-up and avoid having to |
| 77 | +go through the whole CA, cert, and private key process. |
| 78 | + |
| 79 | +A pre-shared key is a binary string of up to 32 bytes and is commonly represented in hex form. In |
| 80 | +addition to the key, clients can also present an id and typically the server allows a different key |
| 81 | +to be associated with each client id. In effect this is very similar to username and password pairs, |
| 82 | +except that unlike a password the key is not directly transmitted to the server, thus a connection to a |
| 83 | +malicious server does not divulge the password. Plus the server is also authenticated to the client. |
| 84 | + |
| 85 | +To use PSK: |
| 86 | +- Generate a random hex string (generating an MD5 or SHA for some file is one way to do this) |
| 87 | +- Come up with a string id for your client and configure your server to accept the id/key pair |
| 88 | +- In NetworkClientSecure use setPreSharedKey (or the appropriate connect method) to |
| 89 | + set the id/key combo |
| 90 | +- When NetworkClientSecure connects to the target server it uses the id/key combo to authenticate the |
| 91 | + server (it must prove that it has the key too), authenticate the client and then negotiate |
| 92 | + encryption for the connection |
| 93 | + |
| 94 | +Please see the NetworkClientPSK example. |
| 95 | + |
| 96 | +Specifying the ALPN Protocol |
| 97 | +---------------------------- |
| 98 | + |
| 99 | +Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension that allows |
| 100 | +the application layer to negotiate which protocol should be performed over a secure connection in a manner |
| 101 | +that avoids additional round trips and which is independent of the application-layer protocols. |
| 102 | + |
| 103 | +For example, this is used with AWS IoT Custom Authorizers where an MQTT client must set the ALPN protocol to ```mqtt```: |
| 104 | + |
| 105 | +``` |
| 106 | +const char *aws_protos[] = {"mqtt", NULL}; |
| 107 | +... |
| 108 | +wiFiClient.setAlpnProtocols(aws_protos); |
| 109 | +``` |
| 110 | + |
| 111 | +Examples |
| 112 | +-------- |
| 113 | +#### NetworkClientInsecure |
| 114 | +Demonstrates usage of insecure connection using `NetworkClientSecure::setInsecure()` |
| 115 | +#### NetworkClientPSK |
| 116 | +Wifi secure connection example for ESP32 using a pre-shared key (PSK) |
| 117 | +This is useful with MQTT servers instead of using a self-signed cert, tested with mosquitto. |
| 118 | +Running on TLS 1.2 using mbedTLS |
| 119 | +#### NetworkClientSecure |
| 120 | +Wifi secure connection example for ESP32 |
| 121 | +Running on TLS 1.2 using mbedTLS |
| 122 | +#### NetworkClientSecureEnterprise |
| 123 | +This example demonstrates a secure connection to a WiFi network using WPA/WPA2 Enterprise (for example eduroam), |
| 124 | +and establishing a secure HTTPS connection with an external server (for example arduino.php5.sk) using the defined anonymous identity, user identity, and password. |
| 125 | + |
| 126 | +.. note:: |
| 127 | + This example is outdated and might not work. For more examples see [https://github.com/martinius96/ESP32-eduroam](https://github.com/martinius96/ESP32-eduroam) |
| 128 | + |
| 129 | +#### NetworkClientShowPeerCredentials |
| 130 | +Example of a establishing a secure connection and then showing the fingerprint of the certificate. |
| 131 | +This can be useful in an IoT setting to know for sure that you are connecting to the right server. |
| 132 | +Especially in situations where you cannot hardcode a trusted root certificate for long |
| 133 | +periods of time (as they tend to get replaced more often than the lifecycle of IoT hardware). |
0 commit comments